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.phys.shapes.CollisionContext
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.shapes.BlockShapes
@ -66,8 +67,22 @@ class BatteryBankBlock : RotatableMatteryBlock(), EntityBlock {
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 {
@JvmField
val BATTERY_SLOTS_PROPS = arrayOf(
BooleanProperty.create("battery_0") 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.util.LazyOptional
import net.minecraftforge.energy.IEnergyStorage
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.block.BatteryBankBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
@ -69,10 +70,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
return extractEnergyInner(howMuch, simulate)
}
/**
* [mode] = true на приём, false на отдачу
*/
fun getDistribution(mode: Boolean): BatteryBankDistribution {
fun getDistribution(isReceiving: Boolean): BatteryBankDistribution {
val distribution = Array(container.containerSize) { ImpreciseFraction.ZERO }
var summ = ImpreciseFraction.ZERO
@ -83,7 +81,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
stack.energy?.let {
val diff: ImpreciseFraction
if (mode) {
if (isReceiving) {
diff = it.receiveEnergy(ImpreciseFraction.LONG_MAX_VALUE, true)
} else {
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)
}
private fun distributeEnergy(mode: Boolean, howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
val distribution = getDistribution(mode)
private fun distributeEnergy(isReceiving: Boolean, howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
val distribution = getDistribution(isReceiving)
if (distribution.maxThroughput.isZero)
return ImpreciseFraction.ZERO
@ -121,7 +119,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
stack.energy?.let {
val diff: ImpreciseFraction
if (mode) {
if (isReceiving) {
diff = it.receiveEnergy(howMuch * distList[i], simulate)
} else {
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 {
return distributeEnergy(false, howMuch, simulate)
return distributeEnergy(isReceiving = false, howMuch, simulate)
}
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 {
return distributeEnergy(true, howMuch, simulate)
return distributeEnergy(isReceiving = true, howMuch, simulate)
}
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 var resolverEnergyReceive = LazyOptional.of { energyReceiver }
private val energyExtractor = BatteryBankEnergy(BankMode.EXTRACT)
private var resolverEnergyExtractor = LazyOptional.of { energyExtractor }
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 resolverItemHandler = LazyOptional.of { itemHandler }
private var valid = true
@ -218,7 +218,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override fun invalidateCaps() {
super.invalidateCaps()
valid = false
resolverEnergyReceive.invalidate()
resolverEnergyReceiver.invalidate()
resolverEnergyExtractor.invalidate()
resolverEnergy.invalidate()
resolverItemHandler.invalidate()
@ -227,7 +227,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override fun reviveCaps() {
super.reviveCaps()
valid = true
resolverEnergyReceive = LazyOptional.of { energyReceiver }
resolverEnergyReceiver = LazyOptional.of { energyReceiver }
resolverEnergyExtractor = LazyOptional.of { energyExtractor }
resolverEnergy = LazyOptional.of { energy }
resolverItemHandler = LazyOptional.of { itemHandler }
@ -235,7 +235,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
override fun setLevel(p_155231_: Level) {
super.setLevel(p_155231_)
tickOnceServer { level: Level -> checkSurroundings(level) }
tickOnceServer(this::checkSurroundings)
}
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))
return resolverEnergyExtractor.cast()
else
return resolverEnergyReceive.cast()
return resolverEnergyReceiver.cast()
}
if (cap == ForgeCapabilities.ITEM_HANDLER) {
@ -257,7 +257,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
return super.getCapability(cap,side)
}
private var outputCapability = LazyOptional.empty<IEnergyStorage>()
private var consumingCapability = LazyOptional.empty<IEnergyStorage>()
fun checkSurroundings(level: Level) {
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))
if (tile == null) {
outputCapability = LazyOptional.empty()
consumingCapability = LazyOptional.empty()
return
}
outputCapability = getAndBind(
outputCapability,
tile,
ForgeCapabilities.ENERGY,
-blockState.getValue(RotatableMatteryBlock.FACING)
consumingCapability = getAndBind(
old = consumingCapability,
provider = tile,
capability = ForgeCapabilities.ENERGY,
side = -blockState.getValue(RotatableMatteryBlock.FACING)
) {
@Suppress("name_shadowing")
val level = this.level
@ -287,16 +287,30 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
if (isBlockedByRedstone)
return
outputCapability.ifPresentK {
consumingCapability.ifPresentK {
val (_, maxThroughput) = energy.getDistribution(false)
if (maxThroughput.isZero)
return@ifPresentK
val diff = it.receiveEnergy(maxThroughput, false)
val diff = it.receiveEnergy(maxThroughput, true)
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 {
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.battery_bank")
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 ru.dbotthepony.mc.otm.addPreWorldTickerOnce
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.container.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 {
@ -103,11 +102,11 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
protected fun <T> getAndBind(
old: LazyOptional<T>,
provider: ICapabilityProvider?,
cap: Capability<T>,
capability: Capability<T>,
side: Direction,
invalidate: Runnable
): LazyOptional<T> {
val get = provider?.getCapability(cap, side) ?: LazyOptional.empty()
val get = provider?.getCapability(capability, side) ?: LazyOptional.empty()
if (old !== get) {
if (get.isPresent) {