Battery bank now have configurable item and energy sides
This commit is contained in:
parent
aeeabe90ee
commit
f88163d1e5
@ -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<Decimal>, 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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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<MatterySlot>
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user