Add wooden hopper inventory interaction
This commit is contained in:
parent
3d305dd890
commit
c7a2c7f0f4
|
@ -1,10 +1,155 @@
|
|||
package net.shadowfacts.extrahoppers.block.wood
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity
|
||||
import net.minecraft.block.entity.Hopper
|
||||
import net.minecraft.block.entity.HopperBlockEntity
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.inventory.Inventories
|
||||
import net.minecraft.inventory.Inventory
|
||||
import net.minecraft.inventory.SidedInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.util.DefaultedList
|
||||
import net.minecraft.util.Tickable
|
||||
import net.minecraft.util.math.Direction
|
||||
import net.shadowfacts.extrahoppers.init.EHBlockEntities
|
||||
import net.shadowfacts.extrahoppers.util.toVec3d
|
||||
|
||||
class WoodHopperBlockEntity: BlockEntity(EHBlockEntities.WOOD_HOPPER), Tickable {
|
||||
override fun tick() {
|
||||
class WoodHopperBlockEntity: BlockEntity(EHBlockEntities.WOOD_HOPPER), Inventory, Hopper, Tickable {
|
||||
companion object {
|
||||
val TRANSFER_COOLDOWN = 40
|
||||
}
|
||||
}
|
||||
|
||||
var inventory: DefaultedList<ItemStack> = DefaultedList.ofSize(1, ItemStack.EMPTY)
|
||||
private set
|
||||
var transferCooldown = -1
|
||||
var lastTickTime = 0L
|
||||
|
||||
override fun toTag(tag: CompoundTag): CompoundTag {
|
||||
Inventories.toTag(tag, inventory)
|
||||
tag.putInt("transferCooldown", transferCooldown)
|
||||
return super.toTag(tag)
|
||||
}
|
||||
|
||||
override fun fromTag(tag: CompoundTag) {
|
||||
super.fromTag(tag)
|
||||
inventory.clear()
|
||||
Inventories.fromTag(tag, inventory)
|
||||
transferCooldown = tag.getInt("transferCooldown")
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
val world = world
|
||||
if (world == null || world.isClient) return
|
||||
|
||||
transferCooldown -= 1
|
||||
lastTickTime = world.time
|
||||
if (transferCooldown <= 0) {
|
||||
transferCooldown = 0
|
||||
insertAndExtract()
|
||||
}
|
||||
}
|
||||
|
||||
fun insertAndExtract() {
|
||||
val world = world
|
||||
if (world == null || world.isClient) return
|
||||
|
||||
var didWork = false
|
||||
if (!isInvEmpty && insert()) {
|
||||
didWork = true
|
||||
}
|
||||
if (!isFull() && HopperBlockEntity.extract(this)) {
|
||||
didWork = true
|
||||
}
|
||||
|
||||
if (didWork) {
|
||||
transferCooldown = TRANSFER_COOLDOWN
|
||||
markDirty()
|
||||
}
|
||||
}
|
||||
|
||||
fun insert(): Boolean {
|
||||
val outputInv = getOutputInventory() ?: return false
|
||||
|
||||
val insertionSide = cachedState.get(WoodHopperBlock.FACING).opposite
|
||||
if (isInventoryFull(outputInv, insertionSide)) return false
|
||||
|
||||
for (slot in 0 until invSize) {
|
||||
if (getInvStack(slot).isEmpty) continue
|
||||
|
||||
val stackCopy = getInvStack(slot).copy()
|
||||
|
||||
val remaining = HopperBlockEntity.transfer(this, outputInv, takeInvStack(slot, 1), insertionSide)
|
||||
if (remaining.isEmpty) {
|
||||
outputInv.markDirty()
|
||||
return true
|
||||
}
|
||||
|
||||
setInvStack(slot, stackCopy)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun isFull(): Boolean {
|
||||
return inventory.none(ItemStack::isEmpty)
|
||||
}
|
||||
|
||||
fun getOutputInventory(): Inventory? {
|
||||
val facing = cachedState.get(WoodHopperBlock.FACING)
|
||||
return HopperBlockEntity.getInventoryAt(world!!, pos.offset(facing))
|
||||
}
|
||||
|
||||
fun inventorySlots(inv: Inventory, side: Direction): Sequence<Int> {
|
||||
return if (inv is SidedInventory) {
|
||||
inv.getInvAvailableSlots(side).asSequence()
|
||||
} else {
|
||||
(0 until inv.invSize).asSequence()
|
||||
}
|
||||
}
|
||||
|
||||
fun isInventoryFull(inv: Inventory, side: Direction): Boolean {
|
||||
val slots = inventorySlots(inv, side)
|
||||
return slots.map(inv::getInvStack).none(ItemStack::isEmpty)
|
||||
}
|
||||
|
||||
// Inventory
|
||||
|
||||
override fun getInvSize() = inventory.size
|
||||
|
||||
override fun takeInvStack(slot: Int, amount: Int): ItemStack {
|
||||
return Inventories.splitStack(inventory, slot, amount)
|
||||
}
|
||||
|
||||
override fun isInvEmpty() = inventory.isEmpty()
|
||||
|
||||
override fun getInvStack(slot: Int) = inventory[slot]
|
||||
|
||||
override fun clear() {
|
||||
inventory.clear()
|
||||
}
|
||||
|
||||
override fun setInvStack(slot: Int, stack: ItemStack) {
|
||||
inventory[slot] = stack
|
||||
}
|
||||
|
||||
override fun removeInvStack(slot: Int): ItemStack {
|
||||
return Inventories.removeStack(inventory, slot)
|
||||
}
|
||||
|
||||
override fun canPlayerUseInv(player: PlayerEntity): Boolean {
|
||||
return if (world?.getBlockEntity(pos) != this) {
|
||||
false
|
||||
} else {
|
||||
val distance = player.squaredDistanceTo(this.pos.toVec3d())
|
||||
distance < 64
|
||||
}
|
||||
}
|
||||
|
||||
// Hopper
|
||||
|
||||
override fun getHopperX() = pos.x.toDouble()
|
||||
override fun getHopperY() = pos.y.toDouble()
|
||||
override fun getHopperZ() = pos.z.toDouble()
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package net.shadowfacts.extrahoppers.util
|
||||
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.Vec3d
|
||||
|
||||
fun BlockPos.toVec3d(): Vec3d {
|
||||
return Vec3d(x + 0.5, y + 0.5, z + 0.5)
|
||||
}
|
Loading…
Reference in New Issue