Energy servo item and energy configurations

This commit is contained in:
DBotThePony 2023-02-25 22:00:40 +07:00
parent 1e48b00c2a
commit ace592b74f
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 60 additions and 61 deletions

View File

@ -1,8 +1,6 @@
package ru.dbotthepony.mc.otm.block.entity.tech package ru.dbotthepony.mc.otm.block.entity.tech
import net.minecraft.core.BlockPos 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.Inventory
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu 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.core.math.Decimal
import ru.dbotthepony.mc.otm.menu.tech.EnergyServoMenu import ru.dbotthepony.mc.otm.menu.tech.EnergyServoMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities 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) { class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.ENERGY_SERVO, blockPos, blockState) {
override val defaultDisplayName: Component val discharge = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
get() = MBlocks.ENERGY_SERVO.name val charge = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer)
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 energy = object : IMatteryEnergyStorage { val energy = object : IMatteryEnergyStorage {
override val energyFlow: FlowDirection get() { override val energyFlow: FlowDirection get() {
val discharge = container[SLOT_DISCHARGE].energy val discharge = discharge[0].energy
val charge = container[SLOT_CHARGE].energy val charge = charge[0].energy
return FlowDirection.of(input = charge?.canReceive() ?: false, output = discharge?.canExtract() ?: false) 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) if (redstoneControl.isBlockedByRedstone)
return Decimal.ZERO 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 { override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (redstoneControl.isBlockedByRedstone) if (redstoneControl.isBlockedByRedstone)
return Decimal.ZERO 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 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 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) { 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 energy.energyStoredMattery = value
} }
override val maxBatteryLevel: Decimal 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 { init {
exposeEnergyGlobally(energy) savetables.stateful(::charge)
exposeItemsGlobally(itemHandler) savetables.stateful(::discharge)
savetable(::container, INVENTORY_KEY)
} }
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
@ -99,8 +81,8 @@ class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
if (redstoneControl.isBlockedByRedstone) if (redstoneControl.isBlockedByRedstone)
return return
val charge = container[SLOT_CHARGE] val charge = charge[0]
val discharge = container[SLOT_DISCHARGE] val discharge = discharge[0]
if (!charge.isEmpty && !discharge.isEmpty) { if (!charge.isEmpty && !discharge.isEmpty) {
val chargeEnergy = charge.energy ?: return 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
}
} }

View File

@ -62,7 +62,7 @@ class EnergyServoScreen(menu: EnergyServoMenu, inventory: Inventory, title: Comp
it.dockRight it.dockRight
} }
makeDeviceControls(this, frame, redstone = menu.redstone) makeDeviceControls(this, frame, redstone = menu.redstone, itemConfig = menu.itemConfig, energyConfig = menu.energyConfig)
return frame return frame
} }

View File

@ -16,6 +16,28 @@ interface HandlerFilter {
fun preInsert(slot: Int, stack: ItemStack, simulate: Boolean) {} fun preInsert(slot: Int, stack: ItemStack, simulate: Boolean) {}
fun preExtract(slot: Int, amount: Int, 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 { object OnlyIn : HandlerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean { override fun canInsert(slot: Int, stack: ItemStack): Boolean {
return true return true

View File

@ -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.capability.energy
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.MatterySlot 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.EnumInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.ItemHandlerPlayerInput
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.registry.MMenus import ru.dbotthepony.mc.otm.registry.MMenus
@ -19,34 +21,32 @@ class EnergyServoMenu @JvmOverloads constructor(
inventory: Inventory, inventory: Inventory,
tile: EnergyServoBlockEntity? = null tile: EnergyServoBlockEntity? = null
) : MatteryMenu(MMenus.ENERGY_SERVO, p_38852_, inventory, tile) { ) : MatteryMenu(MMenus.ENERGY_SERVO, p_38852_, inventory, tile) {
val dischargeSlot: MatterySlot val dischargeSlot = object : MatterySlot(tile?.discharge ?: SimpleContainer(1), 0) {
val chargeSlot: MatterySlot 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 powerGauge = LevelGaugeWidget(this, tile?.energy)
val itemConfig = ItemHandlerPlayerInput(this)
val energyConfig = EnergyPlayerInput(this, true, true)
val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java)
init { init {
if (tile != null) { if (tile != null) {
redstone.with(tile.redstoneControl::redstoneSetting) redstone.with(tile.redstoneControl::redstoneSetting)
itemConfig.configure(tile.itemConfig)
energyConfig.configure(tile.energyConfig)
} }
} }
init { 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(dischargeSlot)
addSlot(chargeSlot) addSlot(chargeSlot)
addInventorySlots() addInventorySlots()