diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/Ext.kt index 11ba5a8e5..43d4b3bae 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/Ext.kt @@ -4,6 +4,7 @@ import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.core.Vec3i import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.ListTag import net.minecraft.nbt.Tag import java.util.function.Consumer @@ -47,7 +48,7 @@ inline fun CompoundTag.ifHas(s: String, type: Byte, consumer: (Tag) -> Unit) { } } -inline fun CompoundTag.ifHas(s: String, type: Class, consumer: (T) -> Unit) { +inline fun CompoundTag.ifHas(s: String, type: Class, consumer: (T) -> Unit) { val tag = get(s) if (tag != null && tag::class.java == type) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockEnergyCounter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockEnergyCounter.kt index b89068704..b7ad88c11 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockEnergyCounter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockEnergyCounter.kt @@ -1,74 +1,75 @@ -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.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.EnumProperty; -import ru.dbotthepony.mc.otm.Registry; -import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter; -import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterBottler; +import net.minecraft.core.BlockPos +import net.minecraft.core.Direction +import net.minecraft.world.item.context.BlockPlaceContext +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.EnumProperty +import ru.dbotthepony.mc.otm.Registry +import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; - -@ParametersAreNonnullByDefault -@MethodsReturnNonnullByDefault -public class BlockEnergyCounter extends BlockMattery implements EntityBlock { - public static final EnumProperty INPUT_DIRECTION = EnumProperty.create("input", Direction.class); - public static final EnumProperty IF_DIRECTION = EnumProperty.create("if", Direction.class); - - @Nullable - @Override - public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { - return new BlockEntityEnergyCounter(blockPos, blockState); +class BlockEnergyCounter : BlockMattery(), EntityBlock { + override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity { + return BlockEntityEnergyCounter(blockPos, blockState) } - @Nullable - @Override - public BlockEntityTicker getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType p_153214_) { - return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.ENERGY_COUNTER ? null : BlockEntityEnergyCounter::tick; + override fun getTicker( + level: Level, + blockState: BlockState, + blockEntityType: BlockEntityType + ): BlockEntityTicker? { + if (level.isClientSide || blockEntityType !== Registry.BlockEntities.ENERGY_COUNTER) + return null + + return BlockEntityTicker { _, _, _, tile -> if (tile is BlockEntityEnergyCounter) tile.tick() } } - @Nullable - @Override - public BlockState getStateForPlacement(BlockPlaceContext context) { - final var input_direction = context.getPlayer() != null && context.getPlayer().isCrouching() ? context.getClickedFace().getOpposite() : context.getClickedFace(); - final var opposite = input_direction.getOpposite(); + override fun getStateForPlacement(context: BlockPlaceContext): BlockState? { + val inputDir = + if (context.player != null && context.player!!.isCrouching) context.clickedFace.opposite else context.clickedFace - Direction dir = null; + val opposite = inputDir.opposite + var dir: Direction? = null - for (var _dir : context.getNearestLookingDirections()) { - if (_dir != input_direction && _dir != opposite) { - dir = _dir.getOpposite(); - break; + for (_dir in context.nearestLookingDirections) { + if (_dir != inputDir && _dir != opposite) { + dir = _dir.opposite + break } } - assert dir != null; - return defaultBlockState().setValue(INPUT_DIRECTION, input_direction).setValue(IF_DIRECTION, dir); + return defaultBlockState().setValue(INPUT_DIRECTION, inputDir).setValue(IF_DIRECTION, dir!!) } - @Override - protected void createBlockStateDefinition(StateDefinition.Builder p_49915_) { - super.createBlockStateDefinition(p_49915_); - p_49915_.add(INPUT_DIRECTION, IF_DIRECTION); + override fun createBlockStateDefinition(p_49915_: StateDefinition.Builder) { + super.createBlockStateDefinition(p_49915_) + p_49915_.add(INPUT_DIRECTION, IF_DIRECTION) } - @Override - public void neighborChanged(BlockState state, Level level, BlockPos pos, Block sender, BlockPos sender_pos, boolean flag) { - super.neighborChanged(state, level, pos, sender, sender_pos, flag); + 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) - if (!level.isClientSide && level.getBlockEntity(pos) instanceof BlockEntityEnergyCounter tile) { - tile.checkSurroundings(level); + if (!level.isClientSide) { + (level.getBlockEntity(pos) as? BlockEntityEnergyCounter)?.checkSurroundings(level) } } + + companion object { + @JvmField val INPUT_DIRECTION: EnumProperty = EnumProperty.create("input", Direction::class.java) + @JvmField val IF_DIRECTION: EnumProperty = EnumProperty.create("if", Direction::class.java) + } } 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 265c26abe..13a0559ad 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 @@ -188,7 +188,7 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block return distributeEnergy(true, howMuch, simulate) } - override fun getBatteryLevel(): Fraction { + override val batteryLevel: Fraction get() { var result = Fraction.ZERO for (i in 0 until container.containerSize) { @@ -208,7 +208,7 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block return result } - override fun getMaxBatteryLevel(): Fraction { + override val maxBatteryLevel: Fraction get() { var result = Fraction.ZERO for (i in 0 until container.containerSize) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityChemicalGenerator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityChemicalGenerator.kt index 8964590ea..21bdeed01 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityChemicalGenerator.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityChemicalGenerator.kt @@ -29,10 +29,11 @@ import ru.dbotthepony.mc.otm.menu.ChemicalGeneratorMenu import ru.dbotthepony.mc.otm.* import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState +import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.capability.receiveEnergy import java.lang.ref.WeakReference -class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEntityMattery(Registry.BlockEntities.CHEMICAL_GENERATOR, pos, state), IMatteryEnergyStorage { +class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEntityMattery(Registry.BlockEntities.CHEMICAL_GENERATOR, pos, state) { override fun getDefaultDisplayName(): Component { return NAME } @@ -42,13 +43,14 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti } private var valid = true - private var resolver = LazyOptional.of {this} + private var resolver = LazyOptional.of {energy} + @JvmField val energy = MatteryMachineEnergyStorage(this::setChangedLight, MatteryMachineEnergyStorage.MachineType.GENERATOR, MAX_ENERGY, THROUGHPUT) override fun getCapability(cap: Capability, side: Direction?): LazyOptional { - if (valid && (cap == MatteryCapability.ENERGY || cap == CapabilityEnergy.ENERGY) && side != blockState.getValue(BlockMatteryRotatable.FACING)) + if (valid && (cap === MatteryCapability.ENERGY || cap === CapabilityEnergy.ENERGY) && side !== blockState.getValue(BlockMatteryRotatable.FACING)) return resolver.cast() - if (valid && cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) + if (valid && cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.get().cast() return super.getCapability(cap, side) @@ -65,7 +67,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti super.reviveCaps() itemHandler.revive() valid = true - resolver = LazyOptional.of {this} + resolver = LazyOptional.of {energy} } override fun setLevel(level: Level) { @@ -87,7 +89,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti override fun saveAdditional(nbt: CompoundTag) { super.saveAdditional(nbt) - nbt["energy"] = power.serializeNBT() + nbt["energy"] = energy.serializeNBT() nbt["slots"] = container.serializeNBT() nbt["working_ticks"] = workingTicks nbt["working_ticks_total"] = workingTicksTotal @@ -96,8 +98,8 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti override fun load(nbt: CompoundTag) { super.load(nbt) - nbt.ifHas("energy") { - power = Fraction.deserializeNBT(it) + nbt.ifHas("energy", CompoundTag::class.java) { + energy.deserializeNBT(it) } nbt.ifHas("slots") { @@ -169,44 +171,6 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti } } - private var power = Fraction.ZERO - - override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { - return extractEnergyInner(howMuch, simulate) - } - - override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { - val extracted = howMuch.min(THROUGHPUT, power) - - if (!simulate && !extracted.isZero()) { - power -= extracted - check = true - setChangedLight() - } - - return extracted - } - - override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { - return Fraction.ZERO - } - - override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { - val new = (howMuch + power).min(MAX_ENERGY) - val diff = new - power - - if (!simulate) { - power = new - setChangedLight() - } - - return diff - } - - override fun getBatteryLevel(): Fraction = power - override fun getMaxBatteryLevel(): Fraction = MAX_ENERGY - override fun canExtract(): Boolean = true - var workingTicks = 0 private set @@ -218,19 +182,19 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti private fun workWithPower(it: IEnergyStorage) { if (it is IMatteryEnergyStorage) { val demand = it.missingPower - val extracted = extractEnergyInner(demand, true) + val extracted = energy.extractEnergyInner(demand, true) val received = it.receiveEnergyOuter(extracted, false) if (!received.isZero()) { - extractEnergyInner(received, false) + energy.extractEnergyInner(received, false) } } else { val demand = it.receiveEnergy(THROUGHPUT_INT, true) - val extracted = extractEnergyInner(demand, true) + val extracted = energy.extractEnergyInner(demand, true) val received = it.receiveEnergy(extracted, false) if (received != 0) { - extractEnergyInner(received, false) + energy.extractEnergyInner(received, false) } } } @@ -238,7 +202,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti fun tick() { if (workingTicks > 0 && !isBlockedByRedstone) { workingTicks-- - receiveEnergyInner(GENERATION_SPEED, false) + energy.receiveEnergyInner(GENERATION_SPEED, false) if (workingTicks == 0) { workingTicksTotal = 0 @@ -256,7 +220,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti if (!container.getItem(0).isEmpty) { val ticks = ForgeHooks.getBurnTime(container.getItem(0), null) - if (ticks >= 4 && (batteryLevel < Fraction.ONE || GENERATION_SPEED * (ticks / 4) + batteryLevel <= maxBatteryLevel)) { + if (ticks >= 4 && (energy.batteryLevel < Fraction.ONE || GENERATION_SPEED * (ticks / 4) + energy.batteryLevel <= energy.maxBatteryLevel)) { workingTicksTotal = ticks / 4 workingTicks = ticks / 4 container.getItem(0).shrink(1) @@ -266,13 +230,13 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti check = false } - if (power.isZero()) return + if (energy.batteryLevel.isZero()) return val item = container.getItem(1) if (!item.isEmpty) { item.getCapability(CapabilityEnergy.ENERGY).ifPresent(this::workWithPower) - if (power.isZero()) return + if (energy.batteryLevel.isZero()) return } for (consumer in consumers) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.kt index a0e2dcf6d..65c7f2662 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.kt @@ -1,410 +1,349 @@ -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.*; -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.level.Level; -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 org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import ru.dbotthepony.mc.otm.OverdriveThatMatters; -import ru.dbotthepony.mc.otm.Registry; -import ru.dbotthepony.mc.otm.block.BlockEnergyCounter; -import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; -import ru.dbotthepony.mc.otm.capability.MatteryCapability; -import ru.dbotthepony.mc.otm.core.Fraction; -import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu; +import net.minecraft.core.BlockPos +import net.minecraft.core.Direction +import net.minecraft.nbt.ByteArrayTag +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.IntTag +import net.minecraft.nbt.ListTag +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.level.Level +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 ru.dbotthepony.mc.otm.* +import ru.dbotthepony.mc.otm.block.BlockEnergyCounter +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.core.Fraction +import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu +import java.lang.ref.WeakReference -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; -import java.lang.ref.WeakReference; -import java.util.Arrays; +class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(Registry.BlockEntities.ENERGY_COUNTER, p_155229_, p_155230_) { + var passed = Fraction.ZERO + private set -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -public class BlockEntityEnergyCounter extends BlockEntityMattery { - protected Fraction passed = Fraction.ZERO; - protected final Fraction[] history = new Fraction[10 * 20]; - protected int history_tick = 0; + private val history = Array(10 * 20) { Fraction.ZERO } + private var historyTick = 0 - public static void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { - if (t instanceof BlockEntityEnergyCounter tile) { - tile.history_tick = (tile.history_tick + 1) % tile.history.length; - tile.history[tile.history_tick] = Fraction.ZERO; - } - } + fun size() = history.size + operator fun get(i: Int) = history[i] + val lastTick: Fraction get() = history[historyTick] - public Fraction[] getHistory(int ticks) { - if (ticks < 1 || ticks >= history.length) { - throw new IllegalArgumentException("Invalid history length provided"); + fun getHistory(ticks: Int): Array { + require(!(ticks < 1 || ticks >= history.size)) { "Invalid history length provided" } + + val history = Array(ticks) { Fraction.ZERO } + + for (i in 0 until ticks) { + var index = (historyTick - i) % this.history.size + if (index < 0) index += this.history.size + history[i] = this.history[index] } - final var history = new Fraction[ticks]; + return history + } - for (int i = 0; i < ticks; i++) { - int index = (history_tick - i) % this.history.length; + fun calcAverage(ticks: Int): Fraction { + return sumHistory(ticks) / ticks + } - if (index < 0) - index += this.history.length; + fun sumHistory(ticks: Int): Fraction { + require(!(ticks < 1 || ticks >= history.size)) { "Invalid history length provided" } - history[i] = this.history[index]; + var value = Fraction.ZERO + + for (i in 0 until ticks) { + var index = (historyTick - i) % history.size + if (index < 0) index += history.size + value += history[index] } - return history; + return value } - public Fraction calcAverage(int ticks) { - return sumHistory(ticks).div(ticks); + override fun saveAdditional(nbt: CompoundTag) { + super.saveAdditional(nbt) + nbt["passed"] = passed.serializeNBT() + + val list = ListTag() + nbt["history"] = list + nbt["history_tick"] = historyTick + + for (num in history) + list.add(num.serializeNBT()) } - public Fraction sumHistory(int ticks) { - if (ticks < 1 || ticks >= history.length) { - throw new IllegalArgumentException("Invalid history length provided"); + override fun load(nbt: CompoundTag) { + super.load(nbt) + + nbt.ifHas(("passed")) { + passed = Fraction.deserializeNBT(it) } - var value = Fraction.ZERO; - - for (int i = 0; i < ticks; i++) { - int index = (history_tick - i) % this.history.length; - - if (index < 0) - index += this.history.length; - - value = value.plus(history[index]); + nbt.ifHas(("history_tick"), IntTag::class.java) { + historyTick = it.asInt } - return value; - } - - public Fraction getPassed() { - return passed; - } - - public BlockEntityEnergyCounter(BlockPos p_155229_, BlockState p_155230_) { - super(Registry.BlockEntities.ENERGY_COUNTER, p_155229_, p_155230_); - Arrays.fill(history, Fraction.ZERO); - } - - @Override - public void saveAdditional(CompoundTag nbt) { - super.saveAdditional(nbt); - nbt.put("passed", passed.serializeNBT()); - var list = new ListTag(); - nbt.put("history", list); - nbt.putInt("history_tick", history_tick); - - for (var num : history) - list.add(StringTag.valueOf(num.toString())); - } - - private static final Logger LOGGER = LogManager.getLogger(); - - @Override - public void load(CompoundTag nbt) { - super.load(nbt); - - if (nbt.contains("passed")) - passed = Fraction.deserializeNBT(nbt.get("passed")); - - if (nbt.get("history_tick") instanceof IntTag tag) - history_tick = tag.getAsInt(); - - // TODO: старый формат данных, удалить на релизе - var list = nbt.getList("history", Tag.TAG_STRING); - - for (int i = 0; i < list.size(); i++) { - try { - history[i] = Fraction.fromString(list.getString(i)); - } catch(Throwable err) { - LOGGER.error(err); - } - } - - // новый формат данных - list = nbt.getList("history", Tag.TAG_BYTE_ARRAY); - - for (int i = 0; i < list.size(); i++) { - try { - history[i] = Fraction.fromString(list.getString(i)); - } catch(Throwable err) { - LOGGER.error(err); + nbt.ifHas("history", ListTag::class.java) { + for (i in it.indices) { + val bytes = it[i] as? ByteArrayTag + history[i] = if (bytes != null) Fraction.deserializeNBT(bytes) else Fraction.ZERO } } } - private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.energy_counter"); - - @Override - protected Component getDefaultDisplayName() { - return NAME; + override fun getDefaultDisplayName(): Component { + return NAME } - @Nullable - @Override - public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) { - return new EnergyCounterMenu(containerID, inventory, this); + override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { + return EnergyCounterMenu(containerID, inventory, this) } - public final EnergyCounterCap input = new EnergyCounterCap(true); - public final EnergyCounterCap output = new EnergyCounterCap(false); + private val energyInput = EnergyCounterCap(true) + private val energyOutput = EnergyCounterCap(false) - protected LazyOptional input_cap_mte = LazyOptional.empty(); - protected LazyOptional input_cap_fe = LazyOptional.empty(); - protected LazyOptional output_cap_mte = LazyOptional.empty(); - protected LazyOptional output_cap_fe = LazyOptional.empty(); + private var inputCapability = LazyOptional.empty() + private var outputCapability = LazyOptional.empty() - @Override - public void setLevel(Level p_155231_) { - super.setLevel(p_155231_); + override fun setLevel(p_155231_: Level) { + super.setLevel(p_155231_) - if (p_155231_ instanceof ServerLevel level) { - OverdriveThatMatters.tickOnceSelf(level, this::checkSurroundings); + val level = level + if (level is ServerLevel) { + OverdriveThatMatters.tickOnce(level) { checkSurroundings(level) } } } - public class EnergyCounterCap implements IMatteryEnergyStorage { - public final boolean is_input; - - public EnergyCounterCap(boolean is_input) { - this.is_input = is_input; + private inner class EnergyCounterCap(val is_input: Boolean) : IMatteryEnergyStorage { + override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { + return extractEnergyInner(howMuch, simulate) } - private EnergyCounterCap opposite() { - return is_input ? output : input; - } - - @Override - public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) { - return extractEnergyInner(howMuch, simulate); - } - - @Override - public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) { + override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { if (is_input) - return Fraction.ZERO; + return Fraction.ZERO - if (input_cap_mte.isPresent()) { - final var value = input_cap_mte.resolve().get().extractEnergyOuter(howMuch, simulate); + if (inputCapability.isPresent) { + val it = inputCapability.resolve().get() - if (!simulate) { - passed = passed.plus(value); - history[history_tick] = history[history_tick].plus(value); - setChangedLight(); + val diff: Fraction + + if (it is IMatteryEnergyStorage) { + diff = it.extractEnergyOuter(howMuch, simulate) + } else { + diff = Fraction(it.extractEnergy(howMuch, simulate)) } - return value; - } - - if (input_cap_fe.isPresent()) { - final var value = MatteryCapability.drainFE(input_cap_fe.resolve().get(), howMuch, simulate); - if (!simulate) { - passed = passed.plus(value); - history[history_tick] = history[history_tick].plus(value); - setChangedLight(); + passed += diff + history[historyTick] += diff } - return value; + return diff } - return Fraction.ZERO; + return Fraction.ZERO } - @Override - public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) { - return receiveEnergyInner(howMuch, simulate); + override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { + return receiveEnergyInner(howMuch, simulate) } - @Override - public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) { + override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { if (!is_input) - return Fraction.ZERO; + return Fraction.ZERO - if (output_cap_mte.isPresent()) { - final var value = output_cap_mte.resolve().get().receiveEnergyOuter(howMuch, simulate); + if (outputCapability.isPresent) { + val it = outputCapability.resolve().get() + + val diff: Fraction + + if (it is IMatteryEnergyStorage) { + diff = it.receiveEnergyOuter(howMuch, simulate) + } else { + diff = Fraction(it.receiveEnergy(howMuch, simulate)) + } if (!simulate) { - passed = passed.plus(value); - history[history_tick] = history[history_tick].plus(value); - setChangedLight(); + passed += diff + history[historyTick] += diff } - return value; + return diff } - if (output_cap_fe.isPresent()) { - final var value = MatteryCapability.floodFE(output_cap_fe.resolve().get(), howMuch, simulate); + return Fraction.ZERO + } - if (!simulate) { - passed = passed.plus(value); - history[history_tick] = history[history_tick].plus(value); - setChangedLight(); + override val batteryLevel: Fraction + get() { + if (is_input) { + if (outputCapability.isPresent) { + val it = outputCapability.resolve().get() + + if (it is IMatteryEnergyStorage) { + return it.batteryLevel + } + + return Fraction(it.energyStored) + } + } else { + if (inputCapability.isPresent) { + val it = inputCapability.resolve().get() + + if (it is IMatteryEnergyStorage) { + return it.batteryLevel + } + + return Fraction(it.energyStored) + } } - return value; + return Fraction.ZERO } - return Fraction.ZERO; - } + override val maxBatteryLevel: Fraction + get() { + if (is_input) { + if (outputCapability.isPresent) { + val it = outputCapability.resolve().get() - @Override - public Fraction getBatteryLevel() { - if (is_input) { - if (output_cap_mte.isPresent()) { - return output_cap_mte.resolve().get().getBatteryLevel(); + if (it is IMatteryEnergyStorage) { + return it.maxBatteryLevel + } + + return Fraction(it.maxEnergyStored) + } + } else { + if (inputCapability.isPresent) { + val it = inputCapability.resolve().get() + + if (it is IMatteryEnergyStorage) { + return it.maxBatteryLevel + } + + return Fraction(it.maxEnergyStored) + } } - if (output_cap_fe.isPresent()) { - return new Fraction(output_cap_fe.resolve().get().getEnergyStored()); - } - } else { - if (input_cap_mte.isPresent()) { - return input_cap_mte.resolve().get().getBatteryLevel(); - } - - if (input_cap_fe.isPresent()) { - return new Fraction(input_cap_fe.resolve().get().getEnergyStored()); - } + return Fraction.ZERO } - return Fraction.ZERO; - } - - @Override - public Fraction getMaxBatteryLevel() { - if (is_input) { - if (output_cap_mte.isPresent()) { - return output_cap_mte.resolve().get().getMaxBatteryLevel(); - } - - if (output_cap_fe.isPresent()) { - return new Fraction(output_cap_fe.resolve().get().getMaxEnergyStored()); - } - } else { - if (input_cap_mte.isPresent()) { - return input_cap_mte.resolve().get().getMaxBatteryLevel(); - } - - if (input_cap_fe.isPresent()) { - return new Fraction(input_cap_fe.resolve().get().getMaxEnergyStored()); - } - } - - return Fraction.ZERO; - } - - @Override - public boolean canExtract() { - return !is_input; - } - - @Override - public boolean canReceive() { - return is_input; - } + override fun canExtract() = !is_input + override fun canReceive() = is_input } - protected LazyOptional input_resolver = LazyOptional.of(() -> input); - protected LazyOptional output_resolver = LazyOptional.of(() -> output); + private var resolverInput = LazyOptional.of { energyInput } + private var resolverOutput = LazyOptional.of { energyOutput } + private var valid = true - @Override - public void invalidateCaps() { - super.invalidateCaps(); - input_resolver.invalidate(); - output_resolver.invalidate(); + override fun invalidateCaps() { + super.invalidateCaps() + valid = false + resolverInput.invalidate() + resolverOutput.invalidate() } - @Override - public void reviveCaps() { - super.reviveCaps(); - input_resolver = LazyOptional.of(() -> input); - output_resolver = LazyOptional.of(() -> output); + override fun reviveCaps() { + super.reviveCaps() + valid = true + resolverInput = LazyOptional.of { energyInput } + resolverOutput = LazyOptional.of { energyOutput } } - @Override - @SuppressWarnings("deprecation") - public void setBlockState(BlockState p_155251_) { - final var old = getBlockState(); + @Suppress("deprecation") + override fun setBlockState(new: BlockState) { + val old = blockState + super.setBlockState(new) - super.setBlockState(p_155251_); - - if (p_155251_ != old && p_155251_.getValue(BlockEnergyCounter.INPUT_DIRECTION) != old.getValue(BlockEnergyCounter.INPUT_DIRECTION)) { - input_resolver.invalidate(); - output_resolver.invalidate(); - - input_resolver = LazyOptional.of(() -> input); - output_resolver = LazyOptional.of(() -> output); + if (new !== old && new.getValue(BlockEnergyCounter.INPUT_DIRECTION) != old.getValue(BlockEnergyCounter.INPUT_DIRECTION)) { + resolverInput.invalidate() + resolverOutput.invalidate() + resolverInput = LazyOptional.of { energyInput } + resolverOutput = LazyOptional.of { energyOutput } if (level != null) - checkSurroundings(level); + checkSurroundings(level) } } - private LazyOptional getAndBind(Level level, LazyOptional old, Capability cap, Direction side) { - final var ent = level.getBlockEntity(getBlockPos().offset(side.getNormal())); + private fun getAndBind( + level: Level, + old: LazyOptional, + side: Direction + ): LazyOptional { + val ent = level.getBlockEntity(blockPos.offset(side.normal)) ?: return LazyOptional.empty() + val resolve = ent.getCapability(CapabilityEnergy.ENERGY, side.opposite) - if (ent == null) - return LazyOptional.empty(); + if (resolve !== old) { + val weak = WeakReference(this) - final var resolve = ent.getCapability(cap, side.getOpposite()); + resolve.addListener { + val get = weak.get() - if (resolve != old) { - final var weak = new WeakReference<>(this); - - resolve.addListener((l) -> { - final var get = weak.get(); - - if (get != null && get.level != null) { - get.checkSurroundings(get.level); + if (get?.level != null) { + get.checkSurroundings(get.level) } - }); + } - return resolve; + return resolve } - return old; + return old } - public void checkSurroundings(Level level) { - if (isRemoved() || !(level instanceof ServerLevel)) - return; + fun checkSurroundings(level: Level?) { + if (isRemoved || level !is ServerLevel) return - input_cap_mte = getAndBind(level, input_cap_mte, MatteryCapability.ENERGY, getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION)); - input_cap_fe = getAndBind(level, input_cap_fe, CapabilityEnergy.ENERGY, getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION)); + inputCapability = getAndBind( + level, + inputCapability, + blockState.getValue(BlockEnergyCounter.INPUT_DIRECTION) + ) - output_cap_mte = getAndBind(level, output_cap_mte, MatteryCapability.ENERGY, getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION).getOpposite()); - output_cap_fe = getAndBind(level, output_cap_fe, CapabilityEnergy.ENERGY, getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION).getOpposite()); + outputCapability = getAndBind( + level, + outputCapability, + -blockState.getValue(BlockEnergyCounter.INPUT_DIRECTION) + ) } - @Nonnull - @Override - public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { - if (side == null || isRemoved()) - return super.getCapability(cap, side); + override fun getCapability(cap: Capability, side: Direction?): LazyOptional { + if (side == null || isRemoved) + return super.getCapability(cap, side) - if (side == getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION)) { - if (cap == MatteryCapability.ENERGY || cap == CapabilityEnergy.ENERGY) { - return input_resolver.cast(); - } - } else if (side == getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION).getOpposite()) { - if (cap == MatteryCapability.ENERGY || cap == CapabilityEnergy.ENERGY) { - return output_resolver.cast(); + if (valid) { + if (side == blockState.getValue(BlockEnergyCounter.INPUT_DIRECTION)) { + if (cap === MatteryCapability.ENERGY || cap === CapabilityEnergy.ENERGY) { + return resolverInput.cast() + } + } else if (side == blockState.getValue(BlockEnergyCounter.INPUT_DIRECTION).opposite) { + if (cap === MatteryCapability.ENERGY || cap === CapabilityEnergy.ENERGY) { + return resolverOutput.cast() + } } } - return super.getCapability(cap, side); + return super.getCapability(cap, side) } -} + + fun tick() { + historyTick = (historyTick + 1) % history.size + history[historyTick] = Fraction.ZERO + } + + companion object { + private val NAME = TranslatableComponent("block.overdrive_that_matters.energy_counter") + } +} \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.kt index ff493e73e..61807d83f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.kt @@ -1,123 +1,104 @@ -package ru.dbotthepony.mc.otm.capability; +package ru.dbotthepony.mc.otm.capability -import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraftforge.energy.IEnergyStorage; -import ru.dbotthepony.mc.otm.core.Fraction; - -import javax.annotation.ParametersAreNonnullByDefault; +import net.minecraftforge.energy.IEnergyStorage +import ru.dbotthepony.mc.otm.core.Fraction // IEnergyStorage for direct compat with Forge Energy -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -@SuppressWarnings("unused") -public interface IMatteryEnergyStorage extends IEnergyStorage { +interface IMatteryEnergyStorage : IEnergyStorage { // such as cables. This is something that would work only with energy storage - Fraction extractEnergyOuter(Fraction howMuch, boolean simulate); + fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction // for internal needs, e.g. for work // CAN also be used by something that does evil // e.g. sucking out energy anomaly should use this - Fraction extractEnergyInner(Fraction howMuch, boolean simulate); + fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction // energy is received from outside, e.g. cables - Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate); + fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction // energy is received from inside, e.g. generator generates power - Fraction receiveEnergyInner(Fraction howMuch, boolean simulate); + fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction - default Fraction extractEnergyOuter(long howMuch, boolean simulate) { - return extractEnergyOuter(new Fraction(howMuch), simulate); + fun extractEnergyOuter(howMuch: Long, simulate: Boolean): Fraction { + return extractEnergyOuter(Fraction(howMuch), simulate) } - default Fraction extractEnergyOuter(int howMuch, boolean simulate) { - return extractEnergyOuter(new Fraction(howMuch), simulate); + fun extractEnergyOuter(howMuch: Int, simulate: Boolean): Fraction { + return extractEnergyOuter(Fraction(howMuch), simulate) } - default Fraction receiveEnergyOuter(long howMuch, boolean simulate) { - return receiveEnergyOuter(new Fraction(howMuch), simulate); + fun receiveEnergyOuter(howMuch: Long, simulate: Boolean): Fraction { + return receiveEnergyOuter(Fraction(howMuch), simulate) } - default Fraction receiveEnergyOuter(int howMuch, boolean simulate) { - return receiveEnergyOuter(new Fraction(howMuch), simulate); + fun receiveEnergyOuter(howMuch: Int, simulate: Boolean): Fraction { + return receiveEnergyOuter(Fraction(howMuch), simulate) } - default Fraction extractEnergyInner(long howMuch, boolean simulate) { - return extractEnergyInner(new Fraction(howMuch), simulate); + fun extractEnergyInner(howMuch: Long, simulate: Boolean): Fraction { + return extractEnergyInner(Fraction(howMuch), simulate) } - default Fraction extractEnergyInner(int howMuch, boolean simulate) { - return extractEnergyInner(new Fraction(howMuch), simulate); + fun extractEnergyInner(howMuch: Int, simulate: Boolean): Fraction { + return extractEnergyInner(Fraction(howMuch), simulate) } - default Fraction receiveEnergyInner(long howMuch, boolean simulate) { - return receiveEnergyInner(new Fraction(howMuch), simulate); + fun receiveEnergyInner(howMuch: Long, simulate: Boolean): Fraction { + return receiveEnergyInner(Fraction(howMuch), simulate) } - default Fraction receiveEnergyInner(int howMuch, boolean simulate) { - return receiveEnergyInner(new Fraction(howMuch), simulate); + fun receiveEnergyInner(howMuch: Int, simulate: Boolean): Fraction { + return receiveEnergyInner(Fraction(howMuch), simulate) } - Fraction getBatteryLevel(); + val batteryLevel: Fraction + val maxBatteryLevel: Fraction + val missingPower: Fraction + get() = maxBatteryLevel - batteryLevel - Fraction getMaxBatteryLevel(); + override fun receiveEnergy(maxReceive: Int, simulate: Boolean): Int { + val received = receiveEnergyOuter(maxReceive, true).toInt() - default Fraction getMissingPower() { - return getMaxBatteryLevel().minus(getBatteryLevel()); + // Receiving only a fraction + if (received == 0) + return 0 + + return receiveEnergyOuter(Fraction(received), simulate).toInt() } - @Override - default int receiveEnergy(int maxReceive, boolean simulate) { - int received = receiveEnergyOuter(maxReceive, true).toInt(); + override fun extractEnergy(maxReceive: Int, simulate: Boolean): Int { + val extracted = extractEnergyOuter(maxReceive, true).toInt() - if (received == 0) { - // Receiving only a fraction - return 0; - } + // Extracting only a fraction + if (extracted == 0) + return 0 - return receiveEnergyOuter(new Fraction(received), simulate).toInt(); + return extractEnergyOuter(Fraction(extracted), simulate).toInt() } - @Override - default int extractEnergy(int maxReceive, boolean simulate) { - int extracted = extractEnergyOuter(maxReceive, true).toInt(); + override fun getEnergyStored(): Int { + val level = batteryLevel - if (extracted == 0) { - // Extracting only a fraction - return 0; - } + if (level < MatteryCapability.INT_MAX_VALUE) + return level.toInt() - return extractEnergyOuter(new Fraction(extracted), simulate).toInt(); + return Int.MAX_VALUE } - @Override - default int getEnergyStored() { - Fraction level = getBatteryLevel(); + override fun getMaxEnergyStored(): Int { + val level = maxBatteryLevel - if (level.compareTo(MatteryCapability.INT_MAX_VALUE) < 0) { - return level.toInt(); - } + if (level < MatteryCapability.INT_MAX_VALUE) + return level.toInt() - return Integer.MAX_VALUE; + return Int.MAX_VALUE } - @Override - default int getMaxEnergyStored() { - Fraction level = getMaxBatteryLevel(); - - if (level.compareTo(MatteryCapability.INT_MAX_VALUE) < 0) { - return level.toInt(); - } - - return Integer.MAX_VALUE; + override fun canExtract(): Boolean { + return extractEnergyOuter(Fraction.ONE, true) > Fraction.ZERO } - @Override - default boolean canExtract() { - return extractEnergyOuter(Fraction.ONE, true).compareTo(Fraction.ZERO) > 0; + override fun canReceive(): Boolean { + return receiveEnergyOuter(Fraction.ONE, true) > Fraction.ZERO } - - @Override - default boolean canReceive() { - return receiveEnergyOuter(Fraction.ONE, true).compareTo(Fraction.ZERO) > 0; - } -} +} \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.kt index 1819379aa..88eb850d9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.kt @@ -1,144 +1,103 @@ -package ru.dbotthepony.mc.otm.capability; +package ru.dbotthepony.mc.otm.capability -import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.common.util.INBTSerializable; -import ru.dbotthepony.mc.otm.core.Fraction; +import net.minecraft.nbt.CompoundTag +import net.minecraft.world.level.block.entity.BlockEntity +import net.minecraftforge.common.util.INBTSerializable +import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.Fraction.Companion.deserializeNBT +import ru.dbotthepony.mc.otm.ifHas +import ru.dbotthepony.mc.otm.set -import javax.annotation.Nonnull; -import javax.annotation.ParametersAreNonnullByDefault; -import java.math.BigDecimal; +open class MatteryMachineEnergyStorage @JvmOverloads constructor( + protected val listener: () -> Unit, + val type: MachineType, + override var maxBatteryLevel: Fraction = DEFAULT_MAX_CAPACITY, + protected var maxInput: Fraction = DEFAULT_MAX_RECEIVE, + protected var maxOutput: Fraction = maxInput +) : IMatteryEnergyStorage, INBTSerializable { + @JvmOverloads + constructor( + listener: BlockEntity, + type: MachineType, + maxBatteryLevel: Fraction = DEFAULT_MAX_CAPACITY, + maxInput: Fraction = DEFAULT_MAX_RECEIVE, + maxOutput: Fraction = maxInput) : this({listener.setChanged()}, type, maxBatteryLevel, maxInput, maxOutput) -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTSerializable { - public enum MachineType { - WORKER, - GENERATOR, - CAPACITOR, + enum class MachineType { + WORKER, GENERATOR, CAPACITOR } - public static final Fraction DEFAULT_MAX_RECEIVE = new Fraction(200); - public static final Fraction DEFAULT_MAX_EXTRACT = new Fraction(200); - public static final Fraction DEFAULT_MAX_CAPACITY = new Fraction(60000); + override var batteryLevel = Fraction.ZERO + protected set - protected Fraction energy_stored = Fraction.ZERO; - protected Fraction energy_stored_max; - protected Fraction max_input; - protected Fraction max_output; - protected final MachineType machine_type; - protected final BlockEntity listener; + override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { + if (type == MachineType.WORKER) + return Fraction.ZERO - public MatteryMachineEnergyStorage(BlockEntity listener, MachineType type, Fraction capacity) { - this(listener, type, capacity, DEFAULT_MAX_RECEIVE, DEFAULT_MAX_EXTRACT); + return extractEnergyInner(howMuch, simulate) } - public MatteryMachineEnergyStorage(BlockEntity listener, MachineType type) { - this(listener, type, DEFAULT_MAX_CAPACITY); - } + override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + val new = batteryLevel.minus(howMuch.min(maxOutput)).moreThanZero() + val diff = batteryLevel.minus(new) - public MatteryMachineEnergyStorage(BlockEntity listener, MachineType type, Fraction capacity, Fraction maxReceive, Fraction maxExtract) { - this.listener = listener; - energy_stored_max = capacity; - max_input = maxReceive; - max_output = maxExtract; - machine_type = type; - } - - @Nonnull - @Override - public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) { - if (machine_type == MachineType.WORKER) { - return Fraction.ZERO; + if (!simulate && batteryLevel != new) { + batteryLevel = new + listener() } - return extractEnergyInner(howMuch, simulate); + return diff } - @Nonnull - @Override - public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) { - Fraction new_energy = energy_stored.minus(howMuch.min(max_output)).moreThanZero(); - Fraction diff = energy_stored.minus(new_energy); + override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { + if (type == MachineType.GENERATOR) + return Fraction.ZERO - if (!simulate && !energy_stored.equalsCompact(new_energy)) { - energy_stored = new_energy; - listener.setChanged(); + return receiveEnergyInner(howMuch, simulate) + } + + override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + val new = batteryLevel.plus(howMuch.min(maxInput)).min(maxBatteryLevel) + val diff = new.minus(batteryLevel) + + if (!simulate && batteryLevel != new) { + batteryLevel = new + listener() } - return diff; + return diff } - @Nonnull - @Override - public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) { - if (machine_type == MachineType.GENERATOR) { - return Fraction.ZERO; - } - - return receiveEnergyInner(howMuch, simulate); + override fun canExtract(): Boolean { + return type != MachineType.WORKER } - @Nonnull - @Override - public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) { - Fraction new_energy = energy_stored.plus(howMuch.min(max_input)).min(energy_stored_max); - Fraction diff = new_energy.minus(energy_stored); - - if (!simulate && !energy_stored.equalsCompact(new_energy)) { - energy_stored = new_energy; - listener.setChanged(); - } - - return diff; + override fun canReceive(): Boolean { + return type != MachineType.GENERATOR } - @Nonnull - @Override - public Fraction getBatteryLevel() { - return energy_stored; + override fun serializeNBT(): CompoundTag { + val tag = CompoundTag() + // TODO: А это вообще надо? + tag["energy_stored"] = batteryLevel.serializeNBT() + + // tag["energy_stored_max"] = maxBatteryLevel.serializeNBT() + // tag["max_input"] = maxInput.serializeNBT() + // tag["max_output"] = maxOutput.serializeNBT() + + return tag } - @Nonnull - @Override - public Fraction getMaxBatteryLevel() { - return energy_stored_max; + override fun deserializeNBT(nbt: CompoundTag) { + nbt.ifHas("energy_stored") { batteryLevel = deserializeNBT(it) } + // nbt.ifHas("energy_stored_max") { maxBatteryLevel = deserializeNBT(it) } + // nbt.ifHas("max_input") { maxInput = deserializeNBT(it) } + // nbt.ifHas("max_output") { maxOutput = deserializeNBT(it) } } - @Override - public boolean canExtract() { - return machine_type != MachineType.WORKER; + companion object { + val DEFAULT_MAX_RECEIVE = Fraction(200) + val DEFAULT_MAX_EXTRACT = Fraction(200) + val DEFAULT_MAX_CAPACITY = Fraction(60000) } - - @Override - public boolean canReceive() { - return machine_type != MachineType.GENERATOR; - } - - @Override - @Nonnull - public CompoundTag serializeNBT() { - CompoundTag tag = new CompoundTag(); - tag.put("energy_stored", energy_stored.serializeNBT()); - tag.put("energy_stored_max", energy_stored_max.serializeNBT()); - tag.put("max_input", max_input.serializeNBT()); - tag.put("max_output", max_output.serializeNBT()); - return tag; - } - - @Override - public void deserializeNBT(CompoundTag nbt) { - if (nbt.contains("energy_stored")) - energy_stored = Fraction.deserializeNBT(nbt.get("energy_stored")); - - if (nbt.contains("energy_stored_max")) - energy_stored_max = Fraction.deserializeNBT(nbt.get("energy_stored_max")); - - if (nbt.contains("max_input")) - max_input = Fraction.deserializeNBT(nbt.get("max_input")); - - if (nbt.contains("max_output")) - max_output = Fraction.deserializeNBT(nbt.get("max_output")); - } -} +} \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.kt index f411d9ffb..723930beb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.kt @@ -386,7 +386,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab return ent } - override fun getBatteryLevel(): Fraction { + override val batteryLevel: Fraction get() { if (!batteryItemStack.isEmpty) { val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve() @@ -404,7 +404,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab return battery } - override fun getMaxBatteryLevel(): Fraction { + override val maxBatteryLevel: Fraction get() { if (batteryItemStack != ItemStack.EMPTY) { val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.kt index 79cd63f47..e6d643f8b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.kt @@ -1,63 +1,78 @@ -package ru.dbotthepony.mc.otm.client.screen; +package ru.dbotthepony.mc.otm.client.screen -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.world.entity.player.Inventory; -import ru.dbotthepony.mc.otm.client.screen.panels.Dock; -import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel; -import ru.dbotthepony.mc.otm.client.screen.panels.Label; -import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu; -import ru.dbotthepony.mc.otm.menu.FormattingHelper; +import net.minecraft.network.chat.Component +import net.minecraft.network.chat.TranslatableComponent +import net.minecraft.world.entity.player.Inventory +import ru.dbotthepony.mc.otm.client.screen.panels.Dock +import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.Label +import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu +import ru.dbotthepony.mc.otm.menu.FormattingHelper -import javax.annotation.Nullable; +class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title: Component) : MatteryScreen(menu, inventory, title) { + override fun makeMainFrame(): FramePanel { + val frame = super.makeMainFrame()!! -public class EnergyCounterScreen extends MatteryScreen { - public EnergyCounterScreen(EnergyCounterMenu menu, Inventory inventory, Component title) { - super(menu, inventory, title); + var label: Label = object : Label(this@EnergyCounterScreen, frame) { + override fun tick() { + super.tick() + setText( + TranslatableComponent( + "otm.item.power.passed", + FormattingHelper.formatPower(menu.passed.value) + ) + ) + } + } + + label.dock = Dock.TOP + label.setDockMargin(4f, 0f, 0f, 0f) + + label = object : Label(this@EnergyCounterScreen, frame) { + override fun tick() { + super.tick() + setText( + TranslatableComponent( + "otm.item.power.average", + FormattingHelper.formatPower(menu.average.value) + ) + ) + } + } + + label.dock = Dock.TOP + label.setDockMargin(4f, 0f, 0f, 0f) + + label = object : Label(this@EnergyCounterScreen, frame) { + override fun tick() { + super.tick() + setText( + TranslatableComponent( + "otm.item.power.last_20_ticks", + FormattingHelper.formatPower(menu.last20Ticks.value) + ) + ) + } + } + + label.dock = Dock.TOP + label.setDockMargin(4f, 0f, 0f, 0f) + + label = object : Label(this@EnergyCounterScreen, frame) { + override fun tick() { + super.tick() + setText( + TranslatableComponent( + "otm.item.power.last_tick", + FormattingHelper.formatPower(menu.lastTick.value) + ) + ) + } + } + + label.dock = Dock.TOP + label.setDockMargin(4f, 0f, 0f, 0f) + + return frame } - - @Nullable - @Override - protected FramePanel makeMainFrame() { - var frame = super.makeMainFrame(); - - var label = (Label) new Label(this, frame) { - @Override - public void tick() { - super.tick(); - - setText(new TranslatableComponent("otm.item.power.passed", FormattingHelper.formatPower(menu.passed.getValue()))); - } - }; - - label.setDock(Dock.TOP); - label.setDockMargin(4, 0, 0, 0); - - label = new Label(this, frame) { - @Override - public void tick() { - super.tick(); - - setText(new TranslatableComponent("otm.item.power.average", FormattingHelper.formatPower(menu.average.getValue()))); - } - }; - - label.setDock(Dock.TOP); - label.setDockMargin(4, 0, 0, 0); - - label = new Label(this, frame) { - @Override - public void tick() { - super.tick(); - - setText(new TranslatableComponent("otm.item.power.last_20_ticks", FormattingHelper.formatPower(menu.last_20_ticks.getValue()))); - } - }; - - label.setDock(Dock.TOP); - label.setDockMargin(4, 0, 0, 0); - - return frame; - } -} +} \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemBattery.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemBattery.kt index cb83a2a5c..4185619d4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemBattery.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemBattery.kt @@ -66,15 +66,15 @@ class ItemBattery : Item { return diff } - override fun getMissingPower(): Fraction { - return if (isCreative) MatteryCapability.LONG_MAX_VALUE else super.getMissingPower() + override val missingPower: Fraction get() { + return if (isCreative) MatteryCapability.LONG_MAX_VALUE else super.missingPower } - override fun getBatteryLevel(): Fraction { + override val batteryLevel: Fraction get() { return if (isCreative) MatteryCapability.LONG_MAX_VALUE else energy() } - override fun getMaxBatteryLevel(): Fraction { + override val maxBatteryLevel: Fraction get() { return storage } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ChemicalGeneratorMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ChemicalGeneratorMenu.kt index 5ca322acb..05852e243 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ChemicalGeneratorMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/ChemicalGeneratorMenu.kt @@ -29,7 +29,7 @@ class ChemicalGeneratorMenu @JvmOverloads constructor(id: Int, inv: Inventory, t } val progress = ProgressGaugeWidget(this) { 1f - tile!!.workingTicks.toFloat() / tile.workingTicksTotal } - val energy = LevelGaugeWidget(this, tile) + val energy = LevelGaugeWidget(this, tile?.energy) val burnTime = IntDataContainer() init { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.kt index ed35413a5..2d6ad0bfd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.kt @@ -1,59 +1,52 @@ -package ru.dbotthepony.mc.otm.menu; +package ru.dbotthepony.mc.otm.menu -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.inventory.MenuType; -import net.minecraft.world.level.block.entity.BlockEntity; -import ru.dbotthepony.mc.otm.Registry; -import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter; -import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer; -import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer; +import kotlin.jvm.JvmOverloads +import net.minecraft.world.entity.player.Inventory +import ru.dbotthepony.mc.otm.Registry +import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter +import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer -import javax.annotation.Nullable; +class EnergyCounterMenu @JvmOverloads constructor( + p_38852_: Int, + inventory: Inventory, + tile: BlockEntityEnergyCounter? = null +) : MatteryMenu(Registry.Menus.ENERGY_COUNTER, p_38852_, inventory, tile) { + @JvmField val passed = FractionDataContainer() + @JvmField val average = FractionDataContainer() + @JvmField val last20Ticks = FractionDataContainer() + @JvmField val lastTick = FractionDataContainer() -public class EnergyCounterMenu extends MatteryMenu { - public final FractionDataContainer passed = new FractionDataContainer(); - public final FractionDataContainer average = new FractionDataContainer(); - public final FractionDataContainer last_20_ticks = new FractionDataContainer(); // TODO: Graph and proper networking for it - private int ticks_passed = 0; + private var ticksPassed = 0 - public EnergyCounterMenu(int p_38852_, Inventory inventory) { - this(p_38852_, inventory, null); + init { + addDataSlots(passed) + addDataSlots(average) + addDataSlots(last20Ticks) + addDataSlots(lastTick) } - public EnergyCounterMenu(int p_38852_, Inventory inventory, BlockEntityEnergyCounter tile) { - super(Registry.Menus.ENERGY_COUNTER, p_38852_, inventory, tile); + override fun broadcastChanges() { + if (tile is BlockEntityEnergyCounter) { + passed.value = tile.passed + average.value = tile.calcAverage(20) + lastTick.value = tile.lastTick - addDataSlots(passed); - addDataSlots(average); - addDataSlots(last_20_ticks); - } - - @Override - public void broadcastChanges() { - if (tile != null) { - BlockEntityEnergyCounter tile = (BlockEntityEnergyCounter) this.tile; - - passed.setValue(tile.getPassed()); - average.setValue(tile.calcAverage(20)); - - if (ticks_passed == 0) { - last_20_ticks.setValue(tile.sumHistory(20)); + if (ticksPassed == 0) { + last20Ticks.value = tile.sumHistory(20) } - ticks_passed = (ticks_passed + 1) % 20; + ticksPassed = (ticksPassed + 1) % 20 } - super.broadcastChanges(); + super.broadcastChanges() } - @Override - protected int getWorkingSlotStart() { - return 0; + override fun getWorkingSlotStart(): Int { + return 0 } - @Override - protected int getWorkingSlotEnd() { - return 0; + override fun getWorkingSlotEnd(): Int { + return 0 } -} +} \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/LevelGaugeWidget.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/LevelGaugeWidget.kt index 509cbcac4..dabc99612 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/LevelGaugeWidget.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/LevelGaugeWidget.kt @@ -23,8 +23,8 @@ class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) { ) : this(menu) { if (power == null) return - this.level = power::getBatteryLevel - this.maxLevel = power::getMaxBatteryLevel + this.level = power::batteryLevel + this.maxLevel = power::maxBatteryLevel } constructor( diff --git a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json index 097b1f8c4..af2a00a9c 100644 --- a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json +++ b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json @@ -40,6 +40,7 @@ "otm.item.power.passed": "Passed energy: %s", "otm.item.power.average": "Average throughput: %s/t", "otm.item.power.last_20_ticks": "Last second: %s", + "otm.item.power.last_tick": "Last tick: %s", "otm.item.power.normal.storage": "Stored energy: %s / %s", "otm.item.power.normal.throughput": "Max I/O %s / %s",