diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageBusBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageBusBlockEntity.kt index 6515312cb..25277c481 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageBusBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageBusBlockEntity.kt @@ -66,6 +66,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter val filter = ItemFilter(MAX_FILTERS) { _, _, _ -> component?.scan() + setChangedLight() } override fun setLevel(p_155231_: Level) { @@ -122,7 +123,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter override fun load(nbt: CompoundTag) { super.load(nbt) - nbt.ifHas("filter", ListTag::class.java, filter::deserializeNBT) + nbt.ifHas("filter", CompoundTag::class.java, filter::deserializeNBT) } fun checkSurroundings() { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageInterfaces.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageInterfaces.kt index dc5f62ad6..262f2bfa7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageInterfaces.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageInterfaces.kt @@ -10,6 +10,7 @@ import net.minecraft.server.level.ServerLevel import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu +import net.minecraft.world.item.ItemStack import net.minecraft.world.level.Level import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState @@ -100,12 +101,14 @@ abstract class AbstractStorageImportExport( } } -class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractStorageImportExport(MBlockEntities.STORAGE_IMPORTER, blockPos, blockState) { +class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) + : AbstractStorageImportExport(MBlockEntities.STORAGE_IMPORTER, blockPos, blockState), + IItemHandler { override val defaultDisplayName: Component get() = MACHINE_NAME val filter = ItemFilter(MAX_FILTERS) { _, _, _ -> - + setChangedLight() } override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { @@ -129,7 +132,69 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : A override fun load(nbt: CompoundTag) { super.load(nbt) - nbt.ifHas("filter", ListTag::class.java, filter::deserializeNBT) + nbt.ifHas("filter", CompoundTag::class.java, filter::deserializeNBT) + } + + private var valid = true + private var resolverItemHandler = LazyOptional.of { this } + + override fun invalidateCaps() { + super.invalidateCaps() + resolverItemHandler.invalidate() + valid = false + } + + override fun reviveCaps() { + super.reviveCaps() + resolverItemHandler = LazyOptional.of { this } + valid = true + } + + override fun getCapability(cap: Capability, side: Direction?): LazyOptional { + if (valid && cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && side == blockState.getValue(RotatableMatteryBlock.FACING_FULL)) { + return resolverItemHandler.cast() + } + + return super.getCapability(cap, side) + } + + override fun getSlots(): Int { + return 1 + } + + override fun getStackInSlot(slot: Int): ItemStack { + return ItemStack.EMPTY + } + + override fun insertItem(slot: Int, stack: ItemStack, simulate: Boolean): ItemStack { + if (!filter.match(stack)) + return stack + + val view = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return stack + val maxMove = energy.extractStepInner(ITEM_STORAGE.energyPerOperation, stack.count, true) + + if (maxMove == 0) + return stack + + val leftover = view.insertStack(ItemStackWrapper(stack).also { it.count = maxMove.toImpreciseFraction() }, simulate) + + if (simulate) + return leftover.stack + + energy.extractStepInner(ITEM_STORAGE.energyPerOperation, maxMove - leftover.count.toInt(), false) + return leftover.stack + } + + override fun extractItem(slot: Int, amount: Int, simulate: Boolean): ItemStack { + return ItemStack.EMPTY + } + + override fun getSlotLimit(slot: Int): Int { + return Int.MAX_VALUE + } + + override fun isItemValid(slot: Int, stack: ItemStack): Boolean { + return filter.match(stack) } fun tick() { @@ -140,7 +205,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : A if (nextTick <= 0 && target.isPresent && enoughEnergy) { val graph = cell.storageGraph ?: return - val items = graph.getVirtualComponent(OverdriveThatMatters.INSTANCE.ITEM_STORAGE()) + val items = graph.getVirtualComponent(ITEM_STORAGE) val resolved = target.orThrow() @@ -217,6 +282,8 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : } lastSlot = 0 + + setChangedLight() }.also { it.isWhitelist = true } private var lastSlot = 0 @@ -241,7 +308,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : override fun load(nbt: CompoundTag) { super.load(nbt) - nbt.ifHas("filter", ListTag::class.java, filter::deserializeNBT) + nbt.ifHas("filter", CompoundTag::class.java, filter::deserializeNBT) } fun tick() { @@ -263,6 +330,10 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : var hit = false for (stack in exportStacks) { + if (!resolved.isItemValid(lastSlot, stack.second.item)) { + continue + } + val exportAmountA = items.extractStack(stack.first, stack.second.count.toInt().coerceAtMost(MAX_MOVE_PER_OPERATION).toImpreciseFraction(), true).count.toInt() if (exportAmountA == 0) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt index dbc5855a8..15b58b1a4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/ItemFilter.kt @@ -9,7 +9,9 @@ import net.minecraftforge.common.util.INBTSerializable import net.minecraftforge.network.NetworkEvent import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.ifHas import ru.dbotthepony.mc.otm.menu.MatteryMenu +import ru.dbotthepony.mc.otm.set import java.util.LinkedList import java.util.function.Supplier @@ -78,7 +80,7 @@ data class ItemFilterNetworkSlot(val slotID: Int, val networkID: Int, val filter class ItemFilter( val size: Int, private val modified: (slot: Int?, oldValue: ItemStack?, newValue: ItemStack?) -> Unit -) : INBTSerializable { +) : INBTSerializable { private val filter = Array(size) { ItemStack.EMPTY } private val linkedFilter = LinkedList() @@ -139,25 +141,33 @@ class ItemFilter( return true } - override fun serializeNBT(): ListTag { - return ListTag().also { - for (value in filter) { - it.add(value.serializeNBT()) + override fun serializeNBT(): CompoundTag { + return CompoundTag().also { + it["items"] = ListTag().also { + for (value in filter) { + it.add(value.serializeNBT()) + } } + + it["is_whitelist"] = isWhitelist } } - override fun deserializeNBT(nbt: ListTag?) { + override fun deserializeNBT(nbt: CompoundTag?) { for (i in filter.indices) filter[i] = ItemStack.EMPTY if (nbt == null) return - for ((i, value) in nbt.withIndex()) { - if (value is CompoundTag) { - filter[i] = ItemStack.of(value) + nbt.ifHas("items", ListTag::class.java) { + for ((i, value) in it.withIndex()) { + if (value is CompoundTag) { + filter[i] = ItemStack.of(value) + } } } + + isWhitelist = nbt.getBoolean("is_whitelist") } }