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