Add wooden hopper inventory interaction

This commit is contained in:
Shadowfacts 2020-03-28 00:00:23 -04:00
parent 3d305dd890
commit c7a2c7f0f4
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
2 changed files with 156 additions and 3 deletions

View File

@ -1,10 +1,155 @@
package net.shadowfacts.extrahoppers.block.wood package net.shadowfacts.extrahoppers.block.wood
import net.minecraft.block.entity.BlockEntity 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.Tickable
import net.minecraft.util.math.Direction
import net.shadowfacts.extrahoppers.init.EHBlockEntities import net.shadowfacts.extrahoppers.init.EHBlockEntities
import net.shadowfacts.extrahoppers.util.toVec3d
class WoodHopperBlockEntity: BlockEntity(EHBlockEntities.WOOD_HOPPER), Tickable { class WoodHopperBlockEntity: BlockEntity(EHBlockEntities.WOOD_HOPPER), Inventory, Hopper, Tickable {
override fun tick() { 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()
}

View File

@ -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)
}