diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/BatteryBankBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/BatteryBankBlock.kt index f280758b8..d752836ff 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/BatteryBankBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/BatteryBankBlock.kt @@ -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, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BatteryBankBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BatteryBankBlockEntity.kt index b6a0fea83..e3774cf8e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BatteryBankBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BatteryBankBlockEntity.kt @@ -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 getCapability(cap: Capability, side: Direction?): LazyOptional { @@ -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() + private var consumingCapability = LazyOptional.empty() 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() } } \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt index 95c0ad057..6f6f20736 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt @@ -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 getAndBind( old: LazyOptional, provider: ICapabilityProvider?, - cap: Capability, + capability: Capability, side: Direction, invalidate: Runnable ): LazyOptional { - val get = provider?.getCapability(cap, side) ?: LazyOptional.empty() + val get = provider?.getCapability(capability, side) ?: LazyOptional.empty() if (old !== get) { if (get.isPresent) {