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/
|
||||
libs/
|
||||
logs/
|
||||
|
||||
# Files from Forge MDK
|
||||
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.EventHandler;
|
||||
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.network.MatteryNetworking;
|
||||
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper;
|
||||
@ -129,7 +128,6 @@ public class OverdriveThatMatters {
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
MinecraftForge.EVENT_BUS.register(AndroidCapabilityPlayer.class);
|
||||
MinecraftForge.EVENT_BUS.register(AndroidCapability.class);
|
||||
MinecraftForge.EVENT_BUS.register(MatterGrid.class);
|
||||
MinecraftForge.EVENT_BUS.register(MatterRegistry.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.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell;
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@ -172,62 +171,6 @@ public class BlockMatterCable extends Block implements EntityBlock {
|
||||
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
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
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 ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
||||
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.IMatterTaskProvider;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
||||
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.RoundingMode;
|
||||
|
||||
@ -18,7 +17,7 @@ public class MatteryCapability {
|
||||
public static final Capability<IMatteryEnergyStorage> ENERGY = 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<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<IMatterTaskProvider> TASK = 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(IAndroidCapability.class);
|
||||
event.register(IMatterHandler.class);
|
||||
event.register(IMatterGridCell.class);
|
||||
event.register(IPatternStorage.class);
|
||||
event.register(IMatterTaskProvider.class);
|
||||
event.register(IMatteryDrive.class);
|
||||
event.register(IStorageGridCell.class);
|
||||
event.register(IMatterGraphNode.class);
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
|
@ -21,7 +21,7 @@ public class MatterReplicatorMenu extends PoweredMatteryMenu {
|
||||
public MatterReplicatorMenu(int p_38852_, Inventory inventory, BlockEntityMatterReplicator 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++) {
|
||||
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 javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public record MatterTaskPacket(boolean action, MatterTask...state) {
|
||||
public record MatterTaskPacket(boolean action, Collection<MatterTask> state) {
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
buffer.writeBoolean(action);
|
||||
buffer.writeInt(state.length);
|
||||
buffer.writeInt(state.size());
|
||||
|
||||
for (var state1 : state)
|
||||
state1.write(buffer);
|
||||
@ -42,10 +44,10 @@ public record MatterTaskPacket(boolean action, MatterTask...state) {
|
||||
public static MatterTaskPacket read(FriendlyByteBuf buffer) {
|
||||
boolean action = buffer.readBoolean();
|
||||
int amount = buffer.readInt();
|
||||
var list = new MatterTask[amount];
|
||||
var list = new ArrayList<MatterTask>(amount);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -44,11 +44,17 @@ public class NetworkHelper {
|
||||
}
|
||||
|
||||
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++) {
|
||||
values[i * 2] = (byte) (input[i] & 0xFF);
|
||||
values[i * 2 + 1] = (byte) ((input[i] & 0xFF00) >> 8);
|
||||
public static byte[] shortsToBytes(short[] input, int offset) {
|
||||
byte[] values = new byte[(input.length - offset) * 2];
|
||||
|
||||
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;
|
||||
|
@ -10,14 +10,16 @@ import ru.dbotthepony.mc.otm.capability.matter.PatternState;
|
||||
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public record PatternGridPacket(boolean action, PatternState ...state) {
|
||||
public record PatternGridPacket(boolean action, Collection<PatternState> state) {
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
buffer.writeBoolean(action);
|
||||
buffer.writeInt(state.length);
|
||||
buffer.writeInt(state.size());
|
||||
|
||||
for (var state1 : state)
|
||||
state1.write(buffer);
|
||||
@ -44,10 +46,10 @@ public record PatternGridPacket(boolean action, PatternState ...state) {
|
||||
public static PatternGridPacket read(FriendlyByteBuf buffer) {
|
||||
boolean action = buffer.readBoolean();
|
||||
int amount = buffer.readInt();
|
||||
var list = new PatternState[amount];
|
||||
var list = new ArrayList<PatternState>(amount);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -44,3 +44,11 @@ fun CompoundTag.ifHas(s: String, type: Byte, consumer: (Tag) -> Unit) {
|
||||
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.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterBottler;
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable
|
||||
import net.minecraft.world.level.block.EntityBlock
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterBottler
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import ru.dbotthepony.mc.otm.Registry
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public class BlockMatterBottler extends BlockMatteryRotatable implements EntityBlock {
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return new BlockEntityMatterBottler(blockPos, blockState);
|
||||
class BlockMatterBottler : BlockMatteryRotatable(), EntityBlock {
|
||||
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
|
||||
return BlockEntityMatterBottler(blockPos, blockState)
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) {
|
||||
return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.MATTER_BOTTLER ? null : BlockEntityMatterBottler::tick;
|
||||
override fun <T : BlockEntity?> getTicker(
|
||||
p_153212_: Level,
|
||||
p_153213_: BlockState,
|
||||
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
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
super.createBlockStateDefinition(builder);
|
||||
builder.add(WorkerState.SEMI_WORKER_STATE);
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
super.createBlockStateDefinition(builder)
|
||||
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.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterDecomposer;
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState;
|
||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.List;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable
|
||||
import net.minecraft.world.level.block.EntityBlock
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterDecomposer
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
import ru.dbotthepony.mc.otm.Registry
|
||||
import ru.dbotthepony.mc.otm.block.BlockMatterDecomposer
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public class BlockMatterDecomposer extends BlockMatteryRotatable implements EntityBlock {
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
|
||||
return new BlockEntityMatterDecomposer(blockPos, blockState);
|
||||
class BlockMatterDecomposer : BlockMatteryRotatable(), EntityBlock {
|
||||
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
|
||||
return BlockEntityMatterDecomposer(blockPos, blockState)
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) {
|
||||
return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.MATTER_DECOMPOSER ? null : BlockEntityMatterDecomposer::tick;
|
||||
override fun <T : BlockEntity?> getTicker(
|
||||
p_153212_: Level,
|
||||
p_153213_: BlockState,
|
||||
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
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
super.createBlockStateDefinition(builder);
|
||||
builder.add(WorkerState.WORKER_STATE);
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
super.createBlockStateDefinition(builder)
|
||||
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 {
|
||||
var def = BlockShapes.MATTER_DECOMPOSER.computeShape();
|
||||
companion object {
|
||||
private val def = BlockShapes.MATTER_DECOMPOSER.computeShape()
|
||||
|
||||
SHAPES = List.of(
|
||||
private val SHAPES: List<VoxelShape> = listOf(
|
||||
def,
|
||||
def,
|
||||
def,
|
||||
BlockShapes.MATTER_DECOMPOSER.rotate(Direction.NORTH).computeShape(),
|
||||
BlockShapes.MATTER_DECOMPOSER.rotate(Direction.WEST).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 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))
|
||||
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.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.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState;
|
||||
import ru.dbotthepony.mc.otm.capability.*;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell;
|
||||
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.container.MatteryContainerHandler;
|
||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
||||
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.math.BigDecimal;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.items.CapabilityItemHandler
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.chat.Component
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
import ru.dbotthepony.mc.otm.Registry
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
||||
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.set
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implements IMatterGridCell {
|
||||
public BlockEntityMatterBottler(BlockPos p_155229_, BlockState p_155230_) {
|
||||
super(Registry.BlockEntities.MATTER_BOTTLER, p_155229_, p_155230_);
|
||||
energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER);
|
||||
}
|
||||
class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
BlockEntityMatteryPowered(Registry.BlockEntities.MATTER_BOTTLER, p_155229_, p_155230_), IMatterGraphNode {
|
||||
|
||||
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() {
|
||||
return work_flow;
|
||||
}
|
||||
|
||||
public void setWorkFlow(boolean work_flow) {
|
||||
this.work_flow = work_flow;
|
||||
this.setChanged();
|
||||
}
|
||||
|
||||
public void switchWorkFlow() {
|
||||
setWorkFlow(!work_flow);
|
||||
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||
return node
|
||||
}
|
||||
|
||||
// true - bottling
|
||||
// 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
|
||||
// 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) {
|
||||
@Override
|
||||
public int getMaxStackSize(int slot) {
|
||||
return 1;
|
||||
@JvmField
|
||||
val container: MatteryContainer = object : MatteryContainer(this::setChangedLight, 6) {
|
||||
override fun getMaxStackSize(slot: Int): Int {
|
||||
return 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public final MatteryContainerHandler work_slots_handler = work_slots.handler((slot, stack) -> {
|
||||
if (work_flow) {
|
||||
return slot < 3 && stack.getCapability(MatteryCapability.MATTER).isPresent();
|
||||
val itemHandler = container.handler({ slot: Int, stack: ItemStack ->
|
||||
if (this.workFlow) {
|
||||
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();
|
||||
}, (slot, amount, stack) -> {
|
||||
if (work_flow) {
|
||||
return slot >= 3;
|
||||
}
|
||||
private var initialCapacity: Fraction? = null
|
||||
private var lastWorkStack: ItemStack? = null
|
||||
|
||||
return slot < 3;
|
||||
});
|
||||
|
||||
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 fun getMatterHandler(): IMatterHandler {
|
||||
return matter
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidMatterCell() {
|
||||
return valid;
|
||||
override fun setLevel(p_155231_: Level) {
|
||||
super.setLevel(p_155231_)
|
||||
|
||||
if (p_155231_ is ServerLevel)
|
||||
MatterNetworkGraph.discoverFull(this, node)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMatterGrid(MatterGrid grid) {
|
||||
this.grid = grid;
|
||||
private var valid = true
|
||||
|
||||
override fun invalidateCaps() {
|
||||
super.invalidateCaps()
|
||||
valid = false
|
||||
itemHandler.invalidate()
|
||||
matter.invalidate()
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IMatterHandler getMatterHandler() {
|
||||
return matter;
|
||||
override fun reviveCaps() {
|
||||
super.reviveCaps()
|
||||
valid = true
|
||||
itemHandler.revive()
|
||||
matter.revive()
|
||||
}
|
||||
|
||||
@Override
|
||||
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) {
|
||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||
if (valid) {
|
||||
if (cap == MatteryCapability.MATTER) {
|
||||
return matter.get().cast();
|
||||
if (cap === MatteryCapability.MATTER) {
|
||||
return matter.get().cast()
|
||||
}
|
||||
|
||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
||||
return work_slots_handler.get().cast();
|
||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
||||
return itemHandler.get().cast()
|
||||
}
|
||||
|
||||
if (cap == MatteryCapability.MATTER_CELL) {
|
||||
return cell_resolver.cast();
|
||||
if (cap === MatteryCapability.MATTER_CELL) {
|
||||
return resolverNode.cast()
|
||||
}
|
||||
}
|
||||
|
||||
return super.getCapability(cap, side);
|
||||
return super.getCapability(cap, side)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Component getDefaultDisplayName() {
|
||||
return MACHINE_NAME;
|
||||
override fun getDefaultDisplayName(): Component {
|
||||
return MACHINE_NAME
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
||||
return new MatterBottlerMenu(containerID, inventory, this);
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||
return MatterBottlerMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAdditional(CompoundTag nbt) {
|
||||
super.saveAdditional(nbt);
|
||||
nbt.put("work_slots", work_slots.serializeNBT());
|
||||
nbt.putBoolean("work_flow", work_flow);
|
||||
nbt.put("matter_capability", matter.serializeNBT());
|
||||
override fun saveAdditional(nbt: CompoundTag) {
|
||||
super.saveAdditional(nbt)
|
||||
nbt["work_slots"] = container.serializeNBT()
|
||||
nbt["work_flow"] = this.workFlow
|
||||
nbt["matter_capability"] = matter.serializeNBT()
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(CompoundTag nbt) {
|
||||
super.load(nbt);
|
||||
work_slots.deserializeNBT(nbt.get("work_slots"));
|
||||
work_flow = nbt.getBoolean("work_flow");
|
||||
override fun load(nbt: CompoundTag) {
|
||||
super.load(nbt)
|
||||
container.deserializeNBT(nbt["work_slots"])
|
||||
workFlow = nbt.getBoolean("work_flow")
|
||||
|
||||
if (nbt.get("matter_capability") instanceof CompoundTag _matter)
|
||||
matter.deserializeNBT(_matter);
|
||||
nbt.ifHas("matter_capability", CompoundTag::class.java) {
|
||||
matter.deserializeNBT(it)
|
||||
}
|
||||
}
|
||||
|
||||
private static final Fraction EXTRACTION_TICKS = new Fraction(200);
|
||||
init {
|
||||
energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER)
|
||||
}
|
||||
|
||||
public float getWorkProgress() {
|
||||
if (last_work_stack == null) {
|
||||
return 0;
|
||||
fun getWorkProgress(): Float {
|
||||
if (lastWorkStack == null) {
|
||||
return 0f
|
||||
}
|
||||
|
||||
var cap = last_work_stack.getCapability(MatteryCapability.MATTER).resolve();
|
||||
val resolver = lastWorkStack!!.getCapability(MatteryCapability.MATTER).resolve()
|
||||
|
||||
if (cap.isEmpty()) {
|
||||
return 0;
|
||||
if (resolver.isEmpty) {
|
||||
return 0f
|
||||
}
|
||||
|
||||
if (work_flow) {
|
||||
if (cap.get().getMaxStoredMatter().minus(initial_capacity).compareTo(Fraction.ZERO) <= 0) {
|
||||
return 0;
|
||||
val cap = resolver.get()
|
||||
|
||||
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) {
|
||||
return 0;
|
||||
if (initialCapacity!! <= Fraction.ZERO) {
|
||||
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) {
|
||||
if (t instanceof BlockEntityMatterBottler tile) {
|
||||
tile.batteryChargeLoop();
|
||||
fun tick() {
|
||||
batteryChargeLoop()
|
||||
|
||||
if (tile.isBlockedByRedstone()) {
|
||||
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);
|
||||
}
|
||||
|
||||
return;
|
||||
if (isBlockedByRedstone) {
|
||||
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) {
|
||||
level!!.setBlock(
|
||||
blockPos,
|
||||
blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE),
|
||||
Block.UPDATE_CLIENTS
|
||||
)
|
||||
}
|
||||
|
||||
ItemStack work_stack = null;
|
||||
IMatterHandler capability = null;
|
||||
int align = tile.work_flow ? 0 : 3;
|
||||
int work_slot = -1;
|
||||
return
|
||||
}
|
||||
|
||||
for (int i = align; i < align + 3; i++) {
|
||||
var get = tile.work_slots.getItem(i);
|
||||
var work_stack: ItemStack? = null
|
||||
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()) {
|
||||
var cap = get.getCapability(MatteryCapability.MATTER).resolve();
|
||||
for (i in align until align + 3) {
|
||||
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)) {
|
||||
work_stack = get;
|
||||
capability = cap.get();
|
||||
work_slot = i;
|
||||
break;
|
||||
if (!itemStack.isEmpty) {
|
||||
val cap = itemStack.getCapability(MatteryCapability.MATTER).resolve()
|
||||
|
||||
if (cap.isPresent && cap.get().direction != unexpectedDirection) {
|
||||
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) {
|
||||
tile.last_work_stack = null;
|
||||
tile.initial_capacity = null;
|
||||
} else if (work_stack != tile.last_work_stack) {
|
||||
tile.last_work_stack = work_stack;
|
||||
tile.initial_capacity = capability.getStoredMatter();
|
||||
if (work_stack == null) {
|
||||
lastWorkStack = null
|
||||
initialCapacity = null
|
||||
} else if (work_stack != lastWorkStack) {
|
||||
lastWorkStack = work_stack
|
||||
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 (capability != null) {
|
||||
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);
|
||||
if (workFlow) {
|
||||
if (matter.storedMatter < MATTER_EXCHANGE_RATE && graph != null) {
|
||||
val extracted = graph.extractMatter(
|
||||
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 (tile.grid != null) {
|
||||
var extracted = tile.grid.extractMatter(
|
||||
tile.matter.getMissingMatter()
|
||||
.min(MATTER_EXCHANGE_RATE.times(EXTRACTION_TICKS))
|
||||
.min(capability.getMissingMatter().minus(tile.matter.getStoredMatter()))
|
||||
, true);
|
||||
if (matter.storedMatter > Fraction.ZERO) {
|
||||
val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true)
|
||||
|
||||
if (extracted.compareTo(Fraction.ZERO) > 0) {
|
||||
var received = tile.matter.receiveMatterOuter(extracted, false);
|
||||
tile.grid.extractMatter(received, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!energyExtracted.isZero()) {
|
||||
val matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(matter.storedMatter) * (energyExtracted / ENERGY_CONSUMPTION), true)
|
||||
|
||||
if (tile.matter.getStoredMatter().compareTo(Fraction.ZERO) > 0) {
|
||||
var energy = tile.energy.extractEnergyInner(ENERGY_CONSUMPTION, true);
|
||||
if (!matter.isZero()) {
|
||||
energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE,false)
|
||||
|
||||
if (energy.compareTo(Fraction.ZERO) > 0) {
|
||||
var matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getStoredMatter()).times(energy.div(ENERGY_CONSUMPTION)), true);
|
||||
capability.receiveMatterOuter(matter, false)
|
||||
this.matter.extractMatterInner(matter, false)
|
||||
|
||||
if (matter.compareTo(Fraction.ZERO) > 0) {
|
||||
tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.times(matter.div(MATTER_EXCHANGE_RATE)), false);
|
||||
capability.receiveMatterOuter(matter, false);
|
||||
tile.matter.extractMatterInner(matter, false);
|
||||
|
||||
if (capability.getMissingMatter().compareTo(Fraction.ZERO) == 0) {
|
||||
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;
|
||||
}
|
||||
if (capability.missingMatter.isZero()) {
|
||||
for (i in 3..5) {
|
||||
if (container.getItem(i).isEmpty) {
|
||||
container.setItem(work_slot, ItemStack.EMPTY)
|
||||
container.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 {
|
||||
if (capability != null) {
|
||||
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);
|
||||
}
|
||||
val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true)
|
||||
|
||||
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) {
|
||||
var matter = capability.extractMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getMissingMatter()).times(energy.div(ENERGY_CONSUMPTION)), true);
|
||||
if (!matter.isZero()) {
|
||||
this.energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE,false)
|
||||
|
||||
if (matter.compareTo(Fraction.ZERO) > 0) {
|
||||
tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.times(matter.div(MATTER_EXCHANGE_RATE)), false);
|
||||
capability.extractMatterOuter(matter, false);
|
||||
tile.matter.receiveMatterInner(matter, false);
|
||||
capability.extractMatterOuter(matter, false)
|
||||
this.matter.receiveMatterInner(matter, false)
|
||||
|
||||
if (capability.getStoredMatter().compareTo(Fraction.ZERO) == 0) {
|
||||
for (int i = 2; i >= 0; i--) {
|
||||
if (tile.work_slots.getItem(i).isEmpty()) {
|
||||
tile.work_slots.setItem(work_slot, ItemStack.EMPTY);
|
||||
tile.work_slots.setItem(i, work_stack);
|
||||
break;
|
||||
}
|
||||
if (capability.storedMatter.isZero()) {
|
||||
for (i in 2 downTo 0) {
|
||||
if (container.getItem(i).isEmpty) {
|
||||
container.setItem(work_slot, ItemStack.EMPTY)
|
||||
container.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);
|
||||
}
|
||||
}
|
||||
|
||||
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.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.Block;
|
||||
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.block.BlockBatteryBank;
|
||||
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.Registry;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
||||
import ru.dbotthepony.mc.otm.menu.MatterCapacitorBankMenu;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import ru.dbotthepony.mc.otm.Registry
|
||||
import ru.dbotthepony.mc.otm.block.BlockBatteryBank
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection
|
||||
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.menu.MatterCapacitorBankMenu
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implements IMatterGridCell {
|
||||
public final IMatterHandler matter = new IMatterHandler() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Fraction getStoredMatter() {
|
||||
Fraction summ = Fraction.ZERO;
|
||||
class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
BlockEntityMattery(Registry.BlockEntities.MATTER_CAPACITOR_BANK, p_155229_, p_155230_), IMatterGraphNode, IMatterHandler {
|
||||
|
||||
for (int i = 0; i < matter_container.getContainerSize(); i++) {
|
||||
ItemStack stack = matter_container.getItem(i);
|
||||
private val node = Graph6Node<IMatterGraphNode>(this)
|
||||
private val resolverNode = LazyOptional.of { this }
|
||||
|
||||
if (!stack.isEmpty()) {
|
||||
Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve();
|
||||
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||
return node
|
||||
}
|
||||
|
||||
if (handler.isPresent()) {
|
||||
summ = summ.plus(handler.get().getStoredMatter());
|
||||
}
|
||||
override fun getStoredMatter(): Fraction {
|
||||
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
|
||||
@Override
|
||||
public Fraction getMaxStoredMatter() {
|
||||
Fraction summ = Fraction.ZERO;
|
||||
return summ
|
||||
}
|
||||
|
||||
for (int i = 0; i < matter_container.getContainerSize(); i++) {
|
||||
ItemStack stack = matter_container.getItem(i);
|
||||
override fun extractMatterOuter(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||
return extractMatterInner(howMuch, simulate)
|
||||
}
|
||||
|
||||
if (!stack.isEmpty()) {
|
||||
Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve();
|
||||
override fun extractMatterInner(howMuch: Fraction, simulate: Boolean): Fraction {
|
||||
var howMuch = howMuch
|
||||
var summ = Fraction.ZERO
|
||||
|
||||
if (handler.isPresent()) {
|
||||
summ = summ.plus(handler.get().getMaxStoredMatter());
|
||||
}
|
||||
for (stack in matterContainer) {
|
||||
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
|
||||
public Fraction receiveMatterOuter(Fraction howMuch, boolean simulate) {
|
||||
return receiveMatterInner(howMuch, simulate);
|
||||
}
|
||||
override fun getDirection(): MatterDirection {
|
||||
return MatterDirection.BIDIRECTIONAL
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Fraction receiveMatterInner(Fraction howMuch, boolean simulate) {
|
||||
Fraction summ = Fraction.ZERO;
|
||||
private var resolver = LazyOptional.of { this }
|
||||
|
||||
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().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);
|
||||
@JvmField
|
||||
val matterContainer = object : MatteryContainer(this::setChangedLight, 6 * 2) {
|
||||
override fun setChanged(slot: Int, new_state: ItemStack, old_state: ItemStack) {
|
||||
super.setChanged(slot, new_state, old_state)
|
||||
val level = level
|
||||
|
||||
if (level != null) {
|
||||
var state = getBlockState();
|
||||
var state = blockState
|
||||
|
||||
for (int i = 0; i < BlockBatteryBank.BATTERY_SLOTS_PROPS.length; i++) {
|
||||
state = state.setValue(BlockBatteryBank.BATTERY_SLOTS_PROPS[i], getItem(i).getCapability(MatteryCapability.MATTER).isPresent());
|
||||
for (i in BlockBatteryBank.BATTERY_SLOTS_PROPS.indices) {
|
||||
state = state.setValue(
|
||||
BlockBatteryBank.BATTERY_SLOTS_PROPS[i],
|
||||
getItem(i).getCapability(MatteryCapability.MATTER).isPresent
|
||||
)
|
||||
}
|
||||
|
||||
if (state != getBlockState()) {
|
||||
level.setBlock(getBlockPos(), state, Block.UPDATE_CLIENTS);
|
||||
if (state !== blockState) {
|
||||
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");
|
||||
|
||||
@Override
|
||||
protected Component getDefaultDisplayName() {
|
||||
return MACHINE_NAME;
|
||||
companion object {
|
||||
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_capacitor_bank")
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAdditional(CompoundTag nbt) {
|
||||
super.saveAdditional(nbt);
|
||||
nbt.put("matter_container", matter_container.serializeNBT());
|
||||
override fun getDefaultDisplayName(): Component {
|
||||
return MACHINE_NAME
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(CompoundTag nbt) {
|
||||
matter_container.deserializeNBT(nbt.get("matter_container"));
|
||||
super.load(nbt);
|
||||
override fun saveAdditional(nbt: CompoundTag) {
|
||||
super.saveAdditional(nbt)
|
||||
nbt["matter_container"] = matterContainer.serializeNBT()
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
||||
return new MatterCapacitorBankMenu(containerID, inventory, this);
|
||||
override fun load(nbt: CompoundTag) {
|
||||
matterContainer.deserializeNBT(nbt["matter_container"])
|
||||
super.load(nbt)
|
||||
}
|
||||
|
||||
private boolean valid = true;
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
valid = false;
|
||||
resolver.invalidate();
|
||||
resolver_grid.invalidate();
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||
return MatterCapacitorBankMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reviveCaps() {
|
||||
super.reviveCaps();
|
||||
valid = true;
|
||||
resolver = LazyOptional.of(() -> matter);
|
||||
resolver_grid = LazyOptional.of(() -> this);
|
||||
private var valid = true
|
||||
|
||||
override fun invalidateCaps() {
|
||||
super.invalidateCaps()
|
||||
valid = false
|
||||
resolver.invalidate()
|
||||
}
|
||||
|
||||
private LazyOptional<IMatterGridCell> resolver_grid = LazyOptional.of(() -> this);
|
||||
override fun reviveCaps() {
|
||||
super.reviveCaps()
|
||||
valid = true
|
||||
resolver = LazyOptional.of { this }
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||
if (valid) {
|
||||
if (cap == MatteryCapability.MATTER)
|
||||
return resolver.cast();
|
||||
|
||||
if (cap == MatteryCapability.MATTER_CELL)
|
||||
return resolver_grid.cast();
|
||||
if (cap === MatteryCapability.MATTER) return resolver.cast()
|
||||
if (cap === MatteryCapability.MATTER_CELL) return resolverNode.cast()
|
||||
}
|
||||
|
||||
return super.getCapability(cap, side);
|
||||
return super.getCapability(cap, side)
|
||||
}
|
||||
|
||||
private MatterGrid grid;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MatterGrid getMatterGrid() {
|
||||
return grid;
|
||||
override fun setRemoved() {
|
||||
super.setRemoved()
|
||||
node.destroy(::MatterNetworkGraph)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoved() {
|
||||
super.setRemoved();
|
||||
override fun setLevel(p_155231_: Level) {
|
||||
super.setLevel(p_155231_)
|
||||
|
||||
if (grid != null)
|
||||
grid.remove(this);
|
||||
if (p_155231_ is ServerLevel)
|
||||
MatterNetworkGraph.discoverFull(this, node)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLevel(Level p_155231_) {
|
||||
super.setLevel(p_155231_);
|
||||
|
||||
if (!p_155231_.isClientSide)
|
||||
MatterGrid.scheduleDiscoverNeighbours(this, getBlockPos(), p_155231_);
|
||||
override fun getMatterHandler(): IMatterHandler {
|
||||
return this
|
||||
}
|
||||
|
||||
@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.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
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.level.Level;
|
||||
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.capability.*;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.*;
|
||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
||||
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider
|
||||
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import java.util.HashMap
|
||||
import java.util.UUID
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterTask
|
||||
import java.util.stream.Collectors
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterTaskAllocation
|
||||
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.level.Level
|
||||
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
|
||||
@ParametersAreNonnullByDefault
|
||||
public class BlockEntityMatterPanel extends BlockEntityMattery implements IMatterGridCell, IMatterTaskProvider {
|
||||
public BlockEntityMatterPanel(BlockPos p_155229_, BlockState p_155230_) {
|
||||
super(Registry.BlockEntities.MATTER_PANEL, p_155229_, p_155230_);
|
||||
class BlockEntityMatterPanel(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
BlockEntityMattery(Registry.BlockEntities.MATTER_PANEL, p_155229_, p_155230_), IMatterGraphNode, IMatterTaskProvider {
|
||||
|
||||
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");
|
||||
|
||||
private final ArrayList<MatterPanelMenu> listeners = new ArrayList<>();
|
||||
|
||||
public void attachMenu(MatterPanelMenu menu) {
|
||||
listeners.add(menu);
|
||||
fun attachMenu(menu: MatterPanelMenu) {
|
||||
listeners.add(menu)
|
||||
}
|
||||
|
||||
public void deatachMenu(MatterPanelMenu menu) {
|
||||
listeners.remove(menu);
|
||||
fun deatachMenu(menu: MatterPanelMenu) {
|
||||
listeners.remove(menu)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Component getDefaultDisplayName() {
|
||||
return NAME;
|
||||
override fun getDefaultDisplayName(): Component {
|
||||
return NAME
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
||||
return new MatterPanelMenu(containerID, inventory, this);
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||
return MatterPanelMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
private boolean valid = true;
|
||||
private var valid = true
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
valid = false;
|
||||
resolver.invalidate();
|
||||
override fun invalidateCaps() {
|
||||
super.invalidateCaps()
|
||||
valid = false
|
||||
resolver.invalidate()
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reviveCaps() {
|
||||
super.reviveCaps();
|
||||
valid = true;
|
||||
resolver = LazyOptional.of(() -> this);
|
||||
override fun reviveCaps() {
|
||||
super.reviveCaps()
|
||||
valid = true
|
||||
resolver = LazyOptional.of { this }
|
||||
}
|
||||
|
||||
private LazyOptional<BlockEntityMatterPanel> resolver = LazyOptional.of(() -> this);
|
||||
private var resolver = LazyOptional.of { this }
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
||||
if (valid && (cap == MatteryCapability.MATTER_CELL || cap == MatteryCapability.TASK))
|
||||
return resolver.cast();
|
||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||
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
|
||||
public void setLevel(Level p_155231_) {
|
||||
super.setLevel(p_155231_);
|
||||
|
||||
if (grid == null)
|
||||
scheduleDiscoverNeighbours(p_155231_, getBlockPos());
|
||||
if (p_155231_ is ServerLevel)
|
||||
MatterNetworkGraph.discoverFull(this, node)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoved() {
|
||||
super.setRemoved();
|
||||
|
||||
if (level != null && !level.isClientSide && grid != null)
|
||||
grid.remove(this);
|
||||
override fun setRemoved() {
|
||||
super.setRemoved()
|
||||
node.destroy(::MatterNetworkGraph)
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MatterGrid getMatterGrid() {
|
||||
return grid;
|
||||
override fun getTaskHandler(): IMatterTaskProvider? {
|
||||
return this
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidMatterCell() {
|
||||
return valid;
|
||||
private val tasks = HashMap<UUID, MatterTask?>()
|
||||
|
||||
override fun getTasks(): Collection<MatterTask> {
|
||||
return tasks.values.stream().filter { task: MatterTask? -> task!!.required() > 0 }.collect(Collectors.toList()) as Collection<MatterTask>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMatterGrid(MatterGrid grid) {
|
||||
this.grid = grid;
|
||||
override fun getAllTasks(): Collection<MatterTask> {
|
||||
return List.copyOf(tasks.values) as Collection<MatterTask>
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IMatterTaskProvider getTaskProvider() {
|
||||
return this;
|
||||
}
|
||||
override fun allocateTask(simulate: Boolean): MatterTaskAllocation? {
|
||||
val graph = node.graph as MatterNetworkGraph? ?: return null
|
||||
|
||||
private final HashMap<UUID, MatterTask> tasks = new HashMap<>();
|
||||
for ((key, task) in tasks) {
|
||||
if (task!!.required > 0) {
|
||||
val getPattern = graph.getPattern(task.pattern!!)
|
||||
|
||||
@Nonnull
|
||||
@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 (getPattern != null) {
|
||||
if (!simulate) {
|
||||
var newer = task.shrinkRequired(1);
|
||||
tasks.put(entry.getKey(), newer);
|
||||
listeners.forEach(menu -> menu.taskUpdated(newer));
|
||||
grid.onMatterTaskUpdated(newer, task);
|
||||
setChanged();
|
||||
val new = task.shrinkRequired(1)
|
||||
tasks[key] = new
|
||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(new) }
|
||||
graph.onMatterTaskUpdated(new, task)
|
||||
setChanged()
|
||||
}
|
||||
|
||||
return new MatterTaskAllocation(task, get_pattern);
|
||||
return MatterTaskAllocation(task, getPattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean notifyTaskCompletion(MatterTask task) {
|
||||
var get_task = tasks.get(task.id());
|
||||
override fun notifyTaskCompletion(task: MatterTask): Boolean {
|
||||
var localTask = tasks[task.id] ?: return false
|
||||
val oldTask = localTask
|
||||
|
||||
if (get_task == null) {
|
||||
return false;
|
||||
}
|
||||
localTask = localTask.shrinkInProgress(1)
|
||||
val graph = node.graph as MatterNetworkGraph?
|
||||
|
||||
var old_task = get_task;
|
||||
get_task = get_task.shrinkInProgress(1);
|
||||
|
||||
if (get_task.required() <= 0 && get_task.in_progress() <= 0) {
|
||||
tasks.remove(task.id());
|
||||
|
||||
if (grid != null)
|
||||
grid.onMatterTaskCreated(task);
|
||||
|
||||
MatterTask finalGet_task1 = get_task;
|
||||
listeners.forEach(menu -> menu.taskRemoved(finalGet_task1));
|
||||
// Задача полностью выполнена
|
||||
if (localTask.required <= 0 && localTask.in_progress <= 0) {
|
||||
tasks.remove(task.id)
|
||||
graph?.onMatterTaskCreated(task)
|
||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskRemoved(localTask) }
|
||||
} else {
|
||||
tasks.put(task.id(), get_task);
|
||||
|
||||
if (grid != null) {
|
||||
grid.onMatterTaskUpdated(get_task, old_task);
|
||||
}
|
||||
|
||||
MatterTask finalGet_task = get_task;
|
||||
listeners.forEach(menu -> menu.taskUpdated(finalGet_task));
|
||||
// Задача обновлена
|
||||
tasks[task.id()] = localTask
|
||||
graph?.onMatterTaskUpdated(localTask, oldTask)
|
||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(localTask) }
|
||||
}
|
||||
|
||||
setChanged();
|
||||
|
||||
return true;
|
||||
setChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAdditional(CompoundTag nbt) {
|
||||
super.saveAdditional(nbt);
|
||||
ListTag list = new ListTag();
|
||||
override fun saveAdditional(nbt: CompoundTag) {
|
||||
super.saveAdditional(nbt)
|
||||
|
||||
for (MatterTask task : tasks.values()) {
|
||||
list.add(task.serializeNBT());
|
||||
val list = ListTag()
|
||||
|
||||
for (task in tasks.values) {
|
||||
list.add(task!!.serializeNBT())
|
||||
}
|
||||
|
||||
nbt.put("tasks", list);
|
||||
nbt.put("tasks", list)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(CompoundTag nbt) {
|
||||
super.load(nbt);
|
||||
tasks.clear();
|
||||
override fun load(nbt: CompoundTag) {
|
||||
super.load(nbt)
|
||||
tasks.clear()
|
||||
val list = nbt.getList("tasks", Tag.TAG_COMPOUND.toInt())
|
||||
|
||||
ListTag list = nbt.getList("tasks", Tag.TAG_COMPOUND);
|
||||
|
||||
for (Tag tag : list) {
|
||||
MatterTask task = MatterTask.deserializeNBT(tag);
|
||||
for (tag in list) {
|
||||
val task = MatterTask.deserializeNBT(tag)
|
||||
|
||||
if (task != null) {
|
||||
tasks.put(task.id(), task);
|
||||
tasks[task.id()] = task
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MatterTask getTask(UUID id) {
|
||||
return tasks.get(id);
|
||||
override fun getTask(id: UUID): MatterTask? {
|
||||
return tasks[id]
|
||||
}
|
||||
|
||||
public void removeTask(UUID id) {
|
||||
var task = tasks.get(id);
|
||||
fun removeTask(id: UUID) {
|
||||
val task = tasks[id] ?: return
|
||||
tasks.remove(id)
|
||||
|
||||
if (task == null)
|
||||
return;
|
||||
(node.graph as MatterNetworkGraph?)?.onMatterTaskRemoved(task)
|
||||
|
||||
tasks.remove(id);
|
||||
|
||||
if (grid != null)
|
||||
grid.onMatterTaskRemoved(task);
|
||||
|
||||
listeners.forEach(menu -> menu.taskRemoved(task));
|
||||
setChanged();
|
||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskRemoved(task) }
|
||||
setChanged()
|
||||
}
|
||||
|
||||
public void removeTask(PatternState state) {
|
||||
removeTask(state.id());
|
||||
fun removeTask(state: PatternState) = 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) {
|
||||
var task = new MatterTask(UUID.randomUUID(), state.id(), state.item(), 0, 0, how_much);
|
||||
tasks.put(task.id(), task);
|
||||
override fun dropAllTasks() {
|
||||
val graph = node.graph as MatterNetworkGraph?
|
||||
|
||||
if (grid != null)
|
||||
grid.onMatterTaskCreated(task);
|
||||
for (task in tasks.values) {
|
||||
graph?.onMatterTaskRemoved(task!!)
|
||||
listeners.forEach { menu: MatterPanelMenu -> menu.taskUpdated(task!!) }
|
||||
}
|
||||
|
||||
listeners.forEach(menu -> menu.taskUpdated(task));
|
||||
|
||||
setChanged();
|
||||
|
||||
return task;
|
||||
tasks.clear()
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropAllTasks() {
|
||||
tasks.clear();
|
||||
companion object {
|
||||
private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_panel")
|
||||
}
|
||||
}
|
||||
}
|
@ -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.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.state.BlockState;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
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.MachineJob;
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus;
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkTickContext;
|
||||
import ru.dbotthepony.mc.otm.capability.*;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.*;
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler;
|
||||
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.MatterReplicatorMenu;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.math.BigDecimal;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJob
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterTask
|
||||
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||
import ru.dbotthepony.mc.otm.matter.MatterRegistry
|
||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkTickContext
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import net.minecraftforge.items.CapabilityItemHandler
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
import ru.dbotthepony.mc.otm.Registry
|
||||
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.set
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implements IMatterGridCell {
|
||||
public BlockEntityMatterReplicator(BlockPos p_155229_, BlockState p_155230_) {
|
||||
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));
|
||||
class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_), IMatterGraphNode {
|
||||
|
||||
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
|
||||
public final MatteryContainer reserved_slots = new MatteryContainer(this::setChanged, 3);
|
||||
// запросы от matter replicator interface?
|
||||
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");
|
||||
|
||||
private static final Fraction BASE_CONSUMPTION = new Fraction(400);
|
||||
|
||||
@Override
|
||||
protected Component getDefaultDisplayName() {
|
||||
return NAME;
|
||||
override fun getDefaultDisplayName(): Component {
|
||||
return NAME
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
||||
return new MatterReplicatorMenu(containerID, inventory, this);
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||
return MatterReplicatorMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected Fraction getBaseConsumption() {
|
||||
return BASE_CONSUMPTION;
|
||||
override fun getBaseConsumption(): Fraction {
|
||||
return BASE_CONSUMPTION
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected MachineJobStatus onJobFinish(MachineJob job) {
|
||||
if (!regular_slots.fullyAddItem(job.stack())) {
|
||||
return new MachineJobStatus(false, 20);
|
||||
override fun onJobFinish(job: MachineJob): MachineJobStatus {
|
||||
if (!regularSlots.fullyAddItem(job.stack())) {
|
||||
return MachineJobStatus(false, 20)
|
||||
}
|
||||
|
||||
if (grid != null) {
|
||||
grid.notifyTaskCompletion(MatterTask.deserializeNBT(job.data().get("task")));
|
||||
}
|
||||
|
||||
return new MachineJobStatus();
|
||||
(node.graph as MatterNetworkGraph?)?.notifyTaskCompletion(MatterTask.deserializeNBT(job.data["task"])!!)
|
||||
return MachineJobStatus()
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMatterTaskCreated(MatterTask task) {
|
||||
is_idling = false;
|
||||
override fun onMatterTaskCreated(task: MatterTask) {
|
||||
is_idling = false
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMatterTaskUpdated(MatterTask new_state, MatterTask old_state) {
|
||||
is_idling = false;
|
||||
override fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) {
|
||||
is_idling = false
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPatternAdded(PatternState state) {
|
||||
is_idling = false;
|
||||
override fun onPatternAdded(state: PatternState) {
|
||||
is_idling = false
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoved() {
|
||||
super.setRemoved();
|
||||
|
||||
if (level != null && !level.isClientSide && grid != null)
|
||||
grid.remove(this);
|
||||
override fun setRemoved() {
|
||||
super.setRemoved()
|
||||
node.destroy(::MatterNetworkGraph)
|
||||
}
|
||||
|
||||
private static final double TICKS_PER_MTU = 20_000d;
|
||||
private static final Fraction TICKS_PER_MTU_BD = new Fraction(20_000);
|
||||
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 fun setLevel(p_155231_: Level) {
|
||||
super.setLevel(p_155231_)
|
||||
|
||||
@Override
|
||||
public void setLevel(Level p_155231_) {
|
||||
super.setLevel(p_155231_);
|
||||
|
||||
if (grid == null)
|
||||
scheduleDiscoverNeighbours(p_155231_, getBlockPos());
|
||||
if (p_155231_ is ServerLevel)
|
||||
MatterNetworkGraph.discoverFull(this, node)
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected MachineJob getNextJob() {
|
||||
if (grid == null)
|
||||
return null;
|
||||
|
||||
MatterTaskAllocation allocation = grid.allocateTask(false);
|
||||
|
||||
if (allocation == null)
|
||||
return null;
|
||||
|
||||
ItemStack stack = allocation.task().stack(1);
|
||||
override fun getNextJob(): MachineJob? {
|
||||
val graph = node.graph as MatterNetworkGraph? ?: return null
|
||||
val allocation = graph.allocateTask(false) ?: return null
|
||||
val stack = allocation.task().stack(1)
|
||||
|
||||
// ????????
|
||||
if (!MatterRegistry.hasMatterValue(stack))
|
||||
return null;
|
||||
if (!MatterRegistry.hasMatterValue(stack)) 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());
|
||||
|
||||
if (allocation.pattern() != null)
|
||||
job.data().put("pattern", allocation.pattern().serializeNBT());
|
||||
|
||||
return job;
|
||||
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
|
||||
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 (matter.extractMatterInner(drainPerTick, true) < drainPerTick) {
|
||||
// в машине недостаточно материи
|
||||
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));
|
||||
var drain = grid.extractMatter(to_extract, true);
|
||||
val toExtract = drainPerTick - matter.extractMatterInner(drainPerTick, 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);
|
||||
grid.extractMatter(drain, false);
|
||||
|
||||
return new MachineJobStatus();
|
||||
matter.extractMatterInner(drainPerTick, false)
|
||||
graph.extractMatter(drain, false)
|
||||
return MachineJobStatus()
|
||||
} else {
|
||||
// в тик требуется меньше материи, чем её может хранить репликатор
|
||||
// примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше
|
||||
var to_extract = matter.getMissingMatter().min(drain_per_tick.times(DRAIN_MULT));
|
||||
var drain = grid.extractMatter(to_extract, true);
|
||||
val toExtract =
|
||||
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);
|
||||
grid.extractMatter(received, false);
|
||||
val received = matter.receiveMatterOuter(drain, false)
|
||||
graph.extractMatter(received, false)
|
||||
|
||||
// получили материю, проверяем возможность работы
|
||||
if (matter.extractMatterInner(drain_per_tick, false).compareTo(drain_per_tick) >= 0) {
|
||||
return new MachineJobStatus();
|
||||
if (matter.extractMatterInner(drainPerTick, false) >= drainPerTick) {
|
||||
return MachineJobStatus()
|
||||
} else {
|
||||
// :(
|
||||
return new MachineJobStatus(false, 200);
|
||||
return MachineJobStatus(false, 200)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// в машине достаточно материи
|
||||
|
||||
matter.extractMatterInner(drain_per_tick, false);
|
||||
return new MachineJobStatus();
|
||||
matter.extractMatterInner(drainPerTick, false)
|
||||
return MachineJobStatus()
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAdditional(CompoundTag nbt) {
|
||||
super.saveAdditional(nbt);
|
||||
nbt.put("regular_slots", regular_slots.serializeNBT());
|
||||
nbt.put("reserved_slots", reserved_slots.serializeNBT());
|
||||
nbt.put("matter_capability", matter.serializeNBT());
|
||||
override fun saveAdditional(nbt: CompoundTag) {
|
||||
super.saveAdditional(nbt)
|
||||
nbt["regular_slots"] = regularSlots.serializeNBT()
|
||||
nbt["reserved_slots"] = reservedSlots.serializeNBT()
|
||||
nbt["matter_capability"] = matter.serializeNBT()
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(CompoundTag nbt) {
|
||||
super.load(nbt);
|
||||
regular_slots.deserializeNBT(nbt.get("regular_slots"));
|
||||
reserved_slots.deserializeNBT(nbt.get("reserved_slots"));
|
||||
override fun load(nbt: CompoundTag) {
|
||||
super.load(nbt)
|
||||
regularSlots.deserializeNBT(nbt["regular_slots"])
|
||||
reservedSlots.deserializeNBT(nbt["reserved_slots"])
|
||||
|
||||
if (nbt.get("matter_capability") instanceof CompoundTag tag)
|
||||
matter.deserializeNBT(tag);
|
||||
nbt.ifHas("matter_capability", CompoundTag::class.java) {
|
||||
matter.deserializeNBT(it)
|
||||
}
|
||||
}
|
||||
|
||||
private boolean valid = true;
|
||||
private var valid = true
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
valid = false;
|
||||
slots_handler.invalidate();
|
||||
resolver_self.invalidate();
|
||||
override fun invalidateCaps() {
|
||||
super.invalidateCaps()
|
||||
valid = false
|
||||
itemHandler.invalidate()
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reviveCaps() {
|
||||
super.reviveCaps();
|
||||
valid = true;
|
||||
slots_handler.revive();
|
||||
resolver_self = LazyOptional.of(() -> this);
|
||||
override fun reviveCaps() {
|
||||
super.reviveCaps()
|
||||
valid = true
|
||||
itemHandler.revive()
|
||||
}
|
||||
|
||||
private LazyOptional<BlockEntityMatterReplicator> resolver_self = LazyOptional.of(() -> this);
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||
if (valid) {
|
||||
if (cap == MatteryCapability.MATTER_CELL)
|
||||
return resolver_self.cast();
|
||||
|
||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
return slots_handler.get().cast();
|
||||
if (cap === MatteryCapability.MATTER_CELL) return resolverNode.cast()
|
||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.get().cast()
|
||||
}
|
||||
|
||||
return super.getCapability(cap, side);
|
||||
return super.getCapability(cap, side)
|
||||
}
|
||||
|
||||
private MatterGrid grid;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MatterGrid getMatterGrid() {
|
||||
return grid;
|
||||
init {
|
||||
energy = MatteryMachineEnergyStorage(
|
||||
this,
|
||||
MatteryMachineEnergyStorage.MachineType.WORKER,
|
||||
Fraction(200000),
|
||||
Fraction(4000),
|
||||
Fraction(4000)
|
||||
)
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidMatterCell() {
|
||||
return valid;
|
||||
companion object {
|
||||
private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_replicator")
|
||||
private val BASE_CONSUMPTION = Fraction(400)
|
||||
private const val TICKS_PER_MTU = 20000.0
|
||||
private val TICKS_PER_MTU_BD = Fraction(20000)
|
||||
private const val MTU_PER_TICK = 1.0 / 20000.0
|
||||
private val MTU_PER_TICK_BD = Fraction.ONE.div(TICKS_PER_MTU_BD)
|
||||
private val DRAIN_MULT = Fraction(200)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMatterGrid(MatterGrid grid) {
|
||||
this.grid = grid;
|
||||
}
|
||||
}
|
||||
}
|
@ -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.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 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.*;
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler;
|
||||
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.Registry;
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
||||
import ru.dbotthepony.mc.otm.menu.MatterScannerMenu;
|
||||
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 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.*
|
||||
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.matter.MatterRegistry
|
||||
import ru.dbotthepony.mc.otm.menu.MatterScannerMenu
|
||||
import java.util.*
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_SCANNER, p_155229_, p_155230_), IMatterGraphNode {
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implements IMatterGridCell {
|
||||
private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.matter_scanner");
|
||||
val input_slot = MatteryContainer(this::setChanged, 1)
|
||||
|
||||
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(
|
||||
(slot, stack) -> MatterRegistry.canDecompose(stack),
|
||||
(slot, amount, stack) -> is_idling
|
||||
);
|
||||
|
||||
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));
|
||||
// IMatterGraphNode
|
||||
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||
return matterNode
|
||||
}
|
||||
|
||||
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
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
||||
override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {
|
||||
is_idling = false
|
||||
}
|
||||
// /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 (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
return input_handler.get().cast();
|
||||
|
||||
if (cap == MatteryCapability.MATTER_CELL)
|
||||
return resolver_grid.cast();
|
||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return inputHandler.get().cast()
|
||||
//if (cap === MatteryCapability.MATTER_CELL) return resolver_grid.cast()
|
||||
if (cap == MatteryCapability.MATTER_CELL) return resolverNode.cast()
|
||||
}
|
||||
|
||||
return super.getCapability(cap, side);
|
||||
return super.getCapability(cap, side)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
valid = false;
|
||||
input_handler.invalidate();
|
||||
resolver_grid.invalidate();
|
||||
override fun invalidateCaps() {
|
||||
super.invalidateCaps()
|
||||
valid = false
|
||||
inputHandler.invalidate()
|
||||
resolverNode.invalidate()
|
||||
matterNode.destroy(::MatterNetworkGraph)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reviveCaps() {
|
||||
super.reviveCaps();
|
||||
valid = true;
|
||||
input_handler.revive();
|
||||
resolver_grid = LazyOptional.of(() -> this);
|
||||
override fun reviveCaps() {
|
||||
super.reviveCaps()
|
||||
valid = true
|
||||
inputHandler.revive()
|
||||
resolverNode = LazyOptional.of { this }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPatternAdded(PatternState state) {
|
||||
is_idling = false;
|
||||
override fun setRemoved() {
|
||||
super.setRemoved()
|
||||
matterNode.destroy(::MatterNetworkGraph)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPatternRemoved(PatternState state) {
|
||||
is_idling = false;
|
||||
override fun getDefaultDisplayName(): Component {
|
||||
return NAME
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPatternUpdated(PatternState new_state, PatternState old_state) {
|
||||
is_idling = false;
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? {
|
||||
return MatterScannerMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoved() {
|
||||
super.setRemoved();
|
||||
|
||||
if (level != null && !level.isClientSide && grid != null)
|
||||
grid.remove(this);
|
||||
override fun saveAdditional(nbt: CompoundTag) {
|
||||
super.saveAdditional(nbt)
|
||||
nbt.put("work_slots", input_slot.serializeNBT())
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighbourMatterCell(Level level, BlockPos pos, Direction direction, IMatterGridCell cell, BlockEntity entity) {
|
||||
is_idling = false;
|
||||
override fun load(nbt: CompoundTag) {
|
||||
input_slot.deserializeNBT(nbt["work_slots"])
|
||||
super.load(nbt)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Component getDefaultDisplayName() {
|
||||
return NAME;
|
||||
override fun getBaseConsumption(): Fraction {
|
||||
return BASE_CONSUMPTION
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
||||
return new MatterScannerMenu(containerID, inventory, this);
|
||||
}
|
||||
override fun onJobFinish(job: MachineJob): MachineJobStatus {
|
||||
val grid = matterNode.graph as MatterNetworkGraph? ?: return MachineJobStatus(false, 100)
|
||||
|
||||
@Override
|
||||
public void saveAdditional(CompoundTag nbt) {
|
||||
super.saveAdditional(nbt);
|
||||
nbt.put("work_slots", input_slot.serializeNBT());
|
||||
}
|
||||
val stack = job.stack()
|
||||
if (stack.isEmpty || !MatterRegistry.hasMatterValue(stack)) return MachineJobStatus()
|
||||
|
||||
@Override
|
||||
public void load(CompoundTag nbt) {
|
||||
input_slot.deserializeNBT(nbt.get("work_slots"));
|
||||
super.load(nbt);
|
||||
}
|
||||
val get_state = grid.findPatterns(stack.item)
|
||||
var find_state: PatternState? = null
|
||||
|
||||
private static final Fraction BASE_CONSUMPTION = new Fraction("40");
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
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;
|
||||
for (state in get_state) {
|
||||
if (state.item() === stack.item) {
|
||||
if (find_state == null && state.research_percent() < 1.0) {
|
||||
find_state = state
|
||||
} 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) {
|
||||
new_state = new PatternState(find_state.id(), stack.getItem(), find_state.research_percent() + 0.2d);
|
||||
if (grid.insertPattern(new_state, false, false).status != PatternInsertStatus.Status.FAIL) {
|
||||
return MachineJobStatus()
|
||||
} 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
|
||||
protected MachineJob getNextJob() {
|
||||
if (grid == null)
|
||||
return null;
|
||||
override fun getNextJob(): MachineJob? {
|
||||
val grid = matterNode.graph as MatterNetworkGraph? ?: 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))
|
||||
return null;
|
||||
val getState = grid.findPatterns(stack.item)
|
||||
var findState: PatternState? = null
|
||||
|
||||
Collection<PatternState> get_state = grid.findPatterns(stack.getItem());
|
||||
PatternState find_state = null;
|
||||
|
||||
for (PatternState state : get_state) {
|
||||
if (state.item() == stack.getItem() && state.research_percent() < 1d) {
|
||||
find_state = state;
|
||||
} else if (state.item() == stack.getItem() && state.research_percent() >= 1d) {
|
||||
return null;
|
||||
for (state in getState) {
|
||||
if (state.item() === stack.item && state.research_percent() < 1.0) {
|
||||
findState = state
|
||||
} else if (state.item() === stack.item && state.research_percent() >= 1.0) {
|
||||
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) {
|
||||
new_state = new PatternState(find_state.id(), stack.getItem(), find_state.research_percent() + 0.2d);
|
||||
} else {
|
||||
new_state = new PatternState(UUID.randomUUID(), stack.getItem(), 0.2d);
|
||||
if (grid.insertPattern(new_state, false, true).status != PatternInsertStatus.Status.FAIL) {
|
||||
val copy = stack.copy()
|
||||
copy.count = 1
|
||||
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) {
|
||||
ItemStack copy = stack.copy();
|
||||
copy.setCount(1);
|
||||
stack.shrink(1);
|
||||
input_slot.setChanged();
|
||||
return new MachineJob(copy, MatterRegistry.getMatterValue(copy).toDouble() * 35_000d);
|
||||
return null
|
||||
}
|
||||
|
||||
init {
|
||||
energy = MatteryMachineEnergyStorage(
|
||||
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
|
||||
@Override
|
||||
public IPatternStorage getPatternStorage() {
|
||||
return null;
|
||||
companion object {
|
||||
private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_scanner")
|
||||
private val BASE_CONSUMPTION = Fraction("40")
|
||||
}
|
||||
|
||||
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 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.Block;
|
||||
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.block.BlockPatternStorage;
|
||||
import ru.dbotthepony.mc.otm.capability.*;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.*;
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler;
|
||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
||||
import ru.dbotthepony.mc.otm.menu.PatternStorageMenu;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import java.lang.Runnable
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||
import ru.dbotthepony.mc.otm.block.BlockPatternStorage
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.items.CapabilityItemHandler
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import ru.dbotthepony.mc.otm.menu.PatternStorageMenu
|
||||
import net.minecraft.MethodsReturnNonnullByDefault
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.network.chat.Component
|
||||
import ru.dbotthepony.mc.otm.capability.matter.PatternInsertStatus
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Block
|
||||
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 ru.dbotthepony.mc.otm.ifHas
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import java.util.ArrayList
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public class BlockEntityPatternStorage extends BlockEntityMattery implements IMatterGridCell, IPatternStorage {
|
||||
public BlockEntityPatternStorage(BlockPos p_155229_, BlockState p_155230_) {
|
||||
super(Registry.BlockEntities.PATTERN_STORAGE, p_155229_, p_155230_);
|
||||
}
|
||||
class BlockEntityPatternStorage(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
BlockEntityMattery(Registry.BlockEntities.PATTERN_STORAGE, p_155229_, p_155230_), IMatterGraphNode, IPatternStorage {
|
||||
|
||||
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 (!old_state.isEmpty()) {
|
||||
old_state.getCapability(MatteryCapability.PATTERN).ifPresent(cap -> cap.getStoredPatterns().forEach(grid::onPatternRemoved));
|
||||
if (!old_state.isEmpty) {
|
||||
old_state.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
||||
cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternRemoved(state!!) }
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_state.isEmpty()) {
|
||||
new_state.getCapability(MatteryCapability.PATTERN).ifPresent(cap -> cap.getStoredPatterns().forEach(grid::onPatternAdded));
|
||||
if (!new_state.isEmpty) {
|
||||
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
|
||||
public int getMaxStackSize() {
|
||||
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);
|
||||
override fun getMaxStackSize(): Int {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
private final MatteryContainerHandler resolver_item = patterns.handler(
|
||||
((slot, stack) -> stack.getCapability(MatteryCapability.PATTERN).isPresent())
|
||||
);
|
||||
private fun updateBlockstate() {
|
||||
val level = level ?: return
|
||||
|
||||
private MatterGrid grid;
|
||||
var state = blockState
|
||||
|
||||
@Override
|
||||
public void saveAdditional(CompoundTag nbt) {
|
||||
super.saveAdditional(nbt);
|
||||
nbt.put("patterns", patterns.serializeNBT());
|
||||
for (i in 0..7) {
|
||||
state = state.setValue(
|
||||
BlockPatternStorage.PATTERN_STORAGE_DISKS_PROPS[i],
|
||||
patterns.getItem(i).getCapability(MatteryCapability.PATTERN).isPresent
|
||||
)
|
||||
}
|
||||
|
||||
if (state !== blockState) {
|
||||
level.setBlock(blockPos, state, Block.UPDATE_CLIENTS)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(CompoundTag nbt) {
|
||||
super.load(nbt);
|
||||
patterns.deserializeNBT(nbt.get("patterns"));
|
||||
private val resolverItem =
|
||||
patterns.handler { slot: Int, stack: ItemStack -> stack.getCapability(MatteryCapability.PATTERN).isPresent }
|
||||
|
||||
override fun saveAdditional(nbt: CompoundTag) {
|
||||
super.saveAdditional(nbt)
|
||||
nbt["patterns"] = patterns.serializeNBT()
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLevel(Level p_155231_) {
|
||||
super.setLevel(p_155231_);
|
||||
override fun load(nbt: CompoundTag) {
|
||||
super.load(nbt)
|
||||
|
||||
if (grid == null)
|
||||
MatterGrid.scheduleDiscoverNeighbours(this, getBlockPos(), p_155231_);
|
||||
nbt.ifHas("patterns") {
|
||||
patterns.deserializeNBT(it)
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MatterGrid getMatterGrid() {
|
||||
return grid;
|
||||
override fun setLevel(p_155231_: Level) {
|
||||
super.setLevel(p_155231_)
|
||||
|
||||
if (p_155231_ is ServerLevel)
|
||||
MatterNetworkGraph.discoverFull(this, node)
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IMatterHandler getMatterHandler() {
|
||||
return null;
|
||||
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
|
||||
return node
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IPatternStorage getPatternStorage() {
|
||||
return valid ? this : null;
|
||||
override fun getPatternHandler(): IPatternStorage {
|
||||
return this
|
||||
}
|
||||
|
||||
private boolean valid = true;
|
||||
private var valid = true
|
||||
|
||||
@Override
|
||||
public boolean isValidMatterCell() {
|
||||
return valid;
|
||||
override fun invalidateCaps() {
|
||||
super.invalidateCaps()
|
||||
valid = false
|
||||
resolverItem.invalidate()
|
||||
node.destroy(::MatterNetworkGraph)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMatterGrid(MatterGrid grid) {
|
||||
this.grid = grid;
|
||||
override fun reviveCaps() {
|
||||
super.reviveCaps()
|
||||
valid = true
|
||||
resolverItem.revive()
|
||||
}
|
||||
|
||||
@Override
|
||||
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) {
|
||||
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||
if (valid) {
|
||||
if (cap == MatteryCapability.PATTERN || cap == MatteryCapability.MATTER_CELL)
|
||||
return resolver.cast();
|
||||
|
||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
return resolver_item.get().cast();
|
||||
if (cap === MatteryCapability.PATTERN) return resolverPatterns.cast()
|
||||
if (cap === MatteryCapability.MATTER_CELL) return resolverNode.cast()
|
||||
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return resolverItem.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
|
||||
protected Component getDefaultDisplayName() {
|
||||
return NAME;
|
||||
override fun getDefaultDisplayName(): Component {
|
||||
return NAME
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
|
||||
return new PatternStorageMenu(containerID, inventory, this);
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||
return PatternStorageMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Collection<PatternState> getStoredPatterns() {
|
||||
ArrayList<PatternState> list = new ArrayList<>();
|
||||
patterns.consumeCapability(MatteryCapability.PATTERN, capability -> list.addAll(capability.getStoredPatterns()));
|
||||
return ImmutableList.copyOf(list);
|
||||
override fun getStoredPatterns(): Collection<PatternState> {
|
||||
val list = ArrayList<PatternState>()
|
||||
patterns.consumeCapability(MatteryCapability.PATTERN) { capability: IPatternStorage -> list.addAll(capability.storedPatterns) }
|
||||
return list
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCapacity() {
|
||||
long stored = 0;
|
||||
override fun getCapacity(): Int {
|
||||
var stored = 0L
|
||||
|
||||
for (var pattern : patterns.capabilityIterator(MatteryCapability.PATTERN)) {
|
||||
stored += pattern.getCapacity();
|
||||
}
|
||||
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
|
||||
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
|
||||
public int getStored() {
|
||||
long stored = 0;
|
||||
override fun getStored(): Int {
|
||||
var stored = 0L
|
||||
|
||||
for (var pattern : patterns.capabilityIterator(MatteryCapability.PATTERN)) {
|
||||
stored += pattern.getStored();
|
||||
}
|
||||
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
|
||||
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
|
||||
public void setRemoved() {
|
||||
super.setRemoved();
|
||||
|
||||
if (level != null && !level.isClientSide && grid != null)
|
||||
grid.remove(this);
|
||||
override fun setRemoved() {
|
||||
super.setRemoved()
|
||||
node.destroy(::MatterNetworkGraph)
|
||||
}
|
||||
|
||||
@Override
|
||||
public PatternInsertStatus insertPattern(PatternState pattern, boolean only_update, boolean simulate) {
|
||||
for (IPatternStorage storage : patterns.capabilityIterator(MatteryCapability.PATTERN)) {
|
||||
var status = storage.insertPattern(pattern, only_update, simulate);
|
||||
override fun insertPattern(pattern: PatternState, only_update: Boolean, simulate: Boolean): PatternInsertStatus {
|
||||
for (storage in patterns.capabilityIterator(MatteryCapability.PATTERN)) {
|
||||
val status = storage.insertPattern(pattern, only_update, simulate)
|
||||
|
||||
if (status.status() != PatternInsertStatus.Status.FAIL) {
|
||||
if (!simulate) {
|
||||
setChanged();
|
||||
setChanged()
|
||||
|
||||
if (grid != null) {
|
||||
val graph = node.graph as MatterNetworkGraph?
|
||||
|
||||
if (graph != null) {
|
||||
if (status.status() == PatternInsertStatus.Status.INSERTED) {
|
||||
grid.onPatternAdded(status.new_state());
|
||||
graph.onPatternAdded(status.new_state()!!)
|
||||
} 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")
|
||||
}
|
||||
}
|
@ -24,4 +24,4 @@ class BatteryBankScreen(menu: BatteryBankMenu, p_97742_: Inventory, p_97743_: Co
|
||||
|
||||
return frame
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.TranslatableComponent;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.*;
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel;
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel;
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel;
|
||||
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu;
|
||||
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.ButtonPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.SlotPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
||||
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
class MatterBottlerScreen(menu: MatterBottlerMenu, inventory: Inventory, title: Component) :
|
||||
MatteryScreen<MatterBottlerMenu>(menu, inventory, title) {
|
||||
|
||||
public class MatterBottlerScreen extends MatteryScreen<MatterBottlerMenu> {
|
||||
public MatterBottlerScreen(MatterBottlerMenu menu, Inventory inventory, Component title) {
|
||||
super(menu, inventory, title);
|
||||
private var progress: ProgressGaugePanel? = null
|
||||
|
||||
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
|
||||
protected FramePanel makeMainFrame() {
|
||||
var frame = super.makeMainFrame();
|
||||
override fun containerTick() {
|
||||
super.containerTick()
|
||||
|
||||
var mode = new ButtonPanel(this, frame, 0, 0, 100, 20, new TranslatableComponent("otm.matter_bottler.switch_mode"));
|
||||
mode.bindOnPress(menu::switchBottlerMode);
|
||||
mode.setDock(Dock.TOP);
|
||||
mode.asGrid(); // for auto alignment on center
|
||||
|
||||
return frame;
|
||||
progress?.flop = !menu.workFlow.value
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import net.minecraft.nbt.ByteArrayTag
|
||||
import net.minecraft.nbt.StringTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
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_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
|
||||
@Suppress("unused")
|
||||
@ -72,26 +263,21 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
||||
val c = divisor.signum()
|
||||
|
||||
if (a != b && a != c) {
|
||||
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
||||
if (isZero(divisor))
|
||||
return Fraction(-value, -divisor)
|
||||
|
||||
val mod = value % divisor
|
||||
val mod = value.divideAndRemainder(divisor)
|
||||
|
||||
if (mod == BigInteger.ZERO)
|
||||
return Fraction(-value / -divisor, compact = compact)
|
||||
if (isZero(mod[1]))
|
||||
return Fraction(mod[0], compact = compact)
|
||||
|
||||
return Fraction(-value, -divisor)
|
||||
}
|
||||
|
||||
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
||||
if (isZero(divisor))
|
||||
return this
|
||||
|
||||
val mod = value % divisor
|
||||
|
||||
if (mod == BigInteger.ZERO)
|
||||
return Fraction(value / divisor, compact = compact)
|
||||
|
||||
return this
|
||||
return compactTwo(value, divisor, compact)
|
||||
}
|
||||
|
||||
fun isZero(): Boolean {
|
||||
@ -108,12 +294,7 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
||||
if (divisor == BigInteger.ZERO || divisor == BI_MINUS_ZERO)
|
||||
return this
|
||||
|
||||
val mod = value % divisor
|
||||
|
||||
if (mod == BigInteger.ZERO)
|
||||
return Fraction(value / divisor, compact = compact)
|
||||
|
||||
return this
|
||||
return compactTwo(value, divisor, compact)
|
||||
}
|
||||
|
||||
fun canonize(): Fraction {
|
||||
@ -181,8 +362,8 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
||||
if (isNaN()) return this
|
||||
|
||||
if (divisor == other.divisor) {
|
||||
if (divisor == BigInteger.ONE)
|
||||
return Fraction(value + other.value)
|
||||
if (isOne(divisor))
|
||||
return Fraction(value + other.value, divisor)
|
||||
|
||||
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)
|
||||
return Fraction(new, divisor)
|
||||
|
||||
val mod = new % divisor
|
||||
|
||||
if (mod == BigInteger.ZERO)
|
||||
return Fraction(new / divisor)
|
||||
|
||||
return Fraction(new, divisor)
|
||||
return compactTwo(new, 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)
|
||||
return Fraction(new, div)
|
||||
|
||||
val mod = new % div
|
||||
|
||||
if (mod == BigInteger.ZERO)
|
||||
return Fraction(new / div)
|
||||
|
||||
return Fraction(new, div)
|
||||
return compactTwo(new, div)
|
||||
}
|
||||
|
||||
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 {
|
||||
if (divisor == other.divisor) {
|
||||
if (divisor == BigInteger.ONE)
|
||||
return Fraction(value - other.value)
|
||||
if (isOne(divisor))
|
||||
return Fraction(value - other.value, divisor)
|
||||
|
||||
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)
|
||||
return Fraction(new, divisor)
|
||||
|
||||
val mod = new % divisor
|
||||
|
||||
if (mod == BigInteger.ZERO)
|
||||
return Fraction(new / divisor)
|
||||
|
||||
return Fraction(new, divisor)
|
||||
return compactTwo(new, 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)
|
||||
return Fraction(new, div)
|
||||
|
||||
val mod = new % div
|
||||
|
||||
if (mod == BigInteger.ZERO)
|
||||
return Fraction(new / div)
|
||||
|
||||
return Fraction(new, div)
|
||||
return compactTwo(new, div)
|
||||
}
|
||||
|
||||
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)
|
||||
return Fraction(new, div)
|
||||
|
||||
val mod = new % div
|
||||
|
||||
if (mod == BigInteger.ZERO)
|
||||
return Fraction(new / div)
|
||||
|
||||
return Fraction(new, div)
|
||||
return compactTwo(new, div)
|
||||
}
|
||||
|
||||
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)
|
||||
return Fraction(new, div)
|
||||
|
||||
val mod = new % div
|
||||
|
||||
if (mod == BigInteger.ZERO)
|
||||
return Fraction(new / div)
|
||||
|
||||
return Fraction(new, div)
|
||||
return compactTwo(new, div)
|
||||
}
|
||||
|
||||
operator fun div(other: Fraction): Fraction {
|
||||
@ -423,13 +574,32 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
||||
|
||||
fun toByteArray(): ByteArray {
|
||||
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 bytesB = divisor.toByteArray()
|
||||
val magValue = magnitude(value)
|
||||
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 {
|
||||
@ -592,6 +762,8 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
|
||||
@JvmField
|
||||
val ZERO = Fraction(BigInteger.ZERO)
|
||||
|
||||
@ -635,11 +807,27 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
|
||||
|
||||
@JvmStatic
|
||||
fun fromByteArray(bytes: ByteArray): Fraction {
|
||||
val bytesA = bytes.copyOfRange(1, 1 + bytes[0].toInt())
|
||||
val offsetB = 1 + bytes[0].toInt()
|
||||
val bytesB = bytes.copyOfRange(offsetB + 1, offsetB + 1 + bytes[offsetB].toInt())
|
||||
try {
|
||||
val rangeA = unsignedInt(bytes[0]) or (unsignedInt(bytes[1]) shl 8)
|
||||
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
|
||||
|
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.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterBottler;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
||||
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
|
||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget;
|
||||
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget;
|
||||
import ru.dbotthepony.mc.otm.network.MatterBottlerSwitchPacket;
|
||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
|
||||
import ru.dbotthepony.mc.otm.client.screen.UVWindingOrder;
|
||||
import net.minecraft.world.SimpleContainer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.Registry
|
||||
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.menu.data.BooleanDataContainer
|
||||
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot
|
||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
||||
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
|
||||
import ru.dbotthepony.mc.otm.network.MatterBottlerSwitchPacket
|
||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||
|
||||
public class MatterBottlerMenu extends PoweredMatteryMenu {
|
||||
public MatterBottlerMenu(int p_38852_, Inventory inventory) {
|
||||
this(p_38852_, inventory, null);
|
||||
}
|
||||
class MatterBottlerMenu @JvmOverloads constructor(
|
||||
p_38852_: Int,
|
||||
inventory: Inventory,
|
||||
tile: BlockEntityMatterBottler? = null
|
||||
) : PoweredMatteryMenu(
|
||||
Registry.Menus.MATTER_BOTTLER, p_38852_, inventory, tile
|
||||
) {
|
||||
var workFlow = BooleanDataContainer()
|
||||
|
||||
public ContainerData work_flow = new ContainerData() {
|
||||
private int value;
|
||||
val progressWidget: ProgressGaugeWidget
|
||||
val matterWidget: LevelGaugeWidget
|
||||
val container = arrayOfNulls<MatterySlot>(6)
|
||||
|
||||
@Override
|
||||
public int get(int i) {
|
||||
if (tile != null) {
|
||||
return ((BlockEntityMatterBottler) tile).getWorkFlow() ? 1 : 0;
|
||||
init {
|
||||
val container = tile?.container ?: SimpleContainer(6)
|
||||
|
||||
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
|
||||
public void set(int i, int i1) {
|
||||
value = i1;
|
||||
}
|
||||
addDataSlots(workFlow)
|
||||
addBatterySlot()
|
||||
addInventorySlots()
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
override fun broadcastChanges() {
|
||||
super.broadcastChanges()
|
||||
workFlow.value = (tile as BlockEntityMatterBottler).workFlow
|
||||
}
|
||||
|
||||
public ProgressGaugeWidget progress;
|
||||
public LevelGaugeWidget matter_widget;
|
||||
override fun getWorkingSlotStart(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
public MatterySlot[] work_slots = new MatterySlot[6];
|
||||
|
||||
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);
|
||||
override fun getWorkingSlotEnd(): Int {
|
||||
return 7
|
||||
}
|
||||
|
||||
fun switchBottlerMode() {
|
||||
if (tile == null) {
|
||||
progress = new ProgressGaugeWidget(this);
|
||||
matter_widget = new LevelGaugeWidget(this);
|
||||
MatteryNetworking.CHANNEL.sendToServer(MatterBottlerSwitchPacket())
|
||||
} else {
|
||||
progress = new ProgressGaugeWidget(this, tile::getWorkProgress);
|
||||
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();
|
||||
(tile as BlockEntityMatterBottler).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.entity.player.Inventory;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCapacitorBank;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
|
||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
||||
import ru.dbotthepony.mc.otm.menu.slot.MatterContainerInputSlot;
|
||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget;
|
||||
import net.minecraft.world.SimpleContainer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import ru.dbotthepony.mc.otm.Registry
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCapacitorBank
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||
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.widget.LevelGaugeWidget
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class MatterCapacitorBankMenu extends MatteryMenu {
|
||||
public MatterCapacitorBankMenu(int p_38852_, Inventory inventory) {
|
||||
this(p_38852_, inventory, null);
|
||||
}
|
||||
|
||||
public LevelGaugeWidget matter_widget;
|
||||
public LevelGaugeWidget total_matter_widget;
|
||||
|
||||
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);
|
||||
class MatterCapacitorBankMenu @JvmOverloads constructor(
|
||||
p_38852_: Int,
|
||||
inventory: Inventory?,
|
||||
tile: BlockEntityMatterCapacitorBank? = null
|
||||
) : MatteryMenu(
|
||||
Registry.Menus.MATTER_CAPACITOR_BANK, p_38852_, inventory!!, tile
|
||||
) {
|
||||
val matter_widget: LevelGaugeWidget
|
||||
val total_matter_widget: LevelGaugeWidget
|
||||
val container_slots = arrayOfNulls<MatterContainerInputSlot>(2 * 6)
|
||||
|
||||
init {
|
||||
if (tile == null) {
|
||||
matter_widget = new LevelGaugeWidget(this);
|
||||
total_matter_widget = new LevelGaugeWidget(this);
|
||||
matter_widget = LevelGaugeWidget(this)
|
||||
total_matter_widget = LevelGaugeWidget(this)
|
||||
} else {
|
||||
matter_widget = new LevelGaugeWidget(this, tile.matter);
|
||||
total_matter_widget = new LevelGaugeWidget(this, () -> {
|
||||
if (tile.getMatterGrid() != null) {
|
||||
return tile.getMatterGrid().getStored();
|
||||
}
|
||||
|
||||
return Fraction.ZERO;
|
||||
}, () -> {
|
||||
if (tile.getMatterGrid() != null) {
|
||||
return tile.getMatterGrid().getCapacity();
|
||||
}
|
||||
|
||||
return Fraction.ZERO;
|
||||
});
|
||||
matter_widget = LevelGaugeWidget(this, tile)
|
||||
total_matter_widget = LevelGaugeWidget(this, {
|
||||
(tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getMatterStorageLevel() ?: Fraction.ZERO
|
||||
}, {
|
||||
(tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getMatterStorageMaxLevel() ?: 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 (int column = 0; column < 6; column++) {
|
||||
container_slots[row * 6 + column] = new MatterContainerInputSlot(container, row * 6 + column, 44 + column * 18, 20 + row * 18, true, IMatterHandler.MatterDirection.BIDIRECTIONAL);
|
||||
addSlot(container_slots[row * 6 + column]);
|
||||
for (row in 0..1) {
|
||||
for (column in 0..5) {
|
||||
container_slots[row * 6 + column] = MatterContainerInputSlot(
|
||||
container,
|
||||
row * 6 + column,
|
||||
44 + column * 18,
|
||||
20 + row * 18,
|
||||
true,
|
||||
IMatterHandler.MatterDirection.BIDIRECTIONAL
|
||||
)
|
||||
|
||||
addSlot(container_slots[row * 6 + column]!!)
|
||||
}
|
||||
}
|
||||
|
||||
addInventorySlots();
|
||||
addInventorySlots()
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getWorkingSlotStart() {
|
||||
return 0;
|
||||
override fun getWorkingSlotStart(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getWorkingSlotEnd() {
|
||||
return 2 * 6;
|
||||
override fun getWorkingSlotEnd(): Int {
|
||||
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.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
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.PatternState;
|
||||
import ru.dbotthepony.mc.otm.matter.MatterGrid;
|
||||
import ru.dbotthepony.mc.otm.network.CancelMatterTaskPacket;
|
||||
import ru.dbotthepony.mc.otm.network.MatterTaskPacket;
|
||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
|
||||
import ru.dbotthepony.mc.otm.network.PatternGridPacket;
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.Registry
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterPanel
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterTask
|
||||
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener
|
||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||
import ru.dbotthepony.mc.otm.network.CancelMatterTaskPacket
|
||||
import ru.dbotthepony.mc.otm.network.MatterTaskPacket
|
||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||
import ru.dbotthepony.mc.otm.network.PatternGridPacket
|
||||
import java.util.*
|
||||
import java.util.function.Consumer
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MatterPanelMenu extends MatteryMenu implements IMatterGridListener {
|
||||
public MatterPanelMenu(int p_38852_, Inventory inventory) {
|
||||
this(p_38852_, inventory, null);
|
||||
class MatterPanelMenu @JvmOverloads constructor(
|
||||
p_38852_: Int,
|
||||
inventory: Inventory,
|
||||
tile: BlockEntityMatterPanel? = null
|
||||
) : MatteryMenu(Registry.Menus.MATTER_PANEL, p_38852_, inventory, tile), IMatterGraphListener {
|
||||
fun taskUpdated(task: MatterTask) {
|
||||
sendNetwork(MatterTaskPacket(true, listOf(task)))
|
||||
}
|
||||
|
||||
private BlockEntityMatterPanel tile;
|
||||
private MatterGrid grid;
|
||||
|
||||
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));
|
||||
fun taskRemoved(task: MatterTask) {
|
||||
sendNetwork(MatterTaskPacket(false, listOf(task)))
|
||||
}
|
||||
|
||||
// client code
|
||||
public ArrayList<PatternState> patterns = new ArrayList<>();
|
||||
public ArrayList<MatterTask> tasks = new ArrayList<>();
|
||||
public int changeset = 0;
|
||||
@JvmField
|
||||
var patterns = ArrayList<PatternState>()
|
||||
|
||||
public void networkPatternsUpdated(PatternState[] patterns) {
|
||||
changeset++;
|
||||
@JvmField
|
||||
var tasks = ArrayList<MatterTask>()
|
||||
|
||||
for (var pattern : patterns) {
|
||||
var index_of = this.patterns.indexOf(pattern);
|
||||
var changeset = 0
|
||||
|
||||
if (index_of != -1) {
|
||||
this.patterns.set(index_of, pattern);
|
||||
fun networkPatternsUpdated(patterns: Collection<PatternState>) {
|
||||
changeset++
|
||||
|
||||
for (pattern in patterns) {
|
||||
val index = this.patterns.indexOf(pattern)
|
||||
|
||||
if (index != -1) {
|
||||
this.patterns[index] = pattern
|
||||
} else {
|
||||
this.patterns.add(pattern);
|
||||
this.patterns.add(pattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void networkPatternsRemoved(PatternState[] patterns) {
|
||||
changeset++;
|
||||
fun networkPatternsRemoved(patterns: Collection<PatternState>) {
|
||||
changeset++
|
||||
|
||||
for (var pattern : patterns) {
|
||||
this.patterns.remove(pattern);
|
||||
for (pattern in patterns) {
|
||||
this.patterns.remove(pattern)
|
||||
}
|
||||
}
|
||||
|
||||
public void networkTasksUpdated(MatterTask[] tasks) {
|
||||
changeset++;
|
||||
fun networkTasksUpdated(tasks: Collection<MatterTask>) {
|
||||
changeset++
|
||||
|
||||
for (var task : tasks) {
|
||||
var index_of = this.tasks.indexOf(task);
|
||||
for (task in tasks) {
|
||||
val index = this.tasks.indexOf(task)
|
||||
|
||||
if (index_of != -1) {
|
||||
this.tasks.set(index_of, task);
|
||||
if (index != -1) {
|
||||
this.tasks[index] = task
|
||||
} 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) {
|
||||
changeset++;
|
||||
fun networkTasksRemoved(tasks: Collection<MatterTask>) {
|
||||
changeset++
|
||||
|
||||
for (var task : tasks) {
|
||||
this.tasks.remove(task);
|
||||
|
||||
if (watcher_delete != null)
|
||||
watcher_delete.accept(task);
|
||||
for (task in tasks) {
|
||||
this.tasks.remove(task)
|
||||
watcher_delete?.accept(task)
|
||||
}
|
||||
}
|
||||
|
||||
private Consumer<MatterTask> watcher_delete;
|
||||
private Consumer<MatterTask> watcher_update;
|
||||
private var watcher_delete: Consumer<MatterTask>? = null
|
||||
private var watcher_update: Consumer<MatterTask>? = null
|
||||
|
||||
public void networkTaskWatcher(Consumer<MatterTask> watcher_update, Consumer<MatterTask> watcher_delete) {
|
||||
this.watcher_delete = watcher_delete;
|
||||
this.watcher_update = watcher_update;
|
||||
fun networkTaskWatcher(watcher_update: Consumer<MatterTask>, watcher_delete: Consumer<MatterTask>) {
|
||||
this.watcher_delete = watcher_delete
|
||||
this.watcher_update = watcher_update
|
||||
}
|
||||
|
||||
// server code
|
||||
public void requestReplication(ServerPlayer ply, PatternState state, int how_much) {
|
||||
if (tile == null)
|
||||
return;
|
||||
fun requestReplication(ply: ServerPlayer, state: PatternState, how_much: Int) {
|
||||
val tile = tile as BlockEntityMatterPanel? ?: return
|
||||
|
||||
var grid = tile.getMatterGrid();
|
||||
val graph = tile.getAsMatterNode().graph as MatterNetworkGraph? ?: return
|
||||
|
||||
if (grid == null)
|
||||
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;
|
||||
if (graph.getPattern(state) == 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) {
|
||||
if (tile == null)
|
||||
return;
|
||||
|
||||
tile.removeTask(id);
|
||||
fun receiveTaskCancel(ply: ServerPlayer, id: UUID) {
|
||||
(tile as BlockEntityMatterPanel?)?.removeTask(id)
|
||||
}
|
||||
|
||||
public void requestTaskCancel(UUID id) {
|
||||
MatteryNetworking.CHANNEL.sendToServer(new CancelMatterTaskPacket(id));
|
||||
fun requestTaskCancel(id: UUID) {
|
||||
MatteryNetworking.CHANNEL.sendToServer(CancelMatterTaskPacket(id))
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPatternAdded(PatternState state) {
|
||||
sendNetwork(new PatternGridPacket(true, state));
|
||||
override fun onPatternAdded(state: PatternState) {
|
||||
sendNetwork(PatternGridPacket(true, listOf(state)))
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPatternRemoved(PatternState state) {
|
||||
sendNetwork(new PatternGridPacket(false, state));
|
||||
override fun onPatternRemoved(state: PatternState) {
|
||||
sendNetwork(PatternGridPacket(false, listOf(state)))
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPatternUpdated(PatternState new_state, PatternState old_state) {
|
||||
sendNetwork(new PatternGridPacket(true, new_state));
|
||||
override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {
|
||||
sendNetwork(PatternGridPacket(true, listOf(new_state)))
|
||||
}
|
||||
|
||||
private boolean initial_send = false;
|
||||
private var initial_send = false
|
||||
|
||||
@Override
|
||||
public void removed(Player p_38940_) {
|
||||
super.removed(p_38940_);
|
||||
private var listeningGrid: MatterNetworkGraph? = null
|
||||
|
||||
if (tile != null)
|
||||
tile.deatachMenu(this);
|
||||
|
||||
if (grid != null)
|
||||
grid.detach(this);
|
||||
init {
|
||||
if (tile != null) {
|
||||
listeningGrid = tile.getAsMatterNode().graph as MatterNetworkGraph?
|
||||
tile.attachMenu(this)
|
||||
listeningGrid?.addListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastChanges() {
|
||||
super.broadcastChanges();
|
||||
|
||||
if (!initial_send)
|
||||
fullPatternBroadcast();
|
||||
override fun removed(p_38940_: Player) {
|
||||
super.removed(p_38940_)
|
||||
(tile as BlockEntityMatterPanel?)?.deatachMenu(this)
|
||||
listeningGrid?.removeListener(this)
|
||||
}
|
||||
|
||||
private void sendNetwork(Object packet) {
|
||||
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) inventory.player), packet);
|
||||
override fun broadcastChanges() {
|
||||
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) {
|
||||
initial_send = true;
|
||||
return;
|
||||
initial_send = true
|
||||
return
|
||||
}
|
||||
|
||||
val tile = tile as BlockEntityMatterPanel?
|
||||
|
||||
if (tile != null) {
|
||||
var grid = tile.getMatterGrid();
|
||||
val grid = tile.getAsMatterNode().graph as MatterNetworkGraph?
|
||||
|
||||
if (grid != null) {
|
||||
initial_send = true;
|
||||
sendNetwork(new PatternGridPacket(true, grid.getStoredPatterns().toArray(new PatternState[0])));
|
||||
initial_send = true
|
||||
sendNetwork(PatternGridPacket(true, grid.getStoredPatterns()))
|
||||
}
|
||||
|
||||
sendNetwork(new MatterTaskPacket(true, tile.getAllTasks().toArray(new MatterTask[0])));
|
||||
sendNetwork(MatterTaskPacket(true, tile.allTasks))
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getWorkingSlotStart() {
|
||||
return 0;
|
||||
override fun getWorkingSlotStart(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getWorkingSlotEnd() {
|
||||
return 0;
|
||||
override fun getWorkingSlotEnd(): Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import net.minecraft.world.SimpleContainer
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.Registry
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||
import ru.dbotthepony.mc.otm.matter.MatterRegistry
|
||||
import java.math.BigInteger
|
||||
|
||||
@ -38,8 +39,8 @@ class MatterScannerMenu @JvmOverloads constructor(
|
||||
if (tile != null) {
|
||||
progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }) { tile.cantProcessJob() }
|
||||
patterns = LevelGaugeWidget(this,
|
||||
{ Fraction(tile.matterGrid?.storedPatternCount?.toBigInteger() ?: BigInteger.ZERO) },
|
||||
{ Fraction(tile.matterGrid?.patternCapacity?.toBigInteger() ?: BigInteger.ZERO) })
|
||||
{ Fraction(tile.getAsMatterGraph()?.getPatternCount()?.toBigInteger() ?: BigInteger.ZERO) },
|
||||
{ Fraction(tile.getAsMatterGraph()?.getPatternCapacity()?.toBigInteger() ?: BigInteger.ZERO) })
|
||||
} else {
|
||||
progress = ProgressGaugeWidget(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.entity.player.Inventory;
|
||||
import ru.dbotthepony.mc.otm.Registry;
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityPatternStorage;
|
||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
||||
import ru.dbotthepony.mc.otm.menu.slot.PatternSlot;
|
||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget;
|
||||
import net.minecraft.world.SimpleContainer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import ru.dbotthepony.mc.otm.Registry
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityPatternStorage
|
||||
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.widget.LevelGaugeWidget
|
||||
|
||||
public class PatternStorageMenu extends MatteryMenu {
|
||||
public PatternStorageMenu(int p_38852_, Inventory inventory) {
|
||||
this(p_38852_, inventory, null);
|
||||
}
|
||||
|
||||
public PatternSlot[] pattern_slots = new PatternSlot[2 * 4];
|
||||
|
||||
public LevelGaugeWidget stored_this;
|
||||
public LevelGaugeWidget stored_grid;
|
||||
|
||||
public PatternStorageMenu(int p_38852_, Inventory inventory, BlockEntityPatternStorage tile) {
|
||||
super(Registry.Menus.PATTERN_STORAGE, p_38852_, inventory, tile);
|
||||
class PatternStorageMenu @JvmOverloads constructor(
|
||||
p_38852_: Int,
|
||||
inventory: Inventory?,
|
||||
tile: BlockEntityPatternStorage? = null
|
||||
) : MatteryMenu(
|
||||
Registry.Menus.PATTERN_STORAGE, p_38852_, inventory!!, tile
|
||||
) {
|
||||
val pattern_slots = arrayOfNulls<PatternSlot>(2 * 4)
|
||||
val stored_this: LevelGaugeWidget
|
||||
val stored_grid: LevelGaugeWidget
|
||||
|
||||
init {
|
||||
if (tile == null) {
|
||||
stored_this = new LevelGaugeWidget(this);
|
||||
stored_grid = new LevelGaugeWidget(this);
|
||||
stored_this = LevelGaugeWidget(this)
|
||||
stored_grid = LevelGaugeWidget(this)
|
||||
} else {
|
||||
stored_this = new LevelGaugeWidget(this, tile.getPatternStorage());
|
||||
stored_grid = new LevelGaugeWidget(this, () -> {
|
||||
if (tile.getMatterGrid() != null) {
|
||||
return new Fraction(tile.getMatterGrid().getStoredPatternCount());
|
||||
}
|
||||
|
||||
return Fraction.ZERO;
|
||||
}, () -> {
|
||||
if (tile.getMatterGrid() != null) {
|
||||
return new Fraction(tile.getMatterGrid().getPatternCapacity());
|
||||
}
|
||||
|
||||
return Fraction.ZERO;
|
||||
});
|
||||
stored_this = LevelGaugeWidget(this, tile)
|
||||
stored_grid = LevelGaugeWidget(this, {
|
||||
Fraction((tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getPatternCount() ?: 0)
|
||||
}, {
|
||||
Fraction((tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getPatternCapacity() ?: 0)
|
||||
})
|
||||
}
|
||||
|
||||
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 (int column = 0; column < 4; column++) {
|
||||
pattern_slots[row * 4 + column] = new PatternSlot(patterns, row * 4 + column, 48 + column * 20, 27 + row * 24);
|
||||
addSlot(pattern_slots[row * 4 + column]);
|
||||
for (row in 0..1) {
|
||||
for (column in 0..3) {
|
||||
pattern_slots[row * 4 + column] = PatternSlot(patterns, row * 4 + column, 48 + column * 20, 27 + row * 24)
|
||||
addSlot(pattern_slots[row * 4 + column]!!)
|
||||
}
|
||||
}
|
||||
|
||||
addInventorySlots();
|
||||
addInventorySlots()
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getWorkingSlotStart() {
|
||||
return 0;
|
||||
override fun getWorkingSlotStart(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getWorkingSlotEnd() {
|
||||
return 2 * 4;
|
||||
override fun getWorkingSlotEnd(): Int {
|
||||
return 2 * 4
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +1,47 @@
|
||||
package ru.dbotthepony.mc.otm.menu.data
|
||||
|
||||
import net.minecraft.world.inventory.ContainerData
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import ru.dbotthepony.mc.otm.network.NetworkHelper
|
||||
import java.util.zip.CRC32
|
||||
|
||||
class FractionDataContainer : ContainerData {
|
||||
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 _value2: Fraction? = Fraction.ZERO
|
||||
|
||||
fun hasComputedValue(): Boolean {
|
||||
return _value != null
|
||||
}
|
||||
|
||||
private var mute = false
|
||||
|
||||
var value: Fraction
|
||||
get() {
|
||||
if (_value != null)
|
||||
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!!
|
||||
}
|
||||
set(value) {
|
||||
@ -31,7 +52,28 @@ class FractionDataContainer : ContainerData {
|
||||
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)
|
||||
@ -42,6 +84,7 @@ class FractionDataContainer : ContainerData {
|
||||
|
||||
override operator fun set(p_39285_: Int, p_39286_: Int) {
|
||||
buffer[p_39285_] = p_39286_.toShort()
|
||||
if (_value != null) _value2 = _value
|
||||
_value = null
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,10 @@ import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import java.lang.Math.floor
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
import kotlin.random.Random
|
||||
|
||||
object FractionTests {
|
||||
@Test
|
||||
@ -113,12 +115,121 @@ object FractionTests {
|
||||
fun math() {
|
||||
assert((Fraction(1) / Fraction(1)) == Fraction(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(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
|
||||
@DisplayName("Fraction serialization test")
|
||||
fun serialization() {
|
||||
@ -146,6 +257,26 @@ object FractionTests {
|
||||
serialized = value.serializeNBT()
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user