From d1ea0845165c13ef92fcf6e95c0b753794aaecb8 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 3 Jan 2022 16:34:42 +0700 Subject: [PATCH] Update Battery Bank code --- .../mc/otm/block/BlockBatteryBank.kt | 166 +++--- .../block/entity/BlockEntityBatteryBank.kt | 535 +++++++++--------- 2 files changed, 339 insertions(+), 362 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockBatteryBank.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockBatteryBank.kt index 172982574..b216cbd94 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockBatteryBank.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockBatteryBank.kt @@ -1,101 +1,103 @@ -package ru.dbotthepony.mc.otm.block; +package ru.dbotthepony.mc.otm.block -import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityTicker; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.phys.shapes.BooleanOp; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.dbotthepony.mc.otm.Registry; -import ru.dbotthepony.mc.otm.block.entity.BlockEntityBatteryBank; -import ru.dbotthepony.mc.otm.shapes.BlockShapes; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; -import java.util.List; +import net.minecraft.MethodsReturnNonnullByDefault +import javax.annotation.ParametersAreNonnullByDefault +import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable +import net.minecraft.world.level.block.EntityBlock +import net.minecraft.world.item.context.BlockPlaceContext +import net.minecraft.world.level.block.state.BlockState +import net.minecraft.world.level.block.state.properties.BooleanProperty +import ru.dbotthepony.mc.otm.block.BlockBatteryBank +import net.minecraft.world.level.block.entity.BlockEntity +import net.minecraft.world.level.block.entity.BlockEntityType +import net.minecraft.world.level.block.entity.BlockEntityTicker +import net.minecraft.world.level.block.state.StateDefinition +import net.minecraft.core.BlockPos +import net.minecraft.core.Direction +import ru.dbotthepony.mc.otm.block.entity.BlockEntityBatteryBank +import net.minecraft.world.level.BlockGetter +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.Registry +import ru.dbotthepony.mc.otm.shapes.BlockShapes @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -public class BlockBatteryBank extends BlockMatteryRotatable implements EntityBlock { - public static final BooleanProperty[] BATTERY_SLOTS_PROPS = new BooleanProperty[] { - BooleanProperty.create("battery_0"), - BooleanProperty.create("battery_1"), - BooleanProperty.create("battery_2"), - BooleanProperty.create("battery_3"), - BooleanProperty.create("battery_4"), - BooleanProperty.create("battery_5"), - BooleanProperty.create("battery_6"), - BooleanProperty.create("battery_7"), - BooleanProperty.create("battery_8"), - BooleanProperty.create("battery_9"), - BooleanProperty.create("battery_10"), - BooleanProperty.create("battery_11"), - }; +class BlockBatteryBank : BlockMatteryRotatable(), EntityBlock { + override fun getStateForPlacement(context: BlockPlaceContext): BlockState { + var state = super.getStateForPlacement(context)!! - @Nullable - @Override - public BlockState getStateForPlacement(BlockPlaceContext context) { - var state = super.getStateForPlacement(context); + for (prop in BATTERY_SLOTS_PROPS) + state = state.setValue(prop, false) - for (var prop : BATTERY_SLOTS_PROPS) - state = state.setValue(prop, false); - - return state; + return state } - @Nullable - @Override - public BlockEntityTicker getTicker(Level level, BlockState p_153213_, BlockEntityType type) { - return level.isClientSide || type != Registry.BlockEntities.BATTERY_BANK ? null : BlockEntityBatteryBank::tick; + override fun getTicker( + level: Level, + p_153213_: BlockState, + type: BlockEntityType + ): BlockEntityTicker? { + if (level.isClientSide || type !== Registry.BlockEntities.BATTERY_BANK) + return null + + return BlockEntityTicker { _, _, _, tile -> if (tile is BlockEntityBatteryBank) tile.tick() } } - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(BATTERY_SLOTS_PROPS); - super.createBlockStateDefinition(builder); + override fun createBlockStateDefinition(builder: StateDefinition.Builder) { + builder.add(*BATTERY_SLOTS_PROPS) + super.createBlockStateDefinition(builder) } - @Nullable - @Override - public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { - return new BlockEntityBatteryBank(blockPos, blockState); + override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? { + return BlockEntityBatteryBank(blockPos, blockState) } - private static final List SHAPES; - - static { - var def = BlockShapes.BATTERY_BANK.computeShape(); - - SHAPES = List.of( - def, - def, - def, - BlockShapes.BATTERY_BANK.rotate(Direction.NORTH).computeShape(), - BlockShapes.BATTERY_BANK.rotate(Direction.WEST).computeShape(), - BlockShapes.BATTERY_BANK.rotate(Direction.EAST).computeShape() - ); + override fun getShape( + p_60555_: BlockState, + p_60556_: BlockGetter, + p_60557_: BlockPos, + p_60558_: CollisionContext + ): VoxelShape { + return SHAPES[p_60555_.getValue(FACING).ordinal] } - @Override - @SuppressWarnings("deprecation") - public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) { - return SHAPES.get(p_60555_.getValue(FACING).ordinal()); + override fun faceToPlayer(context: BlockPlaceContext): Boolean { + return false } - @Override - public boolean faceToPlayer(BlockPlaceContext context) { - return false; + companion object { + @JvmField + val BATTERY_SLOTS_PROPS = arrayOf( + BooleanProperty.create("battery_0"), + BooleanProperty.create("battery_1"), + BooleanProperty.create("battery_2"), + BooleanProperty.create("battery_3"), + BooleanProperty.create("battery_4"), + BooleanProperty.create("battery_5"), + BooleanProperty.create("battery_6"), + BooleanProperty.create("battery_7"), + BooleanProperty.create("battery_8"), + BooleanProperty.create("battery_9"), + BooleanProperty.create("battery_10"), + BooleanProperty.create("battery_11") + ) + + private val SHAPES: List + + init { + val def = BlockShapes.BATTERY_BANK.computeShape() + + SHAPES = java.util.List.of( + def, + def, + def, + BlockShapes.BATTERY_BANK.rotate(Direction.NORTH).computeShape(), + BlockShapes.BATTERY_BANK.rotate(Direction.WEST).computeShape(), + BlockShapes.BATTERY_BANK.rotate(Direction.EAST).computeShape() + ) + } } -} +} \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.kt index fa3bfbf78..265c26abe 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.kt @@ -1,167 +1,165 @@ -package ru.dbotthepony.mc.otm.block.entity; +package ru.dbotthepony.mc.otm.block.entity -import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.energy.CapabilityEnergy; -import net.minecraftforge.energy.IEnergyStorage; -import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.IItemHandler; -import ru.dbotthepony.mc.otm.Registry; -import ru.dbotthepony.mc.otm.block.BlockBatteryBank; -import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable; -import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; -import ru.dbotthepony.mc.otm.capability.MatteryCapability; -import ru.dbotthepony.mc.otm.container.MatteryContainer; -import ru.dbotthepony.mc.otm.core.Fraction; -import ru.dbotthepony.mc.otm.menu.BatteryBankMenu; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; -import java.math.BigDecimal; -import java.util.Optional; +import net.minecraft.MethodsReturnNonnullByDefault +import net.minecraft.core.BlockPos +import net.minecraft.core.Direction +import net.minecraft.nbt.CompoundTag +import net.minecraft.network.chat.Component +import net.minecraft.network.chat.TranslatableComponent +import net.minecraft.server.level.ServerLevel +import net.minecraft.world.entity.player.Inventory +import net.minecraft.world.entity.player.Player +import net.minecraft.world.inventory.AbstractContainerMenu +import net.minecraft.world.item.ItemStack +import net.minecraft.world.level.Level +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.state.BlockState +import net.minecraftforge.common.capabilities.Capability +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.energy.CapabilityEnergy +import net.minecraftforge.energy.IEnergyStorage +import net.minecraftforge.items.CapabilityItemHandler +import net.minecraftforge.items.IItemHandler +import ru.dbotthepony.mc.otm.Registry +import ru.dbotthepony.mc.otm.block.BlockBatteryBank +import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable +import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage +import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.capability.extractEnergy +import ru.dbotthepony.mc.otm.capability.receiveEnergy +import ru.dbotthepony.mc.otm.container.MatteryContainer +import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.ifHas +import ru.dbotthepony.mc.otm.menu.BatteryBankMenu +import ru.dbotthepony.mc.otm.set +import ru.dbotthepony.mc.otm.unaryMinus +import javax.annotation.ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -public class BlockEntityBatteryBank extends BlockEntityMattery { +class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(Registry.BlockEntities.BATTERY_BANK, p_155229_, p_155230_) { // 6 на 2 - public final MatteryContainer battery_container = new MatteryContainer(this::setChanged, 6 * 2) { - @Override - public void setChanged(int slot, ItemStack new_state, ItemStack old_state) { - super.setChanged(slot, new_state, old_state); + val container: MatteryContainer = object : MatteryContainer(this::setChanged, 6 * 2) { + override fun setChanged(slot: Int, new_state: ItemStack, old_state: ItemStack) { + super.setChanged(slot, new_state, old_state) + val level = level if (level != null) { - var state = getBlockState(); + var state = blockState - for (int i = 0; i < BlockBatteryBank.BATTERY_SLOTS_PROPS.length; i++) { - state = state.setValue(BlockBatteryBank.BATTERY_SLOTS_PROPS[i], getItem(i).getCapability(CapabilityEnergy.ENERGY).isPresent()); + for (i in BlockBatteryBank.BATTERY_SLOTS_PROPS.indices) { + state = state.setValue(BlockBatteryBank.BATTERY_SLOTS_PROPS[i], getItem(i).getCapability(CapabilityEnergy.ENERGY).isPresent) } - if (state != getBlockState()) { - level.setBlock(getBlockPos(), state, Block.UPDATE_CLIENTS); + if (state !== blockState) { + level.setBlock(blockPos, state, Block.UPDATE_CLIENTS) } } } - }; - - private final LazyOptional item_handler_resolver = LazyOptional.of(() -> battery_container.handler( - (slot, stack) -> stack.getCapability(CapabilityEnergy.ENERGY).isPresent(), - (slot, amount, stack) -> true - )); - - public record BatteryBankDistribution(Fraction[] distribution, Fraction max_throughput) { - } - public class BatteryBankEnergy implements IMatteryEnergyStorage { - private final BankMode mode; + private val itemHandler = container.handler( + { slot: Int, stack: ItemStack -> stack.getCapability(CapabilityEnergy.ENERGY).isPresent }, + { slot: Int, amount: Int, stack: ItemStack? -> true } + ) - public BatteryBankEnergy(BankMode mode) { - this.mode = mode; - } + private data class BatteryBankDistribution(val distribution: Array, val maxThroughput: Fraction) + private enum class BankMode { RECEIVE, EXTRACT, BIDIRECTIONAL } - public enum BankMode { - RECEIVE, - EXTRACT, - BIDIRECTIONAL - } + private inner class BatteryBankEnergy(private val mode: BankMode) : IMatteryEnergyStorage { + override fun canExtract() = mode != BankMode.RECEIVE + override fun canReceive() = mode != BankMode.EXTRACT - @Override - public boolean canExtract() { - return mode == BankMode.EXTRACT || mode == BankMode.BIDIRECTIONAL; - } - - @Override - public boolean canReceive() { - return mode == BankMode.RECEIVE || mode == BankMode.BIDIRECTIONAL; - } - - @Nonnull - @Override - public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) { + override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { if (mode == BankMode.RECEIVE) - return Fraction.ZERO; + return Fraction.ZERO - return extractEnergyInner(howMuch, simulate); + return extractEnergyInner(howMuch, simulate) } - BatteryBankDistribution getDistribution(boolean mode) { - Fraction[] distribution = new Fraction[battery_container.getContainerSize()]; - Fraction summ = Fraction.ZERO; + /** + * [mode] = true на приём, false на отдачу + */ + fun getDistribution(mode: Boolean): BatteryBankDistribution { + val distribution = Array(container.containerSize) { Fraction.ZERO } + var summ = Fraction.ZERO - for (int i = 0; i < battery_container.getContainerSize(); i++) { - ItemStack stack = battery_container.getItem(i); + for (i in 0 until container.containerSize) { + val stack = container.getItem(i) - if (!stack.isEmpty()) { - Optional cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); + if (!stack.isEmpty) { + stack.getCapability(CapabilityEnergy.ENERGY).ifPresent { + if (it is IMatteryEnergyStorage) { + val diff: Fraction - if (cap.isPresent()) { - Fraction diff = mode ? cap.get().receiveEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true) : cap.get().extractEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true); - distribution[i] = diff; - summ = summ.plus(diff); - } else { - Optional cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); + if (mode) { + diff = it.receiveEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true) + } else { + diff = it.extractEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true) + } - if (cap2.isPresent()) { - Fraction diff = new Fraction(mode ? cap2.get().receiveEnergy(Integer.MAX_VALUE, true) : cap2.get().extractEnergy(Integer.MAX_VALUE, true)); - distribution[i] = diff; - summ = summ.plus(diff); + distribution[i] = diff + summ += diff + } else { + val diff: Int + + if (mode) { + diff = it.receiveEnergy(MatteryCapability.LONG_MAX_VALUE, true) + } else { + diff = it.extractEnergy(MatteryCapability.LONG_MAX_VALUE, true) + } + + distribution[i] = Fraction(diff) + summ += distribution[i] } } - } else { - distribution[i] = Fraction.ZERO; } } - if (summ.compareTo(Fraction.ZERO) != 0) { - for (int i = 0; i < battery_container.getContainerSize(); i++) { - distribution[i] = distribution[i].div(summ); + if (!summ.isZero()) { + for (i in 0 until container.containerSize) { + distribution[i] = distribution[i] / summ } } - return new BatteryBankDistribution(distribution, summ); + return BatteryBankDistribution(distribution, summ) } - private Fraction distributeEnergy(boolean mode, Fraction howMuch, boolean simulate) { - BatteryBankDistribution distribution = getDistribution(mode); + private fun distributeEnergy(mode: Boolean, howMuch: Fraction, simulate: Boolean): Fraction { + val distribution = getDistribution(mode) - if (distribution.max_throughput.compareTo(Fraction.ZERO) == 0) - return Fraction.ZERO; + if (distribution.maxThroughput.isZero()) + return Fraction.ZERO - Fraction[] distList = distribution.distribution; - Fraction summ = Fraction.ZERO; + val distList: Array = distribution.distribution + var summ = Fraction.ZERO - for (int i = 0; i < battery_container.getContainerSize(); i++) { - if (!distList[i].equals(Fraction.ZERO)) { - ItemStack stack = battery_container.getItem(i); + for (i in 0 until container.containerSize) { + if (!distList[i].isZero()) { + val stack = container.getItem(i) - if (!stack.isEmpty()) { - Optional cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); + if (!stack.isEmpty) { + stack.getCapability(CapabilityEnergy.ENERGY).ifPresent { + if (it is IMatteryEnergyStorage) { + val diff: Fraction - if (cap.isPresent()) { - Fraction diff = mode ? cap.get().receiveEnergyOuter(howMuch.times(distList[i]), simulate) : cap.get().extractEnergyOuter(howMuch.times(distList[i]), simulate); - summ = summ.plus(diff); - } else { - Optional cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); + if (mode) { + diff = it.receiveEnergyOuter(howMuch * distList[i], simulate) + } else { + diff = it.extractEnergyOuter(howMuch * distList[i], simulate) + } - if (cap2.isPresent()) { - Fraction diff = mode ? MatteryCapability.floodFE(cap2.get(), howMuch.times(distList[i]), simulate) : MatteryCapability.drainFE(cap2.get(), howMuch.times(distList[i]), simulate); - summ = summ.plus(diff); + summ += diff + } else { + val diff: Int + + if (mode) { + diff = it.receiveEnergy(howMuch * distList[i], simulate) + } else { + diff = it.extractEnergy(howMuch * distList[i], simulate) + } + + summ += Fraction(diff) } } } @@ -169,216 +167,193 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { } if (!simulate && !summ.isZero()) { - setChangedLight(); + setChangedLight() } - return summ; + return summ } - @Nonnull - @Override - public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) { - return distributeEnergy(false, howMuch, simulate); + override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + return distributeEnergy(false, howMuch, simulate) } - @Nonnull - @Override - public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) { + override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { if (mode == BankMode.EXTRACT) - return Fraction.ZERO; + return Fraction.ZERO - return receiveEnergyInner(howMuch, simulate); + return receiveEnergyInner(howMuch, simulate) } - @Nonnull - @Override - public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) { - return distributeEnergy(true, howMuch, simulate); + override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + return distributeEnergy(true, howMuch, simulate) } - @Nonnull - @Override - public Fraction getBatteryLevel() { - Fraction result = Fraction.ZERO; + override fun getBatteryLevel(): Fraction { + var result = Fraction.ZERO - for (int i = 0; i < battery_container.getContainerSize(); i++) { - ItemStack stack = battery_container.getItem(i); + for (i in 0 until container.containerSize) { + val stack = container.getItem(i) - if (!stack.isEmpty()) { - Optional cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); - - if (cap.isPresent()) { - result = result.plus(cap.get().getBatteryLevel()); - } else { - Optional cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); - - if (cap2.isPresent()) { - result = result.plus(cap2.get().getEnergyStored()); + if (!stack.isEmpty) { + stack.getCapability(CapabilityEnergy.ENERGY).ifPresent { + if (it is IMatteryEnergyStorage) { + result += it.batteryLevel + } else { + result += it.energyStored } } } } - return result; + return result } - @Nonnull - @Override - public Fraction getMaxBatteryLevel() { - Fraction result = Fraction.ZERO; + override fun getMaxBatteryLevel(): Fraction { + var result = Fraction.ZERO - for (int i = 0; i < battery_container.getContainerSize(); i++) { - ItemStack stack = battery_container.getItem(i); + for (i in 0 until container.containerSize) { + val stack = container.getItem(i) - if (!stack.isEmpty()) { - Optional cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); - - if (cap.isPresent()) { - result = result.plus(cap.get().getMaxBatteryLevel()); - } else { - Optional cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); - - if (cap2.isPresent()) { - result = result.plus(cap2.get().getMaxEnergyStored()); + if (!stack.isEmpty) { + stack.getCapability(CapabilityEnergy.ENERGY).ifPresent { + if (it is IMatteryEnergyStorage) { + result += it.maxBatteryLevel + } else { + result += it.maxEnergyStored } } } } - return result; + return result } } - public final BatteryBankEnergy energy_receiver = new BatteryBankEnergy(BatteryBankEnergy.BankMode.RECEIVE); - private LazyOptional energy_receiver_resolver = LazyOptional.of(() -> energy_receiver); + 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 resolverEnergy = LazyOptional.of { energy } + private var resolverItemHandler = LazyOptional.of { itemHandler } - public final BatteryBankEnergy energy_extractor = new BatteryBankEnergy(BatteryBankEnergy.BankMode.EXTRACT); - private LazyOptional energy_extractor_resolver = LazyOptional.of(() -> energy_extractor); + private var valid = true - public final BatteryBankEnergy energy = new BatteryBankEnergy(BatteryBankEnergy.BankMode.BIDIRECTIONAL); - private LazyOptional energy_resolver = LazyOptional.of(() -> energy); - - protected boolean valid = true; - - public BlockEntityBatteryBank(BlockPos p_155229_, BlockState p_155230_) { - super(Registry.BlockEntities.BATTERY_BANK, p_155229_, p_155230_); + override fun saveAdditional(nbt: CompoundTag) { + super.saveAdditional(nbt) + nbt["battery_bank"] = container.serializeNBT() } - @Override - public void saveAdditional(CompoundTag nbt) { - super.saveAdditional(nbt); - nbt.put("battery_bank", battery_container.serializeNBT()); - } - - @Override - public void load(CompoundTag nbt) { - battery_container.deserializeNBT(nbt.get("battery_bank")); - super.load(nbt); - } - - private final TranslatableComponent MACHINE_NAME = new TranslatableComponent("block.overdrive_that_matters.battery_bank"); - - @Override - protected Component getDefaultDisplayName() { - return MACHINE_NAME; - } - - @Nullable - @Override - public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) { - return new BatteryBankMenu(containerID, inventory, this, this.battery_container); - } - - @Override - public void invalidateCaps() { - super.invalidateCaps(); - valid = false; - energy_receiver_resolver.invalidate(); - energy_extractor_resolver.invalidate(); - energy_resolver.invalidate(); - } - - @Override - public void reviveCaps() { - super.reviveCaps(); - valid = true; - energy_receiver_resolver = LazyOptional.of(() -> energy_receiver); - energy_extractor_resolver = LazyOptional.of(() -> energy_extractor); - energy_resolver = LazyOptional.of(() -> energy); - } - - @Override - public void setLevel(Level p_155231_) { - super.setLevel(p_155231_); - tickOnceServer(this::checkSurroundings); - } - - @Nonnull - public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { - if (valid && (cap == MatteryCapability.ENERGY || cap == CapabilityEnergy.ENERGY)) { - if (side == null) - return energy_resolver.cast(); - - if (side == getBlockState().getValue(BlockMatteryRotatable.FACING)) - return energy_extractor_resolver.cast(); - - return energy_receiver_resolver.cast(); + override fun load(nbt: CompoundTag) { + nbt.ifHas("battery_bank") { + container.deserializeNBT(it) } - if (valid && cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) - return item_handler_resolver.cast(); - - return super.getCapability(cap, side); + super.load(nbt) } - protected LazyOptional output_cap_mte = LazyOptional.empty(); - protected LazyOptional output_cap_fe = LazyOptional.empty(); - - protected void _checkSurroundings() { - if (level instanceof ServerLevel level) - checkSurroundings(level); + companion object { + private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.battery_bank") } - public void checkSurroundings(Level level) { - if (isRemoved()) - return; + override fun getDefaultDisplayName(): Component { + return MACHINE_NAME + } - final var get_entity = level.getBlockEntity(getBlockPos().offset(getBlockState().getValue(BlockMatteryRotatable.FACING).getNormal())); + override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? { + return BatteryBankMenu(containerID, inventory, this, container) + } - if (get_entity == null) { - output_cap_mte = LazyOptional.empty(); - output_cap_fe = LazyOptional.empty(); - return; + override fun invalidateCaps() { + super.invalidateCaps() + valid = false + resolverEnergyReceive.invalidate() + resolverEnergyExtractor.invalidate() + resolverEnergy.invalidate() + resolverItemHandler.invalidate() + } + + override fun reviveCaps() { + super.reviveCaps() + valid = true + resolverEnergyReceive = LazyOptional.of { energyReceiver } + resolverEnergyExtractor = LazyOptional.of { energyExtractor } + resolverEnergy = LazyOptional.of { energy } + resolverItemHandler = LazyOptional.of { itemHandler } + } + + override fun setLevel(p_155231_: Level) { + super.setLevel(p_155231_) + tickOnceServer { level: Level -> checkSurroundings(level) } + } + + override fun getCapability(cap: Capability, side: Direction?): LazyOptional { + if (valid) { + if (cap === MatteryCapability.ENERGY || cap === CapabilityEnergy.ENERGY) { + if (side == null) return resolverEnergy.cast() + + if (side == blockState.getValue(BlockMatteryRotatable.FACING)) + return resolverEnergyExtractor.cast() + else + return resolverEnergyReceive.cast() + } + + if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { + return resolverItemHandler.cast() + } } - output_cap_mte = getAndBind(output_cap_mte, get_entity, MatteryCapability.ENERGY, getBlockState().getValue(BlockMatteryRotatable.FACING).getOpposite(), this::_checkSurroundings); - output_cap_fe = getAndBind(output_cap_fe, get_entity, CapabilityEnergy.ENERGY, getBlockState().getValue(BlockMatteryRotatable.FACING).getOpposite(), this::_checkSurroundings); + return super.getCapability(cap,side) } - public static void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { - if (t instanceof BlockEntityBatteryBank tile) { - if (tile.isBlockedByRedstone()) - return; + private var outputCapability = LazyOptional.empty() - if (tile.output_cap_mte.isPresent()) { - final var cap = tile.output_cap_mte.resolve().get(); + fun checkSurroundings(level: Level) { + if (isRemoved) return - if (cap.canReceive()) { - BatteryBankDistribution distribution = tile.energy.getDistribution(false); - Fraction diff = cap.receiveEnergyOuter(distribution.max_throughput, true); - diff = tile.energy.extractEnergyOuter(diff, false); - cap.receiveEnergyOuter(diff, false); + val tile = level.getBlockEntity(blockPos.offset(blockState.getValue(BlockMatteryRotatable.FACING).normal)) + + if (tile == null) { + outputCapability = LazyOptional.empty() + return + } + + outputCapability = getAndBind( + outputCapability, + tile, + CapabilityEnergy.ENERGY, + -blockState.getValue(BlockMatteryRotatable.FACING) + ) { + val level = this.level + + if (level is ServerLevel) + checkSurroundings(level) + } + } + + fun tick() { + if (isBlockedByRedstone) + return + + outputCapability.ifPresent { + val (_, maxThroughput) = energy.getDistribution(false) + + if (maxThroughput.isZero()) + return@ifPresent + + if (it is IMatteryEnergyStorage) { + val diff = it.receiveEnergyOuter(maxThroughput, false) + + if (!diff.isZero()) { + energy.extractEnergyInner(diff, false) } - } else if (tile.output_cap_fe.isPresent()) { - final var cap = tile.output_cap_fe.resolve().get(); + } else { + val diff = it.receiveEnergy(maxThroughput, false) - if (cap.canReceive()) { - BatteryBankDistribution distribution = tile.energy.getDistribution(false); - Fraction diff = MatteryCapability.floodFE(cap, distribution.max_throughput, true); - diff = tile.energy.extractEnergyOuter(diff, false); - MatteryCapability.floodFE(cap, diff, false); + if (diff != 0) { + energy.extractEnergyInner(diff, false) } } } } -} +} \ No newline at end of file