New graph system, Matter interaction system rewrite
Port more code to Kotlin Update Fraction to crunch down numbers with GCDs
This commit is contained in:
parent
b86f71b910
commit
994863b9bc
1
.gitignore
vendored
1
.gitignore
vendored
@ -23,6 +23,7 @@ run
|
|||||||
|
|
||||||
design/
|
design/
|
||||||
libs/
|
libs/
|
||||||
|
logs/
|
||||||
|
|
||||||
# Files from Forge MDK
|
# Files from Forge MDK
|
||||||
forge*changelog.txt
|
forge*changelog.txt
|
||||||
|
@ -28,7 +28,6 @@ import ru.dbotthepony.mc.otm.capability.drive.DrivePool;
|
|||||||
import ru.dbotthepony.mc.otm.client.AndroidGui;
|
import ru.dbotthepony.mc.otm.client.AndroidGui;
|
||||||
import ru.dbotthepony.mc.otm.client.EventHandler;
|
import ru.dbotthepony.mc.otm.client.EventHandler;
|
||||||
import ru.dbotthepony.mc.otm.item.ItemPortableCondensationDrive;
|
import ru.dbotthepony.mc.otm.item.ItemPortableCondensationDrive;
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterRegistry;
|
import ru.dbotthepony.mc.otm.matter.MatterRegistry;
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
|
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
|
||||||
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper;
|
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper;
|
||||||
@ -129,7 +128,6 @@ public class OverdriveThatMatters {
|
|||||||
MinecraftForge.EVENT_BUS.register(this);
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
MinecraftForge.EVENT_BUS.register(AndroidCapabilityPlayer.class);
|
MinecraftForge.EVENT_BUS.register(AndroidCapabilityPlayer.class);
|
||||||
MinecraftForge.EVENT_BUS.register(AndroidCapability.class);
|
MinecraftForge.EVENT_BUS.register(AndroidCapability.class);
|
||||||
MinecraftForge.EVENT_BUS.register(MatterGrid.class);
|
|
||||||
MinecraftForge.EVENT_BUS.register(MatterRegistry.class);
|
MinecraftForge.EVENT_BUS.register(MatterRegistry.class);
|
||||||
MinecraftForge.EVENT_BUS.register(BlockEntityBlackHole.BlackHoleExplosionQueue.class);
|
MinecraftForge.EVENT_BUS.register(BlockEntityBlackHole.BlackHoleExplosionQueue.class);
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ import net.minecraft.world.phys.shapes.BooleanOp;
|
|||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.Shapes;
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell;
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCable;
|
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCable;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -172,62 +171,6 @@ public class BlockMatterCable extends Block implements EntityBlock {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// doesn't work at all
|
|
||||||
/*
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForPlacement(BlockPlaceContext p_49820_) {
|
|
||||||
Level level = p_49820_.getLevel();
|
|
||||||
|
|
||||||
if (level.isClientSide)
|
|
||||||
return this.defaultBlockState();
|
|
||||||
|
|
||||||
BlockState state = this.defaultBlockState();
|
|
||||||
|
|
||||||
for (int i = 0; i < MAPPING_CONNECTION_PROP.length; i++) {
|
|
||||||
OverdriveThatMatters.LOGGER.info("{} {} {}", Direction.values()[i], p_49820_.getClickedPos().offset(Direction.values()[i].getNormal()), level.getBlockEntity(p_49820_.getClickedPos().offset(p_49820_.getClickedFace().getNormal()).offset(Direction.values()[i].getNormal())));
|
|
||||||
|
|
||||||
if (
|
|
||||||
level.getBlockEntity(p_49820_.getClickedPos().offset(Direction.values()[i].getNormal())) instanceof IMatterGridCell cell && cell.isValidMatterCell()// ||
|
|
||||||
//level.getBlockState(p_49820_.getClickedPos().offset(p_49820_.getClickedFace().getNormal()).offset(Direction.values()[i].getNormal())).getBlock() instanceof BlockMatterCable
|
|
||||||
) {
|
|
||||||
state.setValue(MAPPING_CONNECTION_PROP[i], true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// blocks
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void neighborChanged(BlockState self, Level level, BlockPos position_self, Block block_notifier, BlockPos position_notifier, boolean unknown_flag) {
|
|
||||||
Direction normal = Direction.fromNormal(position_notifier.subtract(position_self));
|
|
||||||
boolean updated = false;
|
|
||||||
BlockEntity get_entity = level.getBlockEntity(position_notifier);
|
|
||||||
|
|
||||||
if (!self.getValue(MAPPING_CONNECTION_PROP[normal.ordinal()]) && get_entity instanceof IMatterGridCell cell && cell.isValidMatterCell()) {
|
|
||||||
self = self.setValue(MAPPING_CONNECTION_PROP[normal.ordinal()], true);
|
|
||||||
updated = true;
|
|
||||||
} else if (self.getValue(MAPPING_CONNECTION_PROP[normal.ordinal()]) && (get_entity == null || get_entity instanceof IMatterGridCell cell && !cell.isValidMatterCell())) {
|
|
||||||
self = self.setValue(MAPPING_CONNECTION_PROP[normal.ordinal()], false);
|
|
||||||
updated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updated) {
|
|
||||||
level.setBlock(position_self, self, UPDATE_CLIENTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.neighborChanged(self, level, position_self, block_notifier, position_notifier, unknown_flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
// tiles
|
|
||||||
/*@Override
|
|
||||||
public void onNeighborChange(BlockState state, LevelReader world, BlockPos pos, BlockPos neighbor) {
|
|
||||||
super.onNeighborChange(state, world, pos, neighbor);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||||
builder.add(CONNECTION_SOUTH,
|
builder.add(CONNECTION_SOUTH,
|
||||||
|
@ -1,111 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity;
|
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
|
||||||
import ru.dbotthepony.mc.otm.block.BlockMatterCable;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public class BlockEntityMatterCable extends BlockEntity implements IMatterGridCell {
|
|
||||||
public BlockEntityMatterCable(BlockPos p_155229_, BlockState p_155230_) {
|
|
||||||
super(Registry.BlockEntities.MATTER_CABLE, p_155229_, p_155230_);
|
|
||||||
// OverdriveThatMatters.LOGGER.debug("create cable block entity {} {} {}", this, p_155229_, p_155230_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MatterGrid grid;
|
|
||||||
|
|
||||||
private LazyOptional<IMatterGridCell> resolver_grid = LazyOptional.of(() -> this);
|
|
||||||
private boolean valid = true;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCaps() {
|
|
||||||
super.invalidateCaps();
|
|
||||||
valid = false;
|
|
||||||
resolver_grid.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reviveCaps() {
|
|
||||||
super.reviveCaps();
|
|
||||||
valid = true;
|
|
||||||
resolver_grid = LazyOptional.of(() -> this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
|
||||||
if (valid && cap == MatteryCapability.MATTER_CELL)
|
|
||||||
return resolver_grid.cast();
|
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLevel(Level p_155231_) {
|
|
||||||
super.setLevel(p_155231_);
|
|
||||||
|
|
||||||
if (grid == null)
|
|
||||||
MatterGrid.scheduleDiscoverNeighbours(this, getBlockPos(), p_155231_);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public IPatternStorage getPatternStorage() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNeighbourMatterCell(Level level, BlockPos pos, Direction direction, IMatterGridCell cell, BlockEntity entity) {
|
|
||||||
BlockState new_state = getBlockState().setValue(BlockMatterCable.MAPPING_CONNECTION_PROP[direction.ordinal()], true);
|
|
||||||
|
|
||||||
if (new_state != getBlockState())
|
|
||||||
level.setBlock(getBlockPos(), new_state, Block.UPDATE_CLIENTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRemoved() {
|
|
||||||
super.setRemoved();
|
|
||||||
|
|
||||||
if (grid != null)
|
|
||||||
grid.remove(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public MatterGrid getMatterGrid() {
|
|
||||||
return grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public IMatterHandler getMatterHandler() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValidMatterCell() {
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMatterGrid(MatterGrid grid) {
|
|
||||||
this.grid = grid;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,221 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity;
|
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
|
||||||
import ru.dbotthepony.mc.otm.*;
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker;
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJob;
|
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.*;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell;
|
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterRegistry;
|
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implements IMatterGridCell {
|
|
||||||
private static final TranslatableComponent MACHINE_NAME = new TranslatableComponent("block.overdrive_that_matters.matter_decomposer");
|
|
||||||
private boolean valid = true;
|
|
||||||
public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.EXTRACT, new Fraction("20"));
|
|
||||||
private LazyOptional<IMatterHandler> matter_resolver = LazyOptional.of(() -> matter);
|
|
||||||
|
|
||||||
// вход, выход
|
|
||||||
public final MatteryContainer item_container = new MatteryContainer(this::setChanged, 2);
|
|
||||||
|
|
||||||
private final LazyOptional<IItemHandler> handler_resolver = LazyOptional.of(() -> item_container.handler(
|
|
||||||
(slot, stack) -> slot == 0 && MatterRegistry.canDecompose(stack),
|
|
||||||
(slot, amount, stack) -> slot == 1
|
|
||||||
));
|
|
||||||
|
|
||||||
public BlockEntityMatterDecomposer(BlockPos p_155229_, BlockState p_155230_) {
|
|
||||||
super(Registry.BlockEntities.MATTER_DECOMPOSER, p_155229_, p_155230_);
|
|
||||||
energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new Fraction(400_000), new Fraction(2000), new Fraction(2000));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Component getDefaultDisplayName() {
|
|
||||||
return MACHINE_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
|
||||||
return new MatterDecomposerMenu(containerID, inventory, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public IPatternStorage getPatternStorage() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
|
||||||
super.saveAdditional(nbt);
|
|
||||||
nbt.put("work_slots", item_container.serializeNBT());
|
|
||||||
nbt.put("matter_capability", matter.serializeNBT());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(CompoundTag nbt) {
|
|
||||||
super.load(nbt);
|
|
||||||
|
|
||||||
if (nbt.contains("matter_capability") && nbt.get("matter_capability") instanceof CompoundTag tag)
|
|
||||||
matter.deserializeNBT(tag);
|
|
||||||
|
|
||||||
item_container.deserializeNBT(nbt.get("work_slots"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reviveCaps() {
|
|
||||||
valid = true;
|
|
||||||
super.reviveCaps();
|
|
||||||
matter_resolver = LazyOptional.of(() -> matter);
|
|
||||||
resolver_grid = LazyOptional.of(() -> this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCaps() {
|
|
||||||
valid = false;
|
|
||||||
super.invalidateCaps();
|
|
||||||
matter_resolver.invalidate();
|
|
||||||
resolver_grid.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private LazyOptional<IMatterGridCell> resolver_grid = LazyOptional.of(() -> this);
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
|
||||||
if (valid) {
|
|
||||||
if (cap == MatteryCapability.MATTER)
|
|
||||||
return matter_resolver.cast();
|
|
||||||
|
|
||||||
if (cap == MatteryCapability.MATTER_CELL)
|
|
||||||
return resolver_grid.cast();
|
|
||||||
|
|
||||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
|
||||||
return handler_resolver.cast();
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
protected MachineJobStatus onJobFinish(MachineJob job) {
|
|
||||||
var matter_value = MatterRegistry.getMatterValue(job.stack());
|
|
||||||
matter.receiveMatterInner(matter_value, false);
|
|
||||||
return new MachineJobStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
protected MachineJob getNextJob() {
|
|
||||||
ItemStack stack = item_container.getItem(0);
|
|
||||||
|
|
||||||
if (!stack.isEmpty()) {
|
|
||||||
ItemStack copy = stack.copy();
|
|
||||||
copy.setCount(1);
|
|
||||||
|
|
||||||
if (MatterRegistry.canDecompose(copy)) {
|
|
||||||
var matter_value = MatterRegistry.getMatterValue(copy);
|
|
||||||
|
|
||||||
if (!matter_value.equals(Fraction.ZERO) && matter.canReceiveAll(matter_value)) {
|
|
||||||
stack.shrink(1);
|
|
||||||
return new MachineJob(copy, matter_value.toDouble() * 12_500d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) {
|
|
||||||
if (t instanceof BlockEntityMatterDecomposer tile) {
|
|
||||||
tile.batteryChargeLoop();
|
|
||||||
tile.workerLoop();
|
|
||||||
|
|
||||||
if (tile.matter.getStoredMatter().compareTo(Fraction.ZERO) > 0 && tile.grid != null) {
|
|
||||||
var diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true);
|
|
||||||
var diff2 = tile.grid.softPushMatter(diff, true);
|
|
||||||
|
|
||||||
tile.matter.extractMatterInner(diff2, false);
|
|
||||||
tile.grid.softPushMatter(diff2, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MatterGrid grid;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRemoved() {
|
|
||||||
super.setRemoved();
|
|
||||||
|
|
||||||
if (level != null && !level.isClientSide && grid != null)
|
|
||||||
grid.remove(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLevel(Level p_155231_) {
|
|
||||||
super.setLevel(p_155231_);
|
|
||||||
|
|
||||||
if (!p_155231_.isClientSide)
|
|
||||||
MatterGrid.scheduleDiscoverNeighbours(this, getBlockPos(), p_155231_);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public MatterGrid getMatterGrid() {
|
|
||||||
return grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public IMatterHandler getMatterHandler() {
|
|
||||||
return valid ? matter : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValidMatterCell() {
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMatterGrid(MatterGrid grid) {
|
|
||||||
this.grid = grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Fraction BASE_CONSUMPTION = new Fraction(240);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Fraction getBaseConsumption() {
|
|
||||||
return BASE_CONSUMPTION;
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,13 +4,12 @@ import net.minecraftforge.common.capabilities.*;
|
|||||||
import net.minecraftforge.energy.IEnergyStorage;
|
import net.minecraftforge.energy.IEnergyStorage;
|
||||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
||||||
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
|
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider;
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
import ru.dbotthepony.mc.otm.core.Fraction;
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
|
||||||
@ -18,7 +17,7 @@ public class MatteryCapability {
|
|||||||
public static final Capability<IMatteryEnergyStorage> ENERGY = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IMatteryEnergyStorage> ENERGY = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
public static final Capability<IAndroidCapability> ANDROID = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IAndroidCapability> ANDROID = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
public static final Capability<IMatterHandler> MATTER = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IMatterHandler> MATTER = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
public static final Capability<IMatterGridCell> MATTER_CELL = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IMatterGraphNode> MATTER_CELL = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
public static final Capability<IPatternStorage> PATTERN = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IPatternStorage> PATTERN = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
public static final Capability<IMatterTaskProvider> TASK = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IMatterTaskProvider> TASK = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
public static final Capability<IMatteryDrive> DRIVE = CapabilityManager.get(new CapabilityToken<>() {});
|
public static final Capability<IMatteryDrive> DRIVE = CapabilityManager.get(new CapabilityToken<>() {});
|
||||||
@ -29,11 +28,11 @@ public class MatteryCapability {
|
|||||||
event.register(IMatteryEnergyStorage.class);
|
event.register(IMatteryEnergyStorage.class);
|
||||||
event.register(IAndroidCapability.class);
|
event.register(IAndroidCapability.class);
|
||||||
event.register(IMatterHandler.class);
|
event.register(IMatterHandler.class);
|
||||||
event.register(IMatterGridCell.class);
|
|
||||||
event.register(IPatternStorage.class);
|
event.register(IPatternStorage.class);
|
||||||
event.register(IMatterTaskProvider.class);
|
event.register(IMatterTaskProvider.class);
|
||||||
event.register(IMatteryDrive.class);
|
event.register(IMatteryDrive.class);
|
||||||
event.register(IStorageGridCell.class);
|
event.register(IStorageGridCell.class);
|
||||||
|
event.register(IMatterGraphNode.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final MathContext ROUND_RULES = new MathContext(32, RoundingMode.HALF_DOWN);
|
public static final MathContext ROUND_RULES = new MathContext(32, RoundingMode.HALF_DOWN);
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability.matter;
|
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
|
|
||||||
import static ru.dbotthepony.mc.otm.AbstractGrid.createOrConnectGrid;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public interface IMatterGridCell extends IMatterGridListener {
|
|
||||||
@Nullable
|
|
||||||
MatterGrid getMatterGrid();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
default IMatterHandler getMatterHandler() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
default IPatternStorage getPatternStorage() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
default IMatterTaskProvider getTaskProvider() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isValidMatterCell();
|
|
||||||
|
|
||||||
void setMatterGrid(@Nullable MatterGrid grid);
|
|
||||||
|
|
||||||
default void scheduleDiscoverNeighbours(Level level, BlockPos pos) {
|
|
||||||
MatterGrid.scheduleDiscoverNeighbours(this, pos, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean connectOrCreateMatterGrid(Level level, BlockPos pos) {
|
|
||||||
return connectOrCreateMatterGrid(pos, level, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
default void onNeighbourMatterCell(Level level, BlockPos pos, Direction direction, IMatterGridCell cell, BlockEntity entity) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean connectOrCreateMatterGrid(BlockPos pos, Level level, boolean force) {
|
|
||||||
return createOrConnectGrid(
|
|
||||||
this,
|
|
||||||
MatteryCapability.MATTER_CELL,
|
|
||||||
level,
|
|
||||||
pos,
|
|
||||||
force,
|
|
||||||
MatterGrid::new,
|
|
||||||
IMatterGridCell::getMatterGrid,
|
|
||||||
this::onNeighbourMatterCell
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability.matter;
|
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public interface IMatterGridListener {
|
|
||||||
default void onPatternAdded(PatternState state) { }
|
|
||||||
default void onPatternRemoved(PatternState state) { }
|
|
||||||
default void onPatternUpdated(PatternState new_state, PatternState old_state) { }
|
|
||||||
|
|
||||||
default void onMatterTaskCreated(MatterTask task) { }
|
|
||||||
default void onMatterTaskUpdated(MatterTask new_state, MatterTask old_state) { }
|
|
||||||
default void onMatterTaskFinished(MatterTask state) { }
|
|
||||||
default void onMatterTaskRemoved(MatterTask state) { }
|
|
||||||
}
|
|
@ -1,453 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.matter;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import ru.dbotthepony.mc.otm.AbstractGrid;
|
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*;
|
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public class MatterGrid extends AbstractGrid<IMatterGridCell> implements IMatterGridListener {
|
|
||||||
private final Set<IMatterGridListener> listeners = new HashSet<>();
|
|
||||||
|
|
||||||
public static void scheduleDiscoverNeighbours(IMatterGridCell cell, BlockPos pos, Level level) {
|
|
||||||
if (level instanceof ServerLevel)
|
|
||||||
OverdriveThatMatters.tickUntil(level, () -> !cell.isValidMatterCell() || cell.connectOrCreateMatterGrid(pos, level, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
public MatterGrid() {
|
|
||||||
super(MatteryCapability.MATTER_CELL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Fraction getCapacity() {
|
|
||||||
Fraction summ = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IMatterHandler handler = cell.getMatterHandler();
|
|
||||||
|
|
||||||
if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
|
|
||||||
summ = summ.plus(handler.getMaxStoredMatter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return summ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Fraction getPotentialCapacity() {
|
|
||||||
Fraction summ = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IMatterHandler handler = cell.getMatterHandler();
|
|
||||||
|
|
||||||
if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) {
|
|
||||||
summ = summ.plus(handler.getMaxStoredMatter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return summ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Fraction getStored() {
|
|
||||||
Fraction summ = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IMatterHandler handler = cell.getMatterHandler();
|
|
||||||
|
|
||||||
if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
|
|
||||||
summ = summ.plus(handler.getStoredMatter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return summ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Fraction getPotentialStored() {
|
|
||||||
Fraction summ = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IMatterHandler handler = cell.getMatterHandler();
|
|
||||||
|
|
||||||
if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) {
|
|
||||||
summ = summ.plus(handler.getStoredMatter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return summ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Fraction extractMatter(Fraction howMuch, boolean simulate) {
|
|
||||||
if (howMuch.compareTo(Fraction.ZERO) <= 0)
|
|
||||||
return Fraction.ZERO;
|
|
||||||
|
|
||||||
validate();
|
|
||||||
|
|
||||||
Fraction extracted = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IMatterHandler handler = cell.getMatterHandler();
|
|
||||||
|
|
||||||
if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) {
|
|
||||||
var drain = handler.extractMatterOuter(howMuch, simulate);
|
|
||||||
|
|
||||||
if (!drain.equalsCompact(Fraction.ZERO)) {
|
|
||||||
extracted = extracted.plus(drain);
|
|
||||||
howMuch = howMuch.minus(drain);
|
|
||||||
|
|
||||||
if (howMuch.compareTo(Fraction.ZERO) <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return extracted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Fraction softPushMatter(Fraction howMuch, boolean simulate) {
|
|
||||||
if (howMuch.compareTo(Fraction.ZERO) <= 0)
|
|
||||||
return Fraction.ZERO;
|
|
||||||
|
|
||||||
validate();
|
|
||||||
|
|
||||||
Fraction received = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IMatterHandler handler = cell.getMatterHandler();
|
|
||||||
|
|
||||||
if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
|
|
||||||
var receive = handler.receiveMatterOuter(howMuch, simulate);
|
|
||||||
|
|
||||||
if (!receive.equalsCompact(Fraction.ZERO)) {
|
|
||||||
received = received.plus(receive);
|
|
||||||
howMuch = howMuch.minus(receive);
|
|
||||||
|
|
||||||
if (howMuch.compareTo(Fraction.ZERO) <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return received;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Fraction pushMatter(Fraction howMuch, boolean simulate) {
|
|
||||||
if (howMuch.compareTo(Fraction.ZERO) <= 0)
|
|
||||||
return Fraction.ZERO;
|
|
||||||
|
|
||||||
validate();
|
|
||||||
|
|
||||||
Fraction received = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IMatterHandler handler = cell.getMatterHandler();
|
|
||||||
|
|
||||||
if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.EXTRACT) {
|
|
||||||
var receive = handler.receiveMatterOuter(howMuch, simulate);
|
|
||||||
|
|
||||||
if (!receive.equalsCompact(Fraction.ZERO)) {
|
|
||||||
received = received.plus(receive);
|
|
||||||
howMuch = howMuch.minus(receive);
|
|
||||||
|
|
||||||
if (howMuch.compareTo(Fraction.ZERO) <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return received;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PatternInsertStatus insertPattern(PatternState state, boolean only_update, boolean simulate) {
|
|
||||||
validate();
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IPatternStorage storage = cell.getPatternStorage();
|
|
||||||
|
|
||||||
if (storage != null) {
|
|
||||||
var status = storage.insertPattern(state, true, simulate);
|
|
||||||
|
|
||||||
if (status.status() != PatternInsertStatus.Status.FAIL) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (only_update)
|
|
||||||
return new PatternInsertStatus();
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IPatternStorage storage = cell.getPatternStorage();
|
|
||||||
|
|
||||||
if (storage != null) {
|
|
||||||
var status = storage.insertPattern(state, false, simulate);
|
|
||||||
|
|
||||||
if (status.status() != PatternInsertStatus.Status.FAIL) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new PatternInsertStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<PatternState> getStoredPatterns() {
|
|
||||||
validate();
|
|
||||||
|
|
||||||
ArrayList<PatternState> list = new ArrayList<>();
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IPatternStorage storage = cell.getPatternStorage();
|
|
||||||
|
|
||||||
if (storage != null) {
|
|
||||||
list.addAll(storage.getStoredPatterns());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ImmutableList.copyOf(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getStoredPatternCount() {
|
|
||||||
validate();
|
|
||||||
|
|
||||||
long value = 0;
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IPatternStorage storage = cell.getPatternStorage();
|
|
||||||
|
|
||||||
if (storage != null) {
|
|
||||||
value += storage.getStored();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getPatternCapacity() {
|
|
||||||
validate();
|
|
||||||
|
|
||||||
long value = 0;
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IPatternStorage storage = cell.getPatternStorage();
|
|
||||||
|
|
||||||
if (storage != null) {
|
|
||||||
value += storage.getCapacity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<PatternState> findPatterns(Item item) {
|
|
||||||
return findPatterns((patternState -> item == patternState.item()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<PatternState> findPatterns(Predicate<PatternState> item) {
|
|
||||||
validate();
|
|
||||||
|
|
||||||
ArrayList<PatternState> list = new ArrayList<>();
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IPatternStorage storage = cell.getPatternStorage();
|
|
||||||
|
|
||||||
if (storage != null) {
|
|
||||||
list.addAll(storage.findPatterns(item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ImmutableList.copyOf(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public PatternState getPattern(PatternState state) {
|
|
||||||
return getPattern(state.id());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public PatternState getPattern(UUID id) {
|
|
||||||
validate();
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IPatternStorage storage = cell.getPatternStorage();
|
|
||||||
|
|
||||||
if (storage != null) {
|
|
||||||
var get = storage.getPattern(id);
|
|
||||||
|
|
||||||
if (get != null) {
|
|
||||||
return get;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasPattern(UUID id) {
|
|
||||||
return getPattern(id) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public MatterTaskAllocation allocateTask(boolean simulate) {
|
|
||||||
validate();
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IMatterTaskProvider tasks = cell.getTaskProvider();
|
|
||||||
|
|
||||||
if (tasks != null) {
|
|
||||||
MatterTaskAllocation allocated = tasks.allocateTask(simulate);
|
|
||||||
|
|
||||||
if (allocated != null) {
|
|
||||||
return allocated;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean notifyTaskCompletion(MatterTask task) {
|
|
||||||
validate();
|
|
||||||
|
|
||||||
for (IMatterGridCell cell : cells) {
|
|
||||||
IMatterTaskProvider tasks = cell.getTaskProvider();
|
|
||||||
|
|
||||||
if (tasks != null) {
|
|
||||||
if (tasks.notifyTaskCompletion(task)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onAdded(IMatterGridCell cell) {
|
|
||||||
cell.setMatterGrid(this);
|
|
||||||
|
|
||||||
var tasks = cell.getTaskProvider();
|
|
||||||
|
|
||||||
if (tasks != null) {
|
|
||||||
for (var task : tasks.getAllTasks()) {
|
|
||||||
onMatterTaskCreated(task);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var patterns = cell.getPatternStorage();
|
|
||||||
|
|
||||||
if (patterns != null) {
|
|
||||||
for (var pattern : patterns.getStoredPatterns()) {
|
|
||||||
onPatternAdded(pattern);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onRemoved(IMatterGridCell cell) {
|
|
||||||
cell.setMatterGrid(null);
|
|
||||||
|
|
||||||
var tasks = cell.getTaskProvider();
|
|
||||||
|
|
||||||
if (tasks != null) {
|
|
||||||
for (var task : tasks.getAllTasks()) {
|
|
||||||
onMatterTaskRemoved(task);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var patterns = cell.getPatternStorage();
|
|
||||||
|
|
||||||
if (patterns != null) {
|
|
||||||
for (var pattern : patterns.getStoredPatterns()) {
|
|
||||||
onPatternRemoved(pattern);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void attach(IMatterGridListener listener) {
|
|
||||||
listeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void detach(IMatterGridListener listener) {
|
|
||||||
listeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validate() {
|
|
||||||
ArrayList<IMatterGridCell> invalid = new ArrayList<>();
|
|
||||||
|
|
||||||
for (IMatterGridCell entity : cells) {
|
|
||||||
if (!entity.isValidMatterCell()) {
|
|
||||||
invalid.add(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (invalid.size() != 0) {
|
|
||||||
for (IMatterGridCell entity : invalid) {
|
|
||||||
remove(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPatternAdded(PatternState state) {
|
|
||||||
// validate();
|
|
||||||
cells.forEach(cell -> cell.onPatternAdded(state));
|
|
||||||
listeners.forEach(cell -> cell.onPatternAdded(state));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPatternRemoved(PatternState state) {
|
|
||||||
// validate();
|
|
||||||
cells.forEach(cell -> cell.onPatternRemoved(state));
|
|
||||||
listeners.forEach(cell -> cell.onPatternRemoved(state));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPatternUpdated(PatternState new_state, PatternState old_state) {
|
|
||||||
// validate();
|
|
||||||
cells.forEach(cell -> cell.onPatternUpdated(new_state, old_state));
|
|
||||||
listeners.forEach(cell -> cell.onPatternUpdated(new_state, old_state));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMatterTaskCreated(MatterTask task) {
|
|
||||||
// validate();
|
|
||||||
cells.forEach(cell -> cell.onMatterTaskCreated(task));
|
|
||||||
listeners.forEach(cell -> cell.onMatterTaskCreated(task));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMatterTaskUpdated(MatterTask new_state, MatterTask old_state) {
|
|
||||||
// validate();
|
|
||||||
cells.forEach(cell -> cell.onMatterTaskUpdated(new_state, old_state));
|
|
||||||
listeners.forEach(cell -> cell.onMatterTaskUpdated(new_state, old_state));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMatterTaskFinished(MatterTask state) {
|
|
||||||
// validate();
|
|
||||||
cells.forEach(cell -> cell.onMatterTaskFinished(state));
|
|
||||||
listeners.forEach(cell -> cell.onMatterTaskFinished(state));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMatterTaskRemoved(MatterTask state) {
|
|
||||||
// validate();
|
|
||||||
cells.forEach(cell -> cell.onMatterTaskRemoved(state));
|
|
||||||
listeners.forEach(cell -> cell.onMatterTaskRemoved(state));
|
|
||||||
}
|
|
||||||
}
|
|
@ -27,7 +27,7 @@ public class MatterDecomposerMenu extends PoweredMatteryMenu {
|
|||||||
|
|
||||||
public MatterDecomposerMenu(int containerID, Inventory inventory, @Nullable BlockEntityMatterDecomposer tile) {
|
public MatterDecomposerMenu(int containerID, Inventory inventory, @Nullable BlockEntityMatterDecomposer tile) {
|
||||||
super(Registry.Menus.MATTER_DECOMPOSER, containerID, inventory, tile);
|
super(Registry.Menus.MATTER_DECOMPOSER, containerID, inventory, tile);
|
||||||
Container container = tile != null ? tile.item_container : new SimpleContainer(2);
|
Container container = tile != null ? tile.itemContainer : new SimpleContainer(2);
|
||||||
|
|
||||||
// Вход
|
// Вход
|
||||||
input = new MatterySlot(container, 0, 61, 36) {
|
input = new MatterySlot(container, 0, 61, 36) {
|
||||||
|
@ -21,7 +21,7 @@ public class MatterReplicatorMenu extends PoweredMatteryMenu {
|
|||||||
public MatterReplicatorMenu(int p_38852_, Inventory inventory, BlockEntityMatterReplicator tile) {
|
public MatterReplicatorMenu(int p_38852_, Inventory inventory, BlockEntityMatterReplicator tile) {
|
||||||
super(Registry.Menus.MATTER_REPLICATOR, p_38852_, inventory, tile);
|
super(Registry.Menus.MATTER_REPLICATOR, p_38852_, inventory, tile);
|
||||||
|
|
||||||
Container container = tile != null ? tile.regular_slots : new SimpleContainer(3);
|
Container container = tile != null ? tile.regularSlots : new SimpleContainer(3);
|
||||||
|
|
||||||
for (int i = 0; i < container.getContainerSize(); i++) {
|
for (int i = 0; i < container.getContainerSize(); i++) {
|
||||||
output_slots[i] = new MachineOutputSlot(container, i, 64 + 18 * i, 38, true);
|
output_slots[i] = new MachineOutputSlot(container, i, 64 + 18 * i, 38, true);
|
||||||
|
@ -10,14 +10,16 @@ import ru.dbotthepony.mc.otm.capability.matter.MatterTask;
|
|||||||
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
|
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public record MatterTaskPacket(boolean action, MatterTask...state) {
|
public record MatterTaskPacket(boolean action, Collection<MatterTask> state) {
|
||||||
public void write(FriendlyByteBuf buffer) {
|
public void write(FriendlyByteBuf buffer) {
|
||||||
buffer.writeBoolean(action);
|
buffer.writeBoolean(action);
|
||||||
buffer.writeInt(state.length);
|
buffer.writeInt(state.size());
|
||||||
|
|
||||||
for (var state1 : state)
|
for (var state1 : state)
|
||||||
state1.write(buffer);
|
state1.write(buffer);
|
||||||
@ -42,10 +44,10 @@ public record MatterTaskPacket(boolean action, MatterTask...state) {
|
|||||||
public static MatterTaskPacket read(FriendlyByteBuf buffer) {
|
public static MatterTaskPacket read(FriendlyByteBuf buffer) {
|
||||||
boolean action = buffer.readBoolean();
|
boolean action = buffer.readBoolean();
|
||||||
int amount = buffer.readInt();
|
int amount = buffer.readInt();
|
||||||
var list = new MatterTask[amount];
|
var list = new ArrayList<MatterTask>(amount);
|
||||||
|
|
||||||
for (int i = 0; i < amount; i++)
|
for (int i = 0; i < amount; i++)
|
||||||
list[i] = Objects.requireNonNull(MatterTask.read(buffer));
|
list.add(Objects.requireNonNull(MatterTask.read(buffer)));
|
||||||
|
|
||||||
return new MatterTaskPacket(action, list);
|
return new MatterTaskPacket(action, list);
|
||||||
}
|
}
|
||||||
|
@ -44,11 +44,17 @@ public class NetworkHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] shortsToBytes(short[] input) {
|
public static byte[] shortsToBytes(short[] input) {
|
||||||
byte[] values = new byte[input.length * 2];
|
return shortsToBytes(input, 0);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < input.length; i++) {
|
public static byte[] shortsToBytes(short[] input, int offset) {
|
||||||
values[i * 2] = (byte) (input[i] & 0xFF);
|
byte[] values = new byte[(input.length - offset) * 2];
|
||||||
values[i * 2 + 1] = (byte) ((input[i] & 0xFF00) >> 8);
|
|
||||||
|
for (int i = offset; i < input.length; i++) {
|
||||||
|
int realI = i - offset;
|
||||||
|
|
||||||
|
values[realI * 2] = (byte) (input[i] & 0xFF);
|
||||||
|
values[realI * 2 + 1] = (byte) ((input[i] & 0xFF00) >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
|
@ -10,14 +10,16 @@ import ru.dbotthepony.mc.otm.capability.matter.PatternState;
|
|||||||
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
|
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public record PatternGridPacket(boolean action, PatternState ...state) {
|
public record PatternGridPacket(boolean action, Collection<PatternState> state) {
|
||||||
public void write(FriendlyByteBuf buffer) {
|
public void write(FriendlyByteBuf buffer) {
|
||||||
buffer.writeBoolean(action);
|
buffer.writeBoolean(action);
|
||||||
buffer.writeInt(state.length);
|
buffer.writeInt(state.size());
|
||||||
|
|
||||||
for (var state1 : state)
|
for (var state1 : state)
|
||||||
state1.write(buffer);
|
state1.write(buffer);
|
||||||
@ -44,10 +46,10 @@ public record PatternGridPacket(boolean action, PatternState ...state) {
|
|||||||
public static PatternGridPacket read(FriendlyByteBuf buffer) {
|
public static PatternGridPacket read(FriendlyByteBuf buffer) {
|
||||||
boolean action = buffer.readBoolean();
|
boolean action = buffer.readBoolean();
|
||||||
int amount = buffer.readInt();
|
int amount = buffer.readInt();
|
||||||
var list = new PatternState[amount];
|
var list = new ArrayList<PatternState>(amount);
|
||||||
|
|
||||||
for (int i = 0; i < amount; i++)
|
for (int i = 0; i < amount; i++)
|
||||||
list[i] = Objects.requireNonNull(PatternState.read(buffer));
|
list.add(Objects.requireNonNull(PatternState.read(buffer)));
|
||||||
|
|
||||||
return new PatternGridPacket(action, list);
|
return new PatternGridPacket(action, list);
|
||||||
}
|
}
|
||||||
|
@ -44,3 +44,11 @@ fun CompoundTag.ifHas(s: String, type: Byte, consumer: (Tag) -> Unit) {
|
|||||||
consumer(tag)
|
consumer(tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T : Tag> CompoundTag.ifHas(s: String, type: Class<T>, consumer: (T) -> Unit) {
|
||||||
|
val tag = get(s)
|
||||||
|
|
||||||
|
if (tag != null && tag::class.java == type) {
|
||||||
|
consumer(tag as T)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,40 +1,41 @@
|
|||||||
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.world.level.Level;
|
import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
import net.minecraft.world.level.block.Block
|
||||||
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.entity.BlockEntity
|
||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterBottler
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterBottler;
|
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState;
|
import net.minecraft.world.level.block.state.StateDefinition
|
||||||
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import javax.annotation.Nullable;
|
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class BlockMatterBottler extends BlockMatteryRotatable implements EntityBlock {
|
class BlockMatterBottler : BlockMatteryRotatable(), EntityBlock {
|
||||||
@Nullable
|
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
|
||||||
@Override
|
return BlockEntityMatterBottler(blockPos, blockState)
|
||||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
|
||||||
return new BlockEntityMatterBottler(blockPos, blockState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun <T : BlockEntity?> getTicker(
|
||||||
@Override
|
p_153212_: Level,
|
||||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) {
|
p_153213_: BlockState,
|
||||||
return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.MATTER_BOTTLER ? null : BlockEntityMatterBottler::tick;
|
p_153214_: BlockEntityType<T>
|
||||||
|
): BlockEntityTicker<T>? {
|
||||||
|
if (p_153212_.isClientSide || p_153214_ !== Registry.BlockEntities.MATTER_BOTTLER)
|
||||||
|
return null
|
||||||
|
|
||||||
|
return BlockEntityTicker {_, _, _, tile -> if (tile is BlockEntityMatterBottler) tile.tick()}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
super.createBlockStateDefinition(builder)
|
||||||
super.createBlockStateDefinition(builder);
|
builder.add(WorkerState.SEMI_WORKER_STATE)
|
||||||
builder.add(WorkerState.SEMI_WORKER_STATE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,67 +1,69 @@
|
|||||||
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.level.BlockGetter;
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
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 ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterDecomposer
|
||||||
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.entity.BlockEntityTicker
|
||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
import net.minecraft.world.level.block.state.StateDefinition
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.level.BlockGetter
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.level.Level
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import net.minecraft.world.level.block.Block
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterDecomposer;
|
import net.minecraft.world.phys.shapes.CollisionContext
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState;
|
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.block.BlockMatterDecomposer
|
||||||
import javax.annotation.Nullable;
|
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class BlockMatterDecomposer extends BlockMatteryRotatable implements EntityBlock {
|
class BlockMatterDecomposer : BlockMatteryRotatable(), EntityBlock {
|
||||||
@Nullable
|
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
|
||||||
@Override
|
return BlockEntityMatterDecomposer(blockPos, blockState)
|
||||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
|
||||||
return new BlockEntityMatterDecomposer(blockPos, blockState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun <T : BlockEntity?> getTicker(
|
||||||
@Override
|
p_153212_: Level,
|
||||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) {
|
p_153213_: BlockState,
|
||||||
return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.MATTER_DECOMPOSER ? null : BlockEntityMatterDecomposer::tick;
|
p_153214_: BlockEntityType<T>
|
||||||
|
): BlockEntityTicker<T>? {
|
||||||
|
if (p_153212_.isClientSide || p_153214_ !== Registry.BlockEntities.MATTER_DECOMPOSER)
|
||||||
|
return null
|
||||||
|
|
||||||
|
return BlockEntityTicker {_, _, _, t -> if (t is BlockEntityMatterDecomposer) t.tick()}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
super.createBlockStateDefinition(builder)
|
||||||
super.createBlockStateDefinition(builder);
|
builder.add(WorkerState.WORKER_STATE)
|
||||||
builder.add(WorkerState.WORKER_STATE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final List<VoxelShape> SHAPES;
|
override fun getShape(
|
||||||
|
p_60555_: BlockState,
|
||||||
|
p_60556_: BlockGetter,
|
||||||
|
p_60557_: BlockPos,
|
||||||
|
p_60558_: CollisionContext
|
||||||
|
): VoxelShape {
|
||||||
|
return SHAPES[p_60555_.getValue(FACING).ordinal]
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
companion object {
|
||||||
var def = BlockShapes.MATTER_DECOMPOSER.computeShape();
|
private val def = BlockShapes.MATTER_DECOMPOSER.computeShape()
|
||||||
|
|
||||||
SHAPES = List.of(
|
private val SHAPES: List<VoxelShape> = listOf(
|
||||||
def,
|
def,
|
||||||
def,
|
def,
|
||||||
def,
|
def,
|
||||||
BlockShapes.MATTER_DECOMPOSER.rotate(Direction.NORTH).computeShape(),
|
BlockShapes.MATTER_DECOMPOSER.rotate(Direction.NORTH).computeShape(),
|
||||||
BlockShapes.MATTER_DECOMPOSER.rotate(Direction.WEST).computeShape(),
|
BlockShapes.MATTER_DECOMPOSER.rotate(Direction.WEST).computeShape(),
|
||||||
BlockShapes.MATTER_DECOMPOSER.rotate(Direction.EAST).computeShape()
|
BlockShapes.MATTER_DECOMPOSER.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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -43,7 +43,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
|
|||||||
private var valid = true
|
private var valid = true
|
||||||
private var resolver = LazyOptional.of {energy}
|
private var resolver = LazyOptional.of {energy}
|
||||||
|
|
||||||
override fun <T : Any?> 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()
|
||||||
|
|
||||||
|
@ -1,366 +1,329 @@
|
|||||||
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 javax.annotation.ParametersAreNonnullByDefault
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.entity.player.Player;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import net.minecraft.world.item.ItemStack;
|
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
|
||||||
import net.minecraft.world.level.Level;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraftforge.items.CapabilityItemHandler
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import net.minecraft.nbt.CompoundTag
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState;
|
import net.minecraft.network.chat.Component
|
||||||
import ru.dbotthepony.mc.otm.capability.*;
|
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell;
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
import net.minecraft.server.level.ServerLevel
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability;
|
import net.minecraft.world.level.Level
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
import net.minecraft.world.level.block.Block
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler;
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu;
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import javax.annotation.Nonnull;
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
import javax.annotation.Nullable;
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import ru.dbotthepony.mc.otm.ifHas
|
||||||
import java.math.BigDecimal;
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implements IMatterGridCell {
|
class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
public BlockEntityMatterBottler(BlockPos p_155229_, BlockState p_155230_) {
|
BlockEntityMatteryPowered(Registry.BlockEntities.MATTER_BOTTLER, p_155229_, p_155230_), IMatterGraphNode {
|
||||||
super(Registry.BlockEntities.MATTER_BOTTLER, p_155229_, p_155230_);
|
|
||||||
energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final TranslatableComponent MACHINE_NAME = new TranslatableComponent("block.overdrive_that_matters.matter_bottler");
|
private val node = Graph6Node<IMatterGraphNode>(this)
|
||||||
|
private val resolverNode = LazyOptional.of { this }
|
||||||
|
|
||||||
public boolean getWorkFlow() {
|
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||||
return work_flow;
|
return node
|
||||||
}
|
|
||||||
|
|
||||||
public void setWorkFlow(boolean work_flow) {
|
|
||||||
this.work_flow = work_flow;
|
|
||||||
this.setChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void switchWorkFlow() {
|
|
||||||
setWorkFlow(!work_flow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// true - bottling
|
// true - bottling
|
||||||
// false - unbottling
|
// false - unbottling
|
||||||
protected boolean work_flow = true;
|
var workFlow: Boolean = true
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
this.setChangedLight()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun switchWorkFlow() {
|
||||||
|
workFlow = !workFlow
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: оно должно что то делать
|
||||||
// true - continue even if empty when bottling / if full while unbottling
|
// true - continue even if empty when bottling / if full while unbottling
|
||||||
// false - spit into output slot
|
// false - spit into output slot
|
||||||
protected boolean work_behavior = true;
|
//private var work_behavior = true
|
||||||
|
|
||||||
public final MatteryContainer work_slots = new MatteryContainer(this::setChanged, 6) {
|
@JvmField
|
||||||
@Override
|
val container: MatteryContainer = object : MatteryContainer(this::setChangedLight, 6) {
|
||||||
public int getMaxStackSize(int slot) {
|
override fun getMaxStackSize(slot: Int): Int {
|
||||||
return 1;
|
return 1
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
public final MatteryContainerHandler work_slots_handler = work_slots.handler((slot, stack) -> {
|
val itemHandler = container.handler({ slot: Int, stack: ItemStack ->
|
||||||
if (work_flow) {
|
if (this.workFlow) {
|
||||||
return slot < 3 && stack.getCapability(MatteryCapability.MATTER).isPresent();
|
return@handler slot < 3 && stack.getCapability(MatteryCapability.MATTER).isPresent
|
||||||
|
}
|
||||||
|
slot >= 3 && stack.getCapability(MatteryCapability.MATTER).isPresent
|
||||||
|
}, { slot: Int, amount: Int, stack: ItemStack? ->
|
||||||
|
if (this.workFlow) {
|
||||||
|
return@handler slot >= 3
|
||||||
|
}
|
||||||
|
slot < 3
|
||||||
|
})
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val matter: MatterHandlerCapability =
|
||||||
|
object : MatterHandlerCapability(this::setChangedLight, MatterDirection.BIDIRECTIONAL, Fraction(4)) {
|
||||||
|
override fun getDirection(): MatterDirection {
|
||||||
|
return if (this@BlockEntityMatterBottler.workFlow) MatterDirection.RECEIVE else MatterDirection.EXTRACT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return slot >= 3 && stack.getCapability(MatteryCapability.MATTER).isPresent();
|
private var initialCapacity: Fraction? = null
|
||||||
}, (slot, amount, stack) -> {
|
private var lastWorkStack: ItemStack? = null
|
||||||
if (work_flow) {
|
|
||||||
return slot >= 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return slot < 3;
|
override fun getMatterHandler(): IMatterHandler {
|
||||||
});
|
return matter
|
||||||
|
|
||||||
public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.BIDIRECTIONAL, new Fraction(4)) {
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public MatterDirection getDirection() {
|
|
||||||
return work_flow ? MatterDirection.RECEIVE : MatterDirection.EXTRACT;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final Fraction MATTER_EXCHANGE_RATE = new Fraction("0.04");
|
|
||||||
private static final Fraction ENERGY_CONSUMPTION = new Fraction(20);
|
|
||||||
|
|
||||||
private LazyOptional<IMatterGridCell> cell_resolver = LazyOptional.of(() -> this);
|
|
||||||
|
|
||||||
protected Fraction initial_capacity;
|
|
||||||
protected ItemStack last_work_stack;
|
|
||||||
|
|
||||||
private MatterGrid grid;
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public MatterGrid getMatterGrid() {
|
|
||||||
return grid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun setLevel(p_155231_: Level) {
|
||||||
public boolean isValidMatterCell() {
|
super.setLevel(p_155231_)
|
||||||
return valid;
|
|
||||||
|
if (p_155231_ is ServerLevel)
|
||||||
|
MatterNetworkGraph.discoverFull(this, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private var valid = true
|
||||||
public void setMatterGrid(MatterGrid grid) {
|
|
||||||
this.grid = grid;
|
override fun invalidateCaps() {
|
||||||
|
super.invalidateCaps()
|
||||||
|
valid = false
|
||||||
|
itemHandler.invalidate()
|
||||||
|
matter.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun reviveCaps() {
|
||||||
@Override
|
super.reviveCaps()
|
||||||
public IMatterHandler getMatterHandler() {
|
valid = true
|
||||||
return matter;
|
itemHandler.revive()
|
||||||
|
matter.revive()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
public void setLevel(Level p_155231_) {
|
|
||||||
super.setLevel(p_155231_);
|
|
||||||
|
|
||||||
if (grid == null)
|
|
||||||
scheduleDiscoverNeighbours(p_155231_, getBlockPos());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean valid = true;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCaps() {
|
|
||||||
super.invalidateCaps();
|
|
||||||
valid = false;
|
|
||||||
work_slots_handler.invalidate();
|
|
||||||
matter.invalidate();
|
|
||||||
cell_resolver.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reviveCaps() {
|
|
||||||
super.reviveCaps();
|
|
||||||
valid = true;
|
|
||||||
work_slots_handler.revive();
|
|
||||||
matter.revive();
|
|
||||||
cell_resolver = LazyOptional.of(() -> this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (cap == MatteryCapability.MATTER) {
|
if (cap === MatteryCapability.MATTER) {
|
||||||
return matter.get().cast();
|
return matter.get().cast()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
||||||
return work_slots_handler.get().cast();
|
return itemHandler.get().cast()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cap == MatteryCapability.MATTER_CELL) {
|
if (cap === MatteryCapability.MATTER_CELL) {
|
||||||
return cell_resolver.cast();
|
return resolverNode.cast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
return super.getCapability(cap, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getDefaultDisplayName(): Component {
|
||||||
protected Component getDefaultDisplayName() {
|
return MACHINE_NAME
|
||||||
return MACHINE_NAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
@Override
|
return MatterBottlerMenu(containerID, inventory, this)
|
||||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
|
||||||
return new MatterBottlerMenu(containerID, inventory, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
super.saveAdditional(nbt)
|
||||||
super.saveAdditional(nbt);
|
nbt["work_slots"] = container.serializeNBT()
|
||||||
nbt.put("work_slots", work_slots.serializeNBT());
|
nbt["work_flow"] = this.workFlow
|
||||||
nbt.putBoolean("work_flow", work_flow);
|
nbt["matter_capability"] = matter.serializeNBT()
|
||||||
nbt.put("matter_capability", matter.serializeNBT());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun load(nbt: CompoundTag) {
|
||||||
public void load(CompoundTag nbt) {
|
super.load(nbt)
|
||||||
super.load(nbt);
|
container.deserializeNBT(nbt["work_slots"])
|
||||||
work_slots.deserializeNBT(nbt.get("work_slots"));
|
workFlow = nbt.getBoolean("work_flow")
|
||||||
work_flow = nbt.getBoolean("work_flow");
|
|
||||||
|
|
||||||
if (nbt.get("matter_capability") instanceof CompoundTag _matter)
|
nbt.ifHas("matter_capability", CompoundTag::class.java) {
|
||||||
matter.deserializeNBT(_matter);
|
matter.deserializeNBT(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Fraction EXTRACTION_TICKS = new Fraction(200);
|
init {
|
||||||
|
energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER)
|
||||||
|
}
|
||||||
|
|
||||||
public float getWorkProgress() {
|
fun getWorkProgress(): Float {
|
||||||
if (last_work_stack == null) {
|
if (lastWorkStack == null) {
|
||||||
return 0;
|
return 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
var cap = last_work_stack.getCapability(MatteryCapability.MATTER).resolve();
|
val resolver = lastWorkStack!!.getCapability(MatteryCapability.MATTER).resolve()
|
||||||
|
|
||||||
if (cap.isEmpty()) {
|
if (resolver.isEmpty) {
|
||||||
return 0;
|
return 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
if (work_flow) {
|
val cap = resolver.get()
|
||||||
if (cap.get().getMaxStoredMatter().minus(initial_capacity).compareTo(Fraction.ZERO) <= 0) {
|
|
||||||
return 0;
|
if (this.workFlow) {
|
||||||
|
if (cap.maxStoredMatter - initialCapacity!! <= Fraction.ZERO) {
|
||||||
|
return 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
return cap.get().getStoredMatter().minus(initial_capacity).div(cap.get().getMaxStoredMatter().minus(initial_capacity)).toFloat();
|
return ((cap.storedMatter - initialCapacity!!) / (cap.maxStoredMatter - initialCapacity!!)).toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initial_capacity.compareTo(Fraction.ZERO) <= 0) {
|
if (initialCapacity!! <= Fraction.ZERO) {
|
||||||
return 0;
|
return 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
return Fraction.ONE.minus(cap.get().getStoredMatter().div(initial_capacity)).toFloat();
|
return (Fraction.ONE - cap.storedMatter / initialCapacity!!).toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) {
|
fun tick() {
|
||||||
if (t instanceof BlockEntityMatterBottler tile) {
|
batteryChargeLoop()
|
||||||
tile.batteryChargeLoop();
|
|
||||||
|
|
||||||
if (tile.isBlockedByRedstone()) {
|
if (isBlockedByRedstone) {
|
||||||
if (tile.getBlockState().getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) {
|
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) {
|
||||||
level.setBlock(tile.getBlockPos(), tile.getBlockState().setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS);
|
level!!.setBlock(
|
||||||
}
|
blockPos,
|
||||||
|
blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE),
|
||||||
return;
|
Block.UPDATE_CLIENTS
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack work_stack = null;
|
return
|
||||||
IMatterHandler capability = null;
|
}
|
||||||
int align = tile.work_flow ? 0 : 3;
|
|
||||||
int work_slot = -1;
|
|
||||||
|
|
||||||
for (int i = align; i < align + 3; i++) {
|
var work_stack: ItemStack? = null
|
||||||
var get = tile.work_slots.getItem(i);
|
var capability: IMatterHandler? = null
|
||||||
|
val align = if (workFlow) 0 else 3
|
||||||
|
var work_slot = -1
|
||||||
|
val unexpectedDirection = if (workFlow) MatterDirection.EXTRACT else MatterDirection.RECEIVE
|
||||||
|
|
||||||
if (!get.isEmpty()) {
|
for (i in align until align + 3) {
|
||||||
var cap = get.getCapability(MatteryCapability.MATTER).resolve();
|
val itemStack = container.getItem(i)
|
||||||
|
|
||||||
if (cap.isPresent() && cap.get().getDirection() != (tile.work_flow ? IMatterHandler.MatterDirection.EXTRACT : IMatterHandler.MatterDirection.RECEIVE) && (tile.work_flow ? cap.get().getMissingMatter().compareTo(Fraction.ZERO) > 0 : cap.get().getStoredMatter().compareTo(Fraction.ZERO) > 0)) {
|
if (!itemStack.isEmpty) {
|
||||||
work_stack = get;
|
val cap = itemStack.getCapability(MatteryCapability.MATTER).resolve()
|
||||||
capability = cap.get();
|
|
||||||
work_slot = i;
|
if (cap.isPresent && cap.get().direction != unexpectedDirection) {
|
||||||
break;
|
if (this.workFlow && cap.get().missingMatter > Fraction.ZERO || !this.workFlow && cap.get().storedMatter > Fraction.ZERO) {
|
||||||
|
work_stack = itemStack
|
||||||
|
capability = cap.get()
|
||||||
|
work_slot = i
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (work_stack == null) {
|
if (work_stack == null) {
|
||||||
tile.last_work_stack = null;
|
lastWorkStack = null
|
||||||
tile.initial_capacity = null;
|
initialCapacity = null
|
||||||
} else if (work_stack != tile.last_work_stack) {
|
} else if (work_stack != lastWorkStack) {
|
||||||
tile.last_work_stack = work_stack;
|
lastWorkStack = work_stack
|
||||||
tile.initial_capacity = capability.getStoredMatter();
|
initialCapacity = capability!!.storedMatter
|
||||||
|
}
|
||||||
|
|
||||||
|
val graph = node.graph as MatterNetworkGraph?
|
||||||
|
|
||||||
|
if (capability != null) {
|
||||||
|
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.WORKING) {
|
||||||
|
level!!.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tile.work_flow) {
|
if (workFlow) {
|
||||||
if (capability != null) {
|
if (matter.storedMatter < MATTER_EXCHANGE_RATE && graph != null) {
|
||||||
if (tile.getBlockState().getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.WORKING) {
|
val extracted = graph.extractMatter(
|
||||||
level.setBlock(tile.getBlockPos(), tile.getBlockState().setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS);
|
matter.missingMatter.min(MATTER_EXCHANGE_RATE * EXTRACTION_TICKS, capability.missingMatter - matter.storedMatter), true
|
||||||
|
)
|
||||||
|
|
||||||
|
if (extracted > Fraction.ZERO) {
|
||||||
|
val received = matter.receiveMatterOuter(extracted, false)
|
||||||
|
graph.extractMatter(received, false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tile.matter.getStoredMatter().compareTo(MATTER_EXCHANGE_RATE) < 0) {
|
if (matter.storedMatter > Fraction.ZERO) {
|
||||||
if (tile.grid != null) {
|
val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true)
|
||||||
var extracted = tile.grid.extractMatter(
|
|
||||||
tile.matter.getMissingMatter()
|
|
||||||
.min(MATTER_EXCHANGE_RATE.times(EXTRACTION_TICKS))
|
|
||||||
.min(capability.getMissingMatter().minus(tile.matter.getStoredMatter()))
|
|
||||||
, true);
|
|
||||||
|
|
||||||
if (extracted.compareTo(Fraction.ZERO) > 0) {
|
if (!energyExtracted.isZero()) {
|
||||||
var received = tile.matter.receiveMatterOuter(extracted, false);
|
val matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(matter.storedMatter) * (energyExtracted / ENERGY_CONSUMPTION), true)
|
||||||
tile.grid.extractMatter(received, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile.matter.getStoredMatter().compareTo(Fraction.ZERO) > 0) {
|
if (!matter.isZero()) {
|
||||||
var energy = tile.energy.extractEnergyInner(ENERGY_CONSUMPTION, true);
|
energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE,false)
|
||||||
|
|
||||||
if (energy.compareTo(Fraction.ZERO) > 0) {
|
capability.receiveMatterOuter(matter, false)
|
||||||
var matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getStoredMatter()).times(energy.div(ENERGY_CONSUMPTION)), true);
|
this.matter.extractMatterInner(matter, false)
|
||||||
|
|
||||||
if (matter.compareTo(Fraction.ZERO) > 0) {
|
if (capability.missingMatter.isZero()) {
|
||||||
tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.times(matter.div(MATTER_EXCHANGE_RATE)), false);
|
for (i in 3..5) {
|
||||||
capability.receiveMatterOuter(matter, false);
|
if (container.getItem(i).isEmpty) {
|
||||||
tile.matter.extractMatterInner(matter, false);
|
container.setItem(work_slot, ItemStack.EMPTY)
|
||||||
|
container.setItem(i, work_stack!!)
|
||||||
if (capability.getMissingMatter().compareTo(Fraction.ZERO) == 0) {
|
break
|
||||||
for (int i = 3; i < 6; i++) {
|
|
||||||
if (tile.work_slots.getItem(i).isEmpty()) {
|
|
||||||
tile.work_slots.setItem(work_slot, ItemStack.EMPTY);
|
|
||||||
tile.work_slots.setItem(i, work_stack);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (tile.getBlockState().getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) {
|
|
||||||
level.setBlock(tile.getBlockPos(), tile.getBlockState().setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (capability != null) {
|
val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true)
|
||||||
if (tile.getBlockState().getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.WORKING) {
|
|
||||||
level.setBlock(tile.getBlockPos(), tile.getBlockState().setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
var energy = tile.energy.extractEnergyInner(ENERGY_CONSUMPTION, true);
|
if (!energyExtracted.isZero()) {
|
||||||
|
val matter = capability.extractMatterOuter(MATTER_EXCHANGE_RATE.min(matter.missingMatter) * energyExtracted / ENERGY_CONSUMPTION, true)
|
||||||
|
|
||||||
if (energy.compareTo(Fraction.ZERO) > 0) {
|
if (!matter.isZero()) {
|
||||||
var matter = capability.extractMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getMissingMatter()).times(energy.div(ENERGY_CONSUMPTION)), true);
|
this.energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE,false)
|
||||||
|
|
||||||
if (matter.compareTo(Fraction.ZERO) > 0) {
|
capability.extractMatterOuter(matter, false)
|
||||||
tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.times(matter.div(MATTER_EXCHANGE_RATE)), false);
|
this.matter.receiveMatterInner(matter, false)
|
||||||
capability.extractMatterOuter(matter, false);
|
|
||||||
tile.matter.receiveMatterInner(matter, false);
|
|
||||||
|
|
||||||
if (capability.getStoredMatter().compareTo(Fraction.ZERO) == 0) {
|
if (capability.storedMatter.isZero()) {
|
||||||
for (int i = 2; i >= 0; i--) {
|
for (i in 2 downTo 0) {
|
||||||
if (tile.work_slots.getItem(i).isEmpty()) {
|
if (container.getItem(i).isEmpty) {
|
||||||
tile.work_slots.setItem(work_slot, ItemStack.EMPTY);
|
container.setItem(work_slot, ItemStack.EMPTY)
|
||||||
tile.work_slots.setItem(i, work_stack);
|
container.setItem(i, work_stack!!)
|
||||||
break;
|
break
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (tile.getBlockState().getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) {
|
|
||||||
level.setBlock(tile.getBlockPos(), tile.getBlockState().setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile.matter.getStoredMatter().compareTo(Fraction.ZERO) > 0 && tile.grid != null) {
|
|
||||||
var diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true);
|
|
||||||
var diff2 = tile.grid.softPushMatter(diff, true);
|
|
||||||
|
|
||||||
tile.matter.extractMatterInner(diff2, false);
|
|
||||||
tile.grid.softPushMatter(diff2, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
level!!.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!workFlow && !matter.storedMatter.isZero() && graph != null) {
|
||||||
|
val diff = matter.extractMatterInner(matter.storedMatter, true)
|
||||||
|
val diff2 = graph.receiveMatter(diff, true)
|
||||||
|
matter.extractMatterInner(diff2, false)
|
||||||
|
graph.receiveMatter(diff2, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_bottler")
|
||||||
|
private val MATTER_EXCHANGE_RATE = Fraction("0.04")
|
||||||
|
private val ENERGY_CONSUMPTION = Fraction(20)
|
||||||
|
private val EXTRACTION_TICKS = Fraction(200)
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.Direction
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.Block
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
|
import ru.dbotthepony.mc.otm.block.BlockMatterCable
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
|
import ru.dbotthepony.mc.otm.graph.GraphNodeListener
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
|
|
||||||
|
class BlockEntityMatterCable(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
|
BlockEntity(Registry.BlockEntities.MATTER_CABLE, p_155229_, p_155230_), IMatterGraphNode, GraphNodeListener {
|
||||||
|
|
||||||
|
private var valid = true
|
||||||
|
private val node = Graph6Node<IMatterGraphNode>(this)
|
||||||
|
private val resolverNode = LazyOptional.of { this }
|
||||||
|
|
||||||
|
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invalidateCaps() {
|
||||||
|
super.invalidateCaps()
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reviveCaps() {
|
||||||
|
super.reviveCaps()
|
||||||
|
valid = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
|
if (valid) {
|
||||||
|
if (cap === MatteryCapability.MATTER_CELL)
|
||||||
|
return resolverNode.cast()
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getCapability(cap, side)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLevel(p_155231_: Level) {
|
||||||
|
super.setLevel(p_155231_)
|
||||||
|
|
||||||
|
if (p_155231_ is ServerLevel)
|
||||||
|
MatterNetworkGraph.discoverFull(this, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNeighbour(node: Graph6Node<*>, direction: Direction) {
|
||||||
|
val new_state = blockState.setValue(BlockMatterCable.MAPPING_CONNECTION_PROP[direction.ordinal], true)
|
||||||
|
if (new_state !== blockState) level!!.setBlock(blockPos, new_state, Block.UPDATE_CLIENTS)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUnNeighbour(node: Graph6Node<*>, direction: Direction) {
|
||||||
|
val new_state = blockState.setValue(BlockMatterCable.MAPPING_CONNECTION_PROP[direction.ordinal], false)
|
||||||
|
if (new_state !== blockState) level!!.setBlock(blockPos, new_state, Block.UPDATE_CLIENTS)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setRemoved() {
|
||||||
|
super.setRemoved()
|
||||||
|
node.destroy(::MatterNetworkGraph)
|
||||||
|
}
|
||||||
|
}
|
@ -1,279 +1,207 @@
|
|||||||
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.world.entity.player.Inventory;
|
import net.minecraft.server.level.ServerLevel
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.Block
|
||||||
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 ru.dbotthepony.mc.otm.block.BlockBatteryBank;
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell;
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
import ru.dbotthepony.mc.otm.block.BlockBatteryBank
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterCapacitorBankMenu;
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import javax.annotation.Nonnull;
|
import ru.dbotthepony.mc.otm.menu.MatterCapacitorBankMenu
|
||||||
import javax.annotation.Nullable;
|
import ru.dbotthepony.mc.otm.set
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implements IMatterGridCell {
|
class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
public final IMatterHandler matter = new IMatterHandler() {
|
BlockEntityMattery(Registry.BlockEntities.MATTER_CAPACITOR_BANK, p_155229_, p_155230_), IMatterGraphNode, IMatterHandler {
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Fraction getStoredMatter() {
|
|
||||||
Fraction summ = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (int i = 0; i < matter_container.getContainerSize(); i++) {
|
private val node = Graph6Node<IMatterGraphNode>(this)
|
||||||
ItemStack stack = matter_container.getItem(i);
|
private val resolverNode = LazyOptional.of { this }
|
||||||
|
|
||||||
if (!stack.isEmpty()) {
|
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||||
Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve();
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
if (handler.isPresent()) {
|
override fun getStoredMatter(): Fraction {
|
||||||
summ = summ.plus(handler.get().getStoredMatter());
|
var summ = Fraction.ZERO
|
||||||
}
|
|
||||||
|
for (stack in matterContainer)
|
||||||
|
if (!stack.isEmpty)
|
||||||
|
stack.getCapability(MatteryCapability.MATTER).ifPresent {
|
||||||
|
summ += it.storedMatter
|
||||||
|
}
|
||||||
|
|
||||||
|
return summ
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMaxStoredMatter(): Fraction {
|
||||||
|
var summ = Fraction.ZERO
|
||||||
|
|
||||||
|
for (stack in matterContainer)
|
||||||
|
if (!stack.isEmpty)
|
||||||
|
stack.getCapability(MatteryCapability.MATTER).ifPresent {
|
||||||
|
summ += it.maxStoredMatter
|
||||||
|
}
|
||||||
|
|
||||||
|
return summ
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun receiveMatterOuter(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
|
return receiveMatterInner(howMuch, simulate)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun receiveMatterInner(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
|
var howMuch = howMuch
|
||||||
|
var summ = Fraction.ZERO
|
||||||
|
|
||||||
|
for (stack in matterContainer) {
|
||||||
|
if (!stack.isEmpty) {
|
||||||
|
stack.getCapability(MatteryCapability.MATTER).ifPresent {
|
||||||
|
val diff = it.receiveMatterOuter(howMuch, simulate)
|
||||||
|
summ += diff
|
||||||
|
howMuch -= diff
|
||||||
|
}
|
||||||
|
|
||||||
|
if (howMuch.isZero()) {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return summ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
return summ
|
||||||
@Override
|
}
|
||||||
public Fraction getMaxStoredMatter() {
|
|
||||||
Fraction summ = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (int i = 0; i < matter_container.getContainerSize(); i++) {
|
override fun extractMatterOuter(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
ItemStack stack = matter_container.getItem(i);
|
return extractMatterInner(howMuch, simulate)
|
||||||
|
}
|
||||||
|
|
||||||
if (!stack.isEmpty()) {
|
override fun extractMatterInner(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve();
|
var howMuch = howMuch
|
||||||
|
var summ = Fraction.ZERO
|
||||||
|
|
||||||
if (handler.isPresent()) {
|
for (stack in matterContainer) {
|
||||||
summ = summ.plus(handler.get().getMaxStoredMatter());
|
if (!stack.isEmpty) {
|
||||||
}
|
stack.getCapability(MatteryCapability.MATTER).ifPresent {
|
||||||
|
val diff = it.extractMatterOuter(howMuch, simulate)
|
||||||
|
summ += diff
|
||||||
|
howMuch -= diff
|
||||||
|
}
|
||||||
|
|
||||||
|
if (howMuch.isZero()) {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return summ;
|
|
||||||
}
|
}
|
||||||
|
return summ
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
override fun getDirection(): MatterDirection {
|
||||||
@Override
|
return MatterDirection.BIDIRECTIONAL
|
||||||
public Fraction receiveMatterOuter(Fraction howMuch, boolean simulate) {
|
}
|
||||||
return receiveMatterInner(howMuch, simulate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
private var resolver = LazyOptional.of { this }
|
||||||
@Override
|
|
||||||
public Fraction receiveMatterInner(Fraction howMuch, boolean simulate) {
|
|
||||||
Fraction summ = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (int i = 0; i < matter_container.getContainerSize(); i++) {
|
@JvmField
|
||||||
ItemStack stack = matter_container.getItem(i);
|
val matterContainer = object : MatteryContainer(this::setChangedLight, 6 * 2) {
|
||||||
|
override fun setChanged(slot: Int, new_state: ItemStack, old_state: ItemStack) {
|
||||||
if (!stack.isEmpty()) {
|
super.setChanged(slot, new_state, old_state)
|
||||||
Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve();
|
val level = level
|
||||||
|
|
||||||
if (handler.isPresent()) {
|
|
||||||
var diff = handler.get().receiveMatterOuter(howMuch, simulate);
|
|
||||||
summ = summ.plus(diff);
|
|
||||||
howMuch = howMuch.minus(diff);
|
|
||||||
|
|
||||||
if (howMuch.compareTo(Fraction.ZERO) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return summ;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Fraction extractMatterOuter(Fraction howMuch, boolean simulate) {
|
|
||||||
return extractMatterInner(howMuch, simulate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Fraction extractMatterInner(Fraction howMuch, boolean simulate) {
|
|
||||||
Fraction summ = Fraction.ZERO;
|
|
||||||
|
|
||||||
for (int i = 0; i < matter_container.getContainerSize(); i++) {
|
|
||||||
ItemStack stack = matter_container.getItem(i);
|
|
||||||
|
|
||||||
if (!stack.isEmpty()) {
|
|
||||||
Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve();
|
|
||||||
|
|
||||||
if (handler.isPresent()) {
|
|
||||||
var diff = handler.get().extractMatterOuter(howMuch, simulate);
|
|
||||||
summ = summ.plus(diff);
|
|
||||||
howMuch = howMuch.minus(diff);
|
|
||||||
|
|
||||||
if (howMuch.compareTo(Fraction.ZERO) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return summ;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public MatterDirection getDirection() {
|
|
||||||
return MatterDirection.BIDIRECTIONAL;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private LazyOptional<IMatterHandler> resolver = LazyOptional.of(() -> matter);
|
|
||||||
|
|
||||||
public final MatteryContainer matter_container = new MatteryContainer(this::setChanged, 6 * 2) {
|
|
||||||
@Override
|
|
||||||
public void setChanged(int slot, ItemStack new_state, ItemStack old_state) {
|
|
||||||
super.setChanged(slot, new_state, old_state);
|
|
||||||
|
|
||||||
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(MatteryCapability.MATTER).isPresent());
|
state = state.setValue(
|
||||||
|
BlockBatteryBank.BATTERY_SLOTS_PROPS[i],
|
||||||
|
getItem(i).getCapability(MatteryCapability.MATTER).isPresent
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state != getBlockState()) {
|
if (state !== blockState) {
|
||||||
level.setBlock(getBlockPos(), state, Block.UPDATE_CLIENTS);
|
level.setBlock(blockPos, state, Block.UPDATE_CLIENTS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
public BlockEntityMatterCapacitorBank(BlockPos p_155229_, BlockState p_155230_) {
|
|
||||||
super(Registry.BlockEntities.MATTER_CAPACITOR_BANK, p_155229_, p_155230_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final TranslatableComponent MACHINE_NAME = new TranslatableComponent("block.overdrive_that_matters.matter_capacitor_bank");
|
companion object {
|
||||||
|
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_capacitor_bank")
|
||||||
@Override
|
|
||||||
protected Component getDefaultDisplayName() {
|
|
||||||
return MACHINE_NAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getDefaultDisplayName(): Component {
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
return MACHINE_NAME
|
||||||
super.saveAdditional(nbt);
|
|
||||||
nbt.put("matter_container", matter_container.serializeNBT());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
public void load(CompoundTag nbt) {
|
super.saveAdditional(nbt)
|
||||||
matter_container.deserializeNBT(nbt.get("matter_container"));
|
nbt["matter_container"] = matterContainer.serializeNBT()
|
||||||
super.load(nbt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun load(nbt: CompoundTag) {
|
||||||
@Override
|
matterContainer.deserializeNBT(nbt["matter_container"])
|
||||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
super.load(nbt)
|
||||||
return new MatterCapacitorBankMenu(containerID, inventory, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean valid = true;
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
|
return MatterCapacitorBankMenu(containerID, inventory, this)
|
||||||
@Override
|
|
||||||
public void invalidateCaps() {
|
|
||||||
super.invalidateCaps();
|
|
||||||
valid = false;
|
|
||||||
resolver.invalidate();
|
|
||||||
resolver_grid.invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private var valid = true
|
||||||
public void reviveCaps() {
|
|
||||||
super.reviveCaps();
|
override fun invalidateCaps() {
|
||||||
valid = true;
|
super.invalidateCaps()
|
||||||
resolver = LazyOptional.of(() -> matter);
|
valid = false
|
||||||
resolver_grid = LazyOptional.of(() -> this);
|
resolver.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
private LazyOptional<IMatterGridCell> resolver_grid = LazyOptional.of(() -> this);
|
override fun reviveCaps() {
|
||||||
|
super.reviveCaps()
|
||||||
|
valid = true
|
||||||
|
resolver = LazyOptional.of { this }
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
@Override
|
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (cap == MatteryCapability.MATTER)
|
if (cap === MatteryCapability.MATTER) return resolver.cast()
|
||||||
return resolver.cast();
|
if (cap === MatteryCapability.MATTER_CELL) return resolverNode.cast()
|
||||||
|
|
||||||
if (cap == MatteryCapability.MATTER_CELL)
|
|
||||||
return resolver_grid.cast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
return super.getCapability(cap, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
private MatterGrid grid;
|
override fun setRemoved() {
|
||||||
|
super.setRemoved()
|
||||||
@Nullable
|
node.destroy(::MatterNetworkGraph)
|
||||||
@Override
|
|
||||||
public MatterGrid getMatterGrid() {
|
|
||||||
return grid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun setLevel(p_155231_: Level) {
|
||||||
public void setRemoved() {
|
super.setLevel(p_155231_)
|
||||||
super.setRemoved();
|
|
||||||
|
|
||||||
if (grid != null)
|
if (p_155231_ is ServerLevel)
|
||||||
grid.remove(this);
|
MatterNetworkGraph.discoverFull(this, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getMatterHandler(): IMatterHandler {
|
||||||
public void setLevel(Level p_155231_) {
|
return this
|
||||||
super.setLevel(p_155231_);
|
|
||||||
|
|
||||||
if (!p_155231_.isClientSide)
|
|
||||||
MatterGrid.scheduleDiscoverNeighbours(this, getBlockPos(), p_155231_);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public IMatterHandler getMatterHandler() {
|
|
||||||
return valid ? matter : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public IPatternStorage getPatternStorage() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValidMatterCell() {
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMatterGrid(MatterGrid grid) {
|
|
||||||
this.grid = grid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,186 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.Direction
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.world.entity.player.Inventory
|
||||||
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
|
import net.minecraftforge.items.CapabilityItemHandler
|
||||||
|
import net.minecraftforge.items.IItemHandler
|
||||||
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJob
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
|
||||||
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
|
import ru.dbotthepony.mc.otm.ifHas
|
||||||
|
import ru.dbotthepony.mc.otm.matter.MatterRegistry
|
||||||
|
import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu
|
||||||
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
|
||||||
|
class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
|
||||||
|
: BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_DECOMPOSER, pos, state), IMatterGraphNode {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_decomposer")
|
||||||
|
private val BASE_CONSUMPTION = Fraction(240)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
energy = MatteryMachineEnergyStorage(
|
||||||
|
this,
|
||||||
|
MatteryMachineEnergyStorage.MachineType.WORKER,
|
||||||
|
Fraction(400000),
|
||||||
|
Fraction(2000),
|
||||||
|
Fraction(2000)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var valid = true
|
||||||
|
private val node = Graph6Node<IMatterGraphNode>(this)
|
||||||
|
|
||||||
|
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.EXTRACT, Fraction("20"))
|
||||||
|
|
||||||
|
private var resolverMatter = LazyOptional.of { matter }
|
||||||
|
private var resolverNode = LazyOptional.of { this }
|
||||||
|
|
||||||
|
// вход, выход
|
||||||
|
@JvmField
|
||||||
|
val itemContainer = MatteryContainer(this::setChangedLight, 2)
|
||||||
|
|
||||||
|
private val itemHandler = LazyOptional.of<IItemHandler> {
|
||||||
|
itemContainer.handler(
|
||||||
|
{ slot: Int, stack: ItemStack? -> slot == 0 && MatterRegistry.canDecompose(stack) },
|
||||||
|
{ slot: Int, amount: Int, stack: ItemStack? -> slot == 1 })
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDefaultDisplayName(): Component? {
|
||||||
|
return MACHINE_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
|
return MatterDecomposerMenu(containerID, inventory, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
|
super.saveAdditional(nbt)
|
||||||
|
nbt["work_slots"] = itemContainer.serializeNBT()
|
||||||
|
nbt["matter_capability"] = matter.serializeNBT()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun load(nbt: CompoundTag) {
|
||||||
|
super.load(nbt)
|
||||||
|
|
||||||
|
nbt.ifHas("matter_capability") {
|
||||||
|
if (it is CompoundTag)
|
||||||
|
matter.deserializeNBT(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
nbt.ifHas("work_slots") {
|
||||||
|
itemContainer.deserializeNBT(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reviveCaps() {
|
||||||
|
valid = true
|
||||||
|
super.reviveCaps()
|
||||||
|
resolverMatter = LazyOptional.of { matter }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invalidateCaps() {
|
||||||
|
valid = false
|
||||||
|
super.invalidateCaps()
|
||||||
|
resolverMatter.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
|
if (valid) {
|
||||||
|
if (cap === MatteryCapability.MATTER) return resolverMatter.cast()
|
||||||
|
if (cap === MatteryCapability.MATTER_CELL) return resolverNode.cast()
|
||||||
|
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.cast()
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getCapability(cap, side)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onJobFinish(job: MachineJob): MachineJobStatus {
|
||||||
|
matter.receiveMatterInner(MatterRegistry.getMatterValue(job.stack()), false)
|
||||||
|
return MachineJobStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getNextJob(): MachineJob? {
|
||||||
|
val stack = itemContainer.getItem(0)
|
||||||
|
|
||||||
|
if (!stack.isEmpty) {
|
||||||
|
val copy = stack.copy()
|
||||||
|
copy.count = 1
|
||||||
|
|
||||||
|
if (MatterRegistry.canDecompose(copy)) {
|
||||||
|
val value = MatterRegistry.getMatterValue(copy)
|
||||||
|
|
||||||
|
if (value != Fraction.ZERO && matter.canReceiveAll(value)) {
|
||||||
|
stack.shrink(1)
|
||||||
|
return MachineJob(copy, value.toDouble() * 12500.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setRemoved() {
|
||||||
|
super.setRemoved()
|
||||||
|
node.destroy(::MatterNetworkGraph)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLevel(p_155231_: Level) {
|
||||||
|
super.setLevel(p_155231_)
|
||||||
|
|
||||||
|
if (p_155231_ is ServerLevel)
|
||||||
|
MatterNetworkGraph.discoverFull(this, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMatterHandler(): IMatterHandler {
|
||||||
|
return matter
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBaseConsumption(): Fraction {
|
||||||
|
return BASE_CONSUMPTION
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tick() {
|
||||||
|
batteryChargeLoop();
|
||||||
|
workerLoop();
|
||||||
|
|
||||||
|
val grid = node.graph as MatterNetworkGraph?
|
||||||
|
|
||||||
|
if (!matter.storedMatter.isZero() && grid != null) {
|
||||||
|
val diff = matter.extractMatterInner(matter.getStoredMatter(), true)
|
||||||
|
val diff2 = grid.receiveMatter(diff, true)
|
||||||
|
|
||||||
|
matter.extractMatterInner(diff2, false)
|
||||||
|
grid.receiveMatter(diff2, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,276 +1,229 @@
|
|||||||
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 javax.annotation.ParametersAreNonnullByDefault
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.nbt.ListTag;
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.nbt.Tag;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider
|
||||||
import net.minecraft.network.chat.Component;
|
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
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.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraft.world.level.Level;
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import java.util.HashMap
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import java.util.UUID
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import ru.dbotthepony.mc.otm.capability.matter.MatterTask
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import java.util.stream.Collectors
|
||||||
import ru.dbotthepony.mc.otm.capability.*;
|
import ru.dbotthepony.mc.otm.capability.matter.MatterTaskAllocation
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*;
|
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
import net.minecraft.nbt.CompoundTag
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
|
import net.minecraft.nbt.ListTag
|
||||||
|
import net.minecraft.nbt.Tag
|
||||||
import javax.annotation.Nonnull;
|
import net.minecraft.network.chat.Component
|
||||||
import javax.annotation.Nullable;
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import net.minecraft.server.level.ServerLevel
|
||||||
import java.util.*;
|
import net.minecraft.world.level.Level
|
||||||
import java.util.stream.Collectors;
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
|
import java.util.ArrayList
|
||||||
|
import java.util.List
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class BlockEntityMatterPanel extends BlockEntityMattery implements IMatterGridCell, IMatterTaskProvider {
|
class BlockEntityMatterPanel(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
public BlockEntityMatterPanel(BlockPos p_155229_, BlockState p_155230_) {
|
BlockEntityMattery(Registry.BlockEntities.MATTER_PANEL, p_155229_, p_155230_), IMatterGraphNode, IMatterTaskProvider {
|
||||||
super(Registry.BlockEntities.MATTER_PANEL, p_155229_, p_155230_);
|
|
||||||
|
private val listeners = ArrayList<MatterPanelMenu>()
|
||||||
|
private val node = Graph6Node<IMatterGraphNode>(this)
|
||||||
|
|
||||||
|
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||||
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.matter_panel");
|
fun attachMenu(menu: MatterPanelMenu) {
|
||||||
|
listeners.add(menu)
|
||||||
private final ArrayList<MatterPanelMenu> listeners = new ArrayList<>();
|
|
||||||
|
|
||||||
public void attachMenu(MatterPanelMenu menu) {
|
|
||||||
listeners.add(menu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deatachMenu(MatterPanelMenu menu) {
|
fun deatachMenu(menu: MatterPanelMenu) {
|
||||||
listeners.remove(menu);
|
listeners.remove(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getDefaultDisplayName(): Component {
|
||||||
protected Component getDefaultDisplayName() {
|
return NAME
|
||||||
return NAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
@Override
|
return MatterPanelMenu(containerID, inventory, this)
|
||||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
|
||||||
return new MatterPanelMenu(containerID, inventory, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean valid = true;
|
private var valid = true
|
||||||
|
|
||||||
@Override
|
override fun invalidateCaps() {
|
||||||
public void invalidateCaps() {
|
super.invalidateCaps()
|
||||||
super.invalidateCaps();
|
valid = false
|
||||||
valid = false;
|
resolver.invalidate()
|
||||||
resolver.invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun reviveCaps() {
|
||||||
public void reviveCaps() {
|
super.reviveCaps()
|
||||||
super.reviveCaps();
|
valid = true
|
||||||
valid = true;
|
resolver = LazyOptional.of { this }
|
||||||
resolver = LazyOptional.of(() -> this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LazyOptional<BlockEntityMatterPanel> resolver = LazyOptional.of(() -> this);
|
private var resolver = LazyOptional.of { this }
|
||||||
|
|
||||||
@Nonnull
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
@Override
|
if (valid && (cap === MatteryCapability.MATTER_CELL || cap === MatteryCapability.TASK))
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
return resolver.cast()
|
||||||
if (valid && (cap == MatteryCapability.MATTER_CELL || cap == MatteryCapability.TASK))
|
|
||||||
return resolver.cast();
|
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
return super.getCapability(cap, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
private MatterGrid grid;
|
override fun setLevel(p_155231_: Level) {
|
||||||
|
super.setLevel(p_155231_)
|
||||||
|
|
||||||
@Override
|
if (p_155231_ is ServerLevel)
|
||||||
public void setLevel(Level p_155231_) {
|
MatterNetworkGraph.discoverFull(this, node)
|
||||||
super.setLevel(p_155231_);
|
|
||||||
|
|
||||||
if (grid == null)
|
|
||||||
scheduleDiscoverNeighbours(p_155231_, getBlockPos());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun setRemoved() {
|
||||||
public void setRemoved() {
|
super.setRemoved()
|
||||||
super.setRemoved();
|
node.destroy(::MatterNetworkGraph)
|
||||||
|
|
||||||
if (level != null && !level.isClientSide && grid != null)
|
|
||||||
grid.remove(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun getTaskHandler(): IMatterTaskProvider? {
|
||||||
@Override
|
return this
|
||||||
public MatterGrid getMatterGrid() {
|
|
||||||
return grid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private val tasks = HashMap<UUID, MatterTask?>()
|
||||||
public boolean isValidMatterCell() {
|
|
||||||
return valid;
|
override fun getTasks(): Collection<MatterTask> {
|
||||||
|
return tasks.values.stream().filter { task: MatterTask? -> task!!.required() > 0 }.collect(Collectors.toList()) as Collection<MatterTask>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getAllTasks(): Collection<MatterTask> {
|
||||||
public void setMatterGrid(MatterGrid grid) {
|
return List.copyOf(tasks.values) as Collection<MatterTask>
|
||||||
this.grid = grid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun allocateTask(simulate: Boolean): MatterTaskAllocation? {
|
||||||
@Override
|
val graph = node.graph as MatterNetworkGraph? ?: return null
|
||||||
public IMatterTaskProvider getTaskProvider() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final HashMap<UUID, MatterTask> tasks = new HashMap<>();
|
for ((key, task) in tasks) {
|
||||||
|
if (task!!.required > 0) {
|
||||||
|
val getPattern = graph.getPattern(task.pattern!!)
|
||||||
|
|
||||||
@Nonnull
|
if (getPattern != null) {
|
||||||
@Override
|
|
||||||
public Collection<MatterTask> getTasks() {
|
|
||||||
return tasks.values().stream().filter(task -> task.required() > 0).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Collection<MatterTask> getAllTasks() {
|
|
||||||
return List.copyOf(tasks.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public MatterTaskAllocation allocateTask(boolean simulate) {
|
|
||||||
if (grid == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
for (var entry : tasks.entrySet()) {
|
|
||||||
var task = entry.getValue();
|
|
||||||
|
|
||||||
if (task.required() > 0) {
|
|
||||||
var get_pattern = grid.getPattern(task.pattern());
|
|
||||||
|
|
||||||
if (get_pattern != null) {
|
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
var newer = task.shrinkRequired(1);
|
val new = task.shrinkRequired(1)
|
||||||
tasks.put(entry.getKey(), newer);
|
tasks[key] = new
|
||||||
listeners.forEach(menu -> menu.taskUpdated(newer));
|
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(new) }
|
||||||
grid.onMatterTaskUpdated(newer, task);
|
graph.onMatterTaskUpdated(new, task)
|
||||||
setChanged();
|
setChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MatterTaskAllocation(task, get_pattern);
|
return MatterTaskAllocation(task, getPattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun notifyTaskCompletion(task: MatterTask): Boolean {
|
||||||
public boolean notifyTaskCompletion(MatterTask task) {
|
var localTask = tasks[task.id] ?: return false
|
||||||
var get_task = tasks.get(task.id());
|
val oldTask = localTask
|
||||||
|
|
||||||
if (get_task == null) {
|
localTask = localTask.shrinkInProgress(1)
|
||||||
return false;
|
val graph = node.graph as MatterNetworkGraph?
|
||||||
}
|
|
||||||
|
|
||||||
var old_task = get_task;
|
// Задача полностью выполнена
|
||||||
get_task = get_task.shrinkInProgress(1);
|
if (localTask.required <= 0 && localTask.in_progress <= 0) {
|
||||||
|
tasks.remove(task.id)
|
||||||
if (get_task.required() <= 0 && get_task.in_progress() <= 0) {
|
graph?.onMatterTaskCreated(task)
|
||||||
tasks.remove(task.id());
|
listeners.forEach { menu: MatterPanelMenu -> menu.taskRemoved(localTask) }
|
||||||
|
|
||||||
if (grid != null)
|
|
||||||
grid.onMatterTaskCreated(task);
|
|
||||||
|
|
||||||
MatterTask finalGet_task1 = get_task;
|
|
||||||
listeners.forEach(menu -> menu.taskRemoved(finalGet_task1));
|
|
||||||
} else {
|
} else {
|
||||||
tasks.put(task.id(), get_task);
|
// Задача обновлена
|
||||||
|
tasks[task.id()] = localTask
|
||||||
if (grid != null) {
|
graph?.onMatterTaskUpdated(localTask, oldTask)
|
||||||
grid.onMatterTaskUpdated(get_task, old_task);
|
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(localTask) }
|
||||||
}
|
|
||||||
|
|
||||||
MatterTask finalGet_task = get_task;
|
|
||||||
listeners.forEach(menu -> menu.taskUpdated(finalGet_task));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setChanged();
|
setChanged()
|
||||||
|
return true
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
super.saveAdditional(nbt)
|
||||||
super.saveAdditional(nbt);
|
|
||||||
ListTag list = new ListTag();
|
|
||||||
|
|
||||||
for (MatterTask task : tasks.values()) {
|
val list = ListTag()
|
||||||
list.add(task.serializeNBT());
|
|
||||||
|
for (task in tasks.values) {
|
||||||
|
list.add(task!!.serializeNBT())
|
||||||
}
|
}
|
||||||
|
|
||||||
nbt.put("tasks", list);
|
nbt.put("tasks", list)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun load(nbt: CompoundTag) {
|
||||||
public void load(CompoundTag nbt) {
|
super.load(nbt)
|
||||||
super.load(nbt);
|
tasks.clear()
|
||||||
tasks.clear();
|
val list = nbt.getList("tasks", Tag.TAG_COMPOUND.toInt())
|
||||||
|
|
||||||
ListTag list = nbt.getList("tasks", Tag.TAG_COMPOUND);
|
for (tag in list) {
|
||||||
|
val task = MatterTask.deserializeNBT(tag)
|
||||||
for (Tag tag : list) {
|
|
||||||
MatterTask task = MatterTask.deserializeNBT(tag);
|
|
||||||
|
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
tasks.put(task.id(), task);
|
tasks[task.id()] = task
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun getTask(id: UUID): MatterTask? {
|
||||||
@Override
|
return tasks[id]
|
||||||
public MatterTask getTask(UUID id) {
|
|
||||||
return tasks.get(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeTask(UUID id) {
|
fun removeTask(id: UUID) {
|
||||||
var task = tasks.get(id);
|
val task = tasks[id] ?: return
|
||||||
|
tasks.remove(id)
|
||||||
|
|
||||||
if (task == null)
|
(node.graph as MatterNetworkGraph?)?.onMatterTaskRemoved(task)
|
||||||
return;
|
|
||||||
|
|
||||||
tasks.remove(id);
|
listeners.forEach { menu: MatterPanelMenu -> menu.taskRemoved(task) }
|
||||||
|
setChanged()
|
||||||
if (grid != null)
|
|
||||||
grid.onMatterTaskRemoved(task);
|
|
||||||
|
|
||||||
listeners.forEach(menu -> menu.taskRemoved(task));
|
|
||||||
setChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeTask(PatternState state) {
|
fun removeTask(state: PatternState) = removeTask(state.id)
|
||||||
removeTask(state.id());
|
|
||||||
|
fun addTask(state: PatternState, how_much: Int): MatterTask {
|
||||||
|
val task = MatterTask(UUID.randomUUID(), state.id, state.item, 0, 0, how_much)
|
||||||
|
tasks[task.id()] = task
|
||||||
|
|
||||||
|
(node.graph as MatterNetworkGraph?)?.onMatterTaskCreated(task)
|
||||||
|
|
||||||
|
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(task) }
|
||||||
|
setChanged()
|
||||||
|
|
||||||
|
return task
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatterTask addTask(PatternState state, int how_much) {
|
override fun dropAllTasks() {
|
||||||
var task = new MatterTask(UUID.randomUUID(), state.id(), state.item(), 0, 0, how_much);
|
val graph = node.graph as MatterNetworkGraph?
|
||||||
tasks.put(task.id(), task);
|
|
||||||
|
|
||||||
if (grid != null)
|
for (task in tasks.values) {
|
||||||
grid.onMatterTaskCreated(task);
|
graph?.onMatterTaskRemoved(task!!)
|
||||||
|
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(task!!) }
|
||||||
|
}
|
||||||
|
|
||||||
listeners.forEach(menu -> menu.taskUpdated(task));
|
tasks.clear()
|
||||||
|
|
||||||
setChanged();
|
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
companion object {
|
||||||
public void dropAllTasks() {
|
private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_panel")
|
||||||
tasks.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,278 +1,236 @@
|
|||||||
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 javax.annotation.ParametersAreNonnullByDefault
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
|
||||||
import net.minecraft.world.entity.player.Player;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJob
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker;
|
import ru.dbotthepony.mc.otm.capability.matter.MatterTask
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJob;
|
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus;
|
import ru.dbotthepony.mc.otm.matter.MatterRegistry
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkTickContext;
|
import ru.dbotthepony.mc.otm.block.entity.worker.WorkTickContext
|
||||||
import ru.dbotthepony.mc.otm.capability.*;
|
import net.minecraft.nbt.CompoundTag
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*;
|
import net.minecraft.network.chat.Component
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler;
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
import net.minecraftforge.items.CapabilityItemHandler
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterRegistry;
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu;
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
import javax.annotation.Nonnull;
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import javax.annotation.Nullable;
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
import java.math.BigDecimal;
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
|
import ru.dbotthepony.mc.otm.ifHas
|
||||||
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implements IMatterGridCell {
|
class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
public BlockEntityMatterReplicator(BlockPos p_155229_, BlockState p_155230_) {
|
BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_), IMatterGraphNode {
|
||||||
super(Registry.BlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_);
|
|
||||||
energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new Fraction(200_000), new Fraction(4000), new Fraction(4000));
|
private val node = Graph6Node<IMatterGraphNode>(this)
|
||||||
|
private val resolverNode = LazyOptional.of { this }
|
||||||
|
|
||||||
|
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||||
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.RECEIVE, new Fraction(2));
|
@JvmField
|
||||||
|
val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.RECEIVE, Fraction(2))
|
||||||
|
|
||||||
// обычные запросы
|
// обычные запросы
|
||||||
public final MatteryContainer regular_slots = new MatteryContainer(this::setChanged, 3);
|
@JvmField
|
||||||
|
val regularSlots = MatteryContainer(this::setChangedLight, 3)
|
||||||
|
|
||||||
// запросы от matter replicator interface
|
// запросы от matter replicator interface?
|
||||||
public final MatteryContainer reserved_slots = new MatteryContainer(this::setChanged, 3);
|
val reservedSlots = MatteryContainer(this::setChangedLight, 3)
|
||||||
|
|
||||||
private final MatteryContainerHandler slots_handler = regular_slots.handler((slot, stack) -> false);
|
private val itemHandler = regularSlots.handler { slot: Int, stack: ItemStack? -> false }
|
||||||
|
|
||||||
private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.matter_replicator");
|
override fun getDefaultDisplayName(): Component {
|
||||||
|
return NAME
|
||||||
private static final Fraction BASE_CONSUMPTION = new Fraction(400);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Component getDefaultDisplayName() {
|
|
||||||
return NAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||||
@Override
|
return MatterReplicatorMenu(containerID, inventory, this)
|
||||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
|
||||||
return new MatterReplicatorMenu(containerID, inventory, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
override fun getBaseConsumption(): Fraction {
|
||||||
@Override
|
return BASE_CONSUMPTION
|
||||||
protected Fraction getBaseConsumption() {
|
|
||||||
return BASE_CONSUMPTION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
override fun onJobFinish(job: MachineJob): MachineJobStatus {
|
||||||
@Override
|
if (!regularSlots.fullyAddItem(job.stack())) {
|
||||||
protected MachineJobStatus onJobFinish(MachineJob job) {
|
return MachineJobStatus(false, 20)
|
||||||
if (!regular_slots.fullyAddItem(job.stack())) {
|
|
||||||
return new MachineJobStatus(false, 20);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grid != null) {
|
(node.graph as MatterNetworkGraph?)?.notifyTaskCompletion(MatterTask.deserializeNBT(job.data["task"])!!)
|
||||||
grid.notifyTaskCompletion(MatterTask.deserializeNBT(job.data().get("task")));
|
return MachineJobStatus()
|
||||||
}
|
|
||||||
|
|
||||||
return new MachineJobStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onMatterTaskCreated(task: MatterTask) {
|
||||||
public void onMatterTaskCreated(MatterTask task) {
|
is_idling = false
|
||||||
is_idling = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) {
|
||||||
public void onMatterTaskUpdated(MatterTask new_state, MatterTask old_state) {
|
is_idling = false
|
||||||
is_idling = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onPatternAdded(state: PatternState) {
|
||||||
public void onPatternAdded(PatternState state) {
|
is_idling = false
|
||||||
is_idling = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun setRemoved() {
|
||||||
public void setRemoved() {
|
super.setRemoved()
|
||||||
super.setRemoved();
|
node.destroy(::MatterNetworkGraph)
|
||||||
|
|
||||||
if (level != null && !level.isClientSide && grid != null)
|
|
||||||
grid.remove(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final double TICKS_PER_MTU = 20_000d;
|
override fun setLevel(p_155231_: Level) {
|
||||||
private static final Fraction TICKS_PER_MTU_BD = new Fraction(20_000);
|
super.setLevel(p_155231_)
|
||||||
private static final double MTU_PER_TICK = 1d / 20_000d;
|
|
||||||
private static final Fraction MTU_PER_TICK_BD = Fraction.ONE.div(TICKS_PER_MTU_BD);
|
|
||||||
|
|
||||||
@Override
|
if (p_155231_ is ServerLevel)
|
||||||
public void setLevel(Level p_155231_) {
|
MatterNetworkGraph.discoverFull(this, node)
|
||||||
super.setLevel(p_155231_);
|
|
||||||
|
|
||||||
if (grid == null)
|
|
||||||
scheduleDiscoverNeighbours(p_155231_, getBlockPos());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun getNextJob(): MachineJob? {
|
||||||
@Override
|
val graph = node.graph as MatterNetworkGraph? ?: return null
|
||||||
protected MachineJob getNextJob() {
|
val allocation = graph.allocateTask(false) ?: return null
|
||||||
if (grid == null)
|
val stack = allocation.task().stack(1)
|
||||||
return null;
|
|
||||||
|
|
||||||
MatterTaskAllocation allocation = grid.allocateTask(false);
|
|
||||||
|
|
||||||
if (allocation == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
ItemStack stack = allocation.task().stack(1);
|
|
||||||
|
|
||||||
// ????????
|
// ????????
|
||||||
if (!MatterRegistry.hasMatterValue(stack))
|
if (!MatterRegistry.hasMatterValue(stack)) return null
|
||||||
return null;
|
val job = MachineJob(stack, MatterRegistry.getMatterValue(stack).toDouble() * TICKS_PER_MTU)
|
||||||
|
|
||||||
MachineJob job = new MachineJob(stack, MatterRegistry.getMatterValue(stack).toDouble() * TICKS_PER_MTU);
|
job.data["task"] = allocation.task.serializeNBT()
|
||||||
|
if (allocation.pattern != null) job.data["pattern"] = allocation.pattern!!.serializeNBT()
|
||||||
|
|
||||||
job.data().put("task", allocation.task().serializeNBT());
|
return job
|
||||||
|
|
||||||
if (allocation.pattern() != null)
|
|
||||||
job.data().put("pattern", allocation.pattern().serializeNBT());
|
|
||||||
|
|
||||||
return job;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Fraction DRAIN_MULT = new Fraction(200);
|
override fun onWorkTick(context: WorkTickContext): MachineJobStatus {
|
||||||
|
val drainPerTick = MTU_PER_TICK_BD.times(context.work_speed())
|
||||||
|
val graph = node.graph as MatterNetworkGraph? ?: return MachineJobStatus(false, 20)
|
||||||
|
|
||||||
@Override
|
if (matter.extractMatterInner(drainPerTick, true) < drainPerTick) {
|
||||||
protected MachineJobStatus onWorkTick(WorkTickContext context) {
|
|
||||||
var drain_per_tick = MTU_PER_TICK_BD.times(context.work_speed());
|
|
||||||
|
|
||||||
if (matter.extractMatterInner(drain_per_tick, true).compareTo(drain_per_tick) < 0) {
|
|
||||||
// в машине недостаточно материи
|
// в машине недостаточно материи
|
||||||
if (grid == null)
|
|
||||||
return new MachineJobStatus(false, 20);
|
|
||||||
|
|
||||||
if (drain_per_tick.compareTo(matter.getMaxStoredMatter()) > 0) {
|
if (drainPerTick > matter.maxStoredMatter) {
|
||||||
// в тик требуется больше материи, чем её может хранить репликатор
|
// в тик требуется больше материи, чем её может хранить репликатор
|
||||||
var to_extract = drain_per_tick.minus(matter.extractMatterInner(drain_per_tick, true));
|
val toExtract = drainPerTick - matter.extractMatterInner(drainPerTick, true)
|
||||||
var drain = grid.extractMatter(to_extract, true);
|
val drain = graph.extractMatter(toExtract, true)
|
||||||
|
|
||||||
if (drain.compareTo(to_extract) < 0) {
|
if (drain < toExtract) {
|
||||||
// недостаточно материи в сети
|
// недостаточно материи в сети
|
||||||
return new MachineJobStatus(false, 200);
|
return MachineJobStatus(false, 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// достаточно материи в сети + внутри машины
|
// достаточно материи в сети + внутри машины
|
||||||
matter.extractMatterInner(drain_per_tick, false);
|
matter.extractMatterInner(drainPerTick, false)
|
||||||
grid.extractMatter(drain, false);
|
graph.extractMatter(drain, false)
|
||||||
|
return MachineJobStatus()
|
||||||
return new MachineJobStatus();
|
|
||||||
} else {
|
} else {
|
||||||
// в тик требуется меньше материи, чем её может хранить репликатор
|
// в тик требуется меньше материи, чем её может хранить репликатор
|
||||||
// примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше
|
// примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше
|
||||||
var to_extract = matter.getMissingMatter().min(drain_per_tick.times(DRAIN_MULT));
|
val toExtract =
|
||||||
var drain = grid.extractMatter(to_extract, true);
|
matter.missingMatter.min(drainPerTick.times(DRAIN_MULT))
|
||||||
|
|
||||||
if (drain.compareTo(Fraction.ZERO) == 0) {
|
val drain = graph.extractMatter(toExtract, true)
|
||||||
|
|
||||||
|
if (drain.isZero()) {
|
||||||
// в сети нет материи
|
// в сети нет материи
|
||||||
return new MachineJobStatus(false, 200);
|
return MachineJobStatus(false, 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
var received = matter.receiveMatterOuter(drain, false);
|
val received = matter.receiveMatterOuter(drain, false)
|
||||||
grid.extractMatter(received, false);
|
graph.extractMatter(received, false)
|
||||||
|
|
||||||
// получили материю, проверяем возможность работы
|
// получили материю, проверяем возможность работы
|
||||||
if (matter.extractMatterInner(drain_per_tick, false).compareTo(drain_per_tick) >= 0) {
|
if (matter.extractMatterInner(drainPerTick, false) >= drainPerTick) {
|
||||||
return new MachineJobStatus();
|
return MachineJobStatus()
|
||||||
} else {
|
} else {
|
||||||
// :(
|
// :(
|
||||||
return new MachineJobStatus(false, 200);
|
return MachineJobStatus(false, 200)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// в машине достаточно материи
|
// в машине достаточно материи
|
||||||
|
matter.extractMatterInner(drainPerTick, false)
|
||||||
matter.extractMatterInner(drain_per_tick, false);
|
return MachineJobStatus()
|
||||||
return new MachineJobStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
super.saveAdditional(nbt)
|
||||||
super.saveAdditional(nbt);
|
nbt["regular_slots"] = regularSlots.serializeNBT()
|
||||||
nbt.put("regular_slots", regular_slots.serializeNBT());
|
nbt["reserved_slots"] = reservedSlots.serializeNBT()
|
||||||
nbt.put("reserved_slots", reserved_slots.serializeNBT());
|
nbt["matter_capability"] = matter.serializeNBT()
|
||||||
nbt.put("matter_capability", matter.serializeNBT());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun load(nbt: CompoundTag) {
|
||||||
public void load(CompoundTag nbt) {
|
super.load(nbt)
|
||||||
super.load(nbt);
|
regularSlots.deserializeNBT(nbt["regular_slots"])
|
||||||
regular_slots.deserializeNBT(nbt.get("regular_slots"));
|
reservedSlots.deserializeNBT(nbt["reserved_slots"])
|
||||||
reserved_slots.deserializeNBT(nbt.get("reserved_slots"));
|
|
||||||
|
|
||||||
if (nbt.get("matter_capability") instanceof CompoundTag tag)
|
nbt.ifHas("matter_capability", CompoundTag::class.java) {
|
||||||
matter.deserializeNBT(tag);
|
matter.deserializeNBT(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean valid = true;
|
private var valid = true
|
||||||
|
|
||||||
@Override
|
override fun invalidateCaps() {
|
||||||
public void invalidateCaps() {
|
super.invalidateCaps()
|
||||||
super.invalidateCaps();
|
valid = false
|
||||||
valid = false;
|
itemHandler.invalidate()
|
||||||
slots_handler.invalidate();
|
|
||||||
resolver_self.invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun reviveCaps() {
|
||||||
public void reviveCaps() {
|
super.reviveCaps()
|
||||||
super.reviveCaps();
|
valid = true
|
||||||
valid = true;
|
itemHandler.revive()
|
||||||
slots_handler.revive();
|
|
||||||
resolver_self = LazyOptional.of(() -> this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LazyOptional<BlockEntityMatterReplicator> resolver_self = LazyOptional.of(() -> this);
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (cap == MatteryCapability.MATTER_CELL)
|
if (cap === MatteryCapability.MATTER_CELL) return resolverNode.cast()
|
||||||
return resolver_self.cast();
|
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.get().cast()
|
||||||
|
|
||||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
|
||||||
return slots_handler.get().cast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
return super.getCapability(cap, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
private MatterGrid grid;
|
init {
|
||||||
|
energy = MatteryMachineEnergyStorage(
|
||||||
@Nullable
|
this,
|
||||||
@Override
|
MatteryMachineEnergyStorage.MachineType.WORKER,
|
||||||
public MatterGrid getMatterGrid() {
|
Fraction(200000),
|
||||||
return grid;
|
Fraction(4000),
|
||||||
|
Fraction(4000)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
companion object {
|
||||||
public boolean isValidMatterCell() {
|
private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_replicator")
|
||||||
return valid;
|
private val BASE_CONSUMPTION = Fraction(400)
|
||||||
}
|
private const val TICKS_PER_MTU = 20000.0
|
||||||
|
private val TICKS_PER_MTU_BD = Fraction(20000)
|
||||||
@Override
|
private const val MTU_PER_TICK = 1.0 / 20000.0
|
||||||
public void setMatterGrid(MatterGrid grid) {
|
private val MTU_PER_TICK_BD = Fraction.ONE.div(TICKS_PER_MTU_BD)
|
||||||
this.grid = grid;
|
private val DRAIN_MULT = Fraction(200)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,267 +1,208 @@
|
|||||||
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.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.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.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.items.CapabilityItemHandler
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker;
|
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJob;
|
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJob
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus;
|
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus
|
||||||
import ru.dbotthepony.mc.otm.capability.*;
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*;
|
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler;
|
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterRegistry;
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterScannerMenu;
|
import ru.dbotthepony.mc.otm.matter.MatterRegistry
|
||||||
|
import ru.dbotthepony.mc.otm.menu.MatterScannerMenu
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
import javax.annotation.Nullable;
|
BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_SCANNER, p_155229_, p_155230_), IMatterGraphNode {
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
val input_slot = MatteryContainer(this::setChanged, 1)
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implements IMatterGridCell {
|
|
||||||
private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.matter_scanner");
|
|
||||||
|
|
||||||
public final MatteryContainer input_slot = new MatteryContainer(this::setChanged, 1);
|
private val inputHandler = input_slot.handler(
|
||||||
|
{ slot: Int, stack: ItemStack? -> MatterRegistry.canDecompose(stack) },
|
||||||
|
{ slot: Int, amount: Int, stack: ItemStack? -> is_idling }
|
||||||
|
)
|
||||||
|
|
||||||
private final MatteryContainerHandler input_handler = input_slot.handler(
|
// IMatterGraphNode
|
||||||
(slot, stack) -> MatterRegistry.canDecompose(stack),
|
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||||
(slot, amount, stack) -> is_idling
|
return matterNode
|
||||||
);
|
|
||||||
|
|
||||||
public BlockEntityMatterScanner(BlockPos p_155229_, BlockState p_155230_) {
|
|
||||||
super(Registry.BlockEntities.MATTER_SCANNER, p_155229_, p_155230_);
|
|
||||||
energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new Fraction(40000), new Fraction(400), new Fraction(400));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean valid = true;
|
override fun onPatternAdded(state: PatternState) {
|
||||||
|
is_idling = false
|
||||||
|
}
|
||||||
|
|
||||||
private LazyOptional<IMatterGridCell> resolver_grid = LazyOptional.of(() -> this);
|
override fun onPatternRemoved(state: PatternState) {
|
||||||
|
is_idling = false
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {
|
||||||
@Override
|
is_idling = false
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
}
|
||||||
|
// /IMatterGraphNode
|
||||||
|
|
||||||
|
private var valid = true
|
||||||
|
private val matterNode: Graph6Node<IMatterGraphNode> = Graph6Node(this)
|
||||||
|
private var resolverNode = LazyOptional.of { this }
|
||||||
|
|
||||||
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return inputHandler.get().cast()
|
||||||
return input_handler.get().cast();
|
//if (cap === MatteryCapability.MATTER_CELL) return resolver_grid.cast()
|
||||||
|
if (cap == MatteryCapability.MATTER_CELL) return resolverNode.cast()
|
||||||
if (cap == MatteryCapability.MATTER_CELL)
|
|
||||||
return resolver_grid.cast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
return super.getCapability(cap, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun invalidateCaps() {
|
||||||
public void invalidateCaps() {
|
super.invalidateCaps()
|
||||||
super.invalidateCaps();
|
valid = false
|
||||||
valid = false;
|
inputHandler.invalidate()
|
||||||
input_handler.invalidate();
|
resolverNode.invalidate()
|
||||||
resolver_grid.invalidate();
|
matterNode.destroy(::MatterNetworkGraph)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun reviveCaps() {
|
||||||
public void reviveCaps() {
|
super.reviveCaps()
|
||||||
super.reviveCaps();
|
valid = true
|
||||||
valid = true;
|
inputHandler.revive()
|
||||||
input_handler.revive();
|
resolverNode = LazyOptional.of { this }
|
||||||
resolver_grid = LazyOptional.of(() -> this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun setRemoved() {
|
||||||
public void onPatternAdded(PatternState state) {
|
super.setRemoved()
|
||||||
is_idling = false;
|
matterNode.destroy(::MatterNetworkGraph)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getDefaultDisplayName(): Component {
|
||||||
public void onPatternRemoved(PatternState state) {
|
return NAME
|
||||||
is_idling = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? {
|
||||||
public void onPatternUpdated(PatternState new_state, PatternState old_state) {
|
return MatterScannerMenu(containerID, inventory, this)
|
||||||
is_idling = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
public void setRemoved() {
|
super.saveAdditional(nbt)
|
||||||
super.setRemoved();
|
nbt.put("work_slots", input_slot.serializeNBT())
|
||||||
|
|
||||||
if (level != null && !level.isClientSide && grid != null)
|
|
||||||
grid.remove(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun load(nbt: CompoundTag) {
|
||||||
public void onNeighbourMatterCell(Level level, BlockPos pos, Direction direction, IMatterGridCell cell, BlockEntity entity) {
|
input_slot.deserializeNBT(nbt["work_slots"])
|
||||||
is_idling = false;
|
super.load(nbt)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getBaseConsumption(): Fraction {
|
||||||
protected Component getDefaultDisplayName() {
|
return BASE_CONSUMPTION
|
||||||
return NAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun onJobFinish(job: MachineJob): MachineJobStatus {
|
||||||
@Override
|
val grid = matterNode.graph as MatterNetworkGraph? ?: return MachineJobStatus(false, 100)
|
||||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
|
||||||
return new MatterScannerMenu(containerID, inventory, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
val stack = job.stack()
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
if (stack.isEmpty || !MatterRegistry.hasMatterValue(stack)) return MachineJobStatus()
|
||||||
super.saveAdditional(nbt);
|
|
||||||
nbt.put("work_slots", input_slot.serializeNBT());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
val get_state = grid.findPatterns(stack.item)
|
||||||
public void load(CompoundTag nbt) {
|
var find_state: PatternState? = null
|
||||||
input_slot.deserializeNBT(nbt.get("work_slots"));
|
|
||||||
super.load(nbt);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Fraction BASE_CONSUMPTION = new Fraction("40");
|
for (state in get_state) {
|
||||||
|
if (state.item() === stack.item) {
|
||||||
@Override
|
if (find_state == null && state.research_percent() < 1.0) {
|
||||||
@Nonnull
|
find_state = state
|
||||||
protected Fraction getBaseConsumption() {
|
|
||||||
return BASE_CONSUMPTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
protected MachineJobStatus onJobFinish(MachineJob job) {
|
|
||||||
if (grid == null)
|
|
||||||
return new MachineJobStatus(false, 100);
|
|
||||||
|
|
||||||
ItemStack stack = job.stack();
|
|
||||||
|
|
||||||
if (stack.isEmpty() || !MatterRegistry.hasMatterValue(stack))
|
|
||||||
return new MachineJobStatus();
|
|
||||||
|
|
||||||
|
|
||||||
Collection<PatternState> get_state = grid.findPatterns(stack.getItem());
|
|
||||||
PatternState find_state = null;
|
|
||||||
|
|
||||||
for (PatternState state : get_state) {
|
|
||||||
if (state.item() == stack.getItem()) {
|
|
||||||
if (find_state == null && state.research_percent() < 1d) {
|
|
||||||
find_state = state;
|
|
||||||
} else if (find_state != null && find_state.research_percent() < state.research_percent()) {
|
} else if (find_state != null && find_state.research_percent() < state.research_percent()) {
|
||||||
find_state = state;
|
find_state = state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PatternState new_state;
|
val new_state =
|
||||||
|
if (find_state != null) {
|
||||||
|
PatternState(find_state.id(), stack.item, find_state.research_percent() + 0.2)
|
||||||
|
} else {
|
||||||
|
PatternState(UUID.randomUUID(), stack.item, 0.2)
|
||||||
|
}
|
||||||
|
|
||||||
if (find_state != null) {
|
if (grid.insertPattern(new_state, false, false).status != PatternInsertStatus.Status.FAIL) {
|
||||||
new_state = new PatternState(find_state.id(), stack.getItem(), find_state.research_percent() + 0.2d);
|
return MachineJobStatus()
|
||||||
} else {
|
} else {
|
||||||
new_state = new PatternState(UUID.randomUUID(), stack.getItem(), 0.2d);
|
return MachineJobStatus(false, 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grid.insertPattern(new_state, false, false).status() != PatternInsertStatus.Status.FAIL) {
|
|
||||||
return new MachineJobStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new MachineJobStatus(false, 200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun getNextJob(): MachineJob? {
|
||||||
@Override
|
val grid = matterNode.graph as MatterNetworkGraph? ?: return null
|
||||||
protected MachineJob getNextJob() {
|
|
||||||
if (grid == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
ItemStack stack = input_slot.getItem(0);
|
val stack = input_slot.getItem(0)
|
||||||
|
if (stack.isEmpty || !MatterRegistry.canDecompose(stack)) return null
|
||||||
|
|
||||||
if (stack.isEmpty() || !MatterRegistry.canDecompose(stack))
|
val getState = grid.findPatterns(stack.item)
|
||||||
return null;
|
var findState: PatternState? = null
|
||||||
|
|
||||||
Collection<PatternState> get_state = grid.findPatterns(stack.getItem());
|
for (state in getState) {
|
||||||
PatternState find_state = null;
|
if (state.item() === stack.item && state.research_percent() < 1.0) {
|
||||||
|
findState = state
|
||||||
for (PatternState state : get_state) {
|
} else if (state.item() === stack.item && state.research_percent() >= 1.0) {
|
||||||
if (state.item() == stack.getItem() && state.research_percent() < 1d) {
|
return null
|
||||||
find_state = state;
|
|
||||||
} else if (state.item() == stack.getItem() && state.research_percent() >= 1d) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PatternState new_state;
|
val new_state: PatternState =
|
||||||
|
if (findState != null) {
|
||||||
|
PatternState(findState.id, stack.item, findState.research_percent + 0.2)
|
||||||
|
} else {
|
||||||
|
PatternState(UUID.randomUUID(), stack.item, 0.2)
|
||||||
|
}
|
||||||
|
|
||||||
if (find_state != null) {
|
if (grid.insertPattern(new_state, false, true).status != PatternInsertStatus.Status.FAIL) {
|
||||||
new_state = new PatternState(find_state.id(), stack.getItem(), find_state.research_percent() + 0.2d);
|
val copy = stack.copy()
|
||||||
} else {
|
copy.count = 1
|
||||||
new_state = new PatternState(UUID.randomUUID(), stack.getItem(), 0.2d);
|
stack.shrink(1)
|
||||||
|
input_slot.setChanged()
|
||||||
|
return MachineJob(copy, MatterRegistry.getMatterValue(copy).toDouble() * 35000.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grid.insertPattern(new_state, false, true).status() != PatternInsertStatus.Status.FAIL) {
|
return null
|
||||||
ItemStack copy = stack.copy();
|
}
|
||||||
copy.setCount(1);
|
|
||||||
stack.shrink(1);
|
init {
|
||||||
input_slot.setChanged();
|
energy = MatteryMachineEnergyStorage(
|
||||||
return new MachineJob(copy, MatterRegistry.getMatterValue(copy).toDouble() * 35_000d);
|
this,
|
||||||
|
MatteryMachineEnergyStorage.MachineType.WORKER,
|
||||||
|
Fraction(40000),
|
||||||
|
Fraction(400),
|
||||||
|
Fraction(400)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLevel(p_155231_: Level) {
|
||||||
|
super.setLevel(p_155231_)
|
||||||
|
|
||||||
|
if (p_155231_ is ServerLevel) {
|
||||||
|
MatterNetworkGraph.discoverFull(this, matterNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
companion object {
|
||||||
@Override
|
private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_scanner")
|
||||||
public IPatternStorage getPatternStorage() {
|
private val BASE_CONSUMPTION = Fraction("40")
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MatterGrid grid;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLevel(Level p_155231_) {
|
|
||||||
super.setLevel(p_155231_);
|
|
||||||
|
|
||||||
if (grid == null)
|
|
||||||
scheduleDiscoverNeighbours(p_155231_, getBlockPos());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public MatterGrid getMatterGrid() {
|
|
||||||
return grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public IMatterHandler getMatterHandler() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValidMatterCell() {
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMatterGrid(MatterGrid grid) {
|
|
||||||
this.grid = grid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,243 +1,214 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity;
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import javax.annotation.ParametersAreNonnullByDefault
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.core.Direction;
|
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import net.minecraft.network.chat.Component;
|
import java.lang.Runnable
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import net.minecraft.world.entity.player.Player;
|
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import ru.dbotthepony.mc.otm.block.BlockPatternStorage
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraftforge.items.CapabilityItemHandler
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import ru.dbotthepony.mc.otm.menu.PatternStorageMenu
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraft.MethodsReturnNonnullByDefault
|
||||||
import ru.dbotthepony.mc.otm.block.BlockPatternStorage;
|
import net.minecraft.core.Direction
|
||||||
import ru.dbotthepony.mc.otm.capability.*;
|
import net.minecraft.network.chat.Component
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.*;
|
import ru.dbotthepony.mc.otm.capability.matter.PatternInsertStatus
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler;
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
import net.minecraft.server.level.ServerLevel
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import net.minecraft.world.level.Level
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
import net.minecraft.world.level.block.Block
|
||||||
import ru.dbotthepony.mc.otm.menu.PatternStorageMenu;
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import javax.annotation.Nonnull;
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import javax.annotation.Nullable;
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import java.util.ArrayList;
|
import ru.dbotthepony.mc.otm.ifHas
|
||||||
import java.util.Collection;
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class BlockEntityPatternStorage extends BlockEntityMattery implements IMatterGridCell, IPatternStorage {
|
class BlockEntityPatternStorage(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
public BlockEntityPatternStorage(BlockPos p_155229_, BlockState p_155230_) {
|
BlockEntityMattery(Registry.BlockEntities.PATTERN_STORAGE, p_155229_, p_155230_), IMatterGraphNode, IPatternStorage {
|
||||||
super(Registry.BlockEntities.PATTERN_STORAGE, p_155229_, p_155230_);
|
|
||||||
}
|
private val node = Graph6Node<IMatterGraphNode>(this)
|
||||||
|
private val resolverPatterns = LazyOptional.of { this }
|
||||||
|
private val resolverNode = LazyOptional.of { this }
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val patterns: MatteryContainer = object : MatteryContainer(Runnable { this.setChanged() }, 8) {
|
||||||
|
override fun setChanged(slot: Int, new_state: ItemStack, old_state: ItemStack) {
|
||||||
|
val grid = node.graph as MatterNetworkGraph?
|
||||||
|
|
||||||
public final MatteryContainer patterns = new MatteryContainer(this::setChanged, 8) {
|
|
||||||
@Override
|
|
||||||
public void setChanged(int slot, ItemStack new_state, ItemStack old_state) {
|
|
||||||
if (grid != null && !ItemStack.isSameItemSameTags(new_state, old_state)) {
|
if (grid != null && !ItemStack.isSameItemSameTags(new_state, old_state)) {
|
||||||
if (!old_state.isEmpty()) {
|
if (!old_state.isEmpty) {
|
||||||
old_state.getCapability(MatteryCapability.PATTERN).ifPresent(cap -> cap.getStoredPatterns().forEach(grid::onPatternRemoved));
|
old_state.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
||||||
|
cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternRemoved(state!!) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!new_state.isEmpty()) {
|
if (!new_state.isEmpty) {
|
||||||
new_state.getCapability(MatteryCapability.PATTERN).ifPresent(cap -> cap.getStoredPatterns().forEach(grid::onPatternAdded));
|
new_state.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
||||||
|
cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternAdded(state!!) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBlockstate();
|
updateBlockstate()
|
||||||
}
|
}
|
||||||
|
|
||||||
super.setChanged(slot, new_state, old_state);
|
super.setChanged(slot, new_state, old_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getMaxStackSize(): Int {
|
||||||
public int getMaxStackSize() {
|
return 1
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void updateBlockstate() {
|
|
||||||
if (level == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var state = getBlockState();
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
state = state.setValue(BlockPatternStorage.PATTERN_STORAGE_DISKS_PROPS[i], patterns.getItem(i).getCapability(MatteryCapability.PATTERN).isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state != getBlockState()) {
|
|
||||||
level.setBlock(getBlockPos(), state, Block.UPDATE_CLIENTS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final MatteryContainerHandler resolver_item = patterns.handler(
|
private fun updateBlockstate() {
|
||||||
((slot, stack) -> stack.getCapability(MatteryCapability.PATTERN).isPresent())
|
val level = level ?: return
|
||||||
);
|
|
||||||
|
|
||||||
private MatterGrid grid;
|
var state = blockState
|
||||||
|
|
||||||
@Override
|
for (i in 0..7) {
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
state = state.setValue(
|
||||||
super.saveAdditional(nbt);
|
BlockPatternStorage.PATTERN_STORAGE_DISKS_PROPS[i],
|
||||||
nbt.put("patterns", patterns.serializeNBT());
|
patterns.getItem(i).getCapability(MatteryCapability.PATTERN).isPresent
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state !== blockState) {
|
||||||
|
level.setBlock(blockPos, state, Block.UPDATE_CLIENTS)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private val resolverItem =
|
||||||
public void load(CompoundTag nbt) {
|
patterns.handler { slot: Int, stack: ItemStack -> stack.getCapability(MatteryCapability.PATTERN).isPresent }
|
||||||
super.load(nbt);
|
|
||||||
patterns.deserializeNBT(nbt.get("patterns"));
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
|
super.saveAdditional(nbt)
|
||||||
|
nbt["patterns"] = patterns.serializeNBT()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun load(nbt: CompoundTag) {
|
||||||
public void setLevel(Level p_155231_) {
|
super.load(nbt)
|
||||||
super.setLevel(p_155231_);
|
|
||||||
|
|
||||||
if (grid == null)
|
nbt.ifHas("patterns") {
|
||||||
MatterGrid.scheduleDiscoverNeighbours(this, getBlockPos(), p_155231_);
|
patterns.deserializeNBT(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun setLevel(p_155231_: Level) {
|
||||||
@Override
|
super.setLevel(p_155231_)
|
||||||
public MatterGrid getMatterGrid() {
|
|
||||||
return grid;
|
if (p_155231_ is ServerLevel)
|
||||||
|
MatterNetworkGraph.discoverFull(this, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||||
@Override
|
return node
|
||||||
public IMatterHandler getMatterHandler() {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun getPatternHandler(): IPatternStorage {
|
||||||
@Override
|
return this
|
||||||
public IPatternStorage getPatternStorage() {
|
|
||||||
return valid ? this : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean valid = true;
|
private var valid = true
|
||||||
|
|
||||||
@Override
|
override fun invalidateCaps() {
|
||||||
public boolean isValidMatterCell() {
|
super.invalidateCaps()
|
||||||
return valid;
|
valid = false
|
||||||
|
resolverItem.invalidate()
|
||||||
|
node.destroy(::MatterNetworkGraph)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun reviveCaps() {
|
||||||
public void setMatterGrid(MatterGrid grid) {
|
super.reviveCaps()
|
||||||
this.grid = grid;
|
valid = true
|
||||||
|
resolverItem.revive()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
public void invalidateCaps() {
|
|
||||||
super.invalidateCaps();
|
|
||||||
valid = false;
|
|
||||||
resolver_item.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reviveCaps() {
|
|
||||||
super.reviveCaps();
|
|
||||||
valid = true;
|
|
||||||
resolver_item.revive();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final LazyOptional<BlockEntityPatternStorage> resolver = LazyOptional.of(() -> this);
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (cap == MatteryCapability.PATTERN || cap == MatteryCapability.MATTER_CELL)
|
if (cap === MatteryCapability.PATTERN) return resolverPatterns.cast()
|
||||||
return resolver.cast();
|
if (cap === MatteryCapability.MATTER_CELL) return resolverNode.cast()
|
||||||
|
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return resolverItem.get().cast()
|
||||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
|
||||||
return resolver_item.get().cast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
return super.getCapability(cap, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.pattern_storage");
|
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 PatternStorageMenu(containerID, inventory, this)
|
||||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
|
||||||
return new PatternStorageMenu(containerID, inventory, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
override fun getStoredPatterns(): Collection<PatternState> {
|
||||||
@Override
|
val list = ArrayList<PatternState>()
|
||||||
public Collection<PatternState> getStoredPatterns() {
|
patterns.consumeCapability(MatteryCapability.PATTERN) { capability: IPatternStorage -> list.addAll(capability.storedPatterns) }
|
||||||
ArrayList<PatternState> list = new ArrayList<>();
|
return list
|
||||||
patterns.consumeCapability(MatteryCapability.PATTERN, capability -> list.addAll(capability.getStoredPatterns()));
|
|
||||||
return ImmutableList.copyOf(list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getCapacity(): Int {
|
||||||
public int getCapacity() {
|
var stored = 0L
|
||||||
long stored = 0;
|
|
||||||
|
|
||||||
for (var pattern : patterns.capabilityIterator(MatteryCapability.PATTERN)) {
|
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
|
||||||
stored += pattern.getCapacity();
|
stored += pattern.capacity.toLong()
|
||||||
}
|
|
||||||
|
|
||||||
return stored > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) stored;
|
return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getStored(): Int {
|
||||||
public int getStored() {
|
var stored = 0L
|
||||||
long stored = 0;
|
|
||||||
|
|
||||||
for (var pattern : patterns.capabilityIterator(MatteryCapability.PATTERN)) {
|
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
|
||||||
stored += pattern.getStored();
|
stored += pattern.stored.toLong()
|
||||||
}
|
|
||||||
|
|
||||||
return stored > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) stored;
|
return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun setRemoved() {
|
||||||
public void setRemoved() {
|
super.setRemoved()
|
||||||
super.setRemoved();
|
node.destroy(::MatterNetworkGraph)
|
||||||
|
|
||||||
if (level != null && !level.isClientSide && grid != null)
|
|
||||||
grid.remove(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun insertPattern(pattern: PatternState, only_update: Boolean, simulate: Boolean): PatternInsertStatus {
|
||||||
public PatternInsertStatus insertPattern(PatternState pattern, boolean only_update, boolean simulate) {
|
for (storage in patterns.capabilityIterator(MatteryCapability.PATTERN)) {
|
||||||
for (IPatternStorage storage : patterns.capabilityIterator(MatteryCapability.PATTERN)) {
|
val status = storage.insertPattern(pattern, only_update, simulate)
|
||||||
var status = storage.insertPattern(pattern, only_update, simulate);
|
|
||||||
|
|
||||||
if (status.status() != PatternInsertStatus.Status.FAIL) {
|
if (status.status() != PatternInsertStatus.Status.FAIL) {
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
setChanged();
|
setChanged()
|
||||||
|
|
||||||
if (grid != null) {
|
val graph = node.graph as MatterNetworkGraph?
|
||||||
|
|
||||||
|
if (graph != null) {
|
||||||
if (status.status() == PatternInsertStatus.Status.INSERTED) {
|
if (status.status() == PatternInsertStatus.Status.INSERTED) {
|
||||||
grid.onPatternAdded(status.new_state());
|
graph.onPatternAdded(status.new_state()!!)
|
||||||
} else {
|
} else {
|
||||||
grid.onPatternUpdated(status.new_state(), status.old_state());
|
graph.onPatternUpdated(status.new_state()!!, status.old_state()!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PatternInsertStatus();
|
return PatternInsertStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val NAME = TranslatableComponent("block.overdrive_that_matters.pattern_storage")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,33 +1,48 @@
|
|||||||
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.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.*;
|
import ru.dbotthepony.mc.otm.client.screen.panels.ButtonPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel;
|
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel;
|
import ru.dbotthepony.mc.otm.client.screen.panels.SlotPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel;
|
import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu;
|
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
|
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
||||||
|
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
class MatterBottlerScreen(menu: MatterBottlerMenu, inventory: Inventory, title: Component) :
|
||||||
import java.util.List;
|
MatteryScreen<MatterBottlerMenu>(menu, inventory, title) {
|
||||||
|
|
||||||
public class MatterBottlerScreen extends MatteryScreen<MatterBottlerMenu> {
|
private var progress: ProgressGaugePanel? = null
|
||||||
public MatterBottlerScreen(MatterBottlerMenu menu, Inventory inventory, Component title) {
|
|
||||||
super(menu, inventory, title);
|
override fun makeMainFrame(): FramePanel {
|
||||||
|
val frame = super.makeMainFrame()!!
|
||||||
|
|
||||||
|
val p = PowerGaugePanel(this, frame, menu.battery_widget, LEFT_MARGIN, GAUGE_TOP_WITH_SLOT)
|
||||||
|
MatterGaugePanel(this, frame, menu.matterWidget, LEFT_MARGIN + p.width, GAUGE_TOP_WITH_SLOT)
|
||||||
|
|
||||||
|
SlotPanel(this, frame, menu.battery_slot, LEFT_MARGIN, SLOT_TOP_UNDER_GAUGE)
|
||||||
|
|
||||||
|
for (i in 0 .. 2) {
|
||||||
|
SlotPanel(this, frame, menu.container[i], 31f + i * 18, PROGRESS_SLOT_TOP)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 3 .. 5) {
|
||||||
|
SlotPanel(this, frame, menu.container[i], 116f + (i - 3) * 18, PROGRESS_SLOT_TOP)
|
||||||
|
}
|
||||||
|
|
||||||
|
progress = ProgressGaugePanel(this, frame, menu.progressWidget, 90f, PROGRESS_ARROW_TOP)
|
||||||
|
|
||||||
|
val mode = ButtonPanel(this, frame, 46f, 69f, 100f, 20f, TranslatableComponent("otm.matter_bottler.switch_mode"))
|
||||||
|
mode.bindOnPress { menu.switchBottlerMode() }
|
||||||
|
|
||||||
|
return frame
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun containerTick() {
|
||||||
@Override
|
super.containerTick()
|
||||||
protected FramePanel makeMainFrame() {
|
|
||||||
var frame = super.makeMainFrame();
|
|
||||||
|
|
||||||
var mode = new ButtonPanel(this, frame, 0, 0, 100, 20, new TranslatableComponent("otm.matter_bottler.switch_mode"));
|
progress?.flop = !menu.workFlow.value
|
||||||
mode.bindOnPress(menu::switchBottlerMode);
|
|
||||||
mode.setDock(Dock.TOP);
|
|
||||||
mode.asGrid(); // for auto alignment on center
|
|
||||||
|
|
||||||
return frame;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import net.minecraft.nbt.ByteArrayTag
|
|||||||
import net.minecraft.nbt.StringTag
|
import net.minecraft.nbt.StringTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
import net.minecraft.network.FriendlyByteBuf
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.math.MathContext
|
import java.math.MathContext
|
||||||
@ -44,6 +45,196 @@ inline fun invertCompare(int: Int): Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val BI_MINUS_ZERO = BigInteger("-0")
|
private val BI_MINUS_ZERO = BigInteger("-0")
|
||||||
|
private val BI_MINUS_ONE = BigInteger("-1")
|
||||||
|
private val BI_DIV = BigInteger.valueOf(1_000_000_000)
|
||||||
|
private val BI_DIV2 = BigInteger.valueOf(10)
|
||||||
|
private val BI_MINUS_DIV = BigInteger.valueOf(-1_000_000_000)
|
||||||
|
|
||||||
|
private fun isZero(value: BigInteger): Boolean {
|
||||||
|
return when (value.signum()) {
|
||||||
|
0 -> true
|
||||||
|
1 -> value == BigInteger.ZERO
|
||||||
|
-1 -> value == BI_MINUS_ZERO
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isOne(value: BigInteger): Boolean {
|
||||||
|
return when (value.signum()) {
|
||||||
|
0 -> false
|
||||||
|
1 -> value == BigInteger.ONE
|
||||||
|
-1 -> value == BI_MINUS_ONE
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun compactTwoMod(value1: BigInteger, value2: BigInteger, compact: Boolean = true): Fraction {
|
||||||
|
val mod = value1.divideAndRemainder(value2)
|
||||||
|
|
||||||
|
if (isZero(mod[1]))
|
||||||
|
return Fraction(mod[0], compact = compact)
|
||||||
|
|
||||||
|
return Fraction(value1, value2, compact = compact)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun positive(value: BigInteger): BigInteger {
|
||||||
|
return when (value.signum()) {
|
||||||
|
0 -> value
|
||||||
|
1 -> value
|
||||||
|
-1 -> -value
|
||||||
|
else -> throw InternalError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val GCDs = arrayOf(
|
||||||
|
BigInteger.valueOf(2), BigInteger.valueOf(3), BigInteger.valueOf(5), BigInteger.valueOf(7), BigInteger.valueOf(11), BigInteger.valueOf(13), BigInteger.valueOf(17), BigInteger.valueOf(19), BigInteger.valueOf(23), BigInteger.valueOf(29), BigInteger.valueOf(31), BigInteger.valueOf(37), BigInteger.valueOf(41), BigInteger.valueOf(43), BigInteger.valueOf(47), BigInteger.valueOf(53), BigInteger.valueOf(59), BigInteger.valueOf(61), BigInteger.valueOf(67), BigInteger.valueOf(71),
|
||||||
|
BigInteger.valueOf(73), BigInteger.valueOf(79), BigInteger.valueOf(83), BigInteger.valueOf(89), BigInteger.valueOf(97), BigInteger.valueOf(101), BigInteger.valueOf(103), BigInteger.valueOf(107), BigInteger.valueOf(109), BigInteger.valueOf(113), BigInteger.valueOf(127), BigInteger.valueOf(131), BigInteger.valueOf(137), BigInteger.valueOf(139), BigInteger.valueOf(149), BigInteger.valueOf(151), BigInteger.valueOf(157), BigInteger.valueOf(163), BigInteger.valueOf(167), BigInteger.valueOf(173),
|
||||||
|
BigInteger.valueOf(179), BigInteger.valueOf(181), BigInteger.valueOf(191), BigInteger.valueOf(193), BigInteger.valueOf(197), BigInteger.valueOf(199), BigInteger.valueOf(211), BigInteger.valueOf(223), BigInteger.valueOf(227), BigInteger.valueOf(229), BigInteger.valueOf(233), BigInteger.valueOf(239), BigInteger.valueOf(241), BigInteger.valueOf(251), BigInteger.valueOf(257), BigInteger.valueOf(263), BigInteger.valueOf(269), BigInteger.valueOf(271), BigInteger.valueOf(277), BigInteger.valueOf(281),
|
||||||
|
BigInteger.valueOf(283), BigInteger.valueOf(293), BigInteger.valueOf(307), BigInteger.valueOf(311), BigInteger.valueOf(313), BigInteger.valueOf(317), BigInteger.valueOf(331), BigInteger.valueOf(337), BigInteger.valueOf(347), BigInteger.valueOf(349), BigInteger.valueOf(353), BigInteger.valueOf(359), BigInteger.valueOf(367), BigInteger.valueOf(373), BigInteger.valueOf(379), BigInteger.valueOf(383), BigInteger.valueOf(389), BigInteger.valueOf(397), BigInteger.valueOf(401), BigInteger.valueOf(409),
|
||||||
|
BigInteger.valueOf(419), BigInteger.valueOf(421), BigInteger.valueOf(431), BigInteger.valueOf(433), BigInteger.valueOf(439), BigInteger.valueOf(443), BigInteger.valueOf(449), BigInteger.valueOf(457), BigInteger.valueOf(461), BigInteger.valueOf(463), BigInteger.valueOf(467), BigInteger.valueOf(479), BigInteger.valueOf(487), BigInteger.valueOf(491), BigInteger.valueOf(499), BigInteger.valueOf(503), BigInteger.valueOf(509), BigInteger.valueOf(521), BigInteger.valueOf(523), BigInteger.valueOf(541),
|
||||||
|
BigInteger.valueOf(547), BigInteger.valueOf(557), BigInteger.valueOf(563), BigInteger.valueOf(569), BigInteger.valueOf(571), BigInteger.valueOf(577), BigInteger.valueOf(587), BigInteger.valueOf(593), BigInteger.valueOf(599), BigInteger.valueOf(601), BigInteger.valueOf(607), BigInteger.valueOf(613), BigInteger.valueOf(617), BigInteger.valueOf(619), BigInteger.valueOf(631), BigInteger.valueOf(641), BigInteger.valueOf(643), BigInteger.valueOf(647), BigInteger.valueOf(653), BigInteger.valueOf(659),
|
||||||
|
BigInteger.valueOf(661), BigInteger.valueOf(673), BigInteger.valueOf(677), BigInteger.valueOf(683), BigInteger.valueOf(691), BigInteger.valueOf(701), BigInteger.valueOf(709), BigInteger.valueOf(719), BigInteger.valueOf(727), BigInteger.valueOf(733), BigInteger.valueOf(739), BigInteger.valueOf(743), BigInteger.valueOf(751), BigInteger.valueOf(757), BigInteger.valueOf(761), BigInteger.valueOf(769), BigInteger.valueOf(773), BigInteger.valueOf(787), BigInteger.valueOf(797), BigInteger.valueOf(809),
|
||||||
|
BigInteger.valueOf(811), BigInteger.valueOf(821), BigInteger.valueOf(823), BigInteger.valueOf(827), BigInteger.valueOf(829), BigInteger.valueOf(839), BigInteger.valueOf(853), BigInteger.valueOf(857), BigInteger.valueOf(859), BigInteger.valueOf(863), BigInteger.valueOf(877), BigInteger.valueOf(881), BigInteger.valueOf(883), BigInteger.valueOf(887), BigInteger.valueOf(907), BigInteger.valueOf(911), BigInteger.valueOf(919), BigInteger.valueOf(929), BigInteger.valueOf(937), BigInteger.valueOf(941),
|
||||||
|
BigInteger.valueOf(947), BigInteger.valueOf(953), BigInteger.valueOf(967), BigInteger.valueOf(971), BigInteger.valueOf(977), BigInteger.valueOf(983), BigInteger.valueOf(991), BigInteger.valueOf(997), BigInteger.valueOf(1009), BigInteger.valueOf(1013), BigInteger.valueOf(1019), BigInteger.valueOf(1021), BigInteger.valueOf(1031), BigInteger.valueOf(1033), BigInteger.valueOf(1039), BigInteger.valueOf(1049), BigInteger.valueOf(1051), BigInteger.valueOf(1061), BigInteger.valueOf(1063), BigInteger.valueOf(1069),
|
||||||
|
BigInteger.valueOf(1087), BigInteger.valueOf(1091), BigInteger.valueOf(1093), BigInteger.valueOf(1097), BigInteger.valueOf(1103), BigInteger.valueOf(1109), BigInteger.valueOf(1117), BigInteger.valueOf(1123), BigInteger.valueOf(1129), BigInteger.valueOf(1151), BigInteger.valueOf(1153), BigInteger.valueOf(1163), BigInteger.valueOf(1171), BigInteger.valueOf(1181), BigInteger.valueOf(1187), BigInteger.valueOf(1193), BigInteger.valueOf(1201), BigInteger.valueOf(1213), BigInteger.valueOf(1217), BigInteger.valueOf(1223),
|
||||||
|
BigInteger.valueOf(1229), BigInteger.valueOf(1231), BigInteger.valueOf(1237), BigInteger.valueOf(1249), BigInteger.valueOf(1259), BigInteger.valueOf(1277), BigInteger.valueOf(1279), BigInteger.valueOf(1283), BigInteger.valueOf(1289), BigInteger.valueOf(1291), BigInteger.valueOf(1297), BigInteger.valueOf(1301), BigInteger.valueOf(1303), BigInteger.valueOf(1307), BigInteger.valueOf(1319), BigInteger.valueOf(1321), BigInteger.valueOf(1327), BigInteger.valueOf(1361), BigInteger.valueOf(1367), BigInteger.valueOf(1373),
|
||||||
|
BigInteger.valueOf(1381), BigInteger.valueOf(1399), BigInteger.valueOf(1409), BigInteger.valueOf(1423), BigInteger.valueOf(1427), BigInteger.valueOf(1429), BigInteger.valueOf(1433), BigInteger.valueOf(1439), BigInteger.valueOf(1447), BigInteger.valueOf(1451), BigInteger.valueOf(1453), BigInteger.valueOf(1459), BigInteger.valueOf(1471), BigInteger.valueOf(1481), BigInteger.valueOf(1483), BigInteger.valueOf(1487), BigInteger.valueOf(1489), BigInteger.valueOf(1493), BigInteger.valueOf(1499), BigInteger.valueOf(1511),
|
||||||
|
BigInteger.valueOf(1523), BigInteger.valueOf(1531), BigInteger.valueOf(1543), BigInteger.valueOf(1549), BigInteger.valueOf(1553), BigInteger.valueOf(1559), BigInteger.valueOf(1567), BigInteger.valueOf(1571), BigInteger.valueOf(1579), BigInteger.valueOf(1583), BigInteger.valueOf(1597), BigInteger.valueOf(1601), BigInteger.valueOf(1607), BigInteger.valueOf(1609), BigInteger.valueOf(1613), BigInteger.valueOf(1619), BigInteger.valueOf(1621), BigInteger.valueOf(1627), BigInteger.valueOf(1637), BigInteger.valueOf(1657),
|
||||||
|
BigInteger.valueOf(1663), BigInteger.valueOf(1667), BigInteger.valueOf(1669), BigInteger.valueOf(1693), BigInteger.valueOf(1697), BigInteger.valueOf(1699), BigInteger.valueOf(1709), BigInteger.valueOf(1721), BigInteger.valueOf(1723), BigInteger.valueOf(1733), BigInteger.valueOf(1741), BigInteger.valueOf(1747), BigInteger.valueOf(1753), BigInteger.valueOf(1759), BigInteger.valueOf(1777), BigInteger.valueOf(1783), BigInteger.valueOf(1787), BigInteger.valueOf(1789), BigInteger.valueOf(1801), BigInteger.valueOf(1811),
|
||||||
|
BigInteger.valueOf(1823), BigInteger.valueOf(1831), BigInteger.valueOf(1847), BigInteger.valueOf(1861), BigInteger.valueOf(1867), BigInteger.valueOf(1871), BigInteger.valueOf(1873), BigInteger.valueOf(1877), BigInteger.valueOf(1879), BigInteger.valueOf(1889), BigInteger.valueOf(1901), BigInteger.valueOf(1907), BigInteger.valueOf(1913), BigInteger.valueOf(1931), BigInteger.valueOf(1933), BigInteger.valueOf(1949), BigInteger.valueOf(1951), BigInteger.valueOf(1973), BigInteger.valueOf(1979), BigInteger.valueOf(1987),
|
||||||
|
BigInteger.valueOf(1993), BigInteger.valueOf(1997), BigInteger.valueOf(1999), BigInteger.valueOf(2003), BigInteger.valueOf(2011), BigInteger.valueOf(2017), BigInteger.valueOf(2027), BigInteger.valueOf(2029), BigInteger.valueOf(2039), BigInteger.valueOf(2053), BigInteger.valueOf(2063), BigInteger.valueOf(2069), BigInteger.valueOf(2081), BigInteger.valueOf(2083), BigInteger.valueOf(2087), BigInteger.valueOf(2089), BigInteger.valueOf(2099), BigInteger.valueOf(2111), BigInteger.valueOf(2113), BigInteger.valueOf(2129),
|
||||||
|
BigInteger.valueOf(2131), BigInteger.valueOf(2137), BigInteger.valueOf(2141), BigInteger.valueOf(2143), BigInteger.valueOf(2153), BigInteger.valueOf(2161), BigInteger.valueOf(2179), BigInteger.valueOf(2203), BigInteger.valueOf(2207), BigInteger.valueOf(2213), BigInteger.valueOf(2221), BigInteger.valueOf(2237), BigInteger.valueOf(2239), BigInteger.valueOf(2243), BigInteger.valueOf(2251), BigInteger.valueOf(2267), BigInteger.valueOf(2269), BigInteger.valueOf(2273), BigInteger.valueOf(2281), BigInteger.valueOf(2287),
|
||||||
|
BigInteger.valueOf(2293), BigInteger.valueOf(2297), BigInteger.valueOf(2309), BigInteger.valueOf(2311), BigInteger.valueOf(2333), BigInteger.valueOf(2339), BigInteger.valueOf(2341), BigInteger.valueOf(2347), BigInteger.valueOf(2351), BigInteger.valueOf(2357), BigInteger.valueOf(2371), BigInteger.valueOf(2377), BigInteger.valueOf(2381), BigInteger.valueOf(2383), BigInteger.valueOf(2389), BigInteger.valueOf(2393), BigInteger.valueOf(2399), BigInteger.valueOf(2411), BigInteger.valueOf(2417), BigInteger.valueOf(2423),
|
||||||
|
BigInteger.valueOf(2437), BigInteger.valueOf(2441), BigInteger.valueOf(2447), BigInteger.valueOf(2459), BigInteger.valueOf(2467), BigInteger.valueOf(2473), BigInteger.valueOf(2477), BigInteger.valueOf(2503), BigInteger.valueOf(2521), BigInteger.valueOf(2531), BigInteger.valueOf(2539), BigInteger.valueOf(2543), BigInteger.valueOf(2549), BigInteger.valueOf(2551), BigInteger.valueOf(2557), BigInteger.valueOf(2579), BigInteger.valueOf(2591), BigInteger.valueOf(2593), BigInteger.valueOf(2609), BigInteger.valueOf(2617),
|
||||||
|
BigInteger.valueOf(2621), BigInteger.valueOf(2633), BigInteger.valueOf(2647), BigInteger.valueOf(2657), BigInteger.valueOf(2659), BigInteger.valueOf(2663), BigInteger.valueOf(2671), BigInteger.valueOf(2677), BigInteger.valueOf(2683), BigInteger.valueOf(2687), BigInteger.valueOf(2689), BigInteger.valueOf(2693), BigInteger.valueOf(2699), BigInteger.valueOf(2707), BigInteger.valueOf(2711), BigInteger.valueOf(2713), BigInteger.valueOf(2719), BigInteger.valueOf(2729), BigInteger.valueOf(2731), BigInteger.valueOf(2741),
|
||||||
|
BigInteger.valueOf(2749), BigInteger.valueOf(2753), BigInteger.valueOf(2767), BigInteger.valueOf(2777), BigInteger.valueOf(2789), BigInteger.valueOf(2791), BigInteger.valueOf(2797), BigInteger.valueOf(2801), BigInteger.valueOf(2803), BigInteger.valueOf(2819), BigInteger.valueOf(2833), BigInteger.valueOf(2837), BigInteger.valueOf(2843), BigInteger.valueOf(2851), BigInteger.valueOf(2857), BigInteger.valueOf(2861), BigInteger.valueOf(2879), BigInteger.valueOf(2887), BigInteger.valueOf(2897), BigInteger.valueOf(2903),
|
||||||
|
BigInteger.valueOf(2909), BigInteger.valueOf(2917), BigInteger.valueOf(2927), BigInteger.valueOf(2939), BigInteger.valueOf(2953), BigInteger.valueOf(2957), BigInteger.valueOf(2963), BigInteger.valueOf(2969), BigInteger.valueOf(2971), BigInteger.valueOf(2999), BigInteger.valueOf(3001), BigInteger.valueOf(3011), BigInteger.valueOf(3019), BigInteger.valueOf(3023), BigInteger.valueOf(3037), BigInteger.valueOf(3041), BigInteger.valueOf(3049), BigInteger.valueOf(3061), BigInteger.valueOf(3067), BigInteger.valueOf(3079),
|
||||||
|
BigInteger.valueOf(3083), BigInteger.valueOf(3089), BigInteger.valueOf(3109), BigInteger.valueOf(3119), BigInteger.valueOf(3121), BigInteger.valueOf(3137), BigInteger.valueOf(3163), BigInteger.valueOf(3167), BigInteger.valueOf(3169), BigInteger.valueOf(3181), BigInteger.valueOf(3187), BigInteger.valueOf(3191), BigInteger.valueOf(3203), BigInteger.valueOf(3209), BigInteger.valueOf(3217), BigInteger.valueOf(3221), BigInteger.valueOf(3229), BigInteger.valueOf(3251), BigInteger.valueOf(3253), BigInteger.valueOf(3257),
|
||||||
|
BigInteger.valueOf(3259), BigInteger.valueOf(3271), BigInteger.valueOf(3299), BigInteger.valueOf(3301), BigInteger.valueOf(3307), BigInteger.valueOf(3313), BigInteger.valueOf(3319), BigInteger.valueOf(3323), BigInteger.valueOf(3329), BigInteger.valueOf(3331), BigInteger.valueOf(3343), BigInteger.valueOf(3347), BigInteger.valueOf(3359), BigInteger.valueOf(3361), BigInteger.valueOf(3371), BigInteger.valueOf(3373), BigInteger.valueOf(3389), BigInteger.valueOf(3391), BigInteger.valueOf(3407), BigInteger.valueOf(3413),
|
||||||
|
BigInteger.valueOf(3433), BigInteger.valueOf(3449), BigInteger.valueOf(3457), BigInteger.valueOf(3461), BigInteger.valueOf(3463), BigInteger.valueOf(3467), BigInteger.valueOf(3469), BigInteger.valueOf(3491), BigInteger.valueOf(3499), BigInteger.valueOf(3511), BigInteger.valueOf(3517), BigInteger.valueOf(3527), BigInteger.valueOf(3529), BigInteger.valueOf(3533), BigInteger.valueOf(3539), BigInteger.valueOf(3541), BigInteger.valueOf(3547), BigInteger.valueOf(3557), BigInteger.valueOf(3559), BigInteger.valueOf(3571),
|
||||||
|
)
|
||||||
|
|
||||||
|
private val COMPACT_THRESHOLD = BigInteger("1000000000000000000000")
|
||||||
|
|
||||||
|
private fun compactTwo(value1: BigInteger, value2: BigInteger, compact: Boolean = true): Fraction {
|
||||||
|
when (value1.signum()) {
|
||||||
|
0 -> return Fraction(value1, value2, compact = compact)
|
||||||
|
1 -> if (value1 < BI_DIV) return compactTwoMod(value1, value2, compact)
|
||||||
|
-1 -> if (value1 > BI_MINUS_DIV) return compactTwoMod(value1, value2, compact)
|
||||||
|
}
|
||||||
|
|
||||||
|
when (value2.signum()) {
|
||||||
|
0 -> return Fraction(value1, value2, compact = compact)
|
||||||
|
1 -> if (value2 < BI_DIV) return compactTwoMod(value1, value2, compact)
|
||||||
|
-1 -> if (value2 > BI_MINUS_DIV) return compactTwoMod(value1, value2, compact)
|
||||||
|
}
|
||||||
|
|
||||||
|
var value1 = value1
|
||||||
|
var value2 = value2
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
val _a = value1.divideAndRemainder(BI_DIV)
|
||||||
|
val _b = value2.divideAndRemainder(BI_DIV)
|
||||||
|
|
||||||
|
if (!isZero(_a[1]) || !isZero(_b[1]))
|
||||||
|
break
|
||||||
|
|
||||||
|
value1 = _a[0]
|
||||||
|
value2 = _b[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
val _a = value1.divideAndRemainder(BI_DIV2)
|
||||||
|
val _b = value2.divideAndRemainder(BI_DIV2)
|
||||||
|
|
||||||
|
if (!isZero(_a[1]) || !isZero(_b[1]))
|
||||||
|
break
|
||||||
|
|
||||||
|
value1 = _a[0]
|
||||||
|
value2 = _b[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
val p1 = positive(value1)
|
||||||
|
val p2 = positive(value2)
|
||||||
|
|
||||||
|
if (p1 > COMPACT_THRESHOLD || p2 > COMPACT_THRESHOLD) {
|
||||||
|
var hit = true
|
||||||
|
|
||||||
|
while (hit) {
|
||||||
|
hit = false
|
||||||
|
|
||||||
|
for (i in GCDs.size - 1 downTo 0) {
|
||||||
|
val div = GCDs[i]
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
val _a = value1.divideAndRemainder(div)
|
||||||
|
val _b = value2.divideAndRemainder(div)
|
||||||
|
|
||||||
|
if (!isZero(_a[1]) || !isZero(_b[1]))
|
||||||
|
break
|
||||||
|
|
||||||
|
value1 = _a[0]
|
||||||
|
value2 = _b[0]
|
||||||
|
hit = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (p1 > GCDs[0] && p2 > GCDs[0]) {
|
||||||
|
var hit = true
|
||||||
|
|
||||||
|
while (hit) {
|
||||||
|
hit = false
|
||||||
|
|
||||||
|
for (i in 4 downTo 0) {
|
||||||
|
val div = GCDs[i]
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
val _a = value1.divideAndRemainder(div)
|
||||||
|
val _b = value2.divideAndRemainder(div)
|
||||||
|
|
||||||
|
if (!isZero(_a[1]) || !isZero(_b[1]))
|
||||||
|
break
|
||||||
|
|
||||||
|
value1 = _a[0]
|
||||||
|
value2 = _b[0]
|
||||||
|
hit = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return compactTwoMod(value1, value2, compact)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unsignedInt(value: Byte): Int {
|
||||||
|
if (value < 0) {
|
||||||
|
return 256 + value
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class MagnitudeCrunchResult(val value: BigInteger, val mag: Int)
|
||||||
|
|
||||||
|
private fun magnitude(value: BigInteger): MagnitudeCrunchResult {
|
||||||
|
if (isZero(value))
|
||||||
|
return MagnitudeCrunchResult(value, 0)
|
||||||
|
|
||||||
|
var mag = 0
|
||||||
|
var value = value
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
val c = value.divideAndRemainder(BI_DIV2)
|
||||||
|
|
||||||
|
if (!isZero(c[1]))
|
||||||
|
break
|
||||||
|
|
||||||
|
value = c[0]
|
||||||
|
mag++
|
||||||
|
}
|
||||||
|
|
||||||
|
return MagnitudeCrunchResult(value, mag)
|
||||||
|
}
|
||||||
|
|
||||||
@JvmRecord
|
@JvmRecord
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@ -72,26 +263,21 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
val c = divisor.signum()
|
val c = divisor.signum()
|
||||||
|
|
||||||
if (a != b && a != c) {
|
if (a != b && a != c) {
|
||||||
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
if (isZero(divisor))
|
||||||
return Fraction(-value, -divisor)
|
return Fraction(-value, -divisor)
|
||||||
|
|
||||||
val mod = value % divisor
|
val mod = value.divideAndRemainder(divisor)
|
||||||
|
|
||||||
if (mod == BigInteger.ZERO)
|
if (isZero(mod[1]))
|
||||||
return Fraction(-value / -divisor, compact = compact)
|
return Fraction(mod[0], compact = compact)
|
||||||
|
|
||||||
return Fraction(-value, -divisor)
|
return Fraction(-value, -divisor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
if (isZero(divisor))
|
||||||
return this
|
return this
|
||||||
|
|
||||||
val mod = value % divisor
|
return compactTwo(value, divisor, compact)
|
||||||
|
|
||||||
if (mod == BigInteger.ZERO)
|
|
||||||
return Fraction(value / divisor, compact = compact)
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isZero(): Boolean {
|
fun isZero(): Boolean {
|
||||||
@ -108,12 +294,7 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
||||||
return this
|
return this
|
||||||
|
|
||||||
val mod = value % divisor
|
return compactTwo(value, divisor, compact)
|
||||||
|
|
||||||
if (mod == BigInteger.ZERO)
|
|
||||||
return Fraction(value / divisor, compact = compact)
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun canonize(): Fraction {
|
fun canonize(): Fraction {
|
||||||
@ -181,8 +362,8 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
if (isNaN()) return this
|
if (isNaN()) return this
|
||||||
|
|
||||||
if (divisor == other.divisor) {
|
if (divisor == other.divisor) {
|
||||||
if (divisor == BigInteger.ONE)
|
if (isOne(divisor))
|
||||||
return Fraction(value + other.value)
|
return Fraction(value + other.value, divisor)
|
||||||
|
|
||||||
val new = value + other.value
|
val new = value + other.value
|
||||||
|
|
||||||
@ -192,12 +373,7 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
||||||
return Fraction(new, divisor)
|
return Fraction(new, divisor)
|
||||||
|
|
||||||
val mod = new % divisor
|
return compactTwo(new, divisor)
|
||||||
|
|
||||||
if (mod == BigInteger.ZERO)
|
|
||||||
return Fraction(new / divisor)
|
|
||||||
|
|
||||||
return Fraction(new, divisor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val new = value * other.divisor + other.value * divisor
|
val new = value * other.divisor + other.value * divisor
|
||||||
@ -206,12 +382,7 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
if (div == BigInteger.ZERO || div == BI_MINUS_ZERO)
|
if (div == BigInteger.ZERO || div == BI_MINUS_ZERO)
|
||||||
return Fraction(new, div)
|
return Fraction(new, div)
|
||||||
|
|
||||||
val mod = new % div
|
return compactTwo(new, div)
|
||||||
|
|
||||||
if (mod == BigInteger.ZERO)
|
|
||||||
return Fraction(new / div)
|
|
||||||
|
|
||||||
return Fraction(new, div)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun plus(other: Fraction): Fraction {
|
operator fun plus(other: Fraction): Fraction {
|
||||||
@ -230,8 +401,8 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
|
|
||||||
private fun minusCompact(other: Fraction): Fraction {
|
private fun minusCompact(other: Fraction): Fraction {
|
||||||
if (divisor == other.divisor) {
|
if (divisor == other.divisor) {
|
||||||
if (divisor == BigInteger.ONE)
|
if (isOne(divisor))
|
||||||
return Fraction(value - other.value)
|
return Fraction(value - other.value, divisor)
|
||||||
|
|
||||||
val new = value - other.value
|
val new = value - other.value
|
||||||
|
|
||||||
@ -241,12 +412,7 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
||||||
return Fraction(new, divisor)
|
return Fraction(new, divisor)
|
||||||
|
|
||||||
val mod = new % divisor
|
return compactTwo(new, divisor)
|
||||||
|
|
||||||
if (mod == BigInteger.ZERO)
|
|
||||||
return Fraction(new / divisor)
|
|
||||||
|
|
||||||
return Fraction(new, divisor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val new = value * other.divisor - other.value * divisor
|
val new = value * other.divisor - other.value * divisor
|
||||||
@ -255,12 +421,7 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
if (div == BigInteger.ZERO || div == BI_MINUS_ZERO)
|
if (div == BigInteger.ZERO || div == BI_MINUS_ZERO)
|
||||||
return Fraction(new, div)
|
return Fraction(new, div)
|
||||||
|
|
||||||
val mod = new % div
|
return compactTwo(new, div)
|
||||||
|
|
||||||
if (mod == BigInteger.ZERO)
|
|
||||||
return Fraction(new / div)
|
|
||||||
|
|
||||||
return Fraction(new, div)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun minus(other: Fraction): Fraction {
|
operator fun minus(other: Fraction): Fraction {
|
||||||
@ -288,12 +449,7 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
if (div == BigInteger.ZERO || div == BI_MINUS_ZERO)
|
if (div == BigInteger.ZERO || div == BI_MINUS_ZERO)
|
||||||
return Fraction(new, div)
|
return Fraction(new, div)
|
||||||
|
|
||||||
val mod = new % div
|
return compactTwo(new, div)
|
||||||
|
|
||||||
if (mod == BigInteger.ZERO)
|
|
||||||
return Fraction(new / div)
|
|
||||||
|
|
||||||
return Fraction(new, div)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun times(other: Fraction): Fraction {
|
operator fun times(other: Fraction): Fraction {
|
||||||
@ -317,12 +473,7 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
if (div == BigInteger.ZERO || div == BI_MINUS_ZERO)
|
if (div == BigInteger.ZERO || div == BI_MINUS_ZERO)
|
||||||
return Fraction(new, div)
|
return Fraction(new, div)
|
||||||
|
|
||||||
val mod = new % div
|
return compactTwo(new, div)
|
||||||
|
|
||||||
if (mod == BigInteger.ZERO)
|
|
||||||
return Fraction(new / div)
|
|
||||||
|
|
||||||
return Fraction(new, div)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun div(other: Fraction): Fraction {
|
operator fun div(other: Fraction): Fraction {
|
||||||
@ -423,13 +574,32 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
|
|
||||||
fun toByteArray(): ByteArray {
|
fun toByteArray(): ByteArray {
|
||||||
if (isNaN()) {
|
if (isNaN()) {
|
||||||
return byteArrayOf(1, 0, 1, 0)
|
return byteArrayOf(1, 0, 0, 0, 0, 1, 0, 0, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
val bytesA = value.toByteArray()
|
val magValue = magnitude(value)
|
||||||
val bytesB = divisor.toByteArray()
|
val magDiv = magnitude(divisor)
|
||||||
|
|
||||||
return byteArrayOf(bytesA.size.toByte(), *bytesA, bytesB.size.toByte(), *bytesB)
|
val bytesA = magValue.value.toByteArray()
|
||||||
|
val bytesB = magDiv.value.toByteArray()
|
||||||
|
|
||||||
|
return byteArrayOf(
|
||||||
|
(bytesA.size and 0xFF).toByte(),
|
||||||
|
(bytesA.size ushr 8).toByte(),
|
||||||
|
|
||||||
|
(magValue.mag and 0xFF).toByte(),
|
||||||
|
(magValue.mag ushr 8).toByte(),
|
||||||
|
|
||||||
|
*bytesA,
|
||||||
|
|
||||||
|
(bytesB.size and 0xFF).toByte(),
|
||||||
|
(bytesB.size ushr 8).toByte(),
|
||||||
|
|
||||||
|
(magDiv.mag and 0xFF).toByte(),
|
||||||
|
(magDiv.mag ushr 8).toByte(),
|
||||||
|
|
||||||
|
*bytesB
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toInt(): Int {
|
fun toInt(): Int {
|
||||||
@ -592,6 +762,8 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private val LOGGER = LogManager.getLogger()
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val ZERO = Fraction(BigInteger.ZERO)
|
val ZERO = Fraction(BigInteger.ZERO)
|
||||||
|
|
||||||
@ -635,11 +807,27 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun fromByteArray(bytes: ByteArray): Fraction {
|
fun fromByteArray(bytes: ByteArray): Fraction {
|
||||||
val bytesA = bytes.copyOfRange(1, 1 + bytes[0].toInt())
|
try {
|
||||||
val offsetB = 1 + bytes[0].toInt()
|
val rangeA = unsignedInt(bytes[0]) or (unsignedInt(bytes[1]) shl 8)
|
||||||
val bytesB = bytes.copyOfRange(offsetB + 1, offsetB + 1 + bytes[offsetB].toInt())
|
val magA = unsignedInt(bytes[2]) or (unsignedInt(bytes[3]) shl 8)
|
||||||
|
|
||||||
return Fraction(if (bytesA.isNotEmpty()) BigInteger(bytesA) else BigInteger.ZERO, if (bytesB.isNotEmpty()) BigInteger(bytesB) else BigInteger.ZERO)
|
val bytesA = bytes.copyOfRange(4, 4 + rangeA)
|
||||||
|
|
||||||
|
val offsetB = 4 + rangeA
|
||||||
|
|
||||||
|
val rangeB = unsignedInt(bytes[offsetB]) or (unsignedInt(bytes[offsetB + 1]) shl 8)
|
||||||
|
val magB = unsignedInt(bytes[offsetB + 2]) or (unsignedInt(bytes[offsetB + 3]) shl 8)
|
||||||
|
|
||||||
|
val bytesB = bytes.copyOfRange(offsetB + 4, offsetB + 4 + rangeB)
|
||||||
|
|
||||||
|
if (bytesB.isEmpty())
|
||||||
|
return NaN
|
||||||
|
|
||||||
|
return Fraction(if (bytesA.isNotEmpty()) (BigInteger(bytesA) * BigInteger("1" + "0".repeat(magA))) else BigInteger.ZERO, BigInteger(bytesB) * BigInteger("1" + "0".repeat(magB)))
|
||||||
|
} catch(err: Throwable) {
|
||||||
|
LOGGER.error("Unable to load Fraction from byte array", err)
|
||||||
|
return NaN
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
159
src/main/kotlin/ru/dbotthepony/mc/otm/graph/Abstract6Graph.kt
Normal file
159
src/main/kotlin/ru/dbotthepony/mc/otm/graph/Abstract6Graph.kt
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.graph
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.Direction
|
||||||
|
import net.minecraft.core.SectionPos
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
|
import ru.dbotthepony.mc.otm.plus
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
abstract class Abstract6Graph<T> {
|
||||||
|
@JvmField
|
||||||
|
protected val _nodes = ArrayList<Graph6Node<T>>()
|
||||||
|
fun size() = _nodes.size
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val nodes = Collections.unmodifiableCollection(_nodes)
|
||||||
|
|
||||||
|
abstract fun onNodeRemoved(node: Graph6Node<T>)
|
||||||
|
abstract fun onNodeAdded(node: Graph6Node<T>)
|
||||||
|
|
||||||
|
fun removeNode(node: Graph6Node<T>) {
|
||||||
|
if (!_nodes.contains(node))
|
||||||
|
throw IllegalStateException("Not containing node $node")
|
||||||
|
|
||||||
|
_nodes.remove(node)
|
||||||
|
node.graph = null
|
||||||
|
onNodeRemoved(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addNode(node: Graph6Node<T>) {
|
||||||
|
if (_nodes.contains(node))
|
||||||
|
throw IllegalStateException("Already containing node $node")
|
||||||
|
|
||||||
|
_nodes.add(node)
|
||||||
|
node.graph = this
|
||||||
|
onNodeAdded(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun merge(other: Abstract6Graph<T>): Abstract6Graph<T> {
|
||||||
|
if (other === this)
|
||||||
|
return this
|
||||||
|
|
||||||
|
if (size() >= other.size()) {
|
||||||
|
for (node in other._nodes) {
|
||||||
|
_nodes.add(node)
|
||||||
|
node.graph = this
|
||||||
|
onNodeAdded(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
} else {
|
||||||
|
return other.merge(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun <T, G : Abstract6Graph<T>> discoverFull(
|
||||||
|
level: ServerLevel,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
node: Graph6Node<T>,
|
||||||
|
nodeGetter: (BlockEntity) -> Graph6Node<T>?,
|
||||||
|
factory: () -> G
|
||||||
|
) {
|
||||||
|
OverdriveThatMatters.tickUntil(level) {
|
||||||
|
!node.valid || discover(level, blockPos, node, nodeGetter, factory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun <T, G : Abstract6Graph<T>> discover(
|
||||||
|
level: ServerLevel,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
node: Graph6Node<T>,
|
||||||
|
nodeGetter: (BlockEntity) -> Graph6Node<T>?,
|
||||||
|
factory: () -> G
|
||||||
|
): Boolean {
|
||||||
|
var fullDiscovery = true
|
||||||
|
|
||||||
|
node.nullifyConnections()
|
||||||
|
|
||||||
|
var _graph = node.graph
|
||||||
|
|
||||||
|
// для начала найдем граф к которому будем принадлежать
|
||||||
|
if (_graph == null) {
|
||||||
|
for (dir in Direction.values()) {
|
||||||
|
val offset = blockPos + dir
|
||||||
|
val chunk = level.chunkSource.getChunkNow(SectionPos.blockToSectionCoord(offset.x), SectionPos.blockToSectionCoord(offset.z))
|
||||||
|
|
||||||
|
if (chunk == null) {
|
||||||
|
fullDiscovery = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val entity = chunk.getBlockEntity(offset)
|
||||||
|
|
||||||
|
if (entity != null) {
|
||||||
|
val getNode = nodeGetter(entity)
|
||||||
|
|
||||||
|
if (getNode?.graph != null) {
|
||||||
|
_graph = getNode.graph
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// мы нашли граф рядом
|
||||||
|
if (_graph != null) {
|
||||||
|
node.graph = _graph
|
||||||
|
_graph.addNode(node)
|
||||||
|
} else {
|
||||||
|
// графов рядом нет, создаем свой
|
||||||
|
_graph = factory()
|
||||||
|
node.graph = _graph
|
||||||
|
_graph.addNode(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// теперь снова смотрим на соседей, если у них нет графа - присоединяем к своему
|
||||||
|
// если у них есть граф - слияем его со своим или свой с его
|
||||||
|
for (dir in Direction.values()) {
|
||||||
|
val offset = blockPos + dir
|
||||||
|
val chunk = level.chunkSource.getChunkNow(SectionPos.blockToSectionCoord(offset.x), SectionPos.blockToSectionCoord(offset.z))
|
||||||
|
|
||||||
|
if (chunk == null) {
|
||||||
|
fullDiscovery = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val entity = chunk.getBlockEntity(offset)
|
||||||
|
|
||||||
|
if (entity != null) {
|
||||||
|
val getNode = nodeGetter(entity)
|
||||||
|
|
||||||
|
if (getNode != null) {
|
||||||
|
// у вершины нет своего графа
|
||||||
|
// добавляем в свой граф
|
||||||
|
if (getNode.graph == null) {
|
||||||
|
getNode.graph = node.graph!!
|
||||||
|
node.graph!!.addNode(getNode)
|
||||||
|
} else if (getNode.graph != node.graph) {
|
||||||
|
// у вершины уже есть свой граф, и он не наш
|
||||||
|
// произведём слияние графов
|
||||||
|
val merged = getNode.graph!!.merge(node.graph!!)
|
||||||
|
getNode.graph = merged
|
||||||
|
node.graph = merged
|
||||||
|
}
|
||||||
|
|
||||||
|
node.setToNeightbour(getNode, dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullDiscovery
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
299
src/main/kotlin/ru/dbotthepony/mc/otm/graph/Graph6Node.kt
Normal file
299
src/main/kotlin/ru/dbotthepony/mc/otm/graph/Graph6Node.kt
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.graph
|
||||||
|
|
||||||
|
import net.minecraft.core.Direction
|
||||||
|
|
||||||
|
interface GraphNodeListener {
|
||||||
|
fun onNeighbourTop(node: Graph6Node<*>) = onNeighbour(node, Direction.UP)
|
||||||
|
fun onNeighbourBottom(node: Graph6Node<*>) = onNeighbour(node, Direction.DOWN)
|
||||||
|
fun onNeighbourLeft(node: Graph6Node<*>) = onNeighbour(node, Direction.WEST)
|
||||||
|
fun onNeighbourRight(node: Graph6Node<*>) = onNeighbour(node, Direction.EAST)
|
||||||
|
fun onNeighbourFront(node: Graph6Node<*>) = onNeighbour(node, Direction.SOUTH)
|
||||||
|
fun onNeighbourBack(node: Graph6Node<*>) = onNeighbour(node, Direction.NORTH)
|
||||||
|
|
||||||
|
fun onNeighbour(node: Graph6Node<*>, direction: Direction)
|
||||||
|
|
||||||
|
fun onUnNeighbourTop(node: Graph6Node<*>) = onUnNeighbour(node, Direction.UP)
|
||||||
|
fun onUnNeighbourBottom(node: Graph6Node<*>) = onUnNeighbour(node, Direction.DOWN)
|
||||||
|
fun onUnNeighbourLeft(node: Graph6Node<*>) = onUnNeighbour(node, Direction.WEST)
|
||||||
|
fun onUnNeighbourRight(node: Graph6Node<*>) = onUnNeighbour(node, Direction.EAST)
|
||||||
|
fun onUnNeighbourFront(node: Graph6Node<*>) = onUnNeighbour(node, Direction.SOUTH)
|
||||||
|
fun onUnNeighbourBack(node: Graph6Node<*>) = onUnNeighbour(node, Direction.NORTH)
|
||||||
|
|
||||||
|
fun onUnNeighbour(node: Graph6Node<*>, direction: Direction)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вершина графа, содержит то, к какому графу принадлежит, соседей и своё "значение"
|
||||||
|
class Graph6Node<T>(@JvmField val value: T, graph: Abstract6Graph<T>? = null) {
|
||||||
|
var graph: Abstract6Graph<T>? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.graph = graph
|
||||||
|
}
|
||||||
|
|
||||||
|
var top: Graph6Node<T>? = null
|
||||||
|
set(value) {
|
||||||
|
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
||||||
|
|
||||||
|
if (field != value && this.value is GraphNodeListener) {
|
||||||
|
if (field != null) {
|
||||||
|
this.value.onUnNeighbourTop(field!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
this.value.onNeighbourTop(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var bottom: Graph6Node<T>? = null
|
||||||
|
set(value) {
|
||||||
|
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
||||||
|
|
||||||
|
if (field != value && this.value is GraphNodeListener) {
|
||||||
|
if (field != null) {
|
||||||
|
this.value.onUnNeighbourBottom(field!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
this.value.onNeighbourBottom(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var left: Graph6Node<T>? = null
|
||||||
|
set(value) {
|
||||||
|
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
||||||
|
|
||||||
|
if (field != value && this.value is GraphNodeListener) {
|
||||||
|
if (field != null) {
|
||||||
|
this.value.onUnNeighbourLeft(field!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
this.value.onNeighbourLeft(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var right: Graph6Node<T>? = null
|
||||||
|
set(value) {
|
||||||
|
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
||||||
|
|
||||||
|
if (field != value && this.value is GraphNodeListener) {
|
||||||
|
if (field != null) {
|
||||||
|
this.value.onUnNeighbourRight(field!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
this.value.onNeighbourRight(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var front: Graph6Node<T>? = null
|
||||||
|
set(value) {
|
||||||
|
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
||||||
|
|
||||||
|
if (field != value && this.value is GraphNodeListener) {
|
||||||
|
if (field != null) {
|
||||||
|
this.value.onUnNeighbourFront(field!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
this.value.onNeighbourFront(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var back: Graph6Node<T>? = null
|
||||||
|
set(value) {
|
||||||
|
if (value != null && (graph == null || value.graph !== graph)) throw IllegalStateException("Can not be neighbour with node from different graph")
|
||||||
|
|
||||||
|
if (field != value && this.value is GraphNodeListener) {
|
||||||
|
if (field != null) {
|
||||||
|
this.value.onUnNeighbourBack(field!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
this.value.onNeighbourBack(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun nullifyConnections() {
|
||||||
|
top?.bottom = null
|
||||||
|
bottom?.top = null
|
||||||
|
left?.right = null
|
||||||
|
right?.left = null
|
||||||
|
front?.back = null
|
||||||
|
back?.front = null
|
||||||
|
|
||||||
|
top = null
|
||||||
|
bottom = null
|
||||||
|
left = null
|
||||||
|
right = null
|
||||||
|
front = null
|
||||||
|
back = null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setToNeightbour(node: Graph6Node<T>, direction: Direction) {
|
||||||
|
when (direction) {
|
||||||
|
Direction.DOWN -> {
|
||||||
|
node.top = this
|
||||||
|
bottom = node
|
||||||
|
}
|
||||||
|
|
||||||
|
Direction.UP -> {
|
||||||
|
node.bottom = this
|
||||||
|
top = node
|
||||||
|
}
|
||||||
|
|
||||||
|
Direction.NORTH -> {
|
||||||
|
node.front = this
|
||||||
|
back = node
|
||||||
|
}
|
||||||
|
|
||||||
|
Direction.SOUTH -> {
|
||||||
|
node.back = this
|
||||||
|
front = node
|
||||||
|
}
|
||||||
|
|
||||||
|
Direction.WEST -> {
|
||||||
|
node.right = this
|
||||||
|
left = node
|
||||||
|
}
|
||||||
|
|
||||||
|
Direction.EAST -> {
|
||||||
|
node.left = this
|
||||||
|
right = node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var seen: Int = 0
|
||||||
|
|
||||||
|
private fun _flood(): List<GraphFlooder<T>> {
|
||||||
|
val list = ArrayList<GraphFlooder<T>>()
|
||||||
|
var seen = Int.MAX_VALUE
|
||||||
|
|
||||||
|
GraphFlooder.floodIf(top, seen) {
|
||||||
|
seen = it.seen
|
||||||
|
list.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphFlooder.floodIf(bottom, seen) {
|
||||||
|
seen = it.seen
|
||||||
|
list.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphFlooder.floodIf(left, seen) {
|
||||||
|
seen = it.seen
|
||||||
|
list.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphFlooder.floodIf(right, seen) {
|
||||||
|
seen = it.seen
|
||||||
|
list.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphFlooder.floodIf(front, seen) {
|
||||||
|
seen = it.seen
|
||||||
|
list.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphFlooder.floodIf(back, seen) {
|
||||||
|
seen = it.seen
|
||||||
|
list.add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
fun flood(): List<GraphFlooder<T>> {
|
||||||
|
top?.bottom = null
|
||||||
|
bottom?.top = null
|
||||||
|
left?.right = null
|
||||||
|
right?.left = null
|
||||||
|
front?.back = null
|
||||||
|
back?.front = null
|
||||||
|
|
||||||
|
val list = _flood()
|
||||||
|
|
||||||
|
top?.bottom = this
|
||||||
|
bottom?.top = this
|
||||||
|
left?.right = this
|
||||||
|
right?.left = this
|
||||||
|
front?.back = this
|
||||||
|
back?.front = this
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
var valid = true
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun destroy(factory: () -> Abstract6Graph<T>): List<GraphFlooder<T>> {
|
||||||
|
if (!valid) return emptyList()
|
||||||
|
|
||||||
|
top?.bottom = null
|
||||||
|
bottom?.top = null
|
||||||
|
left?.right = null
|
||||||
|
right?.left = null
|
||||||
|
front?.back = null
|
||||||
|
back?.front = null
|
||||||
|
|
||||||
|
graph?.removeNode(this)
|
||||||
|
|
||||||
|
var num = 0
|
||||||
|
|
||||||
|
if (top != null) num++
|
||||||
|
if (bottom != null) num++
|
||||||
|
if (left != null) num++
|
||||||
|
if (right != null) num++
|
||||||
|
if (front != null) num++
|
||||||
|
if (back != null) num++
|
||||||
|
|
||||||
|
if (num < 2) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
val paths = _flood()
|
||||||
|
|
||||||
|
if (paths.size < 2) {
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
|
var biggest = paths[0]
|
||||||
|
|
||||||
|
for (i in 1 until paths.size) {
|
||||||
|
if (biggest.size() < paths[i].size()) {
|
||||||
|
biggest = paths[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (flooder in paths) {
|
||||||
|
if (flooder == biggest) continue
|
||||||
|
|
||||||
|
val graph = factory()
|
||||||
|
|
||||||
|
for (node in flooder.nodes) {
|
||||||
|
node.graph?.removeNode(node)
|
||||||
|
graph.addNode(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
}
|
64
src/main/kotlin/ru/dbotthepony/mc/otm/graph/GraphFlooder.kt
Normal file
64
src/main/kotlin/ru/dbotthepony/mc/otm/graph/GraphFlooder.kt
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.graph
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
class GraphFlooder<T>(val startNode: Graph6Node<T>, @JvmField val seen: Int = nextSeen++) {
|
||||||
|
var flooded = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
private val _nodes = ArrayList<Graph6Node<T>>()
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val nodes = Collections.unmodifiableCollection(_nodes)
|
||||||
|
|
||||||
|
fun size() = _nodes.size
|
||||||
|
|
||||||
|
private fun flood(node: Graph6Node<T>) {
|
||||||
|
if (node.seen >= seen) return
|
||||||
|
|
||||||
|
_nodes.add(node)
|
||||||
|
node.seen = seen
|
||||||
|
|
||||||
|
if (node.top != null) flood(node.top!!)
|
||||||
|
if (node.bottom != null) flood(node.bottom!!)
|
||||||
|
if (node.left != null) flood(node.left!!)
|
||||||
|
if (node.right != null) flood(node.right!!)
|
||||||
|
if (node.front != null) flood(node.front!!)
|
||||||
|
if (node.back != null) flood(node.back!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun flood() {
|
||||||
|
if (flooded) throw IllegalStateException("Already flooded")
|
||||||
|
|
||||||
|
flooded = true
|
||||||
|
|
||||||
|
_nodes.add(startNode)
|
||||||
|
startNode.seen = seen
|
||||||
|
|
||||||
|
if (startNode.top != null) flood(startNode.top!!)
|
||||||
|
if (startNode.bottom != null) flood(startNode.bottom!!)
|
||||||
|
if (startNode.left != null) flood(startNode.left!!)
|
||||||
|
if (startNode.right != null) flood(startNode.right!!)
|
||||||
|
if (startNode.front != null) flood(startNode.front!!)
|
||||||
|
if (startNode.back != null) flood(startNode.back!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private var nextSeen = 0
|
||||||
|
|
||||||
|
fun <T> floodIf(node: Graph6Node<T>?, seen: Int, runnable: (GraphFlooder<T>) -> Unit) {
|
||||||
|
if (node != null && node.seen < seen) {
|
||||||
|
if (seen == Int.MAX_VALUE) {
|
||||||
|
val flooder = GraphFlooder(node)
|
||||||
|
flooder.flood()
|
||||||
|
runnable(flooder)
|
||||||
|
} else {
|
||||||
|
val flooder = GraphFlooder(node, seen)
|
||||||
|
flooder.flood()
|
||||||
|
runnable(flooder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.graph.matter
|
||||||
|
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||||
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
|
|
||||||
|
interface IMatterGraphListener {
|
||||||
|
fun onPatternAdded(state: PatternState) {}
|
||||||
|
fun onPatternRemoved(state: PatternState) {}
|
||||||
|
fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {}
|
||||||
|
|
||||||
|
fun onMatterTaskCreated(task: MatterTask) {}
|
||||||
|
fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) {}
|
||||||
|
fun onMatterTaskFinished(state: MatterTask) {}
|
||||||
|
fun onMatterTaskRemoved(state: MatterTask) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IMatterGraphNode : IMatterGraphListener {
|
||||||
|
fun getMatterHandler(): IMatterHandler? = null
|
||||||
|
fun getPatternHandler(): IPatternStorage? = null
|
||||||
|
fun getTaskHandler(): IMatterTaskProvider? = null
|
||||||
|
fun getAsMatterNode(): Graph6Node<IMatterGraphNode>
|
||||||
|
fun getAsMatterGraph(): MatterNetworkGraph? = getAsMatterNode().graph as MatterNetworkGraph?
|
||||||
|
}
|
@ -0,0 +1,416 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.graph.matter
|
||||||
|
|
||||||
|
import net.minecraft.server.level.ServerLevel
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||||
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
|
import ru.dbotthepony.mc.otm.graph.Abstract6Graph
|
||||||
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
import kotlin.collections.HashSet
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListener {
|
||||||
|
private val listeners = HashSet<IMatterGraphListener>()
|
||||||
|
|
||||||
|
fun addListener(listener: IMatterGraphListener) = listeners.add(listener)
|
||||||
|
fun removeListener(listener: IMatterGraphListener) = listeners.remove(listener)
|
||||||
|
|
||||||
|
override fun onNodeRemoved(node: Graph6Node<IMatterGraphNode>) {
|
||||||
|
val patterns = node.value.getPatternHandler()
|
||||||
|
|
||||||
|
if (patterns != null) {
|
||||||
|
for (pattern in patterns.storedPatterns) {
|
||||||
|
onPatternRemoved(pattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val tasks = node.value.getTaskHandler()
|
||||||
|
|
||||||
|
if (tasks != null) {
|
||||||
|
for (task in tasks.tasks) {
|
||||||
|
onMatterTaskRemoved(task)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pattern in getStoredPatterns()) {
|
||||||
|
node.value.onPatternRemoved(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (task in getTasks()) {
|
||||||
|
node.value.onMatterTaskRemoved(task)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNodeAdded(node: Graph6Node<IMatterGraphNode>) {
|
||||||
|
for (pattern in getStoredPatterns()) {
|
||||||
|
node.value.onPatternAdded(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (task in getTasks()) {
|
||||||
|
node.value.onMatterTaskCreated(task)
|
||||||
|
}
|
||||||
|
|
||||||
|
val patterns = node.value.getPatternHandler()
|
||||||
|
|
||||||
|
if (patterns != null) {
|
||||||
|
for (pattern in patterns.storedPatterns) {
|
||||||
|
onPatternAdded(pattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val tasks = node.value.getTaskHandler()
|
||||||
|
|
||||||
|
if (tasks != null) {
|
||||||
|
for (task in tasks.tasks) {
|
||||||
|
onMatterTaskCreated(task)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMatterStorageLevel(): Fraction {
|
||||||
|
var level = Fraction.ZERO
|
||||||
|
|
||||||
|
for (node in _nodes) {
|
||||||
|
val matter = node.value.getMatterHandler()
|
||||||
|
|
||||||
|
if (matter != null && matter.direction == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
|
||||||
|
level += matter.storedMatter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return level
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMatterStorageMaxLevel(): Fraction {
|
||||||
|
var level = Fraction.ZERO
|
||||||
|
|
||||||
|
for (node in _nodes) {
|
||||||
|
val matter = node.value.getMatterHandler()
|
||||||
|
|
||||||
|
if (matter != null && matter.direction == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
|
||||||
|
level += matter.maxStoredMatter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return level
|
||||||
|
}
|
||||||
|
|
||||||
|
fun extractMatter(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
|
if (howMuch <= Fraction.ZERO)
|
||||||
|
return Fraction.ZERO
|
||||||
|
|
||||||
|
var howMuch = howMuch
|
||||||
|
var extracted = Fraction.ZERO
|
||||||
|
|
||||||
|
for (node in _nodes) {
|
||||||
|
val matter = node.value.getMatterHandler()
|
||||||
|
|
||||||
|
if (matter != null) {
|
||||||
|
val value = matter.extractMatterOuter(howMuch, simulate)
|
||||||
|
howMuch -= value
|
||||||
|
extracted += value
|
||||||
|
|
||||||
|
if (howMuch <= Fraction.ZERO)
|
||||||
|
return extracted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return extracted
|
||||||
|
}
|
||||||
|
|
||||||
|
fun receiveMatter(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
|
if (howMuch <= Fraction.ZERO)
|
||||||
|
return Fraction.ZERO
|
||||||
|
|
||||||
|
var howMuch = howMuch
|
||||||
|
var received = Fraction.ZERO
|
||||||
|
|
||||||
|
for (node in _nodes) {
|
||||||
|
val matter = node.value.getMatterHandler()
|
||||||
|
|
||||||
|
if (matter != null && matter.direction == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
|
||||||
|
val value = matter.receiveMatterOuter(howMuch, simulate)
|
||||||
|
howMuch -= value
|
||||||
|
received += value
|
||||||
|
|
||||||
|
if (howMuch <= Fraction.ZERO)
|
||||||
|
return received
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return received
|
||||||
|
}
|
||||||
|
|
||||||
|
fun receiveMatterForce(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||||
|
if (howMuch <= Fraction.ZERO)
|
||||||
|
return Fraction.ZERO
|
||||||
|
|
||||||
|
var howMuch = howMuch
|
||||||
|
var received = Fraction.ZERO
|
||||||
|
|
||||||
|
for (node in _nodes) {
|
||||||
|
val matter = node.value.getMatterHandler()
|
||||||
|
|
||||||
|
if (matter != null && matter.direction != IMatterHandler.MatterDirection.EXTRACT) {
|
||||||
|
val value = matter.receiveMatterOuter(howMuch, simulate)
|
||||||
|
howMuch -= value
|
||||||
|
received += value
|
||||||
|
|
||||||
|
if (howMuch <= Fraction.ZERO)
|
||||||
|
return received
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return received
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun _insertPattern(state: PatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus {
|
||||||
|
for (node in _nodes) {
|
||||||
|
val storage = node.value.getPatternHandler()
|
||||||
|
|
||||||
|
if (storage != null) {
|
||||||
|
val status = storage.insertPattern(state, onlyUpdate, simulate)
|
||||||
|
|
||||||
|
if (status.status != PatternInsertStatus.Status.FAIL) {
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PatternInsertStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun insertPattern(state: PatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus {
|
||||||
|
if (onlyUpdate) return _insertPattern(state, true, simulate)
|
||||||
|
val status = _insertPattern(state, true, simulate)
|
||||||
|
if (status.status != PatternInsertStatus.Status.FAIL) return status
|
||||||
|
return _insertPattern(state, false, simulate)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTasks(): Collection<MatterTask> {
|
||||||
|
val list = ArrayList<MatterTask>()
|
||||||
|
|
||||||
|
for (node in _nodes) {
|
||||||
|
val tasks = node.value.getTaskHandler()
|
||||||
|
|
||||||
|
if (tasks != null) {
|
||||||
|
list.addAll(tasks.tasks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getStoredPatterns(): Collection<PatternState> {
|
||||||
|
val list = ArrayList<PatternState>()
|
||||||
|
|
||||||
|
for (node in _nodes) {
|
||||||
|
val storage = node.value.getPatternHandler()
|
||||||
|
|
||||||
|
if (storage != null) {
|
||||||
|
list.addAll(storage.storedPatterns)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPatternCount(): Long {
|
||||||
|
var value = 0L
|
||||||
|
|
||||||
|
for (node in _nodes) {
|
||||||
|
val storage = node.value.getPatternHandler()
|
||||||
|
|
||||||
|
if (storage != null) {
|
||||||
|
value += storage.stored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPatternCapacity(): Long {
|
||||||
|
var value = 0L
|
||||||
|
|
||||||
|
for (node in _nodes) {
|
||||||
|
val storage = node.value.getPatternHandler()
|
||||||
|
|
||||||
|
if (storage != null) {
|
||||||
|
value += storage.capacity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPattern(id: UUID): PatternState? {
|
||||||
|
for (node in _nodes) {
|
||||||
|
val storage = node.value.getPatternHandler()
|
||||||
|
|
||||||
|
if (storage != null) {
|
||||||
|
val get = storage.getPattern(id)
|
||||||
|
|
||||||
|
if (get != null) {
|
||||||
|
return get
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPattern(state: PatternState) = getPattern(state.id)
|
||||||
|
fun hasPattern(state: PatternState) = getPattern(state.id) != null
|
||||||
|
fun hasPattern(id: UUID) = getPattern(id) != null
|
||||||
|
|
||||||
|
fun findPattern(predicate: (PatternState) -> Boolean): PatternState? {
|
||||||
|
for (node in _nodes) {
|
||||||
|
val storage = node.value.getPatternHandler()
|
||||||
|
|
||||||
|
if (storage != null) {
|
||||||
|
for (state in storage.storedPatterns) {
|
||||||
|
if (predicate(state)) {
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findPattern(predicate: Item) = findPattern { it.item == predicate }
|
||||||
|
|
||||||
|
fun findPatterns(predicate: (PatternState) -> Boolean): Collection<PatternState> {
|
||||||
|
val list = ArrayList<PatternState>()
|
||||||
|
|
||||||
|
for (node in _nodes) {
|
||||||
|
val storage = node.value.getPatternHandler()
|
||||||
|
|
||||||
|
if (storage != null) {
|
||||||
|
for (state in storage.storedPatterns) {
|
||||||
|
if (predicate(state)) {
|
||||||
|
list.add(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findPatterns(predicate: Item) = findPatterns { it.item == predicate }
|
||||||
|
|
||||||
|
fun allocateTask(simulate: Boolean): MatterTaskAllocation? {
|
||||||
|
for (node in _nodes) {
|
||||||
|
val tasks = node.value.getTaskHandler()
|
||||||
|
|
||||||
|
if (tasks != null) {
|
||||||
|
val allocated = tasks.allocateTask(simulate)
|
||||||
|
|
||||||
|
if (allocated != null) {
|
||||||
|
return allocated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notifyTaskCompletion(task: MatterTask): Boolean {
|
||||||
|
for (node in _nodes) {
|
||||||
|
val tasks = node.value.getTaskHandler()
|
||||||
|
|
||||||
|
if (tasks != null && tasks.notifyTaskCompletion(task)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPatternAdded(state: PatternState) {
|
||||||
|
for (node in _nodes) node.value.onPatternAdded(state)
|
||||||
|
for (node in listeners) node.onPatternAdded(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPatternRemoved(state: PatternState) {
|
||||||
|
for (node in _nodes) node.value.onPatternRemoved(state)
|
||||||
|
for (node in listeners) node.onPatternRemoved(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {
|
||||||
|
for (node in _nodes) node.value.onPatternUpdated(new_state, old_state)
|
||||||
|
for (node in listeners) node.onPatternUpdated(new_state, old_state)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMatterTaskCreated(task: MatterTask) {
|
||||||
|
for (node in _nodes) node.value.onMatterTaskCreated(task)
|
||||||
|
for (node in listeners) node.onMatterTaskCreated(task)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) {
|
||||||
|
for (node in _nodes) node.value.onMatterTaskUpdated(new_state, old_state)
|
||||||
|
for (node in listeners) node.onMatterTaskUpdated(new_state, old_state)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMatterTaskFinished(state: MatterTask) {
|
||||||
|
for (node in _nodes) node.value.onMatterTaskFinished(state)
|
||||||
|
for (node in listeners) node.onMatterTaskFinished(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMatterTaskRemoved(state: MatterTask) {
|
||||||
|
for (node in _nodes) node.value.onMatterTaskRemoved(state)
|
||||||
|
for (node in listeners) node.onMatterTaskRemoved(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun discoverFull(tile: BlockEntity, node: Graph6Node<IMatterGraphNode>) {
|
||||||
|
if (tile.level !is ServerLevel)
|
||||||
|
return
|
||||||
|
|
||||||
|
return discoverFull(
|
||||||
|
tile.level!! as ServerLevel,
|
||||||
|
tile.blockPos,
|
||||||
|
node,
|
||||||
|
fun(_tile): Graph6Node<IMatterGraphNode>? {
|
||||||
|
val resolve = _tile.getCapability(MatteryCapability.MATTER_CELL)
|
||||||
|
|
||||||
|
return if (resolve.isPresent) {
|
||||||
|
resolve.resolve().get().getAsMatterNode()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
::MatterNetworkGraph
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun discover(tile: BlockEntity, node: Graph6Node<IMatterGraphNode>): Boolean {
|
||||||
|
if (tile.level !is ServerLevel)
|
||||||
|
return false
|
||||||
|
|
||||||
|
return discover(
|
||||||
|
tile.level!! as ServerLevel,
|
||||||
|
tile.blockPos,
|
||||||
|
node,
|
||||||
|
fun(_tile): Graph6Node<IMatterGraphNode>? {
|
||||||
|
val resolve = _tile.getCapability(MatteryCapability.MATTER_CELL)
|
||||||
|
|
||||||
|
return if (resolve.isPresent) {
|
||||||
|
resolve.resolve().get().getAsMatterNode()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
::MatterNetworkGraph
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,103 +1,83 @@
|
|||||||
package ru.dbotthepony.mc.otm.menu;
|
package ru.dbotthepony.mc.otm.menu
|
||||||
|
|
||||||
import net.minecraft.world.SimpleContainer;
|
import net.minecraft.world.SimpleContainer
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.inventory.ContainerData;
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.ItemStack;
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterBottler
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterBottler;
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
import ru.dbotthepony.mc.otm.menu.data.BooleanDataContainer
|
||||||
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
|
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot
|
||||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget;
|
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
||||||
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget;
|
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
|
||||||
import ru.dbotthepony.mc.otm.network.MatterBottlerSwitchPacket;
|
import ru.dbotthepony.mc.otm.network.MatterBottlerSwitchPacket
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
|
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||||
import ru.dbotthepony.mc.otm.client.screen.UVWindingOrder;
|
|
||||||
|
|
||||||
public class MatterBottlerMenu extends PoweredMatteryMenu {
|
class MatterBottlerMenu @JvmOverloads constructor(
|
||||||
public MatterBottlerMenu(int p_38852_, Inventory inventory) {
|
p_38852_: Int,
|
||||||
this(p_38852_, inventory, null);
|
inventory: Inventory,
|
||||||
}
|
tile: BlockEntityMatterBottler? = null
|
||||||
|
) : PoweredMatteryMenu(
|
||||||
|
Registry.Menus.MATTER_BOTTLER, p_38852_, inventory, tile
|
||||||
|
) {
|
||||||
|
var workFlow = BooleanDataContainer()
|
||||||
|
|
||||||
public ContainerData work_flow = new ContainerData() {
|
val progressWidget: ProgressGaugeWidget
|
||||||
private int value;
|
val matterWidget: LevelGaugeWidget
|
||||||
|
val container = arrayOfNulls<MatterySlot>(6)
|
||||||
|
|
||||||
@Override
|
init {
|
||||||
public int get(int i) {
|
val container = tile?.container ?: SimpleContainer(6)
|
||||||
if (tile != null) {
|
|
||||||
return ((BlockEntityMatterBottler) tile).getWorkFlow() ? 1 : 0;
|
if (tile == null) {
|
||||||
|
progressWidget = ProgressGaugeWidget(this)
|
||||||
|
matterWidget = LevelGaugeWidget(this)
|
||||||
|
} else {
|
||||||
|
progressWidget = ProgressGaugeWidget(this) { tile.getWorkProgress() }
|
||||||
|
matterWidget = LevelGaugeWidget(this, tile.matter)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 0 until container.containerSize) {
|
||||||
|
this.container[i] = object : MatterySlot(container, i) {
|
||||||
|
override fun mayPlace(p_40231_: ItemStack): Boolean {
|
||||||
|
val cap = p_40231_.getCapability(MatteryCapability.MATTER).resolve()
|
||||||
|
if (!cap.isPresent) return false
|
||||||
|
|
||||||
|
if (workFlow.value) {
|
||||||
|
return index < 3 && cap.get().direction != IMatterHandler.MatterDirection.EXTRACT
|
||||||
|
} else {
|
||||||
|
return index >= 3 && cap.get().direction != IMatterHandler.MatterDirection.RECEIVE
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
addSlot(this.container[i]!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
addDataSlots(workFlow)
|
||||||
public void set(int i, int i1) {
|
addBatterySlot()
|
||||||
value = i1;
|
addInventorySlots()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun broadcastChanges() {
|
||||||
public int getCount() {
|
super.broadcastChanges()
|
||||||
return 1;
|
workFlow.value = (tile as BlockEntityMatterBottler).workFlow
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
public ProgressGaugeWidget progress;
|
override fun getWorkingSlotStart(): Int {
|
||||||
public LevelGaugeWidget matter_widget;
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
public MatterySlot[] work_slots = new MatterySlot[6];
|
override fun getWorkingSlotEnd(): Int {
|
||||||
|
return 7
|
||||||
public MatterBottlerMenu(int p_38852_, Inventory inventory, BlockEntityMatterBottler tile) {
|
}
|
||||||
super(Registry.Menus.MATTER_BOTTLER, p_38852_, inventory, tile);
|
|
||||||
|
|
||||||
var container = tile != null ? tile.work_slots : new SimpleContainer(6);
|
|
||||||
|
|
||||||
|
fun switchBottlerMode() {
|
||||||
if (tile == null) {
|
if (tile == null) {
|
||||||
progress = new ProgressGaugeWidget(this);
|
MatteryNetworking.CHANNEL.sendToServer(MatterBottlerSwitchPacket())
|
||||||
matter_widget = new LevelGaugeWidget(this);
|
|
||||||
} else {
|
} else {
|
||||||
progress = new ProgressGaugeWidget(this, tile::getWorkProgress);
|
(tile as BlockEntityMatterBottler).switchWorkFlow()
|
||||||
matter_widget = new LevelGaugeWidget(this, tile.matter);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < container.getContainerSize(); i++) {
|
|
||||||
work_slots[i] = new MatterySlot(container, i) {
|
|
||||||
@Override
|
|
||||||
public boolean mayPlace(ItemStack p_40231_) {
|
|
||||||
var cap = p_40231_.getCapability(MatteryCapability.MATTER).resolve();
|
|
||||||
|
|
||||||
if (work_flow.get(0) > 0) {
|
|
||||||
return index < 3 && cap.isPresent() && cap.get().getDirection() != IMatterHandler.MatterDirection.EXTRACT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return index >= 3 && cap.isPresent() && cap.get().getDirection() != IMatterHandler.MatterDirection.RECEIVE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
addSlot(work_slots[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
addDataSlots(work_flow);
|
|
||||||
addBatterySlot();
|
|
||||||
addInventorySlots();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getWorkingSlotStart() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getWorkingSlotEnd() {
|
|
||||||
return 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void switchBottlerMode() {
|
|
||||||
if (tile == null) {
|
|
||||||
MatteryNetworking.CHANNEL.sendToServer(new MatterBottlerSwitchPacket());
|
|
||||||
} else {
|
|
||||||
((BlockEntityMatterBottler) tile).switchWorkFlow();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,69 +1,63 @@
|
|||||||
package ru.dbotthepony.mc.otm.menu;
|
package ru.dbotthepony.mc.otm.menu
|
||||||
|
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.SimpleContainer
|
||||||
import net.minecraft.world.SimpleContainer;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCapacitorBank
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCapacitorBank;
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.menu.slot.MatterContainerInputSlot;
|
import ru.dbotthepony.mc.otm.menu.slot.MatterContainerInputSlot
|
||||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget;
|
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
class MatterCapacitorBankMenu @JvmOverloads constructor(
|
||||||
|
p_38852_: Int,
|
||||||
public class MatterCapacitorBankMenu extends MatteryMenu {
|
inventory: Inventory?,
|
||||||
public MatterCapacitorBankMenu(int p_38852_, Inventory inventory) {
|
tile: BlockEntityMatterCapacitorBank? = null
|
||||||
this(p_38852_, inventory, null);
|
) : MatteryMenu(
|
||||||
}
|
Registry.Menus.MATTER_CAPACITOR_BANK, p_38852_, inventory!!, tile
|
||||||
|
) {
|
||||||
public LevelGaugeWidget matter_widget;
|
val matter_widget: LevelGaugeWidget
|
||||||
public LevelGaugeWidget total_matter_widget;
|
val total_matter_widget: LevelGaugeWidget
|
||||||
|
val container_slots = arrayOfNulls<MatterContainerInputSlot>(2 * 6)
|
||||||
public MatterContainerInputSlot[] container_slots = new MatterContainerInputSlot[2 * 6];
|
|
||||||
|
|
||||||
public MatterCapacitorBankMenu(int p_38852_, Inventory inventory, BlockEntityMatterCapacitorBank tile) {
|
|
||||||
super(Registry.Menus.MATTER_CAPACITOR_BANK, p_38852_, inventory, tile);
|
|
||||||
|
|
||||||
|
init {
|
||||||
if (tile == null) {
|
if (tile == null) {
|
||||||
matter_widget = new LevelGaugeWidget(this);
|
matter_widget = LevelGaugeWidget(this)
|
||||||
total_matter_widget = new LevelGaugeWidget(this);
|
total_matter_widget = LevelGaugeWidget(this)
|
||||||
} else {
|
} else {
|
||||||
matter_widget = new LevelGaugeWidget(this, tile.matter);
|
matter_widget = LevelGaugeWidget(this, tile)
|
||||||
total_matter_widget = new LevelGaugeWidget(this, () -> {
|
total_matter_widget = LevelGaugeWidget(this, {
|
||||||
if (tile.getMatterGrid() != null) {
|
(tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getMatterStorageLevel() ?: Fraction.ZERO
|
||||||
return tile.getMatterGrid().getStored();
|
}, {
|
||||||
}
|
(tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getMatterStorageMaxLevel() ?: Fraction.ZERO
|
||||||
|
})
|
||||||
return Fraction.ZERO;
|
|
||||||
}, () -> {
|
|
||||||
if (tile.getMatterGrid() != null) {
|
|
||||||
return tile.getMatterGrid().getCapacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Fraction.ZERO;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Container container = tile != null ? tile.matter_container : new SimpleContainer(2 * 6);
|
val container = tile?.matterContainer ?: SimpleContainer(2 * 6)
|
||||||
|
|
||||||
for (int row = 0; row < 2; row++){
|
for (row in 0..1) {
|
||||||
for (int column = 0; column < 6; column++) {
|
for (column in 0..5) {
|
||||||
container_slots[row * 6 + column] = new MatterContainerInputSlot(container, row * 6 + column, 44 + column * 18, 20 + row * 18, true, IMatterHandler.MatterDirection.BIDIRECTIONAL);
|
container_slots[row * 6 + column] = MatterContainerInputSlot(
|
||||||
addSlot(container_slots[row * 6 + column]);
|
container,
|
||||||
|
row * 6 + column,
|
||||||
|
44 + column * 18,
|
||||||
|
20 + row * 18,
|
||||||
|
true,
|
||||||
|
IMatterHandler.MatterDirection.BIDIRECTIONAL
|
||||||
|
)
|
||||||
|
|
||||||
|
addSlot(container_slots[row * 6 + column]!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addInventorySlots()
|
||||||
addInventorySlots();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getWorkingSlotStart(): Int {
|
||||||
protected int getWorkingSlotStart() {
|
return 0
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getWorkingSlotEnd(): Int {
|
||||||
protected int getWorkingSlotEnd() {
|
return 2 * 6
|
||||||
return 2 * 6;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,214 +1,186 @@
|
|||||||
package ru.dbotthepony.mc.otm.menu;
|
package ru.dbotthepony.mc.otm.menu
|
||||||
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer
|
||||||
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.minecraftforge.network.PacketDistributor;
|
import net.minecraftforge.network.PacketDistributor
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterPanel;
|
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterPanel
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridListener;
|
import ru.dbotthepony.mc.otm.capability.matter.MatterTask
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterTask;
|
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.PatternState;
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.network.CancelMatterTaskPacket;
|
import ru.dbotthepony.mc.otm.network.CancelMatterTaskPacket
|
||||||
import ru.dbotthepony.mc.otm.network.MatterTaskPacket;
|
import ru.dbotthepony.mc.otm.network.MatterTaskPacket
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
|
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||||
import ru.dbotthepony.mc.otm.network.PatternGridPacket;
|
import ru.dbotthepony.mc.otm.network.PatternGridPacket
|
||||||
|
import java.util.*
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
import java.util.ArrayList;
|
class MatterPanelMenu @JvmOverloads constructor(
|
||||||
import java.util.UUID;
|
p_38852_: Int,
|
||||||
import java.util.function.Consumer;
|
inventory: Inventory,
|
||||||
|
tile: BlockEntityMatterPanel? = null
|
||||||
public class MatterPanelMenu extends MatteryMenu implements IMatterGridListener {
|
) : MatteryMenu(Registry.Menus.MATTER_PANEL, p_38852_, inventory, tile), IMatterGraphListener {
|
||||||
public MatterPanelMenu(int p_38852_, Inventory inventory) {
|
fun taskUpdated(task: MatterTask) {
|
||||||
this(p_38852_, inventory, null);
|
sendNetwork(MatterTaskPacket(true, listOf(task)))
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockEntityMatterPanel tile;
|
fun taskRemoved(task: MatterTask) {
|
||||||
private MatterGrid grid;
|
sendNetwork(MatterTaskPacket(false, listOf(task)))
|
||||||
|
|
||||||
public MatterPanelMenu(int p_38852_, Inventory inventory, BlockEntityMatterPanel tile) {
|
|
||||||
super(Registry.Menus.MATTER_PANEL, p_38852_, inventory, tile);
|
|
||||||
this.tile = tile;
|
|
||||||
|
|
||||||
if (tile != null) {
|
|
||||||
grid = tile.getMatterGrid();
|
|
||||||
tile.attachMenu(this);
|
|
||||||
|
|
||||||
if (grid != null) {
|
|
||||||
grid.attach(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void taskUpdated(MatterTask task) {
|
|
||||||
sendNetwork(new MatterTaskPacket(true, task));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void taskRemoved(MatterTask task) {
|
|
||||||
sendNetwork(new MatterTaskPacket(false, task));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// client code
|
// client code
|
||||||
public ArrayList<PatternState> patterns = new ArrayList<>();
|
@JvmField
|
||||||
public ArrayList<MatterTask> tasks = new ArrayList<>();
|
var patterns = ArrayList<PatternState>()
|
||||||
public int changeset = 0;
|
|
||||||
|
|
||||||
public void networkPatternsUpdated(PatternState[] patterns) {
|
@JvmField
|
||||||
changeset++;
|
var tasks = ArrayList<MatterTask>()
|
||||||
|
|
||||||
for (var pattern : patterns) {
|
var changeset = 0
|
||||||
var index_of = this.patterns.indexOf(pattern);
|
|
||||||
|
|
||||||
if (index_of != -1) {
|
fun networkPatternsUpdated(patterns: Collection<PatternState>) {
|
||||||
this.patterns.set(index_of, pattern);
|
changeset++
|
||||||
|
|
||||||
|
for (pattern in patterns) {
|
||||||
|
val index = this.patterns.indexOf(pattern)
|
||||||
|
|
||||||
|
if (index != -1) {
|
||||||
|
this.patterns[index] = pattern
|
||||||
} else {
|
} else {
|
||||||
this.patterns.add(pattern);
|
this.patterns.add(pattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void networkPatternsRemoved(PatternState[] patterns) {
|
fun networkPatternsRemoved(patterns: Collection<PatternState>) {
|
||||||
changeset++;
|
changeset++
|
||||||
|
|
||||||
for (var pattern : patterns) {
|
for (pattern in patterns) {
|
||||||
this.patterns.remove(pattern);
|
this.patterns.remove(pattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void networkTasksUpdated(MatterTask[] tasks) {
|
fun networkTasksUpdated(tasks: Collection<MatterTask>) {
|
||||||
changeset++;
|
changeset++
|
||||||
|
|
||||||
for (var task : tasks) {
|
for (task in tasks) {
|
||||||
var index_of = this.tasks.indexOf(task);
|
val index = this.tasks.indexOf(task)
|
||||||
|
|
||||||
if (index_of != -1) {
|
if (index != -1) {
|
||||||
this.tasks.set(index_of, task);
|
this.tasks[index] = task
|
||||||
} else {
|
} else {
|
||||||
this.tasks.add(task);
|
this.tasks.add(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watcher_update != null)
|
watcher_update?.accept(task)
|
||||||
watcher_update.accept(task);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void networkTasksRemoved(MatterTask[] tasks) {
|
fun networkTasksRemoved(tasks: Collection<MatterTask>) {
|
||||||
changeset++;
|
changeset++
|
||||||
|
|
||||||
for (var task : tasks) {
|
for (task in tasks) {
|
||||||
this.tasks.remove(task);
|
this.tasks.remove(task)
|
||||||
|
watcher_delete?.accept(task)
|
||||||
if (watcher_delete != null)
|
|
||||||
watcher_delete.accept(task);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Consumer<MatterTask> watcher_delete;
|
private var watcher_delete: Consumer<MatterTask>? = null
|
||||||
private Consumer<MatterTask> watcher_update;
|
private var watcher_update: Consumer<MatterTask>? = null
|
||||||
|
|
||||||
public void networkTaskWatcher(Consumer<MatterTask> watcher_update, Consumer<MatterTask> watcher_delete) {
|
fun networkTaskWatcher(watcher_update: Consumer<MatterTask>, watcher_delete: Consumer<MatterTask>) {
|
||||||
this.watcher_delete = watcher_delete;
|
this.watcher_delete = watcher_delete
|
||||||
this.watcher_update = watcher_update;
|
this.watcher_update = watcher_update
|
||||||
}
|
}
|
||||||
|
|
||||||
// server code
|
// server code
|
||||||
public void requestReplication(ServerPlayer ply, PatternState state, int how_much) {
|
fun requestReplication(ply: ServerPlayer, state: PatternState, how_much: Int) {
|
||||||
if (tile == null)
|
val tile = tile as BlockEntityMatterPanel? ?: return
|
||||||
return;
|
|
||||||
|
|
||||||
var grid = tile.getMatterGrid();
|
val graph = tile.getAsMatterNode().graph as MatterNetworkGraph? ?: return
|
||||||
|
|
||||||
if (grid == null)
|
if (graph.getPattern(state) == null) {
|
||||||
return;
|
OverdriveThatMatters.LOGGER.error("Received replication request from {} of {}, but it is no longer in grid", ply, state)
|
||||||
|
return
|
||||||
var get_pattern = grid.getPattern(state);
|
|
||||||
|
|
||||||
if (get_pattern == null) {
|
|
||||||
OverdriveThatMatters.LOGGER.error("Received replication request from {} of {}, but it is no longer in grid", ply, state);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.addTask(state, how_much);
|
tile.addTask(state, how_much)
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveTaskCancel(ServerPlayer ply, UUID id) {
|
fun receiveTaskCancel(ply: ServerPlayer, id: UUID) {
|
||||||
if (tile == null)
|
(tile as BlockEntityMatterPanel?)?.removeTask(id)
|
||||||
return;
|
|
||||||
|
|
||||||
tile.removeTask(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestTaskCancel(UUID id) {
|
fun requestTaskCancel(id: UUID) {
|
||||||
MatteryNetworking.CHANNEL.sendToServer(new CancelMatterTaskPacket(id));
|
MatteryNetworking.CHANNEL.sendToServer(CancelMatterTaskPacket(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onPatternAdded(state: PatternState) {
|
||||||
public void onPatternAdded(PatternState state) {
|
sendNetwork(PatternGridPacket(true, listOf(state)))
|
||||||
sendNetwork(new PatternGridPacket(true, state));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onPatternRemoved(state: PatternState) {
|
||||||
public void onPatternRemoved(PatternState state) {
|
sendNetwork(PatternGridPacket(false, listOf(state)))
|
||||||
sendNetwork(new PatternGridPacket(false, state));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {
|
||||||
public void onPatternUpdated(PatternState new_state, PatternState old_state) {
|
sendNetwork(PatternGridPacket(true, listOf(new_state)))
|
||||||
sendNetwork(new PatternGridPacket(true, new_state));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean initial_send = false;
|
private var initial_send = false
|
||||||
|
|
||||||
@Override
|
private var listeningGrid: MatterNetworkGraph? = null
|
||||||
public void removed(Player p_38940_) {
|
|
||||||
super.removed(p_38940_);
|
|
||||||
|
|
||||||
if (tile != null)
|
init {
|
||||||
tile.deatachMenu(this);
|
if (tile != null) {
|
||||||
|
listeningGrid = tile.getAsMatterNode().graph as MatterNetworkGraph?
|
||||||
if (grid != null)
|
tile.attachMenu(this)
|
||||||
grid.detach(this);
|
listeningGrid?.addListener(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun removed(p_38940_: Player) {
|
||||||
public void broadcastChanges() {
|
super.removed(p_38940_)
|
||||||
super.broadcastChanges();
|
(tile as BlockEntityMatterPanel?)?.deatachMenu(this)
|
||||||
|
listeningGrid?.removeListener(this)
|
||||||
if (!initial_send)
|
|
||||||
fullPatternBroadcast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendNetwork(Object packet) {
|
override fun broadcastChanges() {
|
||||||
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) inventory.player), packet);
|
super.broadcastChanges()
|
||||||
|
if (!initial_send) fullPatternBroadcast()
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fullPatternBroadcast() {
|
private fun sendNetwork(packet: Any) {
|
||||||
|
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with { inventory.player as ServerPlayer }, packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fullPatternBroadcast() {
|
||||||
if (inventory.player.level.isClientSide) {
|
if (inventory.player.level.isClientSide) {
|
||||||
initial_send = true;
|
initial_send = true
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val tile = tile as BlockEntityMatterPanel?
|
||||||
|
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
var grid = tile.getMatterGrid();
|
val grid = tile.getAsMatterNode().graph as MatterNetworkGraph?
|
||||||
|
|
||||||
if (grid != null) {
|
if (grid != null) {
|
||||||
initial_send = true;
|
initial_send = true
|
||||||
sendNetwork(new PatternGridPacket(true, grid.getStoredPatterns().toArray(new PatternState[0])));
|
sendNetwork(PatternGridPacket(true, grid.getStoredPatterns()))
|
||||||
}
|
}
|
||||||
|
|
||||||
sendNetwork(new MatterTaskPacket(true, tile.getAllTasks().toArray(new MatterTask[0])));
|
sendNetwork(MatterTaskPacket(true, tile.allTasks))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getWorkingSlotStart(): Int {
|
||||||
protected int getWorkingSlotStart() {
|
return 0
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getWorkingSlotEnd(): Int {
|
||||||
protected int getWorkingSlotEnd() {
|
return 0
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -11,6 +11,7 @@ import net.minecraft.world.SimpleContainer
|
|||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import ru.dbotthepony.mc.otm.Registry
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.matter.MatterRegistry
|
import ru.dbotthepony.mc.otm.matter.MatterRegistry
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
|
|
||||||
@ -38,8 +39,8 @@ class MatterScannerMenu @JvmOverloads constructor(
|
|||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }) { tile.cantProcessJob() }
|
progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }) { tile.cantProcessJob() }
|
||||||
patterns = LevelGaugeWidget(this,
|
patterns = LevelGaugeWidget(this,
|
||||||
{ Fraction(tile.matterGrid?.storedPatternCount?.toBigInteger() ?: BigInteger.ZERO) },
|
{ Fraction(tile.getAsMatterGraph()?.getPatternCount()?.toBigInteger() ?: BigInteger.ZERO) },
|
||||||
{ Fraction(tile.matterGrid?.patternCapacity?.toBigInteger() ?: BigInteger.ZERO) })
|
{ Fraction(tile.getAsMatterGraph()?.getPatternCapacity()?.toBigInteger() ?: BigInteger.ZERO) })
|
||||||
} else {
|
} else {
|
||||||
progress = ProgressGaugeWidget(this)
|
progress = ProgressGaugeWidget(this)
|
||||||
patterns = LevelGaugeWidget(this)
|
patterns = LevelGaugeWidget(this)
|
||||||
|
@ -1,66 +1,55 @@
|
|||||||
package ru.dbotthepony.mc.otm.menu;
|
package ru.dbotthepony.mc.otm.menu
|
||||||
|
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.SimpleContainer
|
||||||
import net.minecraft.world.SimpleContainer;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.Registry;
|
import ru.dbotthepony.mc.otm.block.entity.BlockEntityPatternStorage
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityPatternStorage;
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.menu.slot.PatternSlot;
|
import ru.dbotthepony.mc.otm.menu.slot.PatternSlot
|
||||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget;
|
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
||||||
|
|
||||||
public class PatternStorageMenu extends MatteryMenu {
|
class PatternStorageMenu @JvmOverloads constructor(
|
||||||
public PatternStorageMenu(int p_38852_, Inventory inventory) {
|
p_38852_: Int,
|
||||||
this(p_38852_, inventory, null);
|
inventory: Inventory?,
|
||||||
}
|
tile: BlockEntityPatternStorage? = null
|
||||||
|
) : MatteryMenu(
|
||||||
public PatternSlot[] pattern_slots = new PatternSlot[2 * 4];
|
Registry.Menus.PATTERN_STORAGE, p_38852_, inventory!!, tile
|
||||||
|
) {
|
||||||
public LevelGaugeWidget stored_this;
|
val pattern_slots = arrayOfNulls<PatternSlot>(2 * 4)
|
||||||
public LevelGaugeWidget stored_grid;
|
val stored_this: LevelGaugeWidget
|
||||||
|
val stored_grid: LevelGaugeWidget
|
||||||
public PatternStorageMenu(int p_38852_, Inventory inventory, BlockEntityPatternStorage tile) {
|
|
||||||
super(Registry.Menus.PATTERN_STORAGE, p_38852_, inventory, tile);
|
|
||||||
|
|
||||||
|
init {
|
||||||
if (tile == null) {
|
if (tile == null) {
|
||||||
stored_this = new LevelGaugeWidget(this);
|
stored_this = LevelGaugeWidget(this)
|
||||||
stored_grid = new LevelGaugeWidget(this);
|
stored_grid = LevelGaugeWidget(this)
|
||||||
} else {
|
} else {
|
||||||
stored_this = new LevelGaugeWidget(this, tile.getPatternStorage());
|
stored_this = LevelGaugeWidget(this, tile)
|
||||||
stored_grid = new LevelGaugeWidget(this, () -> {
|
stored_grid = LevelGaugeWidget(this, {
|
||||||
if (tile.getMatterGrid() != null) {
|
Fraction((tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getPatternCount() ?: 0)
|
||||||
return new Fraction(tile.getMatterGrid().getStoredPatternCount());
|
}, {
|
||||||
}
|
Fraction((tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getPatternCapacity() ?: 0)
|
||||||
|
})
|
||||||
return Fraction.ZERO;
|
|
||||||
}, () -> {
|
|
||||||
if (tile.getMatterGrid() != null) {
|
|
||||||
return new Fraction(tile.getMatterGrid().getPatternCapacity());
|
|
||||||
}
|
|
||||||
|
|
||||||
return Fraction.ZERO;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Container patterns = tile != null ? tile.patterns : new SimpleContainer(2 * 4);
|
val patterns = tile?.patterns ?: SimpleContainer(2 * 4)
|
||||||
|
|
||||||
for (int row = 0; row < 2; row++) {
|
for (row in 0..1) {
|
||||||
for (int column = 0; column < 4; column++) {
|
for (column in 0..3) {
|
||||||
pattern_slots[row * 4 + column] = new PatternSlot(patterns, row * 4 + column, 48 + column * 20, 27 + row * 24);
|
pattern_slots[row * 4 + column] = PatternSlot(patterns, row * 4 + column, 48 + column * 20, 27 + row * 24)
|
||||||
addSlot(pattern_slots[row * 4 + column]);
|
addSlot(pattern_slots[row * 4 + column]!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addInventorySlots();
|
addInventorySlots()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getWorkingSlotStart(): Int {
|
||||||
protected int getWorkingSlotStart() {
|
return 0
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getWorkingSlotEnd(): Int {
|
||||||
protected int getWorkingSlotEnd() {
|
return 2 * 4
|
||||||
return 2 * 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,26 +1,47 @@
|
|||||||
package ru.dbotthepony.mc.otm.menu.data
|
package ru.dbotthepony.mc.otm.menu.data
|
||||||
|
|
||||||
import net.minecraft.world.inventory.ContainerData
|
import net.minecraft.world.inventory.ContainerData
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
import ru.dbotthepony.mc.otm.network.NetworkHelper
|
import ru.dbotthepony.mc.otm.network.NetworkHelper
|
||||||
|
import java.util.zip.CRC32
|
||||||
|
|
||||||
class FractionDataContainer : ContainerData {
|
class FractionDataContainer : ContainerData {
|
||||||
companion object {
|
companion object {
|
||||||
const val NETWORK_PAYLOAD_SIZE = 32
|
// CRC32 + Данные
|
||||||
|
const val NETWORK_PAYLOAD_SIZE = 64 + 2
|
||||||
|
private val LOGGER = LogManager.getLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var _value: Fraction? = Fraction.ZERO
|
private var _value: Fraction? = Fraction.ZERO
|
||||||
|
private var _value2: Fraction? = Fraction.ZERO
|
||||||
|
|
||||||
fun hasComputedValue(): Boolean {
|
fun hasComputedValue(): Boolean {
|
||||||
return _value != null
|
return _value != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var mute = false
|
||||||
|
|
||||||
var value: Fraction
|
var value: Fraction
|
||||||
get() {
|
get() {
|
||||||
if (_value != null)
|
if (_value != null)
|
||||||
return _value!!
|
return _value!!
|
||||||
|
|
||||||
_value = Fraction.fromByteArray(NetworkHelper.shortsToBytes(buffer))
|
val bytes = NetworkHelper.shortsToBytes(buffer, 2)
|
||||||
|
|
||||||
|
val crc = CRC32()
|
||||||
|
crc.update(bytes)
|
||||||
|
val crcValue = crc.value
|
||||||
|
|
||||||
|
val a = (crcValue and 0xFFFF).toShort()
|
||||||
|
val b = ((crcValue and 0xFFFF0000) ushr 16).toShort()
|
||||||
|
|
||||||
|
if (a == buffer[0] && b == buffer[1]) {
|
||||||
|
_value = Fraction.fromByteArray(bytes)
|
||||||
|
} else {
|
||||||
|
_value = _value2
|
||||||
|
}
|
||||||
|
|
||||||
return _value!!
|
return _value!!
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
@ -31,7 +52,28 @@ class FractionDataContainer : ContainerData {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkHelper.bytesToShorts(_value!!.toByteArray()).copyInto(buffer)
|
try {
|
||||||
|
val bytes = ByteArray(128) {0}
|
||||||
|
_value!!.toByteArray().copyInto(bytes)
|
||||||
|
|
||||||
|
val crc = CRC32()
|
||||||
|
crc.update(bytes)
|
||||||
|
val crcValue = crc.value
|
||||||
|
|
||||||
|
val a = (crcValue and 0xFFFF).toShort()
|
||||||
|
val b = ((crcValue and 0xFFFF0000) ushr 16).toShort()
|
||||||
|
buffer[0] = a
|
||||||
|
buffer[1] = b
|
||||||
|
|
||||||
|
NetworkHelper.bytesToShorts(bytes).copyInto(buffer, destinationOffset = 2)
|
||||||
|
} catch(err: Throwable) {
|
||||||
|
if (!mute) {
|
||||||
|
LOGGER.error("Unable to serialize value $value for network transportation", err)
|
||||||
|
mute = true
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.fill(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val buffer = ShortArray(NETWORK_PAYLOAD_SIZE)
|
val buffer = ShortArray(NETWORK_PAYLOAD_SIZE)
|
||||||
@ -42,6 +84,7 @@ class FractionDataContainer : ContainerData {
|
|||||||
|
|
||||||
override operator fun set(p_39285_: Int, p_39286_: Int) {
|
override operator fun set(p_39285_: Int, p_39286_: Int) {
|
||||||
buffer[p_39285_] = p_39286_.toShort()
|
buffer[p_39285_] = p_39286_.toShort()
|
||||||
|
if (_value != null) _value2 = _value
|
||||||
_value = null
|
_value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,10 @@ import org.junit.jupiter.api.DisplayName
|
|||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
|
import java.lang.Math.floor
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
object FractionTests {
|
object FractionTests {
|
||||||
@Test
|
@Test
|
||||||
@ -113,12 +115,121 @@ object FractionTests {
|
|||||||
fun math() {
|
fun math() {
|
||||||
assert((Fraction(1) / Fraction(1)) == Fraction(1))
|
assert((Fraction(1) / Fraction(1)) == Fraction(1))
|
||||||
assert((Fraction(2) / Fraction(1)) == Fraction(2, 1))
|
assert((Fraction(2) / Fraction(1)) == Fraction(2, 1))
|
||||||
assert((Fraction(2) / Fraction(2)) == Fraction(1))
|
assert((Fraction(2) / Fraction(2)) == Fraction(1)) { Fraction(2) / Fraction(2) }
|
||||||
|
|
||||||
assert((Fraction(4, 3) / Fraction(5, 4)) == (Fraction(4, 3) * Fraction(4, 5)))
|
assert((Fraction(4, 3) / Fraction(5, 4)) == (Fraction(4, 3) * Fraction(4, 5)))
|
||||||
assert((Fraction(4, 3) + Fraction(5, 4)) == Fraction(31, 12))
|
assert((Fraction(4, 3) + Fraction(5, 4)) == Fraction(31, 12))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Fraction compacting")
|
||||||
|
fun compacting() {
|
||||||
|
val frac = Fraction("2721280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "25600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
||||||
|
|
||||||
|
println("Compacting $frac => ${frac + Fraction.ZERO}")
|
||||||
|
}
|
||||||
|
|
||||||
|
private val samples = arrayOf(
|
||||||
|
Fraction(9475, 4729),
|
||||||
|
Fraction(23535, 58723),
|
||||||
|
Fraction(-4852, 6859),
|
||||||
|
Fraction(-45623, -76849),
|
||||||
|
Fraction(38494, -76849),
|
||||||
|
Fraction(1043, -648),
|
||||||
|
)
|
||||||
|
|
||||||
|
private val samples2 = arrayOf(
|
||||||
|
(9475.0 / 4729),
|
||||||
|
(23535.0 / 58723),
|
||||||
|
(-4852.0 / 6859),
|
||||||
|
(-45623.0 / -76849),
|
||||||
|
(38494.0 / -76849),
|
||||||
|
(1043.0 / -648),
|
||||||
|
)
|
||||||
|
|
||||||
|
private val samples3 = arrayOf(
|
||||||
|
BigDecimal((9475.0 / 4729).toString()),
|
||||||
|
BigDecimal((23535.0 / 58723).toString()),
|
||||||
|
BigDecimal((-4852.0 / 6859).toString()),
|
||||||
|
BigDecimal((-45623.0 / -76849).toString()),
|
||||||
|
BigDecimal((38494.0 / -76849).toString()),
|
||||||
|
BigDecimal((1043.0 / -648).toString()),
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Fraction performance measurement")
|
||||||
|
fun performance() {
|
||||||
|
val rand = java.util.Random()
|
||||||
|
val blackHole = arrayOfNulls<Fraction>(100_000)
|
||||||
|
val size = samples.size
|
||||||
|
var time = System.currentTimeMillis()
|
||||||
|
|
||||||
|
for (i in 0 until 100_000) {
|
||||||
|
when (rand.nextInt(3)) {
|
||||||
|
0 -> blackHole[i] = samples[rand.nextInt(size)] + samples[rand.nextInt(size)]
|
||||||
|
1 -> blackHole[i] = samples[rand.nextInt(size)] - samples[rand.nextInt(size)]
|
||||||
|
2 -> blackHole[i] = samples[rand.nextInt(size)] * samples[rand.nextInt(size)]
|
||||||
|
// 3 -> blackHole[i] = samples[rand.nextInt(size)] / samples[rand.nextInt(size)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Mean time for Fraction operation is ~${System.currentTimeMillis() - time} ms per 100,000 ops")
|
||||||
|
|
||||||
|
var sum = Fraction.ZERO
|
||||||
|
|
||||||
|
// перемешаем чтоб оптимизатор не отбросил
|
||||||
|
for (i in 0 until size) {
|
||||||
|
sum += blackHole[i]!!
|
||||||
|
blackHole[i] = blackHole[rand.nextInt(size)]
|
||||||
|
}
|
||||||
|
|
||||||
|
val blackHole2 = arrayOfNulls<Double>(100_000)
|
||||||
|
time = System.currentTimeMillis()
|
||||||
|
|
||||||
|
for (i in 0 until 100_000) {
|
||||||
|
when (rand.nextInt(3)) {
|
||||||
|
0 -> blackHole2[i] = samples2[rand.nextInt(size)] + samples2[rand.nextInt(size)]
|
||||||
|
1 -> blackHole2[i] = samples2[rand.nextInt(size)] - samples2[rand.nextInt(size)]
|
||||||
|
2 -> blackHole2[i] = samples2[rand.nextInt(size)] * samples2[rand.nextInt(size)]
|
||||||
|
// 3 -> blackHole2[i] = samples2[rand.nextInt(size)] / samples2[rand.nextInt(size)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Mean time for Double operation is ~${System.currentTimeMillis() - time} ms per 100,000 ops")
|
||||||
|
|
||||||
|
val blackHole3 = arrayOfNulls<BigDecimal>(100_000)
|
||||||
|
time = System.currentTimeMillis()
|
||||||
|
|
||||||
|
for (i in 0 until 100_000) {
|
||||||
|
when (rand.nextInt(3)) {
|
||||||
|
0 -> blackHole3[i] = samples3[rand.nextInt(size)] + samples3[rand.nextInt(size)]
|
||||||
|
1 -> blackHole3[i] = samples3[rand.nextInt(size)] - samples3[rand.nextInt(size)]
|
||||||
|
2 -> blackHole3[i] = samples3[rand.nextInt(size)] * samples3[rand.nextInt(size)]
|
||||||
|
// 3 -> blackHole2[i] = samples2[rand.nextInt(size)] / samples2[rand.nextInt(size)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Mean time for BigDecimal operation is ~${System.currentTimeMillis() - time} ms per 100,000 ops")
|
||||||
|
|
||||||
|
var sum2 = 0.0
|
||||||
|
|
||||||
|
// перемешаем чтоб оптимизатор не отбросил
|
||||||
|
for (i in 0 until size) {
|
||||||
|
sum2 += blackHole2[i]!!
|
||||||
|
blackHole2[i] = blackHole2[rand.nextInt(size)]
|
||||||
|
}
|
||||||
|
|
||||||
|
var sum3 = 0.0
|
||||||
|
|
||||||
|
// перемешаем чтоб оптимизатор не отбросил
|
||||||
|
for (i in 0 until size) {
|
||||||
|
sum3 += blackHole2[i]!!
|
||||||
|
blackHole3[i] = blackHole3[rand.nextInt(size)]
|
||||||
|
}
|
||||||
|
|
||||||
|
println("$sum $sum2 $sum3")
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Fraction serialization test")
|
@DisplayName("Fraction serialization test")
|
||||||
fun serialization() {
|
fun serialization() {
|
||||||
@ -146,6 +257,26 @@ object FractionTests {
|
|||||||
serialized = value.serializeNBT()
|
serialized = value.serializeNBT()
|
||||||
|
|
||||||
assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0)
|
assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0)
|
||||||
|
|
||||||
|
value = Fraction("320", "100")
|
||||||
|
serialized = value.serializeNBT()
|
||||||
|
assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0)
|
||||||
|
|
||||||
|
value = Fraction("324", "100")
|
||||||
|
serialized = value.serializeNBT()
|
||||||
|
assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0)
|
||||||
|
|
||||||
|
value = Fraction("328", "100")
|
||||||
|
serialized = value.serializeNBT()
|
||||||
|
assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0)
|
||||||
|
|
||||||
|
value = Fraction("332", "100")
|
||||||
|
serialized = value.serializeNBT()
|
||||||
|
assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0)
|
||||||
|
|
||||||
|
value = Fraction("336", "100")
|
||||||
|
serialized = value.serializeNBT()
|
||||||
|
assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
Reference in New Issue
Block a user