From f18a3eaaaa28f0948a01453f9c0d6478a0ad2717 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 3 Aug 2023 17:24:32 +0700 Subject: [PATCH] Redo matter bottler --- .../block/entity/MatteryDeviceBlockEntity.kt | 12 +- .../block/entity/MatteryPoweredBlockEntity.kt | 16 +- .../entity/matter/MatterBottlerBlockEntity.kt | 350 +++++++++--------- .../mc/otm/capability/ProxiedItemHandler.kt | 30 ++ .../capability/energy/ProxiedEnergyStorage.kt | 8 + .../jade/providers/MatterBottlerProvider.kt | 2 +- .../mc/otm/container/ContainerIterator.kt | 6 +- .../mc/otm/container/IContainerIterator.kt | 12 + .../mc/otm/menu/matter/MatterBottlerMenu.kt | 42 +-- 9 files changed, 269 insertions(+), 209 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/capability/ProxiedItemHandler.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/container/IContainerIterator.kt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt index fe8636ced..b4a250319 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt @@ -555,12 +555,12 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo capController.expose() } - when (value) { - ItemHandlerMode.DISABLED -> currentHandler = EmptyItemHandler - ItemHandlerMode.INPUT -> currentHandler = input!! - ItemHandlerMode.OUTPUT -> currentHandler = output!! - ItemHandlerMode.INPUT_OUTPUT -> currentHandler = inputOutput!! - ItemHandlerMode.BATTERY -> currentHandler = battery!! + currentHandler = when (value) { + ItemHandlerMode.DISABLED -> EmptyItemHandler + ItemHandlerMode.INPUT -> input!! + ItemHandlerMode.OUTPUT -> output!! + ItemHandlerMode.INPUT_OUTPUT -> inputOutput!! + ItemHandlerMode.BATTERY -> battery!! } } }) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt index c1ef9e92e..92045b5d8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt @@ -39,16 +39,14 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229 if (demand.isZero) return for (stack in batteryContainer) { - if (!stack.isEmpty) { - stack.getCapability(ForgeCapabilities.ENERGY).ifPresentK { - val diff = it.extractEnergy(demand, false) - energy.receiveEnergy(diff, false) - demand -= diff - } - - if (demand <= Decimal.ZERO) - return + stack.getCapability(ForgeCapabilities.ENERGY).ifPresentK { + val diff = it.extractEnergy(demand, false) + energy.receiveEnergy(diff, false) + demand -= diff } + + if (demand <= Decimal.ZERO) + return } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt index 8038cab58..82c8941a5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterBottlerBlockEntity.kt @@ -9,11 +9,14 @@ import net.minecraft.world.item.ItemStack import net.minecraft.world.level.Level import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.state.BlockState +import net.minecraftforge.items.IItemHandler import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity import ru.dbotthepony.mc.otm.block.entity.WorkerState +import ru.dbotthepony.mc.otm.capability.CombinedItemHandler import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.capability.ProxiedItemHandler import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage @@ -32,66 +35,71 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, blockPos, blockState) { val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this, MachinesConfig.MatterBottler.VALUES)) + val energyConfig = ConfigurableEnergy(energy) - var isBottling: Boolean = true - set(value) { - field = value - this.setChangedLight() + private inner class Container : MatteryContainer(3) { + init { + addDroppableContainer(this) } - private fun updateBlockState() { - val level = level as? ServerLevel ?: return - - var state = blockState - val initial = if (isBottling) 0 else 3 - - for (i in initial .. initial + 2) { - val desired = !container.getItem(i).isEmpty && container.getItem(i).getCapability(MatteryCapability.MATTER).isPresent - - if (state.getValue(MatterBottlerBlock.SLOT_PROPERTIES[i - initial]) != desired) { - state = state.setValue(MatterBottlerBlock.SLOT_PROPERTIES[i - initial], desired) - } - } - - if (state !== blockState) { - level.setBlock(blockPos, state, Block.UPDATE_CLIENTS) - } - } - - // TODO: оно должно что то делать - // true - continue even if empty when bottling / if full while unbottling - // false - spit into output slot - //private var work_behavior = true - - val container: MatteryContainer = object : MatteryContainer(this::setChangedLight, 6) { override fun getMaxStackSize(slot: Int, itemStack: ItemStack): Int { return 1 } override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { - super.setChanged(slot, new, old) + setChangedLight() updateBlockState() } - }.also(::addDroppableContainer) + } - val itemHandler = container.handler(object : HandlerFilter { - override fun canInsert(slot: Int, stack: ItemStack): Boolean { - if (isBottling) { - return slot < 3 && stack.getCapability(MatteryCapability.MATTER).isPresent + val unbottling: MatteryContainer = Container() + val bottling: MatteryContainer = Container() + + var isBottling: Boolean = true + set(value) { + field = value + initialCapacity = null + workProgress = 0f + this.setChangedLight() + + if (value) { + inputHandler.parent = bottlingHandler + outputHandler.parent = unbottlingHandler + } else { + inputHandler.parent = unbottlingHandler + outputHandler.parent = bottlingHandler } - return slot >= 3 && stack.getCapability(MatteryCapability.MATTER).isPresent + updateBlockState() } - override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - if (isBottling) { - return slot >= 3 - } + var spitItemsWhenCantWork = false + set(value) { + field = value + this.setChangedLight() + } - return slot < 3 + val bottlingHandler = bottling.handler(object : HandlerFilter { + override fun canInsert(slot: Int, stack: ItemStack): Boolean { + return isBottling && stack.getCapability(MatteryCapability.MATTER).map { it.matterFlow.input && it.missingMatter.isPositive }.orElse(false) } }) + val unbottlingHandler = unbottling.handler(object : HandlerFilter { + override fun canInsert(slot: Int, stack: ItemStack): Boolean { + return !isBottling && stack.getCapability(MatteryCapability.MATTER).map { it.matterFlow.output && it.storedMatter.isPositive }.orElse(false) + } + }) + + private val inputHandler = ProxiedItemHandler(bottlingHandler) + private val outputHandler = ProxiedItemHandler(unbottlingHandler) + + val itemConfig = ConfigurableItemHandler( + input = inputHandler, + output = outputHandler, + battery = batteryItemHandler + ) + val matter: ProfiledMatterStorage = ProfiledMatterStorage(object : MatterStorageImpl(this::setChangedLight, FlowDirection.BI_DIRECTIONAL, MachinesConfig.MatterBottler.VALUES::matterCapacity) { override val matterFlow: FlowDirection get() { return if (this@MatterBottlerBlockEntity.isBottling) FlowDirection.INPUT else FlowDirection.OUTPUT @@ -103,18 +111,19 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : init { exposeGlobally(MatteryCapability.MATTER, matter) exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) - exposeItemsGlobally(itemHandler) savetables.bool(::isBottling) + savetables.bool(::spitItemsWhenCantWork) savetable(::energy, ENERGY_KEY) savetable(::matter, MATTER_STORAGE_KEY) - savetable(::container, INVENTORY_KEY) - - exposeEnergyGlobally(energy) + savetable(::bottling) + savetable(::unbottling) } + var workProgress: Float = 0f + private set + private var initialCapacity: Decimal? = null - private var lastWorkStack: ItemStack? = null override fun setLevel(level: Level) { super.setLevel(level) @@ -125,155 +134,156 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : return MatterBottlerMenu(containerID, inventory, this) } - fun getWorkProgress(): Float { - val lastWorkStack = lastWorkStack ?: return 0f - val initialCapacity = initialCapacity ?: return 0f - val cap = lastWorkStack.getCapability(MatteryCapability.MATTER).orNull() ?: return 0f - - if (this.isBottling) { - if (cap.maxStoredMatter - initialCapacity <= Decimal.ZERO) { - return 0f - } - - return ((cap.storedMatter - initialCapacity) / (cap.maxStoredMatter - initialCapacity)).toFloat() - } - - if (initialCapacity <= Decimal.ZERO) { - return 0f - } - - return (Decimal.ONE - cap.storedMatter / initialCapacity).toFloat() - } - override fun setRemoved() { super.setRemoved() matterNode.isValid = false } + private fun updateBlockState(container: MatteryContainer) { + val level = level as? ServerLevel ?: return + var state = blockState + + for (i in 0 .. 2) { + val desired = !container.getItem(i).isEmpty && container.getItem(i).getCapability(MatteryCapability.MATTER).isPresent + + if (state.getValue(MatterBottlerBlock.SLOT_PROPERTIES[i]) != desired) { + state = state.setValue(MatterBottlerBlock.SLOT_PROPERTIES[i], desired) + } + } + + if (state !== blockState) { + level.setBlock(blockPos, state, Block.UPDATE_CLIENTS) + } + } + + private fun updateBlockState() { + if (isBottling) + updateBlockState(bottling) + else + updateBlockState(unbottling) + } + + private fun blockstateToWorking() { + if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.WORKING) { + level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) + } + } + + private fun blockstateToIdle() { + if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.IDLE) { + level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS) + } + } + override fun tick() { super.tick() if (redstoneControl.isBlockedByRedstone) { - if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.IDLE) { - level?.setBlock( - blockPos, - blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), - Block.UPDATE_CLIENTS - ) - } - + blockstateToIdle() return } - var workStack: ItemStack? = null - var capability: IMatterStorage? = null - val align = if (isBottling) 0 else 3 - var workSlot = -1 - val unexpectedDirection = if (isBottling) FlowDirection.OUTPUT else FlowDirection.INPUT + if (isBottling) { + var any = false + var idle = false + val iterator = bottling.iterator() - for (i in align until align + 3) { - val itemStack = container.getItem(i) + for (item in iterator) { + item.getCapability(MatteryCapability.MATTER).ifPresentK { + if (!it.missingMatter.isPositive) { + unbottling.consumeItem(item, false) + iterator.setChanged() + } else { + any = true + initialCapacity = initialCapacity ?: it.storedMatter + val rate = MachinesConfig.MatterBottler.RATE - if (!itemStack.isEmpty) { - val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: continue + if (matter.storedMatter < rate) { + matter.receiveMatter(matterNode.graph.extractMatter(matter.missingMatter + .coerceAtMost(rate * 200) + .coerceAtMost(it.missingMatter - matter.storedMatter), false), false) + } - if (cap.matterFlow != unexpectedDirection) { - if (this.isBottling && cap.missingMatter > Decimal.ZERO || !this.isBottling && cap.storedMatter > Decimal.ZERO) { - workStack = itemStack - capability = cap - workSlot = i - break - } - } - } - } + if (matter.storedMatter.isPositive) { + matter.extractMatter(it.receiveMatter(rate.coerceAtMost(matter.storedMatter), false), false) - if (workStack == null) { - lastWorkStack = null - initialCapacity = null - } else if (workStack != lastWorkStack) { - lastWorkStack = workStack - initialCapacity = capability!!.storedMatter - } + if (!it.missingMatter.isPositive) { + initialCapacity = null + workProgress = 0f + } else { + workProgress = ((it.storedMatter - initialCapacity!!) / it.maxStoredMatter).toFloat() + } + } else { + idle = true - if (capability != null) { - if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.WORKING) { - level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) - } - - val rate = MachinesConfig.MatterBottler.RATE - val consumption = MachinesConfig.MatterBottler.VALUES.energyConsumption - - if (isBottling) { - if (matter.storedMatter < rate) { - val extracted = matterNode.graph.extractMatter( - matter.missingMatter - .coerceAtMost(rate * 200) - .coerceAtMost(capability.missingMatter - matter.storedMatter), true) - - if (extracted > Decimal.ZERO) { - val received = matter.receiveMatter(extracted, false) - matterNode.graph.extractMatter(received, false) - } - } - - if (matter.storedMatter > Decimal.ZERO) { - val energyExtracted = energy.extractEnergy(consumption, true) - - if (!energyExtracted.isZero) { - val matter = capability.receiveMatter(rate.coerceAtMost(matter.storedMatter) * energyExtracted / consumption, true) - - if (!matter.isZero) { - energy.extractEnergy(consumption * matter / rate, false) - - capability.receiveMatter(matter, false) - this.matter.extractMatter(matter, false) - - if (capability.missingMatter.isZero) { - for (i in 3..5) { - if (container.getItem(i).isEmpty) { - container.setItem(workSlot, ItemStack.EMPTY) - container.setItem(i, workStack!!) - break - } - } + if (spitItemsWhenCantWork) { + unbottling.consumeItem(item, false) + iterator.setChanged() } } } } + + if (any) { + break + } + } + + if (any && !idle) { + blockstateToWorking() } else { - val energyExtracted = energy.extractEnergy(consumption, true) - - if (!energyExtracted.isZero) { - val matter = capability.extractMatter(rate.coerceAtMost(matter.missingMatter) * energyExtracted / consumption, true) - - if (!matter.isZero) { - this.energy.extractEnergy(consumption * matter / rate, false) - - capability.extractMatter(matter, false) - this.matter.receiveMatter(matter, false) - - if (capability.storedMatter.isZero) { - for (i in 2 downTo 0) { - if (container.getItem(i).isEmpty) { - container.setItem(workSlot, ItemStack.EMPTY) - container.setItem(i, workStack!!) - break - } - } - } - } - } + matter.extractMatter(matterNode.graph.receiveMatter(matter.storedMatter, false), false) + blockstateToIdle() } } else { - level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS) - } + matter.extractMatter(matterNode.graph.receiveMatter(matter.storedMatter, false), false) - if (!isBottling && !matter.storedMatter.isZero) { - val diff = matter.extractMatter(matter.storedMatter, true) - val diff2 = matterNode.graph.receiveMatter(diff, true) - matter.extractMatter(diff2, false) - matterNode.graph.receiveMatter(diff2, false) + if (!matter.missingMatter.isPositive) { + if (spitItemsWhenCantWork) { + val iterator = unbottling.iterator() + + for (item in iterator) { + bottling.consumeItem(item, false) + iterator.setChanged() + } + } + + blockstateToIdle() + return + } + + var any = false + + val iterator = unbottling.iterator() + for (item in iterator) { + item.getCapability(MatteryCapability.MATTER).ifPresentK { + if (!it.storedMatter.isPositive) { + bottling.consumeItem(item, false) + iterator.setChanged() + } else { + any = true + initialCapacity = initialCapacity ?: it.storedMatter + matter.receiveMatter(it.extractMatter(MachinesConfig.MatterBottler.RATE, false), false) + + if (!it.storedMatter.isPositive) { + initialCapacity = null + workProgress = 0f + } else { + workProgress = 1f - (it.storedMatter / initialCapacity!!).toFloat() + } + } + } + + if (any) { + break + } + } + + if (any) { + blockstateToWorking() + } else { + blockstateToIdle() + } } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/ProxiedItemHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/ProxiedItemHandler.kt new file mode 100644 index 000000000..82393a0a9 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/ProxiedItemHandler.kt @@ -0,0 +1,30 @@ +package ru.dbotthepony.mc.otm.capability + +import net.minecraft.world.item.ItemStack +import net.minecraftforge.items.IItemHandler + +class ProxiedItemHandler(var parent: T? = null) : IItemHandler { + override fun getSlots(): Int { + return parent?.slots ?: 0 + } + + override fun getStackInSlot(slot: Int): ItemStack { + return parent?.getStackInSlot(slot) ?: ItemStack.EMPTY + } + + override fun insertItem(slot: Int, stack: ItemStack, simulate: Boolean): ItemStack { + return parent?.insertItem(slot, stack, simulate) ?: stack + } + + override fun extractItem(slot: Int, amount: Int, simulate: Boolean): ItemStack { + return parent?.extractItem(slot, amount, simulate) ?: ItemStack.EMPTY + } + + override fun getSlotLimit(slot: Int): Int { + return parent?.getSlotLimit(slot) ?: 0 + } + + override fun isItemValid(slot: Int, stack: ItemStack): Boolean { + return parent?.isItemValid(slot, stack) ?: false + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ProxiedEnergyStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ProxiedEnergyStorage.kt index 70d345734..4aff62fc1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ProxiedEnergyStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ProxiedEnergyStorage.kt @@ -12,6 +12,14 @@ class ProxiedEnergyStorage(var parent: T? = null) : I return parent?.receiveEnergy(howMuch, simulate) ?: Decimal.ZERO } + override fun extractEnergyChecked(howMuch: Decimal, simulate: Boolean): Decimal { + return parent?.extractEnergyChecked(howMuch, simulate) ?: Decimal.ZERO + } + + override fun receiveEnergyChecked(howMuch: Decimal, simulate: Boolean): Decimal { + return parent?.receiveEnergyChecked(howMuch, simulate) ?: Decimal.ZERO + } + override var batteryLevel: Decimal get() = parent?.batteryLevel ?: Decimal.ZERO set(value) { parent?.batteryLevel = value } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatterBottlerProvider.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatterBottlerProvider.kt index 9ac8d29bf..e2314a0ca 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatterBottlerProvider.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jade/providers/MatterBottlerProvider.kt @@ -25,7 +25,7 @@ object MatterBottlerProvider : IBlockComponentProvider, IServerDataProvider { +class ContainerIterator(private val container: Container) : IContainerIterator { private var index = 0 private var lastIndex = -1 @@ -37,6 +37,10 @@ class ContainerIterator(private val container: Container) : MutableIterator { + /** + * Notifies underlying container that last returned [ItemStack] was modified + * + * @throws NoSuchElementException + */ + fun setChanged() +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt index cc50fadfc..636b17f03 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/matter/MatterBottlerMenu.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.menu.matter +import com.google.common.collect.ImmutableList import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import net.minecraft.world.item.ItemStack @@ -9,12 +10,14 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.matter.ProfiledMatterStorage import ru.dbotthepony.mc.otm.capability.matter.canExtractMatter import ru.dbotthepony.mc.otm.capability.matter.canReceiveMatter +import ru.dbotthepony.mc.otm.container.CombinedContainer import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu import ru.dbotthepony.mc.otm.menu.MatterySlot +import ru.dbotthepony.mc.otm.menu.makeSlots import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus @@ -22,38 +25,33 @@ class MatterBottlerMenu @JvmOverloads constructor( p_38852_: Int, inventory: Inventory, tile: MatterBottlerBlockEntity? = null -) : MatteryPoweredMenu( - MMenus.MATTER_BOTTLER, p_38852_, inventory, tile -) { +) : MatteryPoweredMenu(MMenus.MATTER_BOTTLER, p_38852_, inventory, tile) { val workFlow = BooleanInputWithFeedback(this) val progressWidget = ProgressGaugeWidget(this) val matterWidget = ProfiledLevelGaugeWidget(this, tile?.matter, LevelGaugeWidget(this, tile?.matter)) - val storageSlots: List + + val storageSlots: ImmutableList = makeSlots(CombinedContainer(tile?.bottling ?: SimpleContainer(3), tile?.unbottling ?: SimpleContainer(3))) { it, index -> + object : MatterySlot(it, index) { + override fun mayPlace(itemStack: ItemStack): Boolean { + val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: return false + + if (workFlow.value) { + return index < 3 && cap.canReceiveMatter + } else { + return index >= 3 && cap.canExtractMatter + } + } + }.also(this::addStorageSlot) + } + val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget) init { - val container = tile?.container ?: SimpleContainer(6) - if (tile != null) { - progressWidget.with(tile::getWorkProgress) + progressWidget.with(tile::workProgress) workFlow.with(tile::isBottling) } - storageSlots = immutableList(6) { index -> - object : MatterySlot(container, index) { - override fun mayPlace(itemStack: ItemStack): Boolean { - val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: return false - - if (workFlow.value) { - return index < 3 && cap.canReceiveMatter - } else { - return index >= 3 && cap.canExtractMatter - } - } - } - } - - storageSlots.forEach(this::addStorageSlot) addInventorySlots() } }