From f88163d1e5e0a724f044e58f18577b0130b9cd54 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 12 Mar 2023 17:57:39 +0700 Subject: [PATCH] Battery bank now have configurable item and energy sides --- .../entity/tech/BatteryBankBlockEntity.kt | 236 ++++++++---------- .../client/screen/tech/BatteryBankScreen.kt | 2 +- .../mc/otm/menu/tech/BatteryBankMenu.kt | 6 + 3 files changed, 109 insertions(+), 135 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt index a0f1de59c..6367dbfdc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt @@ -25,7 +25,7 @@ import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.menu.tech.BatteryBankMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities -class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.BATTERY_BANK, p_155229_, p_155230_) { +class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.BATTERY_BANK, p_155229_, p_155230_), IMatteryEnergyStorage { var gaugeLevel by synchronizer.float() private set @@ -34,7 +34,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { super.setChanged(slot, new, old) batteryStatus[slot].value = new.getCapability(ForgeCapabilities.ENERGY).isPresent - gaugeLevel = (energy.batteryLevel / energy.maxBatteryLevel).toFloat() + gaugeLevel = (batteryLevel / maxBatteryLevel).toFloat() } }.also(::addDroppableContainer) @@ -42,35 +42,73 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte synchronizer.bool(false) } - private val itemHandler = container.handler( - object : HandlerFilter { - override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return stack.getCapability(ForgeCapabilities.ENERGY).isPresent - } - - override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - return true - } - } + val itemConfig = ConfigurableItemHandler( + input = container.handler(HandlerFilter.Dischargeable.and(HandlerFilter.OnlyIn)), + output = container.handler(HandlerFilter.OnlyOut), + frontDefault = ItemHandlerMode.INPUT_OUTPUT, + backDefault = ItemHandlerMode.INPUT_OUTPUT, + leftDefault = ItemHandlerMode.INPUT_OUTPUT, + rightDefault = ItemHandlerMode.INPUT_OUTPUT, + topDefault = ItemHandlerMode.INPUT_OUTPUT, + bottomDefault = ItemHandlerMode.INPUT_OUTPUT, ) init { - exposeItemsGlobally(itemHandler) savetable(::container, INVENTORY_KEY) } private data class BatteryBankDistribution(val distribution: Array, val maxThroughput: Decimal) - private inner class BatteryBankEnergy(override val energyFlow: FlowDirection) : IMatteryEnergyStorage { - override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal { - return distributeEnergy(isReceiving = false, howMuch, simulate) + override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal { + return distributeEnergy(isReceiving = false, howMuch, simulate) + } + + private fun getDistribution(isReceiving: Boolean): BatteryBankDistribution { + val distribution = Array(container.containerSize) { Decimal.ZERO } + var summ = Decimal.ZERO + + for (i in 0 until container.containerSize) { + val stack = container.getItem(i) + + if (!stack.isEmpty) { + stack.energy?.let { + val diff: Decimal + + if (isReceiving) { + diff = it.receiveEnergy(it.maxEnergyStoredMattery, true) + } else { + diff = it.extractEnergy(it.energyStoredMattery, true) + } + + distribution[i] = diff + summ += distribution[i] + } + } } - fun getDistribution(isReceiving: Boolean): BatteryBankDistribution { - val distribution = Array(container.containerSize) { Decimal.ZERO } - var summ = Decimal.ZERO - + if (!summ.isZero) { for (i in 0 until container.containerSize) { + distribution[i] = distribution[i] / summ + } + } + + return BatteryBankDistribution(distribution, summ) + } + + private fun distributeEnergy(isReceiving: Boolean, howMuch: Decimal, simulate: Boolean, set: Boolean = false): Decimal { + if (!howMuch.isPositive) + return Decimal.ZERO + + val distribution = getDistribution(isReceiving) + + if (distribution.maxThroughput.isZero) + return Decimal.ZERO + + val distList = distribution.distribution + var summ = Decimal.ZERO + + for (i in 0 until container.containerSize) { + if (!distList[i].isZero) { val stack = container.getItem(i) if (!stack.isEmpty) { @@ -78,95 +116,57 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte val diff: Decimal if (isReceiving) { - diff = it.receiveEnergy(it.maxEnergyStoredMattery, true) + diff = it.receiveEnergy(howMuch * distList[i], simulate) } else { - diff = it.extractEnergy(it.energyStoredMattery, true) + diff = it.extractEnergy(howMuch * distList[i], simulate) } - distribution[i] = diff - summ += distribution[i] + summ += diff } } } - - if (!summ.isZero) { - for (i in 0 until container.containerSize) { - distribution[i] = distribution[i] / summ - } - } - - return BatteryBankDistribution(distribution, summ) } - private fun distributeEnergy(isReceiving: Boolean, howMuch: Decimal, simulate: Boolean, set: Boolean = false): Decimal { - if (!howMuch.isPositive) - return Decimal.ZERO + if (!simulate && !summ.isZero) { + setChangedLight() + gaugeLevel = (batteryLevel / maxBatteryLevel).toFloat() + } - val distribution = getDistribution(isReceiving) + return summ + } - if (distribution.maxThroughput.isZero) - return Decimal.ZERO + override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal { + return distributeEnergy(isReceiving = true, howMuch, simulate) + } - val distList = distribution.distribution - var summ = Decimal.ZERO + override val canSetBatteryLevel: Boolean + get() = false + + override val energyFlow: FlowDirection + get() = FlowDirection.BI_DIRECTIONAL + + override var batteryLevel: Decimal + get() { + var result = Decimal.ZERO for (i in 0 until container.containerSize) { - if (!distList[i].isZero) { - val stack = container.getItem(i) + val stack = container.getItem(i) - if (!stack.isEmpty) { - stack.energy?.let { - val diff: Decimal - - if (isReceiving) { - diff = it.receiveEnergy(howMuch * distList[i], simulate) - } else { - diff = it.extractEnergy(howMuch * distList[i], simulate) - } - - summ += diff - } + if (!stack.isEmpty) { + stack.energy?.let { + result += it.energyStoredMattery } } } - if (!simulate && !summ.isZero) { - setChangedLight() - gaugeLevel = (batteryLevel / maxBatteryLevel).toFloat() - } - - return summ + return result + } + set(value) { + throw UnsupportedOperationException("Can't set battery value for battery bank") } - override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal { - return distributeEnergy(isReceiving = true, howMuch, simulate) - } - - override val canSetBatteryLevel: Boolean - get() = false - - override var batteryLevel: Decimal - get() { - var result = Decimal.ZERO - - for (i in 0 until container.containerSize) { - val stack = container.getItem(i) - - if (!stack.isEmpty) { - stack.energy?.let { - result += it.energyStoredMattery - } - } - } - - return result - } - set(value) { - throw UnsupportedOperationException("Can't set battery value for battery bank") - } - - override val maxBatteryLevel: Decimal - get() { + override val maxBatteryLevel: Decimal + get() { var result = Decimal.ZERO for (i in 0 until container.containerSize) { @@ -181,57 +181,25 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte return result } - } - private val energyReceiver = BatteryBankEnergy(FlowDirection.INPUT) - private val energyExtractor = BatteryBankEnergy(FlowDirection.OUTPUT) - private val energy = BatteryBankEnergy(FlowDirection.BI_DIRECTIONAL) + val energyConfig = ConfigurableEnergy( + this, + frontDefault = FlowDirection.OUTPUT, + backDefault = FlowDirection.INPUT, + leftDefault = FlowDirection.INPUT, + rightDefault = FlowDirection.INPUT, + topDefault = FlowDirection.INPUT, + bottomDefault = FlowDirection.INPUT + ) + + init { + energyConfig.front.automatePush = true + } override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { return BatteryBankMenu(containerID, inventory, this) } - init { - exposeEnergySideless(energy) - exposeEnergy(RelativeSide.FRONT, energyExtractor) - - for (side in RelativeSide.values()) { - if (side != RelativeSide.FRONT) { - exposeEnergy(side, energyReceiver) - } - } - } - - private val consumers by front.track(ForgeCapabilities.ENERGY) - - override fun tick() { - super.tick() - - if (redstoneControl.isBlockedByRedstone) - return - - consumers.ifPresentK { - val (_, maxThroughput) = energy.getDistribution(false) - - if (maxThroughput.isZero) - return@ifPresentK - - val diff = it.receiveEnergy(maxThroughput, true) - - if (!diff.isZero) { - val newExtract = energy.extractEnergy(diff, true) - val newReceive = it.receiveEnergy(newExtract, true) - - val extracted = energy.extractEnergy(newReceive, false) - val received = it.receiveEnergy(extracted, false) - - if (received < extracted) { - energy.receiveEnergy(extracted - received, false) - } - } - } - } - companion object { const val CAPACITY = 6 * 2 } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/BatteryBankScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/BatteryBankScreen.kt index bdc576dd3..df622243a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/BatteryBankScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/BatteryBankScreen.kt @@ -23,7 +23,7 @@ class BatteryBankScreen(menu: BatteryBankMenu, p_97742_: Inventory, p_97743_: Co for (i in 6 .. 11) BatterySlotPanel(this, frame, menu.storageSlots[i], 44f + 18 * (i - 6), 32f + 18f) - makeDeviceControls(this, frame, redstone = menu.redstone) + makeDeviceControls(this, frame, redstone = menu.redstone, energyConfig = menu.energyConfig, itemConfig = menu.itemConfig) return frame } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt index 58b2cd957..8b25a38f7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt @@ -13,7 +13,9 @@ import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.menu.BatterySlot import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatterySlot +import ru.dbotthepony.mc.otm.menu.input.EnergyPlayerInput import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback +import ru.dbotthepony.mc.otm.menu.input.ItemHandlerPlayerInput import ru.dbotthepony.mc.otm.registry.MMenus class BatteryBankMenu @JvmOverloads constructor( @@ -24,10 +26,14 @@ class BatteryBankMenu @JvmOverloads constructor( val powerLevel: LevelGaugeWidget val storageSlots: List val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) + val energyConfig = EnergyPlayerInput(this, allowPull = false, allowPush = true) + val itemConfig = ItemHandlerPlayerInput(this, allowPull = false, allowPush = false) init { if (tile != null) { redstone.with(tile.redstoneControl::redstoneSetting) + energyConfig.configure(tile.energyConfig) + itemConfig.configure(tile.itemConfig) } val container: Container = tile?.container ?: SimpleContainer(BatteryBankBlockEntity.CAPACITY)