From 66a4adecf924a05d39c11a8080a061552d8e658b Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sat, 1 Mar 2025 00:06:07 +0700 Subject: [PATCH] Move Fluid tank to SlottedContainer, and make it accept slot filters --- .../entity/decorative/FluidTankBlockEntity.kt | 103 +++++++----- .../screen/decorative/FluidTankScreen.kt | 5 +- .../otm/container/slotted/AutomationFilter.kt | 50 ++++++ .../container/slotted/AutomationFilters.kt | 146 ++++++++++++++++++ .../mc/otm/container/slotted/ContainerSlot.kt | 14 +- .../slotted/FilteredContainerSlot.kt | 7 + .../otm/container/slotted/SimpleCallbacks.kt | 19 --- .../mc/otm/menu/decorative/FluidTankMenu.kt | 12 +- 8 files changed, 288 insertions(+), 68 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilter.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilters.kt delete mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/SimpleCallbacks.kt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt index d6b669f68..8f8a2a83d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt @@ -21,6 +21,11 @@ import ru.dbotthepony.mc.otm.config.ItemsConfig import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.get +import ru.dbotthepony.mc.otm.container.slotted.AutomationFilter +import ru.dbotthepony.mc.otm.container.slotted.AutomationFilters +import ru.dbotthepony.mc.otm.container.slotted.ContainerSlot +import ru.dbotthepony.mc.otm.container.slotted.FilteredContainerSlot +import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotSameAs import ru.dbotthepony.mc.otm.menu.decorative.FluidTankMenu @@ -37,28 +42,42 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery } }), FluidStack.OPTIONAL_STREAM_CODEC.wrap())) - val fillInput = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer) - val drainInput = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer) - val output = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer) + private inner class FillSlot(container: SlottedContainer, slot: Int) : FilteredContainerSlot(container, slot) { + override fun canAutomationPlaceItem(itemStack: ItemStack): Boolean { + if (!super.canAutomationPlaceItem(itemStack)) + return false + + if (fluid.isEmpty) { + return itemStack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.tanks > 0 } ?: false + } + + return itemStack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.fill(fluid[0], IFluidHandler.FluidAction.SIMULATE) > 0 } ?: false + } + + override fun canAutomationTakeItem(desired: Int): Boolean { + return super.canAutomationTakeItem(desired) && !canAutomationPlaceItem(item) + } + } + + val inputContainer = SlottedContainer.Builder() + .add(DRAIN_TAG, AutomationFilters.DRAINABLE_FLUID_CONTAINERS.filteredProvider) + .add(FILL_TAG, ::FillSlot) + .onChanged(::markDirtyFast) + .build() + .also(::addDroppableContainer) + + val outputContainer = SlottedContainer.Builder() + .add(AutomationFilters.ONLY_OUT.simpleProvider) + .onChanged(::markDirtyFast) + .build() + .also(::addDroppableContainer) + + private val fillSlot = inputContainer[FILL_TAG] + private val drainSlot = inputContainer[DRAIN_TAG] val itemConfig = ConfigurableItemHandler( - input = CombinedItemHandler( - drainInput.handler(HandlerFilter.DrainableFluidContainers), - fillInput.handler(object : HandlerFilter { - override fun canInsert(slot: Int, stack: ItemStack): Boolean { - if (fluid.isEmpty) { - return stack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.tanks > 0 } ?: false - } - - return stack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.fill(fluid[0], IFluidHandler.FluidAction.SIMULATE) > 0 } ?: false - } - - override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - return !canInsert(slot, stack) - } - }) - ), - output = output.handler(HandlerFilter.OnlyOut), + input = inputContainer, + output = outputContainer, frontDefault = ItemHandlerMode.INPUT_OUTPUT, backDefault = ItemHandlerMode.INPUT_OUTPUT, leftDefault = ItemHandlerMode.INPUT_OUTPUT, @@ -71,20 +90,19 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery init { savetables.stateful(::fluid, FLUID_KEY) - savetables.stateful(::fillInput) - savetables.stateful(::drainInput) - savetables.stateful(::output) + savetables.stateful(::inputContainer) + savetables.stateful(::outputContainer) } private fun drainItem() { - val item = drainInput[0] + val item = drainSlot.item if (item.isNotEmpty) { val cap = (if (item.count == 1) item else item.copyWithCount(1)).getCapability(Capabilities.FluidHandler.ITEM) if (cap == null) { - if (output.consumeItem(item, simulate = false)) { - drainInput.setChanged(0) + if (outputContainer.consumeItem(item, simulate = false)) { + drainSlot.setChanged() } return @@ -95,17 +113,17 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery val moved0 = moveFluid(source = cap, destination = fluid) if (moved0.isNotEmpty) { - drainInput[0] = cap.container + drainSlot.item = cap.container - if (output.consumeItem(drainInput[0], simulate = false)) { - drainInput.setChanged(0) + if (outputContainer.consumeItem(drainSlot.item, simulate = false)) { + drainSlot.setChanged() } } } else { val moved0 = moveFluid(source = cap, destination = fluid, actuallyFill = false) if (moved0.isNotEmpty) { - if (output.consumeItem(cap.container, simulate = true)) { + if (outputContainer.consumeItem(cap.container, simulate = true)) { val cap1 = item.copyWithCount(1).getCapability(Capabilities.FluidHandler.ITEM) ?: throw ConcurrentModificationException() val moved1 = moveFluid(source = cap1, destination = fluid) @@ -114,9 +132,9 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery LOGGER.error("Error moving fluids in Fluid tank at $blockPos: moved $moved0 during simulation from ${cap.container}, moved $moved1 from ${cap1.container} during execution. This is likely a bug in OTM or other mod!") } else { item.count-- - drainInput.setChanged(0) + drainSlot.setChanged() - if (!output.consumeItem(cap1.container, simulate = false)) { + if (!outputContainer.consumeItem(cap1.container, simulate = false)) { LOGGER.error("Unable to insert ${cap1.container} into output slot of Fluid tank at $blockPos, popping item in world instead to avoid item loss! This is likely a bug in OTM or other mod!") (level as? ServerLevel)?.addFreshEntity(ItemEntity(level!!, blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(), cap1.container)) } @@ -129,14 +147,14 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery } private fun fillItem() { - val item = fillInput[0] + val item = fillSlot.item if (item.isNotEmpty) { val cap = (if (item.count == 1) item else item.copyWithCount(1)).getCapability(Capabilities.FluidHandler.ITEM) if (cap == null) { - if (output.consumeItem(item, simulate = false)) { - fillInput.setChanged(0) + if (outputContainer.consumeItem(item, simulate = false)) { + fillSlot.setChanged() } return @@ -147,17 +165,17 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery val moved0 = moveFluid(source = fluid, destination = cap) if (moved0.isNotEmpty) { - fillInput[0] = cap.container + fillSlot.item = cap.container - if (output.consumeItem(fillInput[0], simulate = false)) { - fillInput.setChanged(0) + if (outputContainer.consumeItem(fillSlot.item, simulate = false)) { + fillSlot.setChanged() } } } else { val moved0 = moveFluid(source = fluid, destination = cap, actuallyDrain = false) if (moved0.isNotEmpty) { - if (output.consumeItem(cap.container, simulate = true)) { + if (outputContainer.consumeItem(cap.container, simulate = true)) { val cap1 = item.copyWithCount(1).getCapability(Capabilities.FluidHandler.ITEM) ?: throw ConcurrentModificationException() val moved1 = moveFluid(source = fluid, destination = cap1) @@ -166,9 +184,9 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery LOGGER.error("Error moving fluids in Fluid tank at $blockPos: moved $moved0 during simulation from ${cap.container}, moved $moved1 from ${cap1.container} during execution. This is likely a bug in OTM or other mod!") } else { item.count-- - fillInput.setChanged(0) + fillSlot.setChanged() - if (!output.consumeItem(cap1.container, simulate = false)) { + if (!outputContainer.consumeItem(cap1.container, simulate = false)) { LOGGER.error("Unable to insert ${cap1.container} into output slot of Fluid tank at $blockPos, popping item in world instead to avoid item loss! This is likely a bug in OTM or other mod!") (level as? ServerLevel)?.addFreshEntity(ItemEntity(level!!, blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(), cap1.container)) } @@ -194,5 +212,8 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery companion object { const val FLUID_KEY = "fluid" private val LOGGER = LogManager.getLogger() + + private val FILL_TAG = SlottedContainer.tag() + private val DRAIN_TAG = SlottedContainer.tag() } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/FluidTankScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/FluidTankScreen.kt index 1027ce7f7..058b7a3a3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/FluidTankScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/decorative/FluidTankScreen.kt @@ -12,6 +12,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.makeCuriosPanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel import ru.dbotthepony.mc.otm.client.screen.panels.SpritePanel +import ru.dbotthepony.mc.otm.client.screen.panels.slot.UserFilteredSlotPanel import ru.dbotthepony.mc.otm.client.screen.widget.FluidGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel import ru.dbotthepony.mc.otm.menu.decorative.FluidTankMenu @@ -25,8 +26,8 @@ class FluidTankScreen(menu: FluidTankMenu, inventory: Inventory, title: Componen val s = SpritePanel(this, frame, ProgressGaugePanel.GAUGE_BACKGROUND, x = 30f, y = 30f) SpritePanel(this, frame, ProgressGaugePanel.GAUGE_BACKGROUND, x = 30f, y = 55f, winding = UVWindingOrder.FLOP) - SlotPanel(this, frame, menu.fillInput, x = 30f + s.width + 4f, y = 28f) - SlotPanel(this, frame, menu.drainInput, x = 30f + s.width + 4f, y = 53f) + UserFilteredSlotPanel(this, frame, menu.fillInput, x = 30f + s.width + 4f, y = 28f) + UserFilteredSlotPanel(this, frame, menu.drainInput, x = 30f + s.width + 4f, y = 53f) SlotPanel(this, frame, menu.output, x = 30f + s.width + 4f + 20f, y = 53f) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilter.kt new file mode 100644 index 000000000..c7cf2bf35 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilter.kt @@ -0,0 +1,50 @@ +package ru.dbotthepony.mc.otm.container.slotted + +import net.minecraft.world.item.ItemStack + +fun interface AutomationPlaceItem { + fun canAutomationPlaceItem(self: S, itemStack: ItemStack): Boolean +} + +fun interface AutomationTakeItem { + fun canAutomationTakeItem(self: S, desired: Int): Boolean +} + +fun interface AutomationModifyPlaceCount { + fun modifyAutomationPlaceCount(self: S, itemStack: ItemStack): Int +} + +fun interface AutomationModifyExtractionCount { + fun modifyAutomationExtractionCount(self: S, desired: Int): Int +} + +interface AutomationFilter : AutomationPlaceItem, AutomationTakeItem, AutomationModifyPlaceCount, AutomationModifyExtractionCount { + override fun modifyAutomationPlaceCount(self: S, itemStack: ItemStack): Int { + return itemStack.count + } + + override fun modifyAutomationExtractionCount(self: S, desired: Int): Int { + return desired + } +} + +fun AutomationFilter.and(other: AutomationFilter): AutomationFilter { + return object : AutomationFilter { + override fun canAutomationPlaceItem(self: T, itemStack: ItemStack): Boolean { + return this@and.canAutomationPlaceItem(self, itemStack) && other.canAutomationPlaceItem(self, itemStack) + } + + override fun canAutomationTakeItem(self: T, desired: Int): Boolean { + return this@and.canAutomationTakeItem(self, desired) && other.canAutomationTakeItem(self, desired) + } + + override fun modifyAutomationPlaceCount(self: T, itemStack: ItemStack): Int { + return this@and.modifyAutomationPlaceCount(self, itemStack) + } + + override fun modifyAutomationExtractionCount(self: T, desired: Int): Int { + return this@and.modifyAutomationExtractionCount(self, desired) + } + } +} + diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilters.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilters.kt new file mode 100644 index 000000000..aa7602ba5 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/AutomationFilters.kt @@ -0,0 +1,146 @@ +package ru.dbotthepony.mc.otm.container.slotted + +import net.minecraft.world.item.ItemStack +import net.neoforged.neoforge.capabilities.Capabilities +import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.capability.fluid.stream +import ru.dbotthepony.mc.otm.core.isNotEmpty +import ru.dbotthepony.mc.otm.core.math.Decimal + +enum class AutomationFilters : AutomationFilter { + ONLY_OUT { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return true + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return false + } + }, + + ONLY_IN { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return false + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return true + } + }, + + ALLOW { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return true + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return true + } + }, + + DENY { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return false + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return false + } + }, + + FLUID_CONTAINERS { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return itemStack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.tanks > 0 } ?: false + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return true + } + }, + + DRAINABLE_FLUID_CONTAINERS { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return itemStack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.stream().anyMatch { it.isNotEmpty } } ?: false + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return !canAutomationPlaceItem(self, self.item) + } + }, + + DICHARGEABLE { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return itemStack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { it.canExtract() && it.extractEnergy(Int.MAX_VALUE, true) > 0 } ?: false + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return self.item.getCapability(Capabilities.EnergyStorage.ITEM)?.let { !it.canExtract() || it.extractEnergy(Int.MAX_VALUE, true) <= 0 } ?: true + } + }, + + CHARGEABLE { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return itemStack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { it.canReceive() && it.receiveEnergy(Int.MAX_VALUE, true) > 0 } ?: false + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return self.item.getCapability(Capabilities.EnergyStorage.ITEM)?.let { !it.canReceive() || it.receiveEnergy(Int.MAX_VALUE, true) <= 0 } ?: true + } + }, + + CHEMICAL_FUEL { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return itemStack.getBurnTime(null) > 0 + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return self.item.getBurnTime(null) <= 0 + } + }, + + IS_PATTERN { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return itemStack.getCapability(MatteryCapability.PATTERN_ITEM) != null + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return true + } + }, + + MATTER_PROVIDERS { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return itemStack.getCapability(MatteryCapability.MATTER_ITEM) + ?.let { it.matterFlow.output && it.extractMatterChecked(Decimal.POSITIVE_INFINITY, true) > Decimal.ZERO } + ?: false + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return self.item.getCapability(MatteryCapability.MATTER_ITEM) + ?.let { !it.matterFlow.output || it.extractMatterChecked(Decimal.POSITIVE_INFINITY, true) <= Decimal.ZERO } + ?: true + } + }, + + MATTER_CONSUMERS { + override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean { + return itemStack.getCapability(MatteryCapability.MATTER_ITEM) + ?.let { it.matterFlow.input && it.receiveMatterChecked(Decimal.POSITIVE_INFINITY, true) > Decimal.ZERO } + ?: false + } + + override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean { + return self.item.getCapability(MatteryCapability.MATTER_ITEM) + ?.let { !it.matterFlow.input || it.receiveMatterChecked(Decimal.POSITIVE_INFINITY, true) <= Decimal.ZERO } + ?: true + } + }; + + val simpleProvider: SlottedContainer.SlotProvider by lazy { + ContainerSlot.Simple(filter = this) + } + + val filteredProvider: SlottedContainer.SlotProvider by lazy { + FilteredContainerSlot.Simple(filter = this) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/ContainerSlot.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/ContainerSlot.kt index 18109d9be..62780ee8c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/ContainerSlot.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/ContainerSlot.kt @@ -52,7 +52,13 @@ open class ContainerSlot( } fun observeChanges(): Boolean { - if (observedItem.count != item.count || !ItemStack.isSameItemSameComponents(item, observedItem)) { + if (observedItem.isNotEmpty && item.isEmpty) { + notifyChanged(observedItem) + observedItem = ItemStack.EMPTY + _item = ItemStack.EMPTY + container.notifyChanged() + return true + } else if (observedItem.count != item.count || !ItemStack.isSameItemSameComponents(item, observedItem)) { notifyChanged(observedItem) observedItem = item.copy() container.notifyChanged() @@ -117,6 +123,12 @@ open class ContainerSlot( private val modifyAutomationPlaceCount: AutomationModifyPlaceCount = AutomationModifyPlaceCount { _, item -> item.count }, private val modifyAutomationExtractionCount: AutomationModifyExtractionCount = AutomationModifyExtractionCount { _, desired -> desired }, ) : SlottedContainer.SlotProvider { + constructor( + listener: (new: ItemStack, old: ItemStack) -> Unit = { _, _ -> }, + maxStackSize: Int = Item.DEFAULT_MAX_STACK_SIZE, + filter: AutomationFilter = AutomationFilters.ALLOW + ) : this(listener, maxStackSize, filter, filter, filter, filter) + private open inner class Instance(container: SlottedContainer, slot: Int) : ContainerSlot(container, slot) { override val maxStackSize: Int get() = this@Simple.maxStackSize diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/FilteredContainerSlot.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/FilteredContainerSlot.kt index 4a067fd75..909534c01 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/FilteredContainerSlot.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/FilteredContainerSlot.kt @@ -9,6 +9,7 @@ import net.minecraft.world.item.ItemStack import ru.dbotthepony.mc.otm.container.IFilteredAutomatedContainerSlot import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.registryName +import java.util.Collections open class FilteredContainerSlot( container: SlottedContainer, @@ -50,6 +51,12 @@ open class FilteredContainerSlot( private val modifyAutomationPlaceCount: AutomationModifyPlaceCount = AutomationModifyPlaceCount { _, item -> item.count }, private val modifyAutomationExtractionCount: AutomationModifyExtractionCount = AutomationModifyExtractionCount { _, desired -> desired }, ) : SlottedContainer.SlotProvider { + constructor( + listener: (new: ItemStack, old: ItemStack) -> Unit = { _, _ -> }, + maxStackSize: Int = Item.DEFAULT_MAX_STACK_SIZE, + filter: AutomationFilter = AutomationFilters.ALLOW + ) : this(listener, maxStackSize, filter, filter, filter, filter) + private open inner class Instance(container: SlottedContainer, slot: Int) : FilteredContainerSlot(container, slot) { override val maxStackSize: Int get() = this@Simple.maxStackSize diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/SimpleCallbacks.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/SimpleCallbacks.kt deleted file mode 100644 index 664d268f0..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/slotted/SimpleCallbacks.kt +++ /dev/null @@ -1,19 +0,0 @@ -package ru.dbotthepony.mc.otm.container.slotted - -import net.minecraft.world.item.ItemStack - -fun interface AutomationPlaceItem { - fun canAutomationPlaceItem(self: S, itemStack: ItemStack): Boolean -} - -fun interface AutomationTakeItem { - fun canAutomationTakeItem(self: S, desired: Int): Boolean -} - -fun interface AutomationModifyPlaceCount { - fun modifyAutomationPlaceCount(self: S, itemStack: ItemStack): Int -} - -fun interface AutomationModifyExtractionCount { - fun modifyAutomationExtractionCount(self: S, desired: Int): Int -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt index abc66ec71..bce9927e0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt @@ -1,6 +1,5 @@ package ru.dbotthepony.mc.otm.menu.decorative -import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.ItemStack import net.neoforged.neoforge.capabilities.Capabilities @@ -8,9 +7,10 @@ import net.neoforged.neoforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.block.entity.decorative.FluidTankBlockEntity import ru.dbotthepony.mc.otm.capability.isNotEmpty +import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer import ru.dbotthepony.mc.otm.menu.OutputMenuSlot import ru.dbotthepony.mc.otm.menu.MatteryMenu -import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot +import ru.dbotthepony.mc.otm.menu.UserFilteredMenuSlot import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback import ru.dbotthepony.mc.otm.menu.input.FluidConfigPlayerInput import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput @@ -24,14 +24,16 @@ class FluidTankMenu(containerId: Int, inventory: Inventory, tile: FluidTankBlock val redstoneConfig = EnumInputWithFeedback(this) val fluidConfig = FluidConfigPlayerInput(this, tile?.fluidConfig) - val drainInput = object : MatteryMenuSlot(tile?.drainInput ?: SimpleContainer(1), 0) { + private val inputContainer = tile?.inputContainer ?: SlottedContainer.filtered(2) + + val drainInput = object : UserFilteredMenuSlot(inputContainer, 0) { override fun mayPlace(itemStack: ItemStack): Boolean { return super.mayPlace(itemStack) && (itemStack.getCapability(Capabilities.FluidHandler.ITEM)?.isNotEmpty ?: false) } } - val fillInput = object : MatteryMenuSlot(tile?.fillInput ?: SimpleContainer(1), 0) { + val fillInput = object : UserFilteredMenuSlot(inputContainer, 1) { override fun mayPlace(itemStack: ItemStack): Boolean { return super.mayPlace(itemStack) && (if (itemStack.count <= 1) itemStack @@ -46,7 +48,7 @@ class FluidTankMenu(containerId: Int, inventory: Inventory, tile: FluidTankBlock } } - val output = OutputMenuSlot(tile?.output ?: SimpleContainer(1), 0) + val output = OutputMenuSlot(tile?.outputContainer ?: SlottedContainer.simple(1), 0) init { // сначала слот на заполнение из бака