Updated energy counter, move energy API to kotlin
This commit is contained in:
parent
bb17f93a91
commit
6c029b98b7
@ -4,6 +4,7 @@ import net.minecraft.core.BlockPos
|
|||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.core.Vec3i
|
import net.minecraft.core.Vec3i
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.nbt.ListTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ inline fun CompoundTag.ifHas(s: String, type: Byte, consumer: (Tag) -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T : Tag> CompoundTag.ifHas(s: String, type: Class<T>, consumer: (T) -> Unit) {
|
inline fun <reified T : Tag> CompoundTag.ifHas(s: String, type: Class<T>, consumer: (T) -> Unit) {
|
||||||
val tag = get(s)
|
val tag = get(s)
|
||||||
|
|
||||||
if (tag != null && tag::class.java == type) {
|
if (tag != null && tag::class.java == type) {
|
||||||
|
@ -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.BlockPos;
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.world.item.context.BlockPlaceContext
|
||||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.StateDefinition
|
||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
import net.minecraft.world.level.block.state.properties.EnumProperty
|
||||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter;
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterBottler;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
class BlockEnergyCounter : BlockMattery(), EntityBlock {
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
|
||||||
|
return BlockEntityEnergyCounter(blockPos, blockState)
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
@MethodsReturnNonnullByDefault
|
|
||||||
public class BlockEnergyCounter extends BlockMattery implements EntityBlock {
|
|
||||||
public static final EnumProperty<Direction> INPUT_DIRECTION = EnumProperty.create("input", Direction.class);
|
|
||||||
public static final EnumProperty<Direction> IF_DIRECTION = EnumProperty.create("if", Direction.class);
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
|
||||||
return new BlockEntityEnergyCounter(blockPos, blockState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun <T : BlockEntity?> getTicker(
|
||||||
@Override
|
level: Level,
|
||||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) {
|
blockState: BlockState,
|
||||||
return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.ENERGY_COUNTER ? null : BlockEntityEnergyCounter::tick;
|
blockEntityType: BlockEntityType<T>
|
||||||
|
): BlockEntityTicker<T>? {
|
||||||
|
if (level.isClientSide || blockEntityType !== Registry.BlockEntities.ENERGY_COUNTER)
|
||||||
|
return null
|
||||||
|
|
||||||
|
return BlockEntityTicker { _, _, _, tile -> if (tile is BlockEntityEnergyCounter) tile.tick() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
|
||||||
@Override
|
val inputDir =
|
||||||
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
if (context.player != null && context.player!!.isCrouching) context.clickedFace.opposite else context.clickedFace
|
||||||
final var input_direction = context.getPlayer() != null && context.getPlayer().isCrouching() ? context.getClickedFace().getOpposite() : context.getClickedFace();
|
|
||||||
final var opposite = input_direction.getOpposite();
|
|
||||||
|
|
||||||
Direction dir = null;
|
val opposite = inputDir.opposite
|
||||||
|
var dir: Direction? = null
|
||||||
|
|
||||||
for (var _dir : context.getNearestLookingDirections()) {
|
for (_dir in context.nearestLookingDirections) {
|
||||||
if (_dir != input_direction && _dir != opposite) {
|
if (_dir != inputDir && _dir != opposite) {
|
||||||
dir = _dir.getOpposite();
|
dir = _dir.opposite
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert dir != null;
|
return defaultBlockState().setValue(INPUT_DIRECTION, inputDir).setValue(IF_DIRECTION, dir!!)
|
||||||
return defaultBlockState().setValue(INPUT_DIRECTION, input_direction).setValue(IF_DIRECTION, dir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun createBlockStateDefinition(p_49915_: StateDefinition.Builder<Block, BlockState>) {
|
||||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_49915_) {
|
super.createBlockStateDefinition(p_49915_)
|
||||||
super.createBlockStateDefinition(p_49915_);
|
p_49915_.add(INPUT_DIRECTION, IF_DIRECTION)
|
||||||
p_49915_.add(INPUT_DIRECTION, IF_DIRECTION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun neighborChanged(
|
||||||
public void neighborChanged(BlockState state, Level level, BlockPos pos, Block sender, BlockPos sender_pos, boolean flag) {
|
state: BlockState,
|
||||||
super.neighborChanged(state, level, pos, sender, sender_pos, flag);
|
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) {
|
if (!level.isClientSide) {
|
||||||
tile.checkSurroundings(level);
|
(level.getBlockEntity(pos) as? BlockEntityEnergyCounter)?.checkSurroundings(level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField val INPUT_DIRECTION: EnumProperty<Direction> = EnumProperty.create("input", Direction::class.java)
|
||||||
|
@JvmField val IF_DIRECTION: EnumProperty<Direction> = EnumProperty.create("if", Direction::class.java)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block
|
|||||||
return distributeEnergy(true, howMuch, simulate)
|
return distributeEnergy(true, howMuch, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBatteryLevel(): Fraction {
|
override val batteryLevel: Fraction get() {
|
||||||
var result = Fraction.ZERO
|
var result = Fraction.ZERO
|
||||||
|
|
||||||
for (i in 0 until container.containerSize) {
|
for (i in 0 until container.containerSize) {
|
||||||
@ -208,7 +208,7 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMaxBatteryLevel(): Fraction {
|
override val maxBatteryLevel: Fraction get() {
|
||||||
var result = Fraction.ZERO
|
var result = Fraction.ZERO
|
||||||
|
|
||||||
for (i in 0 until container.containerSize) {
|
for (i in 0 until container.containerSize) {
|
||||||
|
@ -29,10 +29,11 @@ import ru.dbotthepony.mc.otm.menu.ChemicalGeneratorMenu
|
|||||||
import ru.dbotthepony.mc.otm.*
|
import ru.dbotthepony.mc.otm.*
|
||||||
import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable
|
import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
||||||
import java.lang.ref.WeakReference
|
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 {
|
override fun getDefaultDisplayName(): Component {
|
||||||
return NAME
|
return NAME
|
||||||
}
|
}
|
||||||
@ -42,13 +43,14 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var valid = true
|
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 <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
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()
|
return resolver.cast()
|
||||||
|
|
||||||
if (valid && cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
if (valid && cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||||
return itemHandler.get().cast()
|
return itemHandler.get().cast()
|
||||||
|
|
||||||
return super.getCapability(cap, side)
|
return super.getCapability(cap, side)
|
||||||
@ -65,7 +67,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
|
|||||||
super.reviveCaps()
|
super.reviveCaps()
|
||||||
itemHandler.revive()
|
itemHandler.revive()
|
||||||
valid = true
|
valid = true
|
||||||
resolver = LazyOptional.of {this}
|
resolver = LazyOptional.of {energy}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setLevel(level: Level) {
|
override fun setLevel(level: Level) {
|
||||||
@ -87,7 +89,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
|
|||||||
override fun saveAdditional(nbt: CompoundTag) {
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
super.saveAdditional(nbt)
|
super.saveAdditional(nbt)
|
||||||
|
|
||||||
nbt["energy"] = power.serializeNBT()
|
nbt["energy"] = energy.serializeNBT()
|
||||||
nbt["slots"] = container.serializeNBT()
|
nbt["slots"] = container.serializeNBT()
|
||||||
nbt["working_ticks"] = workingTicks
|
nbt["working_ticks"] = workingTicks
|
||||||
nbt["working_ticks_total"] = workingTicksTotal
|
nbt["working_ticks_total"] = workingTicksTotal
|
||||||
@ -96,8 +98,8 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
|
|||||||
override fun load(nbt: CompoundTag) {
|
override fun load(nbt: CompoundTag) {
|
||||||
super.load(nbt)
|
super.load(nbt)
|
||||||
|
|
||||||
nbt.ifHas("energy") {
|
nbt.ifHas("energy", CompoundTag::class.java) {
|
||||||
power = Fraction.deserializeNBT(it)
|
energy.deserializeNBT(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
nbt.ifHas("slots") {
|
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
|
var workingTicks = 0
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@ -218,19 +182,19 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
|
|||||||
private fun workWithPower(it: IEnergyStorage) {
|
private fun workWithPower(it: IEnergyStorage) {
|
||||||
if (it is IMatteryEnergyStorage) {
|
if (it is IMatteryEnergyStorage) {
|
||||||
val demand = it.missingPower
|
val demand = it.missingPower
|
||||||
val extracted = extractEnergyInner(demand, true)
|
val extracted = energy.extractEnergyInner(demand, true)
|
||||||
val received = it.receiveEnergyOuter(extracted, false)
|
val received = it.receiveEnergyOuter(extracted, false)
|
||||||
|
|
||||||
if (!received.isZero()) {
|
if (!received.isZero()) {
|
||||||
extractEnergyInner(received, false)
|
energy.extractEnergyInner(received, false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val demand = it.receiveEnergy(THROUGHPUT_INT, true)
|
val demand = it.receiveEnergy(THROUGHPUT_INT, true)
|
||||||
val extracted = extractEnergyInner(demand, true)
|
val extracted = energy.extractEnergyInner(demand, true)
|
||||||
val received = it.receiveEnergy(extracted, false)
|
val received = it.receiveEnergy(extracted, false)
|
||||||
|
|
||||||
if (received != 0) {
|
if (received != 0) {
|
||||||
extractEnergyInner(received, false)
|
energy.extractEnergyInner(received, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,7 +202,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
|
|||||||
fun tick() {
|
fun tick() {
|
||||||
if (workingTicks > 0 && !isBlockedByRedstone) {
|
if (workingTicks > 0 && !isBlockedByRedstone) {
|
||||||
workingTicks--
|
workingTicks--
|
||||||
receiveEnergyInner(GENERATION_SPEED, false)
|
energy.receiveEnergyInner(GENERATION_SPEED, false)
|
||||||
|
|
||||||
if (workingTicks == 0) {
|
if (workingTicks == 0) {
|
||||||
workingTicksTotal = 0
|
workingTicksTotal = 0
|
||||||
@ -256,7 +220,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
|
|||||||
if (!container.getItem(0).isEmpty) {
|
if (!container.getItem(0).isEmpty) {
|
||||||
val ticks = ForgeHooks.getBurnTime(container.getItem(0), null)
|
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
|
workingTicksTotal = ticks / 4
|
||||||
workingTicks = ticks / 4
|
workingTicks = ticks / 4
|
||||||
container.getItem(0).shrink(1)
|
container.getItem(0).shrink(1)
|
||||||
@ -266,13 +230,13 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
|
|||||||
check = false
|
check = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (power.isZero()) return
|
if (energy.batteryLevel.isZero()) return
|
||||||
|
|
||||||
val item = container.getItem(1)
|
val item = container.getItem(1)
|
||||||
|
|
||||||
if (!item.isEmpty) {
|
if (!item.isEmpty) {
|
||||||
item.getCapability(CapabilityEnergy.ENERGY).ifPresent(this::workWithPower)
|
item.getCapability(CapabilityEnergy.ENERGY).ifPresent(this::workWithPower)
|
||||||
if (power.isZero()) return
|
if (energy.batteryLevel.isZero()) return
|
||||||
}
|
}
|
||||||
|
|
||||||
for (consumer in consumers) {
|
for (consumer in consumers) {
|
||||||
|
@ -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.BlockPos;
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.nbt.ByteArrayTag
|
||||||
import net.minecraft.nbt.*;
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.nbt.IntTag
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.nbt.ListTag
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.server.level.ServerLevel
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import net.minecraftforge.energy.CapabilityEnergy;
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.energy.IEnergyStorage;
|
import net.minecraftforge.energy.CapabilityEnergy
|
||||||
import org.apache.logging.log4j.LogManager;
|
import net.minecraftforge.energy.IEnergyStorage
|
||||||
import org.apache.logging.log4j.Logger;
|
import ru.dbotthepony.mc.otm.*
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
import ru.dbotthepony.mc.otm.block.BlockEnergyCounter
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.block.BlockEnergyCounter;
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
|
import ru.dbotthepony.mc.otm.capability.extractEnergy
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu;
|
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(Registry.BlockEntities.ENERGY_COUNTER, p_155229_, p_155230_) {
|
||||||
import javax.annotation.Nullable;
|
var passed = Fraction.ZERO
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
private set
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
private val history = Array(10 * 20) { Fraction.ZERO }
|
||||||
@ParametersAreNonnullByDefault
|
private var historyTick = 0
|
||||||
public class BlockEntityEnergyCounter extends BlockEntityMattery {
|
|
||||||
protected Fraction passed = Fraction.ZERO;
|
|
||||||
protected final Fraction[] history = new Fraction[10 * 20];
|
|
||||||
protected int history_tick = 0;
|
|
||||||
|
|
||||||
public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) {
|
fun size() = history.size
|
||||||
if (t instanceof BlockEntityEnergyCounter tile) {
|
operator fun get(i: Int) = history[i]
|
||||||
tile.history_tick = (tile.history_tick + 1) % tile.history.length;
|
val lastTick: Fraction get() = history[historyTick]
|
||||||
tile.history[tile.history_tick] = Fraction.ZERO;
|
|
||||||
}
|
fun getHistory(ticks: Int): Array<Fraction> {
|
||||||
|
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]
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fraction[] getHistory(int ticks) {
|
return history
|
||||||
if (ticks < 1 || ticks >= history.length) {
|
|
||||||
throw new IllegalArgumentException("Invalid history length provided");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final var history = new Fraction[ticks];
|
fun calcAverage(ticks: Int): Fraction {
|
||||||
|
return sumHistory(ticks) / ticks
|
||||||
for (int i = 0; i < ticks; i++) {
|
|
||||||
int index = (history_tick - i) % this.history.length;
|
|
||||||
|
|
||||||
if (index < 0)
|
|
||||||
index += this.history.length;
|
|
||||||
|
|
||||||
history[i] = this.history[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return history;
|
fun sumHistory(ticks: Int): Fraction {
|
||||||
|
require(!(ticks < 1 || ticks >= history.size)) { "Invalid history length provided" }
|
||||||
|
|
||||||
|
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]
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fraction calcAverage(int ticks) {
|
return value
|
||||||
return sumHistory(ticks).div(ticks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fraction sumHistory(int ticks) {
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
if (ticks < 1 || ticks >= history.length) {
|
super.saveAdditional(nbt)
|
||||||
throw new IllegalArgumentException("Invalid history length provided");
|
nbt["passed"] = passed.serializeNBT()
|
||||||
|
|
||||||
|
val list = ListTag()
|
||||||
|
nbt["history"] = list
|
||||||
|
nbt["history_tick"] = historyTick
|
||||||
|
|
||||||
|
for (num in history)
|
||||||
|
list.add(num.serializeNBT())
|
||||||
}
|
}
|
||||||
|
|
||||||
var value = Fraction.ZERO;
|
override fun load(nbt: CompoundTag) {
|
||||||
|
super.load(nbt)
|
||||||
|
|
||||||
for (int i = 0; i < ticks; i++) {
|
nbt.ifHas(("passed")) {
|
||||||
int index = (history_tick - i) % this.history.length;
|
passed = Fraction.deserializeNBT(it)
|
||||||
|
|
||||||
if (index < 0)
|
|
||||||
index += this.history.length;
|
|
||||||
|
|
||||||
value = value.plus(history[index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
nbt.ifHas(("history_tick"), IntTag::class.java) {
|
||||||
|
historyTick = it.asInt
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fraction getPassed() {
|
nbt.ifHas("history", ListTag::class.java) {
|
||||||
return passed;
|
for (i in it.indices) {
|
||||||
}
|
val bytes = it[i] as? ByteArrayTag
|
||||||
|
history[i] = if (bytes != null) Fraction.deserializeNBT(bytes) else Fraction.ZERO
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.energy_counter");
|
override fun getDefaultDisplayName(): Component {
|
||||||
|
return NAME
|
||||||
@Override
|
|
||||||
protected Component getDefaultDisplayName() {
|
|
||||||
return NAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
@Override
|
return EnergyCounterMenu(containerID, inventory, this)
|
||||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
|
||||||
return new EnergyCounterMenu(containerID, inventory, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final EnergyCounterCap input = new EnergyCounterCap(true);
|
private val energyInput = EnergyCounterCap(true)
|
||||||
public final EnergyCounterCap output = new EnergyCounterCap(false);
|
private val energyOutput = EnergyCounterCap(false)
|
||||||
|
|
||||||
protected LazyOptional<IMatteryEnergyStorage> input_cap_mte = LazyOptional.empty();
|
private var inputCapability = LazyOptional.empty<IEnergyStorage>()
|
||||||
protected LazyOptional<IEnergyStorage> input_cap_fe = LazyOptional.empty();
|
private var outputCapability = LazyOptional.empty<IEnergyStorage>()
|
||||||
protected LazyOptional<IMatteryEnergyStorage> output_cap_mte = LazyOptional.empty();
|
|
||||||
protected LazyOptional<IEnergyStorage> output_cap_fe = LazyOptional.empty();
|
|
||||||
|
|
||||||
@Override
|
override fun setLevel(p_155231_: Level) {
|
||||||
public void setLevel(Level p_155231_) {
|
super.setLevel(p_155231_)
|
||||||
super.setLevel(p_155231_);
|
|
||||||
|
|
||||||
if (p_155231_ instanceof ServerLevel level) {
|
val level = level
|
||||||
OverdriveThatMatters.tickOnceSelf(level, this::checkSurroundings);
|
if (level is ServerLevel) {
|
||||||
|
OverdriveThatMatters.tickOnce(level) { checkSurroundings(level) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EnergyCounterCap implements IMatteryEnergyStorage {
|
private inner class EnergyCounterCap(val is_input: Boolean) : IMatteryEnergyStorage {
|
||||||
public final boolean is_input;
|
override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
|
return extractEnergyInner(howMuch, simulate)
|
||||||
public EnergyCounterCap(boolean is_input) {
|
|
||||||
this.is_input = is_input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private EnergyCounterCap opposite() {
|
override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
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) {
|
|
||||||
if (is_input)
|
if (is_input)
|
||||||
return Fraction.ZERO;
|
return Fraction.ZERO
|
||||||
|
|
||||||
if (input_cap_mte.isPresent()) {
|
if (inputCapability.isPresent) {
|
||||||
final var value = input_cap_mte.resolve().get().extractEnergyOuter(howMuch, simulate);
|
val it = inputCapability.resolve().get()
|
||||||
|
|
||||||
|
val diff: Fraction
|
||||||
|
|
||||||
|
if (it is IMatteryEnergyStorage) {
|
||||||
|
diff = it.extractEnergyOuter(howMuch, simulate)
|
||||||
|
} else {
|
||||||
|
diff = Fraction(it.extractEnergy(howMuch, simulate))
|
||||||
|
}
|
||||||
|
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
passed = passed.plus(value);
|
passed += diff
|
||||||
history[history_tick] = history[history_tick].plus(value);
|
history[historyTick] += diff
|
||||||
setChangedLight();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_cap_fe.isPresent()) {
|
return Fraction.ZERO
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
|
return receiveEnergyInner(howMuch, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Fraction.ZERO;
|
override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) {
|
|
||||||
return receiveEnergyInner(howMuch, simulate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) {
|
|
||||||
if (!is_input)
|
if (!is_input)
|
||||||
return Fraction.ZERO;
|
return Fraction.ZERO
|
||||||
|
|
||||||
if (output_cap_mte.isPresent()) {
|
if (outputCapability.isPresent) {
|
||||||
final var value = output_cap_mte.resolve().get().receiveEnergyOuter(howMuch, simulate);
|
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) {
|
if (!simulate) {
|
||||||
passed = passed.plus(value);
|
passed += diff
|
||||||
history[history_tick] = history[history_tick].plus(value);
|
history[historyTick] += diff
|
||||||
setChangedLight();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_cap_fe.isPresent()) {
|
return Fraction.ZERO
|
||||||
final var value = MatteryCapability.floodFE(output_cap_fe.resolve().get(), howMuch, simulate);
|
|
||||||
|
|
||||||
if (!simulate) {
|
|
||||||
passed = passed.plus(value);
|
|
||||||
history[history_tick] = history[history_tick].plus(value);
|
|
||||||
setChangedLight();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
override val batteryLevel: Fraction
|
||||||
}
|
get() {
|
||||||
|
|
||||||
return Fraction.ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fraction getBatteryLevel() {
|
|
||||||
if (is_input) {
|
if (is_input) {
|
||||||
if (output_cap_mte.isPresent()) {
|
if (outputCapability.isPresent) {
|
||||||
return output_cap_mte.resolve().get().getBatteryLevel();
|
val it = outputCapability.resolve().get()
|
||||||
|
|
||||||
|
if (it is IMatteryEnergyStorage) {
|
||||||
|
return it.batteryLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_cap_fe.isPresent()) {
|
return Fraction(it.energyStored)
|
||||||
return new Fraction(output_cap_fe.resolve().get().getEnergyStored());
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (input_cap_mte.isPresent()) {
|
if (inputCapability.isPresent) {
|
||||||
return input_cap_mte.resolve().get().getBatteryLevel();
|
val it = inputCapability.resolve().get()
|
||||||
|
|
||||||
|
if (it is IMatteryEnergyStorage) {
|
||||||
|
return it.batteryLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_cap_fe.isPresent()) {
|
return Fraction(it.energyStored)
|
||||||
return new Fraction(input_cap_fe.resolve().get().getEnergyStored());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Fraction.ZERO;
|
return Fraction.ZERO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override val maxBatteryLevel: Fraction
|
||||||
public Fraction getMaxBatteryLevel() {
|
get() {
|
||||||
if (is_input) {
|
if (is_input) {
|
||||||
if (output_cap_mte.isPresent()) {
|
if (outputCapability.isPresent) {
|
||||||
return output_cap_mte.resolve().get().getMaxBatteryLevel();
|
val it = outputCapability.resolve().get()
|
||||||
|
|
||||||
|
if (it is IMatteryEnergyStorage) {
|
||||||
|
return it.maxBatteryLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_cap_fe.isPresent()) {
|
return Fraction(it.maxEnergyStored)
|
||||||
return new Fraction(output_cap_fe.resolve().get().getMaxEnergyStored());
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (input_cap_mte.isPresent()) {
|
if (inputCapability.isPresent) {
|
||||||
return input_cap_mte.resolve().get().getMaxBatteryLevel();
|
val it = inputCapability.resolve().get()
|
||||||
|
|
||||||
|
if (it is IMatteryEnergyStorage) {
|
||||||
|
return it.maxBatteryLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_cap_fe.isPresent()) {
|
return Fraction(it.maxEnergyStored)
|
||||||
return new Fraction(input_cap_fe.resolve().get().getMaxEnergyStored());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Fraction.ZERO;
|
return Fraction.ZERO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun canExtract() = !is_input
|
||||||
public boolean canExtract() {
|
override fun canReceive() = is_input
|
||||||
return !is_input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private var resolverInput = LazyOptional.of<IMatteryEnergyStorage> { energyInput }
|
||||||
public boolean canReceive() {
|
private var resolverOutput = LazyOptional.of<IMatteryEnergyStorage> { energyOutput }
|
||||||
return is_input;
|
private var valid = true
|
||||||
}
|
|
||||||
|
override fun invalidateCaps() {
|
||||||
|
super.invalidateCaps()
|
||||||
|
valid = false
|
||||||
|
resolverInput.invalidate()
|
||||||
|
resolverOutput.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected LazyOptional<IMatteryEnergyStorage> input_resolver = LazyOptional.of(() -> input);
|
override fun reviveCaps() {
|
||||||
protected LazyOptional<IMatteryEnergyStorage> output_resolver = LazyOptional.of(() -> output);
|
super.reviveCaps()
|
||||||
|
valid = true
|
||||||
@Override
|
resolverInput = LazyOptional.of { energyInput }
|
||||||
public void invalidateCaps() {
|
resolverOutput = LazyOptional.of { energyOutput }
|
||||||
super.invalidateCaps();
|
|
||||||
input_resolver.invalidate();
|
|
||||||
output_resolver.invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Suppress("deprecation")
|
||||||
public void reviveCaps() {
|
override fun setBlockState(new: BlockState) {
|
||||||
super.reviveCaps();
|
val old = blockState
|
||||||
input_resolver = LazyOptional.of(() -> input);
|
super.setBlockState(new)
|
||||||
output_resolver = LazyOptional.of(() -> output);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (new !== old && new.getValue(BlockEnergyCounter.INPUT_DIRECTION) != old.getValue(BlockEnergyCounter.INPUT_DIRECTION)) {
|
||||||
@SuppressWarnings("deprecation")
|
resolverInput.invalidate()
|
||||||
public void setBlockState(BlockState p_155251_) {
|
resolverOutput.invalidate()
|
||||||
final var old = getBlockState();
|
resolverInput = LazyOptional.of { energyInput }
|
||||||
|
resolverOutput = LazyOptional.of { energyOutput }
|
||||||
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 (level != null)
|
if (level != null)
|
||||||
checkSurroundings(level);
|
checkSurroundings(level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> LazyOptional<T> getAndBind(Level level, LazyOptional<T> old, Capability<T> cap, Direction side) {
|
private fun getAndBind(
|
||||||
final var ent = level.getBlockEntity(getBlockPos().offset(side.getNormal()));
|
level: Level,
|
||||||
|
old: LazyOptional<IEnergyStorage>,
|
||||||
|
side: Direction
|
||||||
|
): LazyOptional<IEnergyStorage> {
|
||||||
|
val ent = level.getBlockEntity(blockPos.offset(side.normal)) ?: return LazyOptional.empty()
|
||||||
|
val resolve = ent.getCapability(CapabilityEnergy.ENERGY, side.opposite)
|
||||||
|
|
||||||
if (ent == null)
|
if (resolve !== old) {
|
||||||
return LazyOptional.empty();
|
val weak = WeakReference(this)
|
||||||
|
|
||||||
final var resolve = ent.getCapability(cap, side.getOpposite());
|
resolve.addListener {
|
||||||
|
val get = weak.get()
|
||||||
|
|
||||||
if (resolve != old) {
|
if (get?.level != null) {
|
||||||
final var weak = new WeakReference<>(this);
|
get.checkSurroundings(get.level)
|
||||||
|
|
||||||
resolve.addListener((l) -> {
|
|
||||||
final var get = weak.get();
|
|
||||||
|
|
||||||
if (get != null && get.level != null) {
|
|
||||||
get.checkSurroundings(get.level);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return resolve;
|
|
||||||
}
|
|
||||||
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkSurroundings(Level level) {
|
|
||||||
if (isRemoved() || !(level instanceof 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));
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
return resolve
|
||||||
|
}
|
||||||
|
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkSurroundings(level: Level?) {
|
||||||
|
if (isRemoved || level !is ServerLevel) return
|
||||||
|
|
||||||
|
inputCapability = getAndBind(
|
||||||
|
level,
|
||||||
|
inputCapability,
|
||||||
|
blockState.getValue(BlockEnergyCounter.INPUT_DIRECTION)
|
||||||
|
)
|
||||||
|
|
||||||
|
outputCapability = getAndBind(
|
||||||
|
level,
|
||||||
|
outputCapability,
|
||||||
|
-blockState.getValue(BlockEnergyCounter.INPUT_DIRECTION)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
|
if (side == null || isRemoved)
|
||||||
|
return super.getCapability(cap, side)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tick() {
|
||||||
|
historyTick = (historyTick + 1) % history.size
|
||||||
|
history[historyTick] = Fraction.ZERO
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val NAME = TranslatableComponent("block.overdrive_that_matters.energy_counter")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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 net.minecraftforge.energy.IEnergyStorage;
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
|
|
||||||
// IEnergyStorage for direct compat with Forge Energy
|
// IEnergyStorage for direct compat with Forge Energy
|
||||||
@MethodsReturnNonnullByDefault
|
interface IMatteryEnergyStorage : IEnergyStorage {
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public interface IMatteryEnergyStorage extends IEnergyStorage {
|
|
||||||
// such as cables. This is something that would work only with energy storage
|
// 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
|
// for internal needs, e.g. for work
|
||||||
// CAN also be used by something that does evil
|
// CAN also be used by something that does evil
|
||||||
// e.g. sucking out energy anomaly should use this
|
// 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
|
// 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
|
// 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) {
|
fun extractEnergyOuter(howMuch: Long, simulate: Boolean): Fraction {
|
||||||
return extractEnergyOuter(new Fraction(howMuch), simulate);
|
return extractEnergyOuter(Fraction(howMuch), simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
default Fraction extractEnergyOuter(int howMuch, boolean simulate) {
|
fun extractEnergyOuter(howMuch: Int, simulate: Boolean): Fraction {
|
||||||
return extractEnergyOuter(new Fraction(howMuch), simulate);
|
return extractEnergyOuter(Fraction(howMuch), simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
default Fraction receiveEnergyOuter(long howMuch, boolean simulate) {
|
fun receiveEnergyOuter(howMuch: Long, simulate: Boolean): Fraction {
|
||||||
return receiveEnergyOuter(new Fraction(howMuch), simulate);
|
return receiveEnergyOuter(Fraction(howMuch), simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
default Fraction receiveEnergyOuter(int howMuch, boolean simulate) {
|
fun receiveEnergyOuter(howMuch: Int, simulate: Boolean): Fraction {
|
||||||
return receiveEnergyOuter(new Fraction(howMuch), simulate);
|
return receiveEnergyOuter(Fraction(howMuch), simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
default Fraction extractEnergyInner(long howMuch, boolean simulate) {
|
fun extractEnergyInner(howMuch: Long, simulate: Boolean): Fraction {
|
||||||
return extractEnergyInner(new Fraction(howMuch), simulate);
|
return extractEnergyInner(Fraction(howMuch), simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
default Fraction extractEnergyInner(int howMuch, boolean simulate) {
|
fun extractEnergyInner(howMuch: Int, simulate: Boolean): Fraction {
|
||||||
return extractEnergyInner(new Fraction(howMuch), simulate);
|
return extractEnergyInner(Fraction(howMuch), simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
default Fraction receiveEnergyInner(long howMuch, boolean simulate) {
|
fun receiveEnergyInner(howMuch: Long, simulate: Boolean): Fraction {
|
||||||
return receiveEnergyInner(new Fraction(howMuch), simulate);
|
return receiveEnergyInner(Fraction(howMuch), simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
default Fraction receiveEnergyInner(int howMuch, boolean simulate) {
|
fun receiveEnergyInner(howMuch: Int, simulate: Boolean): Fraction {
|
||||||
return receiveEnergyInner(new Fraction(howMuch), simulate);
|
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default int receiveEnergy(int maxReceive, boolean simulate) {
|
|
||||||
int received = receiveEnergyOuter(maxReceive, true).toInt();
|
|
||||||
|
|
||||||
if (received == 0) {
|
|
||||||
// Receiving only a fraction
|
// Receiving only a fraction
|
||||||
return 0;
|
if (received == 0)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return receiveEnergyOuter(Fraction(received), simulate).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
return receiveEnergyOuter(new Fraction(received), simulate).toInt();
|
override fun extractEnergy(maxReceive: Int, simulate: Boolean): Int {
|
||||||
}
|
val extracted = extractEnergyOuter(maxReceive, true).toInt()
|
||||||
|
|
||||||
@Override
|
|
||||||
default int extractEnergy(int maxReceive, boolean simulate) {
|
|
||||||
int extracted = extractEnergyOuter(maxReceive, true).toInt();
|
|
||||||
|
|
||||||
if (extracted == 0) {
|
|
||||||
// Extracting only a fraction
|
// Extracting only a fraction
|
||||||
return 0;
|
if (extracted == 0)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return extractEnergyOuter(Fraction(extracted), simulate).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
return extractEnergyOuter(new Fraction(extracted), simulate).toInt();
|
override fun getEnergyStored(): Int {
|
||||||
|
val level = batteryLevel
|
||||||
|
|
||||||
|
if (level < MatteryCapability.INT_MAX_VALUE)
|
||||||
|
return level.toInt()
|
||||||
|
|
||||||
|
return Int.MAX_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getMaxEnergyStored(): Int {
|
||||||
default int getEnergyStored() {
|
val level = maxBatteryLevel
|
||||||
Fraction level = getBatteryLevel();
|
|
||||||
|
|
||||||
if (level.compareTo(MatteryCapability.INT_MAX_VALUE) < 0) {
|
if (level < MatteryCapability.INT_MAX_VALUE)
|
||||||
return level.toInt();
|
return level.toInt()
|
||||||
|
|
||||||
|
return Int.MAX_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
return Integer.MAX_VALUE;
|
override fun canExtract(): Boolean {
|
||||||
|
return extractEnergyOuter(Fraction.ONE, true) > Fraction.ZERO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun canReceive(): Boolean {
|
||||||
default int getMaxEnergyStored() {
|
return receiveEnergyOuter(Fraction.ONE, true) > Fraction.ZERO
|
||||||
Fraction level = getMaxBatteryLevel();
|
|
||||||
|
|
||||||
if (level.compareTo(MatteryCapability.INT_MAX_VALUE) < 0) {
|
|
||||||
return level.toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Integer.MAX_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default boolean canExtract() {
|
|
||||||
return extractEnergyOuter(Fraction.ONE, true).compareTo(Fraction.ZERO) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default boolean canReceive() {
|
|
||||||
return receiveEnergyOuter(Fraction.ONE, true).compareTo(Fraction.ZERO) > 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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.nbt.CompoundTag;
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraftforge.common.util.INBTSerializable
|
||||||
import net.minecraftforge.common.util.INBTSerializable;
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
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;
|
open class MatteryMachineEnergyStorage @JvmOverloads constructor(
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
protected val listener: () -> Unit,
|
||||||
import java.math.BigDecimal;
|
val type: MachineType,
|
||||||
|
override var maxBatteryLevel: Fraction = DEFAULT_MAX_CAPACITY,
|
||||||
|
protected var maxInput: Fraction = DEFAULT_MAX_RECEIVE,
|
||||||
|
protected var maxOutput: Fraction = maxInput
|
||||||
|
) : IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
|
||||||
|
@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
|
enum class MachineType {
|
||||||
@ParametersAreNonnullByDefault
|
WORKER, GENERATOR, CAPACITOR
|
||||||
public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
|
|
||||||
public enum MachineType {
|
|
||||||
WORKER,
|
|
||||||
GENERATOR,
|
|
||||||
CAPACITOR,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Fraction DEFAULT_MAX_RECEIVE = new Fraction(200);
|
override var batteryLevel = Fraction.ZERO
|
||||||
public static final Fraction DEFAULT_MAX_EXTRACT = new Fraction(200);
|
protected set
|
||||||
public static final Fraction DEFAULT_MAX_CAPACITY = new Fraction(60000);
|
|
||||||
|
|
||||||
protected Fraction energy_stored = Fraction.ZERO;
|
override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
protected Fraction energy_stored_max;
|
if (type == MachineType.WORKER)
|
||||||
protected Fraction max_input;
|
return Fraction.ZERO
|
||||||
protected Fraction max_output;
|
|
||||||
protected final MachineType machine_type;
|
|
||||||
protected final BlockEntity listener;
|
|
||||||
|
|
||||||
public MatteryMachineEnergyStorage(BlockEntity listener, MachineType type, Fraction capacity) {
|
return extractEnergyInner(howMuch, simulate)
|
||||||
this(listener, type, capacity, DEFAULT_MAX_RECEIVE, DEFAULT_MAX_EXTRACT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatteryMachineEnergyStorage(BlockEntity listener, MachineType type) {
|
override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
this(listener, type, DEFAULT_MAX_CAPACITY);
|
val new = batteryLevel.minus(howMuch.min(maxOutput)).moreThanZero()
|
||||||
|
val diff = batteryLevel.minus(new)
|
||||||
|
|
||||||
|
if (!simulate && batteryLevel != new) {
|
||||||
|
batteryLevel = new
|
||||||
|
listener()
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatteryMachineEnergyStorage(BlockEntity listener, MachineType type, Fraction capacity, Fraction maxReceive, Fraction maxExtract) {
|
return diff
|
||||||
this.listener = listener;
|
|
||||||
energy_stored_max = capacity;
|
|
||||||
max_input = maxReceive;
|
|
||||||
max_output = maxExtract;
|
|
||||||
machine_type = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
@Override
|
if (type == MachineType.GENERATOR)
|
||||||
public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) {
|
return Fraction.ZERO
|
||||||
if (machine_type == MachineType.WORKER) {
|
|
||||||
return Fraction.ZERO;
|
return receiveEnergyInner(howMuch, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
return extractEnergyInner(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()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
return diff
|
||||||
@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);
|
|
||||||
|
|
||||||
if (!simulate && !energy_stored.equalsCompact(new_energy)) {
|
|
||||||
energy_stored = new_energy;
|
|
||||||
listener.setChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff;
|
override fun canExtract(): Boolean {
|
||||||
|
return type != MachineType.WORKER
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
override fun canReceive(): Boolean {
|
||||||
@Override
|
return type != MachineType.GENERATOR
|
||||||
public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) {
|
|
||||||
if (machine_type == MachineType.GENERATOR) {
|
|
||||||
return Fraction.ZERO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return receiveEnergyInner(howMuch, simulate);
|
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 fun deserializeNBT(nbt: CompoundTag) {
|
||||||
@Override
|
nbt.ifHas("energy_stored") { batteryLevel = deserializeNBT(it) }
|
||||||
public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) {
|
// nbt.ifHas("energy_stored_max") { maxBatteryLevel = deserializeNBT(it) }
|
||||||
Fraction new_energy = energy_stored.plus(howMuch.min(max_input)).min(energy_stored_max);
|
// nbt.ifHas("max_input") { maxInput = deserializeNBT(it) }
|
||||||
Fraction diff = new_energy.minus(energy_stored);
|
// nbt.ifHas("max_output") { maxOutput = deserializeNBT(it) }
|
||||||
|
|
||||||
if (!simulate && !energy_stored.equalsCompact(new_energy)) {
|
|
||||||
energy_stored = new_energy;
|
|
||||||
listener.setChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff;
|
companion object {
|
||||||
}
|
val DEFAULT_MAX_RECEIVE = Fraction(200)
|
||||||
|
val DEFAULT_MAX_EXTRACT = Fraction(200)
|
||||||
@Nonnull
|
val DEFAULT_MAX_CAPACITY = Fraction(60000)
|
||||||
@Override
|
|
||||||
public Fraction getBatteryLevel() {
|
|
||||||
return energy_stored;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Fraction getMaxBatteryLevel() {
|
|
||||||
return energy_stored_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canExtract() {
|
|
||||||
return machine_type != MachineType.WORKER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -386,7 +386,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
|||||||
return ent
|
return ent
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBatteryLevel(): Fraction {
|
override val batteryLevel: Fraction get() {
|
||||||
if (!batteryItemStack.isEmpty) {
|
if (!batteryItemStack.isEmpty) {
|
||||||
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()
|
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()
|
||||||
|
|
||||||
@ -404,7 +404,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
|
|||||||
return battery
|
return battery
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMaxBatteryLevel(): Fraction {
|
override val maxBatteryLevel: Fraction get() {
|
||||||
if (batteryItemStack != ItemStack.EMPTY) {
|
if (batteryItemStack != ItemStack.EMPTY) {
|
||||||
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()
|
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()
|
||||||
|
|
||||||
|
@ -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.Component
|
||||||
import net.minecraft.network.chat.TextComponent;
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
|
||||||
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.FramePanel;
|
import ru.dbotthepony.mc.otm.client.screen.panels.Label
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.Label;
|
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu
|
||||||
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu;
|
import ru.dbotthepony.mc.otm.menu.FormattingHelper
|
||||||
import ru.dbotthepony.mc.otm.menu.FormattingHelper;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title: Component) : MatteryScreen<EnergyCounterMenu>(menu, inventory, title) {
|
||||||
|
override fun makeMainFrame(): FramePanel {
|
||||||
|
val frame = super.makeMainFrame()!!
|
||||||
|
|
||||||
public class EnergyCounterScreen extends MatteryScreen<EnergyCounterMenu> {
|
var label: Label = object : Label(this@EnergyCounterScreen, frame) {
|
||||||
public EnergyCounterScreen(EnergyCounterMenu menu, Inventory inventory, Component title) {
|
override fun tick() {
|
||||||
super(menu, inventory, title);
|
super.tick()
|
||||||
|
setText(
|
||||||
|
TranslatableComponent(
|
||||||
|
"otm.item.power.passed",
|
||||||
|
FormattingHelper.formatPower(menu.passed.value)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
label.dock = Dock.TOP
|
||||||
@Override
|
label.setDockMargin(4f, 0f, 0f, 0f)
|
||||||
protected FramePanel makeMainFrame() {
|
|
||||||
var frame = super.makeMainFrame();
|
|
||||||
|
|
||||||
var label = (Label) new Label(this, frame) {
|
label = object : Label(this@EnergyCounterScreen, frame) {
|
||||||
@Override
|
override fun tick() {
|
||||||
public void tick() {
|
super.tick()
|
||||||
super.tick();
|
setText(
|
||||||
|
TranslatableComponent(
|
||||||
setText(new TranslatableComponent("otm.item.power.passed", FormattingHelper.formatPower(menu.passed.getValue())));
|
"otm.item.power.average",
|
||||||
|
FormattingHelper.formatPower(menu.average.value)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
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.dock = Dock.TOP
|
||||||
label.setDockMargin(4, 0, 0, 0);
|
label.setDockMargin(4f, 0f, 0f, 0f)
|
||||||
|
|
||||||
label = new Label(this, frame) {
|
label = object : Label(this@EnergyCounterScreen, frame) {
|
||||||
@Override
|
override fun tick() {
|
||||||
public void tick() {
|
super.tick()
|
||||||
super.tick();
|
setText(
|
||||||
|
TranslatableComponent(
|
||||||
setText(new TranslatableComponent("otm.item.power.last_20_ticks", FormattingHelper.formatPower(menu.last_20_ticks.getValue())));
|
"otm.item.power.last_20_ticks",
|
||||||
|
FormattingHelper.formatPower(menu.last20Ticks.value)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
label.setDock(Dock.TOP);
|
label.dock = Dock.TOP
|
||||||
label.setDockMargin(4, 0, 0, 0);
|
label.setDockMargin(4f, 0f, 0f, 0f)
|
||||||
|
|
||||||
return frame;
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -66,15 +66,15 @@ class ItemBattery : Item {
|
|||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMissingPower(): Fraction {
|
override val missingPower: Fraction get() {
|
||||||
return if (isCreative) MatteryCapability.LONG_MAX_VALUE else super.getMissingPower()
|
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()
|
return if (isCreative) MatteryCapability.LONG_MAX_VALUE else energy()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMaxBatteryLevel(): Fraction {
|
override val maxBatteryLevel: Fraction get() {
|
||||||
return storage
|
return storage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class ChemicalGeneratorMenu @JvmOverloads constructor(id: Int, inv: Inventory, t
|
|||||||
}
|
}
|
||||||
|
|
||||||
val progress = ProgressGaugeWidget(this) { 1f - tile!!.workingTicks.toFloat() / tile.workingTicksTotal }
|
val progress = ProgressGaugeWidget(this) { 1f - tile!!.workingTicks.toFloat() / tile.workingTicksTotal }
|
||||||
val energy = LevelGaugeWidget(this, tile)
|
val energy = LevelGaugeWidget(this, tile?.energy)
|
||||||
val burnTime = IntDataContainer()
|
val burnTime = IntDataContainer()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -1,59 +1,52 @@
|
|||||||
package ru.dbotthepony.mc.otm.menu;
|
package ru.dbotthepony.mc.otm.menu
|
||||||
|
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import kotlin.jvm.JvmOverloads
|
||||||
import net.minecraft.world.inventory.MenuType;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter;
|
import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer
|
||||||
import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer;
|
|
||||||
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
|
// TODO: Graph and proper networking for it
|
||||||
private int ticks_passed = 0;
|
private var ticksPassed = 0
|
||||||
|
|
||||||
public EnergyCounterMenu(int p_38852_, Inventory inventory) {
|
init {
|
||||||
this(p_38852_, inventory, null);
|
addDataSlots(passed)
|
||||||
|
addDataSlots(average)
|
||||||
|
addDataSlots(last20Ticks)
|
||||||
|
addDataSlots(lastTick)
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnergyCounterMenu(int p_38852_, Inventory inventory, BlockEntityEnergyCounter tile) {
|
override fun broadcastChanges() {
|
||||||
super(Registry.Menus.ENERGY_COUNTER, p_38852_, inventory, tile);
|
if (tile is BlockEntityEnergyCounter) {
|
||||||
|
passed.value = tile.passed
|
||||||
|
average.value = tile.calcAverage(20)
|
||||||
|
lastTick.value = tile.lastTick
|
||||||
|
|
||||||
addDataSlots(passed);
|
if (ticksPassed == 0) {
|
||||||
addDataSlots(average);
|
last20Ticks.value = tile.sumHistory(20)
|
||||||
addDataSlots(last_20_ticks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
ticksPassed = (ticksPassed + 1) % 20
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ticks_passed = (ticks_passed + 1) % 20;
|
super.broadcastChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
super.broadcastChanges();
|
override fun getWorkingSlotStart(): Int {
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getWorkingSlotEnd(): Int {
|
||||||
protected int getWorkingSlotStart() {
|
return 0
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getWorkingSlotEnd() {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,8 +23,8 @@ class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) {
|
|||||||
) : this(menu) {
|
) : this(menu) {
|
||||||
if (power == null) return
|
if (power == null) return
|
||||||
|
|
||||||
this.level = power::getBatteryLevel
|
this.level = power::batteryLevel
|
||||||
this.maxLevel = power::getMaxBatteryLevel
|
this.maxLevel = power::maxBatteryLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
"otm.item.power.passed": "Passed energy: %s",
|
"otm.item.power.passed": "Passed energy: %s",
|
||||||
"otm.item.power.average": "Average throughput: %s/t",
|
"otm.item.power.average": "Average throughput: %s/t",
|
||||||
"otm.item.power.last_20_ticks": "Last second: %s",
|
"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.storage": "Stored energy: %s / %s",
|
||||||
"otm.item.power.normal.throughput": "Max I/O %s / %s",
|
"otm.item.power.normal.throughput": "Max I/O %s / %s",
|
||||||
|
Loading…
Reference in New Issue
Block a user