diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt index 8936ba1d9..a179552fd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt @@ -1,8 +1,6 @@ package ru.dbotthepony.mc.otm.block.entity.tech import net.minecraft.core.BlockPos -import net.minecraft.network.chat.Component -import net.minecraft.world.Container import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu @@ -22,36 +20,15 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.menu.tech.EnergyServoMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities -import ru.dbotthepony.mc.otm.registry.MBlocks class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.ENERGY_SERVO, blockPos, blockState) { - override val defaultDisplayName: Component - get() = MBlocks.ENERGY_SERVO.name - - val container = MatteryContainer(this::setChangedLight, 2).also(::addDroppableContainer) - - val itemHandler = container.handler(object : HandlerFilter { - override fun canInsert(slot: Int, stack: ItemStack): Boolean { - return when (slot) { - SLOT_DISCHARGE -> stack.isEmpty || stack.energy?.let { it.extractEnergy(Int.MAX_VALUE, true) > 0 } ?: false - SLOT_CHARGE -> stack.isEmpty || stack.energy?.let { it.receiveEnergy(Int.MAX_VALUE, true) > 0 } ?: false - else -> false - } - } - - override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { - return when (slot) { - SLOT_DISCHARGE -> stack.isEmpty || stack.energy?.let { it.extractEnergy(Int.MAX_VALUE, true) <= 0 } ?: false - SLOT_CHARGE -> stack.isEmpty || stack.energy?.let { it.receiveEnergy(Int.MAX_VALUE, true) <= 0 } ?: false - else -> false - } - } - }) + val discharge = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer) + val charge = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer) val energy = object : IMatteryEnergyStorage { override val energyFlow: FlowDirection get() { - val discharge = container[SLOT_DISCHARGE].energy - val charge = container[SLOT_CHARGE].energy + val discharge = discharge[0].energy + val charge = charge[0].energy return FlowDirection.of(input = charge?.canReceive() ?: false, output = discharge?.canExtract() ?: false) } @@ -59,34 +36,39 @@ class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte if (redstoneControl.isBlockedByRedstone) return Decimal.ZERO - return container[SLOT_DISCHARGE].energy?.extractEnergy(howMuch, simulate) ?: Decimal.ZERO + return discharge[0].energy?.extractEnergy(howMuch, simulate) ?: Decimal.ZERO } override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal { if (redstoneControl.isBlockedByRedstone) return Decimal.ZERO - return container[SLOT_CHARGE].energy?.receiveEnergy(howMuch, simulate) ?: Decimal.ZERO + return charge[0].energy?.receiveEnergy(howMuch, simulate) ?: Decimal.ZERO } override val canSetBatteryLevel: Boolean - get() = container[SLOT_CHARGE].energy?.canSetBatteryMattery ?: container[SLOT_DISCHARGE].energy?.canSetBatteryMattery ?: false + get() = charge[0].energy?.canSetBatteryMattery ?: discharge[0].energy?.canSetBatteryMattery ?: false override var batteryLevel: Decimal - get() = container[SLOT_CHARGE].energy?.energyStoredMattery ?: container[SLOT_DISCHARGE].energy?.energyStoredMattery ?: Decimal.ZERO + get() = charge[0].energy?.energyStoredMattery ?: discharge[0].energy?.energyStoredMattery ?: Decimal.ZERO set(value) { - val energy = container[SLOT_CHARGE].energy ?: container[SLOT_DISCHARGE].energy ?: throw UnsupportedOperationException("No item in slots") + val energy = charge[0].energy ?: discharge[0].energy ?: throw UnsupportedOperationException("No item in slots") energy.energyStoredMattery = value } override val maxBatteryLevel: Decimal - get() = container[SLOT_CHARGE].energy?.maxEnergyStoredMattery ?: container[SLOT_DISCHARGE].energy?.maxEnergyStoredMattery ?: Decimal.ZERO + get() = charge[0].energy?.maxEnergyStoredMattery ?: discharge[0].energy?.maxEnergyStoredMattery ?: Decimal.ZERO } + val energyConfig = ConfigurableEnergy(energy, possibleModes = FlowDirection.BI_DIRECTIONAL) + val itemConfig = ConfigurableItemHandler( + input = charge.handler(HandlerFilter.OnlyIn.and(HandlerFilter.Chargeable)), + output = discharge.handler(HandlerFilter.OnlyOut.and(HandlerFilter.Dischargeable)) + ) + init { - exposeEnergyGlobally(energy) - exposeItemsGlobally(itemHandler) - savetable(::container, INVENTORY_KEY) + savetables.stateful(::charge) + savetables.stateful(::discharge) } override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { @@ -99,8 +81,8 @@ class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte if (redstoneControl.isBlockedByRedstone) return - val charge = container[SLOT_CHARGE] - val discharge = container[SLOT_DISCHARGE] + val charge = charge[0] + val discharge = discharge[0] if (!charge.isEmpty && !discharge.isEmpty) { val chargeEnergy = charge.energy ?: return @@ -121,9 +103,4 @@ class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte } } } - - companion object { - const val SLOT_DISCHARGE = 0 - const val SLOT_CHARGE = 1 - } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt index a33f5d9e6..159c496cb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt @@ -62,7 +62,7 @@ class EnergyServoScreen(menu: EnergyServoMenu, inventory: Inventory, title: Comp it.dockRight } - makeDeviceControls(this, frame, redstone = menu.redstone) + makeDeviceControls(this, frame, redstone = menu.redstone, itemConfig = menu.itemConfig, energyConfig = menu.energyConfig) return frame } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/HandlerFilter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/HandlerFilter.kt index 2089f618e..3dd2450ba 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/HandlerFilter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/HandlerFilter.kt @@ -16,6 +16,28 @@ interface HandlerFilter { fun preInsert(slot: Int, stack: ItemStack, simulate: Boolean) {} fun preExtract(slot: Int, amount: Int, simulate: Boolean) {} + fun and(other: HandlerFilter): HandlerFilter { + return object : HandlerFilter { + override fun canInsert(slot: Int, stack: ItemStack): Boolean { + return this@HandlerFilter.canInsert(slot, stack) && other.canInsert(slot, stack) + } + + override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { + return this@HandlerFilter.canExtract(slot, amount, stack) && other.canExtract(slot, amount, stack) + } + + override fun preInsert(slot: Int, stack: ItemStack, simulate: Boolean) { + this@HandlerFilter.preInsert(slot, stack, simulate) + other.preInsert(slot, stack, simulate) + } + + override fun preExtract(slot: Int, amount: Int, simulate: Boolean) { + this@HandlerFilter.preExtract(slot, amount, simulate) + other.preExtract(slot, amount, simulate) + } + } + } + object OnlyIn : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { return true diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyServoMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyServoMenu.kt index cba9da535..04b0e8892 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyServoMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/EnergyServoMenu.kt @@ -10,7 +10,9 @@ import ru.dbotthepony.mc.otm.block.entity.tech.EnergyServoBlockEntity import ru.dbotthepony.mc.otm.capability.energy 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.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.registry.MMenus @@ -19,34 +21,32 @@ class EnergyServoMenu @JvmOverloads constructor( inventory: Inventory, tile: EnergyServoBlockEntity? = null ) : MatteryMenu(MMenus.ENERGY_SERVO, p_38852_, inventory, tile) { - val dischargeSlot: MatterySlot - val chargeSlot: MatterySlot + val dischargeSlot = object : MatterySlot(tile?.discharge ?: SimpleContainer(1), 0) { + override fun mayPlace(itemStack: ItemStack): Boolean { + return super.mayPlace(itemStack) && (itemStack.energy?.canExtract() ?: false) + } + } + + val chargeSlot = object : MatterySlot(tile?.charge ?: SimpleContainer(1), 0) { + override fun mayPlace(itemStack: ItemStack): Boolean { + return super.mayPlace(itemStack) && (itemStack.energy?.canReceive() ?: false) + } + } val powerGauge = LevelGaugeWidget(this, tile?.energy) - + val itemConfig = ItemHandlerPlayerInput(this) + val energyConfig = EnergyPlayerInput(this, true, true) val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) init { if (tile != null) { redstone.with(tile.redstoneControl::redstoneSetting) + itemConfig.configure(tile.itemConfig) + energyConfig.configure(tile.energyConfig) } } init { - val container = tile?.container ?: SimpleContainer(2) - - dischargeSlot = object : MatterySlot(container, EnergyServoBlockEntity.SLOT_DISCHARGE) { - override fun mayPlace(itemStack: ItemStack): Boolean { - return super.mayPlace(itemStack) && (itemStack.energy?.canExtract() ?: false) - } - } - - chargeSlot = object : MatterySlot(container, EnergyServoBlockEntity.SLOT_CHARGE) { - override fun mayPlace(itemStack: ItemStack): Boolean { - return super.mayPlace(itemStack) && (itemStack.energy?.canReceive() ?: false) - } - } - addSlot(dischargeSlot) addSlot(chargeSlot) addInventorySlots()