Battery bank now have configurable item and energy sides

This commit is contained in:
DBotThePony 2023-03-12 17:57:39 +07:00
parent aeeabe90ee
commit f88163d1e5
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 109 additions and 135 deletions

View File

@ -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.menu.tech.BatteryBankMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities 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() var gaugeLevel by synchronizer.float()
private set private set
@ -34,7 +34,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
super.setChanged(slot, new, old) super.setChanged(slot, new, old)
batteryStatus[slot].value = new.getCapability(ForgeCapabilities.ENERGY).isPresent batteryStatus[slot].value = new.getCapability(ForgeCapabilities.ENERGY).isPresent
gaugeLevel = (energy.batteryLevel / energy.maxBatteryLevel).toFloat() gaugeLevel = (batteryLevel / maxBatteryLevel).toFloat()
} }
}.also(::addDroppableContainer) }.also(::addDroppableContainer)
@ -42,31 +42,28 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
synchronizer.bool(false) synchronizer.bool(false)
} }
private val itemHandler = container.handler( val itemConfig = ConfigurableItemHandler(
object : HandlerFilter { input = container.handler(HandlerFilter.Dischargeable.and(HandlerFilter.OnlyIn)),
override fun canInsert(slot: Int, stack: ItemStack): Boolean { output = container.handler(HandlerFilter.OnlyOut),
return stack.getCapability(ForgeCapabilities.ENERGY).isPresent frontDefault = ItemHandlerMode.INPUT_OUTPUT,
} backDefault = ItemHandlerMode.INPUT_OUTPUT,
leftDefault = ItemHandlerMode.INPUT_OUTPUT,
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean { rightDefault = ItemHandlerMode.INPUT_OUTPUT,
return true topDefault = ItemHandlerMode.INPUT_OUTPUT,
} bottomDefault = ItemHandlerMode.INPUT_OUTPUT,
}
) )
init { init {
exposeItemsGlobally(itemHandler)
savetable(::container, INVENTORY_KEY) savetable(::container, INVENTORY_KEY)
} }
private data class BatteryBankDistribution(val distribution: Array<Decimal>, val maxThroughput: Decimal) private data class BatteryBankDistribution(val distribution: Array<Decimal>, val maxThroughput: Decimal)
private inner class BatteryBankEnergy(override val energyFlow: FlowDirection) : IMatteryEnergyStorage {
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal { override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
return distributeEnergy(isReceiving = false, howMuch, simulate) return distributeEnergy(isReceiving = false, howMuch, simulate)
} }
fun getDistribution(isReceiving: Boolean): BatteryBankDistribution { private fun getDistribution(isReceiving: Boolean): BatteryBankDistribution {
val distribution = Array(container.containerSize) { Decimal.ZERO } val distribution = Array(container.containerSize) { Decimal.ZERO }
var summ = Decimal.ZERO var summ = Decimal.ZERO
@ -145,6 +142,9 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override val canSetBatteryLevel: Boolean override val canSetBatteryLevel: Boolean
get() = false get() = false
override val energyFlow: FlowDirection
get() = FlowDirection.BI_DIRECTIONAL
override var batteryLevel: Decimal override var batteryLevel: Decimal
get() { get() {
var result = Decimal.ZERO var result = Decimal.ZERO
@ -181,57 +181,25 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
return result return result
} }
}
private val energyReceiver = BatteryBankEnergy(FlowDirection.INPUT) val energyConfig = ConfigurableEnergy(
private val energyExtractor = BatteryBankEnergy(FlowDirection.OUTPUT) this,
private val energy = BatteryBankEnergy(FlowDirection.BI_DIRECTIONAL) 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 { override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return BatteryBankMenu(containerID, inventory, this) 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 { companion object {
const val CAPACITY = 6 * 2 const val CAPACITY = 6 * 2
} }

View File

@ -23,7 +23,7 @@ class BatteryBankScreen(menu: BatteryBankMenu, p_97742_: Inventory, p_97743_: Co
for (i in 6 .. 11) for (i in 6 .. 11)
BatterySlotPanel(this, frame, menu.storageSlots[i], 44f + 18 * (i - 6), 32f + 18f) 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 return frame
} }

View File

@ -13,7 +13,9 @@ import ru.dbotthepony.mc.otm.core.orNull
import ru.dbotthepony.mc.otm.menu.BatterySlot import ru.dbotthepony.mc.otm.menu.BatterySlot
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.registry.MMenus import ru.dbotthepony.mc.otm.registry.MMenus
class BatteryBankMenu @JvmOverloads constructor( class BatteryBankMenu @JvmOverloads constructor(
@ -24,10 +26,14 @@ class BatteryBankMenu @JvmOverloads constructor(
val powerLevel: LevelGaugeWidget val powerLevel: LevelGaugeWidget
val storageSlots: List<MatterySlot> val storageSlots: List<MatterySlot>
val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java)
val energyConfig = EnergyPlayerInput(this, allowPull = false, allowPush = true)
val itemConfig = ItemHandlerPlayerInput(this, allowPull = false, allowPush = false)
init { init {
if (tile != null) { if (tile != null) {
redstone.with(tile.redstoneControl::redstoneSetting) redstone.with(tile.redstoneControl::redstoneSetting)
energyConfig.configure(tile.energyConfig)
itemConfig.configure(tile.itemConfig)
} }
val container: Container = tile?.container ?: SimpleContainer(BatteryBankBlockEntity.CAPACITY) val container: Container = tile?.container ?: SimpleContainer(BatteryBankBlockEntity.CAPACITY)