Fixes for battery bank block

This commit is contained in:
DBotThePony 2022-09-04 19:42:17 +07:00
parent 8053ea69f9
commit a1405272f5
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 59 additions and 30 deletions

View File

@ -18,6 +18,7 @@ import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.addPostWorldTickerOnce
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -66,8 +67,22 @@ class BatteryBankBlock : RotatableMatteryBlock(), EntityBlock {
return false return false
} }
override fun neighborChanged(
state: BlockState,
level: Level,
pos: BlockPos,
sender: Block,
sender_pos: BlockPos,
flag: Boolean
) {
super.neighborChanged(state, level, pos, sender, sender_pos, flag)
val blockEntity = level.getBlockEntity(pos) as? BatteryBankBlockEntity ?: return
addPostWorldTickerOnce(level) { blockEntity.checkSurroundings(level) }
}
companion object { companion object {
@JvmField
val BATTERY_SLOTS_PROPS = arrayOf( val BATTERY_SLOTS_PROPS = arrayOf(
BooleanProperty.create("battery_0") as BooleanProperty, BooleanProperty.create("battery_0") as BooleanProperty,
BooleanProperty.create("battery_1") as BooleanProperty, BooleanProperty.create("battery_1") as BooleanProperty,

View File

@ -17,6 +17,7 @@ import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.energy.IEnergyStorage import net.minecraftforge.energy.IEnergyStorage
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.* import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.block.BatteryBankBlock import ru.dbotthepony.mc.otm.block.BatteryBankBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
@ -69,10 +70,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
return extractEnergyInner(howMuch, simulate) return extractEnergyInner(howMuch, simulate)
} }
/** fun getDistribution(isReceiving: Boolean): BatteryBankDistribution {
* [mode] = true на приём, false на отдачу
*/
fun getDistribution(mode: Boolean): BatteryBankDistribution {
val distribution = Array(container.containerSize) { ImpreciseFraction.ZERO } val distribution = Array(container.containerSize) { ImpreciseFraction.ZERO }
var summ = ImpreciseFraction.ZERO var summ = ImpreciseFraction.ZERO
@ -83,7 +81,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
stack.energy?.let { stack.energy?.let {
val diff: ImpreciseFraction val diff: ImpreciseFraction
if (mode) { if (isReceiving) {
diff = it.receiveEnergy(ImpreciseFraction.LONG_MAX_VALUE, true) diff = it.receiveEnergy(ImpreciseFraction.LONG_MAX_VALUE, true)
} else { } else {
diff = it.extractEnergy(ImpreciseFraction.LONG_MAX_VALUE, true) diff = it.extractEnergy(ImpreciseFraction.LONG_MAX_VALUE, true)
@ -104,8 +102,8 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
return BatteryBankDistribution(distribution, summ) return BatteryBankDistribution(distribution, summ)
} }
private fun distributeEnergy(mode: Boolean, howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { private fun distributeEnergy(isReceiving: Boolean, howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
val distribution = getDistribution(mode) val distribution = getDistribution(isReceiving)
if (distribution.maxThroughput.isZero) if (distribution.maxThroughput.isZero)
return ImpreciseFraction.ZERO return ImpreciseFraction.ZERO
@ -121,7 +119,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
stack.energy?.let { stack.energy?.let {
val diff: ImpreciseFraction val diff: ImpreciseFraction
if (mode) { if (isReceiving) {
diff = it.receiveEnergy(howMuch * distList[i], simulate) diff = it.receiveEnergy(howMuch * distList[i], simulate)
} else { } else {
diff = it.extractEnergy(howMuch * distList[i], simulate) diff = it.extractEnergy(howMuch * distList[i], simulate)
@ -141,7 +139,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
} }
override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return distributeEnergy(false, howMuch, simulate) return distributeEnergy(isReceiving = false, howMuch, simulate)
} }
override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
@ -152,7 +150,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
} }
override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return distributeEnergy(true, howMuch, simulate) return distributeEnergy(isReceiving = true, howMuch, simulate)
} }
override val batteryLevel: ImpreciseFraction get() { override val batteryLevel: ImpreciseFraction get() {
@ -189,11 +187,13 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
} }
private val energyReceiver = BatteryBankEnergy(BankMode.RECEIVE) private val energyReceiver = BatteryBankEnergy(BankMode.RECEIVE)
private var resolverEnergyReceive = LazyOptional.of { energyReceiver }
private val energyExtractor = BatteryBankEnergy(BankMode.EXTRACT) private val energyExtractor = BatteryBankEnergy(BankMode.EXTRACT)
private var resolverEnergyExtractor = LazyOptional.of { energyExtractor }
private val energy = BatteryBankEnergy(BankMode.BIDIRECTIONAL) private val energy = BatteryBankEnergy(BankMode.BIDIRECTIONAL)
private var resolverEnergyReceiver = LazyOptional.of { energyReceiver }
private var resolverEnergyExtractor = LazyOptional.of { energyExtractor }
private var resolverEnergy = LazyOptional.of { energy } private var resolverEnergy = LazyOptional.of { energy }
private var resolverItemHandler = LazyOptional.of { itemHandler } private var resolverItemHandler = LazyOptional.of { itemHandler }
private var valid = true private var valid = true
@ -218,7 +218,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override fun invalidateCaps() { override fun invalidateCaps() {
super.invalidateCaps() super.invalidateCaps()
valid = false valid = false
resolverEnergyReceive.invalidate() resolverEnergyReceiver.invalidate()
resolverEnergyExtractor.invalidate() resolverEnergyExtractor.invalidate()
resolverEnergy.invalidate() resolverEnergy.invalidate()
resolverItemHandler.invalidate() resolverItemHandler.invalidate()
@ -227,7 +227,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override fun reviveCaps() { override fun reviveCaps() {
super.reviveCaps() super.reviveCaps()
valid = true valid = true
resolverEnergyReceive = LazyOptional.of { energyReceiver } resolverEnergyReceiver = LazyOptional.of { energyReceiver }
resolverEnergyExtractor = LazyOptional.of { energyExtractor } resolverEnergyExtractor = LazyOptional.of { energyExtractor }
resolverEnergy = LazyOptional.of { energy } resolverEnergy = LazyOptional.of { energy }
resolverItemHandler = LazyOptional.of { itemHandler } resolverItemHandler = LazyOptional.of { itemHandler }
@ -235,7 +235,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override fun setLevel(p_155231_: Level) { override fun setLevel(p_155231_: Level) {
super.setLevel(p_155231_) super.setLevel(p_155231_)
tickOnceServer { level: Level -> checkSurroundings(level) } tickOnceServer(this::checkSurroundings)
} }
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> { override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
@ -246,7 +246,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
if (side == blockState.getValue(RotatableMatteryBlock.FACING)) if (side == blockState.getValue(RotatableMatteryBlock.FACING))
return resolverEnergyExtractor.cast() return resolverEnergyExtractor.cast()
else else
return resolverEnergyReceive.cast() return resolverEnergyReceiver.cast()
} }
if (cap == ForgeCapabilities.ITEM_HANDLER) { if (cap == ForgeCapabilities.ITEM_HANDLER) {
@ -257,7 +257,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
return super.getCapability(cap,side) return super.getCapability(cap,side)
} }
private var outputCapability = LazyOptional.empty<IEnergyStorage>() private var consumingCapability = LazyOptional.empty<IEnergyStorage>()
fun checkSurroundings(level: Level) { fun checkSurroundings(level: Level) {
if (isRemoved) return if (isRemoved) return
@ -265,15 +265,15 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
val tile = level.getBlockEntity(blockPos.offset(blockState.getValue(RotatableMatteryBlock.FACING).normal)) val tile = level.getBlockEntity(blockPos.offset(blockState.getValue(RotatableMatteryBlock.FACING).normal))
if (tile == null) { if (tile == null) {
outputCapability = LazyOptional.empty() consumingCapability = LazyOptional.empty()
return return
} }
outputCapability = getAndBind( consumingCapability = getAndBind(
outputCapability, old = consumingCapability,
tile, provider = tile,
ForgeCapabilities.ENERGY, capability = ForgeCapabilities.ENERGY,
-blockState.getValue(RotatableMatteryBlock.FACING) side = -blockState.getValue(RotatableMatteryBlock.FACING)
) { ) {
@Suppress("name_shadowing") @Suppress("name_shadowing")
val level = this.level val level = this.level
@ -287,16 +287,30 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
if (isBlockedByRedstone) if (isBlockedByRedstone)
return return
outputCapability.ifPresentK { consumingCapability.ifPresentK {
val (_, maxThroughput) = energy.getDistribution(false) val (_, maxThroughput) = energy.getDistribution(false)
if (maxThroughput.isZero) if (maxThroughput.isZero)
return@ifPresentK return@ifPresentK
val diff = it.receiveEnergy(maxThroughput, false) val diff = it.receiveEnergy(maxThroughput, true)
if (!diff.isZero) { if (!diff.isZero) {
energy.extractEnergyInner(diff, false) val newExtract = energy.extractEnergyInner(diff, true)
val newReceive = it.receiveEnergy(newExtract, true)
if (newReceive == newExtract) {
val extracted = energy.extractEnergyInner(diff, false)
val received = it.receiveEnergy(extracted, false)
if (received != extracted) {
LOGGER.error("ENERGY DUPE ALERT: Battery Bank at $blockPos extracted $extracted energy from it's batteries, yet $it received only $received of it.")
if (received < extracted) {
energy.receiveEnergyInner(extracted - received, false)
}
}
}
} }
} }
} }
@ -304,5 +318,6 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
companion object { companion object {
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.battery_bank") private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.battery_bank")
const val CAPACITY = 6 * 2 const val CAPACITY = 6 * 2
private val LOGGER = LogManager.getLogger()
} }
} }

View File

@ -24,7 +24,6 @@ import net.minecraft.world.level.Level
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
import ru.dbotthepony.mc.otm.core.ifHas import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), MenuProvider { abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), MenuProvider {
@ -103,11 +102,11 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
protected fun <T> getAndBind( protected fun <T> getAndBind(
old: LazyOptional<T>, old: LazyOptional<T>,
provider: ICapabilityProvider?, provider: ICapabilityProvider?,
cap: Capability<T>, capability: Capability<T>,
side: Direction, side: Direction,
invalidate: Runnable invalidate: Runnable
): LazyOptional<T> { ): LazyOptional<T> {
val get = provider?.getCapability(cap, side) ?: LazyOptional.empty() val get = provider?.getCapability(capability, side) ?: LazyOptional.empty()
if (old !== get) { if (old !== get) {
if (get.isPresent) { if (get.isPresent) {