Resolve most of issues with pattern network

This commit is contained in:
DBotThePony 2021-08-17 16:25:49 +07:00
parent b8bfddfe97
commit 7ba1cca72d
Signed by: DBot
GPG Key ID: DCC23B5715498507
21 changed files with 562 additions and 254 deletions

View File

@ -159,10 +159,10 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryPoweredWorker
@Override @Override
public void setRemoved() { public void setRemoved() {
super.setRemoved();
if (level != null && !level.isClientSide && grid != null) if (level != null && !level.isClientSide && grid != null)
grid.untrack(this); grid.untrack(this);
super.setRemoved();
} }
@Override @Override

View File

@ -10,17 +10,12 @@ import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.capability.IMatterGridCell; import ru.dbotthepony.mc.otm.capability.*;
import ru.dbotthepony.mc.otm.capability.IMatterTaskProvider;
import ru.dbotthepony.mc.otm.capability.MatterTask;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.matter.MatterGrid;
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu; import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
@ -82,6 +77,14 @@ public class BlockEntityMatterPanel extends BlockEntityMattery implements IMatte
scheduleDiscoverNeighbours(getBlockPos(), p_155231_); scheduleDiscoverNeighbours(getBlockPos(), p_155231_);
} }
@Override
public void setRemoved() {
if (level != null && !level.isClientSide && grid != null)
grid.untrack(this);
super.setRemoved();
}
@Nullable @Nullable
@Override @Override
public MatterGrid getMatterGrid() { public MatterGrid getMatterGrid() {
@ -120,14 +123,26 @@ public class BlockEntityMatterPanel extends BlockEntityMattery implements IMatte
@Nullable @Nullable
@Override @Override
public MatterTask allocateTask(boolean simulate) { public MatterTaskAllocation allocateTask(boolean simulate) {
for (var entry : tasks.entrySet()) { if (grid == null)
if (entry.getValue().required() > 0) { return null;
if (!simulate) {
tasks.put(entry.getKey(), entry.getValue().shrinkRequired(1));
}
return entry.getValue(); for (var entry : tasks.entrySet()) {
var task = entry.getValue();
if (task.required() > 0) {
var get_pattern = grid.getPattern(task.pattern());
if (get_pattern != null) {
if (!simulate) {
var newer = task.shrinkRequired(1);
tasks.put(entry.getKey(), newer);
grid.onMatterTaskUpdated(newer, task);
}
return new MatterTaskAllocation(task, get_pattern);
}
} }
} }
@ -135,20 +150,29 @@ public class BlockEntityMatterPanel extends BlockEntityMattery implements IMatte
} }
@Override @Override
public void notifyTaskCompletion(MatterTask task) { public boolean notifyTaskCompletion(MatterTask task) {
var get_task = tasks.get(task.id()); var get_task = tasks.get(task.id());
if (get_task == null) { if (get_task == null) {
return; return false;
} }
var old_task = get_task;
get_task = get_task.shrinkInProgress(1); get_task = get_task.shrinkInProgress(1);
if (get_task.required() == 0 && get_task.in_progress() == 0) { if (get_task.required() <= 0 && get_task.in_progress() <= 0) {
tasks.remove(task.id()); tasks.remove(task.id());
if (grid != null)
grid.onMatterTaskCreated(task);
} else { } else {
tasks.put(task.id(), get_task); tasks.put(task.id(), get_task);
if (grid != null)
grid.onMatterTaskUpdated(get_task, old_task);
} }
return true;
} }
@Override @Override
@ -186,9 +210,13 @@ public class BlockEntityMatterPanel extends BlockEntityMattery implements IMatte
return tasks.get(id); return tasks.get(id);
} }
public MatterTask addTask(Item item, int how_much) { public MatterTask addTask(PatternState state, int how_much) {
var task = new MatterTask(UUID.randomUUID(), item, 0, 0, how_much); var task = new MatterTask(UUID.randomUUID(), state.id(), state.item(), 0, 0, how_much);
tasks.put(task.id(), task); tasks.put(task.id(), task);
if (grid != null)
grid.onMatterTaskCreated(task);
return task; return task;
} }

View File

@ -80,10 +80,23 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryPoweredWorker
} }
@Override @Override
public void notifyTasksChanged() { public void onMatterTaskCreated(MatterTask task) {
is_idling = false; is_idling = false;
} }
@Override
public void onMatterTaskUpdated(MatterTask new_state, MatterTask old_state) {
is_idling = false;
}
@Override
public void setRemoved() {
if (level != null && !level.isClientSide && grid != null)
grid.untrack(this);
super.setRemoved();
}
private static final double TICKS_PER_MTU = 20_000d; private static final double TICKS_PER_MTU = 20_000d;
private static final BigDecimal TICKS_PER_MTU_BD = new BigDecimal(20_000); private static final BigDecimal TICKS_PER_MTU_BD = new BigDecimal(20_000);
private static final double MTU_PER_TICK = 1d / 20_000d; private static final double MTU_PER_TICK = 1d / 20_000d;
@ -103,12 +116,12 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryPoweredWorker
if (grid == null) if (grid == null)
return null; return null;
MatterTask task = grid.allocateTask(false); MatterTaskAllocation allocation = grid.allocateTask(false);
if (task == null) if (allocation == null)
return null; return null;
ItemStack stack = task.stack(1); ItemStack stack = allocation.task().stack(1);
// ???????? // ????????
if (!MatterRegistry.hasMatterValue(stack)) if (!MatterRegistry.hasMatterValue(stack))
@ -116,7 +129,10 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryPoweredWorker
MachineJob job = new MachineJob(stack, MatterRegistry.getMatterValue(stack).doubleValue() * TICKS_PER_MTU); MachineJob job = new MachineJob(stack, MatterRegistry.getMatterValue(stack).doubleValue() * TICKS_PER_MTU);
job.data().put("task", task.serializeNBT()); job.data().put("task", allocation.task().serializeNBT());
if (allocation.pattern() != null)
job.data().put("pattern", allocation.pattern().serializeNBT());
return job; return job;
} }
@ -125,7 +141,7 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryPoweredWorker
@Override @Override
protected MachineJobStatus onWorkTick(WorkTickContext context) { protected MachineJobStatus onWorkTick(WorkTickContext context) {
BigDecimal drain_per_tick = MatterRegistry.getMatterValue(context.job().stack().getItem()).multiply(MTU_PER_TICK_BD, MatteryCapability.ROUND_RULES).multiply(context.work_speed(), MatteryCapability.ROUND_RULES); BigDecimal drain_per_tick = MTU_PER_TICK_BD.multiply(context.work_speed(), MatteryCapability.ROUND_RULES);
if (matter.extractMatterInner(drain_per_tick, true).compareTo(drain_per_tick) < 0) { if (matter.extractMatterInner(drain_per_tick, true).compareTo(drain_per_tick) < 0) {
// в машине недостаточно материи // в машине недостаточно материи

View File

@ -26,6 +26,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Collection; import java.util.Collection;
import java.util.UUID;
public class BlockEntityMatterScanner extends BlockEntityMatteryPoweredWorker implements IMatterGridCell { public class BlockEntityMatterScanner extends BlockEntityMatteryPoweredWorker implements IMatterGridCell {
private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.matter_scanner"); private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.matter_scanner");
@ -73,10 +74,28 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryPoweredWorker im
} }
@Override @Override
public void notifyPatternsChanged() { public void onPatternAdded(PatternState state) {
is_idling = false; is_idling = false;
} }
@Override
public void onPatternRemoved(PatternState state) {
is_idling = false;
}
@Override
public void onPatternUpdated(PatternState new_state, PatternState old_state) {
is_idling = false;
}
@Override
public void setRemoved() {
if (level != null && !level.isClientSide && grid != null)
grid.untrack(this);
super.setRemoved();
}
@Override @Override
public void onNeighbourMatterCell(BlockPos pos, Level level, Direction direction, IMatterGridCell cell) { public void onNeighbourMatterCell(BlockPos pos, Level level, Direction direction, IMatterGridCell cell) {
is_idling = false; is_idling = false;
@ -125,29 +144,28 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryPoweredWorker im
return new MachineJobStatus(); return new MachineJobStatus();
Collection<IPatternStorage.PatternState> get_state = grid.findPattern(stack.getItem()); Collection<PatternState> get_state = grid.findPatterns(stack.getItem());
IPatternStorage.PatternState find_state = null; PatternState find_state = null;
for (IPatternStorage.PatternState state : get_state) { for (PatternState state : get_state) {
if (state.item() == stack.getItem() && state.research_percent() < 1d) { if (state.item() == stack.getItem()) {
find_state = state; if (find_state == null && state.research_percent() < 1d) {
find_state = state;
} else if (find_state != null && find_state.research_percent() < state.research_percent()) {
find_state = state;
}
} }
// как бы не так
// может быть это было сделано специально?
//else if (state.item() == stack.getItem() && state.research_percent() >= 1d) {
// return null;
//}
} }
IPatternStorage.PatternState new_state; PatternState new_state;
if (find_state != null) { if (find_state != null) {
new_state = new IPatternStorage.PatternState(stack.getItem(), find_state.research_percent() + 0.2d); new_state = new PatternState(find_state.id(), stack.getItem(), find_state.research_percent() + 0.2d);
} else { } else {
new_state = new IPatternStorage.PatternState(stack.getItem(), 0.2d); new_state = new PatternState(UUID.randomUUID(), stack.getItem(), 0.2d);
} }
if (grid.insertPattern(new_state, false, false)) { if (grid.insertPattern(new_state, false, false).status() != PatternInsertStatus.Status.FAIL) {
return new MachineJobStatus(); return new MachineJobStatus();
} }
@ -165,10 +183,10 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryPoweredWorker im
if (stack.isEmpty() || !MatterRegistry.hasMatterValue(stack)) if (stack.isEmpty() || !MatterRegistry.hasMatterValue(stack))
return null; return null;
Collection<IPatternStorage.PatternState> get_state = grid.findPattern(stack.getItem()); Collection<PatternState> get_state = grid.findPatterns(stack.getItem());
IPatternStorage.PatternState find_state = null; PatternState find_state = null;
for (IPatternStorage.PatternState state : get_state) { for (PatternState state : get_state) {
if (state.item() == stack.getItem() && state.research_percent() < 1d) { if (state.item() == stack.getItem() && state.research_percent() < 1d) {
find_state = state; find_state = state;
} else if (state.item() == stack.getItem() && state.research_percent() >= 1d) { } else if (state.item() == stack.getItem() && state.research_percent() >= 1d) {
@ -176,15 +194,15 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryPoweredWorker im
} }
} }
IPatternStorage.PatternState new_state; PatternState new_state;
if (find_state != null) { if (find_state != null) {
new_state = new IPatternStorage.PatternState(stack.getItem(), find_state.research_percent() + 0.2d); new_state = new PatternState(find_state.id(), stack.getItem(), find_state.research_percent() + 0.2d);
} else { } else {
new_state = new IPatternStorage.PatternState(stack.getItem(), 0.2d); new_state = new PatternState(UUID.randomUUID(), stack.getItem(), 0.2d);
} }
if (grid.insertPattern(new_state, false, true)) { if (grid.insertPattern(new_state, false, true).status() != PatternInsertStatus.Status.FAIL) {
ItemStack copy = stack.copy(); ItemStack copy = stack.copy();
copy.setCount(1); copy.setCount(1);
stack.shrink(1); stack.shrink(1);

View File

@ -32,7 +32,7 @@ public class BlockEntityPatternStorage extends BlockEntityMattery implements IMa
super(Registry.BlockEntities.PATTERN_STORAGE, p_155229_, p_155230_); super(Registry.BlockEntities.PATTERN_STORAGE, p_155229_, p_155230_);
} }
public final MatteryContainer patterns = new MatteryContainer(this::setChangedPatterns, 3 * 3) { public final MatteryContainer patterns = new MatteryContainer(this::setChanged, 3 * 3) {
@Override @Override
public int getMaxStackSize() { public int getMaxStackSize() {
return 1; return 1;
@ -43,13 +43,6 @@ public class BlockEntityPatternStorage extends BlockEntityMattery implements IMa
((slot, stack) -> stack.getCapability(MatteryCapability.PATTERN).isPresent()) ((slot, stack) -> stack.getCapability(MatteryCapability.PATTERN).isPresent())
)); ));
private void setChangedPatterns() {
setChanged();
if (grid != null)
grid.notifyPatternsChanged();
}
private MatterGrid grid; private MatterGrid grid;
@Override @Override
@ -143,6 +136,7 @@ public class BlockEntityPatternStorage extends BlockEntityMattery implements IMa
return new PatternStorageMenu(containerID, inventory, this); return new PatternStorageMenu(containerID, inventory, this);
} }
@Nonnull
@Override @Override
public Collection<PatternState> getStoredPatterns() { public Collection<PatternState> getStoredPatterns() {
ArrayList<PatternState> list = new ArrayList<>(); ArrayList<PatternState> list = new ArrayList<>();
@ -165,17 +159,35 @@ public class BlockEntityPatternStorage extends BlockEntityMattery implements IMa
} }
@Override @Override
public boolean insertPattern(PatternState pattern, boolean only_update, boolean simulate) { public void setRemoved() {
if (level != null && !level.isClientSide && grid != null)
grid.untrack(this);
super.setRemoved();
}
@Override
public PatternInsertStatus insertPattern(PatternState pattern, boolean only_update, boolean simulate) {
for (IPatternStorage storage : patterns.capabilityIterator(MatteryCapability.PATTERN)) { for (IPatternStorage storage : patterns.capabilityIterator(MatteryCapability.PATTERN)) {
if (storage.insertPattern(pattern, only_update, simulate)) { var status = storage.insertPattern(pattern, only_update, simulate);
if (status.status() != PatternInsertStatus.Status.FAIL) {
if (!simulate) { if (!simulate) {
setChangedPatterns(); setChanged();
if (grid != null) {
if (status.status() == PatternInsertStatus.Status.INSERTED) {
grid.onPatternAdded(status.new_state());
} else {
grid.onPatternUpdated(status.new_state(), status.old_state());
}
}
} }
return true; return status;
} }
} }
return false; return new PatternInsertStatus();
} }
} }

View File

@ -10,7 +10,7 @@ import ru.dbotthepony.mc.otm.matter.MatterGrid;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public interface IMatterGridCell { public interface IMatterGridCell extends IMatterGridListener {
@Nullable @Nullable
MatterGrid getMatterGrid(); MatterGrid getMatterGrid();
@ -33,14 +33,6 @@ public interface IMatterGridCell {
void setMatterGrid(MatterGrid grid); void setMatterGrid(MatterGrid grid);
default void notifyPatternsChanged() {
}
default void notifyTasksChanged() {
}
default void scheduleDiscoverNeighbours(BlockPos pos, Level level) { default void scheduleDiscoverNeighbours(BlockPos pos, Level level) {
MatterGrid.scheduleDiscoverNeighbours(this, pos, level); MatterGrid.scheduleDiscoverNeighbours(this, pos, level);
} }

View File

@ -0,0 +1,12 @@
package ru.dbotthepony.mc.otm.capability;
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) { }
}

View File

@ -25,18 +25,19 @@ public interface IMatterTaskProvider {
* *
* If required == 0, it should not be returned by this method * If required == 0, it should not be returned by this method
* @param simulate whenever to change internal state * @param simulate whenever to change internal state
* @return MatterTask that should be performed, or null of no tasks available * @return MatterTaskAllocation(task, pattern) that should be performed, or null if no work is available
*/ */
@Nullable @Nullable
MatterTask allocateTask(boolean simulate); MatterTaskAllocation allocateTask(boolean simulate);
/** /**
* Notify about task completion. If this provider indeed contain this task, it should * Notify about task completion. If this provider indeed contain this task, it should
* shrink in_progress by 1 * shrink in_progress by 1
* If in_progress == 0 and required == 0, it should discard the task * If in_progress == 0 and required == 0, it should discard the task
* @param task task being completed. this method should ignore tasks that are not owned by it. * @param task task being completed. this method should ignore tasks that are not owned by it.
* @return whenever task indeed belong to this provider and internal state was updated
*/ */
void notifyTaskCompletion(MatterTask task); boolean notifyTaskCompletion(MatterTask task);
/** /**
* @param id uuid of task * @param id uuid of task

View File

@ -1,45 +1,15 @@
package ru.dbotthepony.mc.otm.capability; package ru.dbotthepony.mc.otm.capability;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.RegistryManager;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Collection; import java.util.Collection;
import java.util.UUID;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public interface IPatternStorage { public interface IPatternStorage {
record PatternState(Item item, double research_percent) {
public PatternState(@Nonnull Item item, double research_percent) {
this.item = item;
this.research_percent = Math.max(0, Math.min(1, research_percent));
}
public boolean equals(PatternState state) {
return state.item == this.item && state.research_percent == this.research_percent;
}
public void write(FriendlyByteBuf buffer) {
buffer.writeInt(((ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class)).getID(item));
buffer.writeDouble(research_percent);
}
@Nullable
public static PatternState read(FriendlyByteBuf buffer) {
int item = buffer.readInt();
double percent = buffer.readDouble();
Item get_item = ((ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class)).getValue(item);
if (get_item == null)
return null;
return new PatternState(get_item, percent);
}
}
/** /**
* @return unmodifiable collection of stored patterns * @return unmodifiable collection of stored patterns
@ -48,41 +18,72 @@ public interface IPatternStorage {
Collection<PatternState> getStoredPatterns(); Collection<PatternState> getStoredPatterns();
@Nonnull @Nonnull
default Collection<PatternState> findPattern(Item item) { default Collection<PatternState> findPatterns(Item item) {
return findPattern((item2) -> item.equals(item2.item)); return findPatterns((item2) -> item.equals(item2.item()));
} }
@Nonnull @Nonnull
default Collection<PatternState> findPattern(Predicate<PatternState> predicate) { default Collection<PatternState> findPatterns(Predicate<PatternState> predicate) {
return getStoredPatterns().stream().filter(predicate).collect(Collectors.toList()); return getStoredPatterns().stream().filter(predicate).collect(Collectors.toList());
} }
default boolean hasExactPattern(PatternState state) { @Nullable
for (PatternState state1 : getStoredPatterns()) { default PatternState findPattern(Item item) {
if (state1.equals(state)) { return findPattern((item2) -> item.equals(item2.item()));
return true; }
@Nullable
default PatternState findPattern(Predicate<PatternState> predicate) {
for (var pattern : getStoredPatterns()) {
if (predicate.test(pattern)) {
return pattern;
} }
} }
return false; return null;
}
@Nullable
default PatternState getPattern(@Nullable UUID id) {
if (id == null)
return null;
for (var pattern : getStoredPatterns()) {
if (pattern.id().equals(id)) {
return pattern;
}
}
return null;
}
default boolean hasPattern(@Nonnull PatternState state) {
return getPattern(state.id()) != null;
}
default boolean hasPattern(@Nullable UUID id) {
return getPattern(id) != null;
} }
int getCapacity(); int getCapacity();
int getStored(); int getStored();
/** /**
* Prefer way to call it is to first call only_update = true
* and if it fail, try only_update = false
*
* @param pattern pattern to be inserted or update value from * @param pattern pattern to be inserted or update value from
* @param only_update do not insert new pattern if no existing patterns match the pattern * @param only_update do not insert new pattern if this pattern's UUID is not matched
* @param simulate whenever to affect state * @param simulate whenever to affect state
* @return whenever operation was successful * @return record of status of the operation (at status() FAIL, UPDATED, INSERTED) as well as new_state and old_state
*/ */
boolean insertPattern(PatternState pattern, boolean only_update, boolean simulate); PatternInsertStatus insertPattern(PatternState pattern, boolean only_update, boolean simulate);
default boolean insertPattern(PatternState pattern, boolean simulate) { default PatternInsertStatus insertPattern(PatternState pattern, boolean simulate) {
return insertPattern(pattern, false, simulate); return insertPattern(pattern, false, simulate);
} }
default boolean updatePattern(PatternState pattern, boolean simulate) { default PatternInsertStatus updatePattern(PatternState pattern, boolean simulate) {
return insertPattern(pattern, true, simulate); return insertPattern(pattern, true, simulate);
} }
} }

View File

@ -2,19 +2,23 @@ package ru.dbotthepony.mc.otm.capability;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.RegistryManager; import net.minecraftforge.registries.RegistryManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
public record MatterTask(UUID id, Item item, int in_progress, int finished, int required) { public record MatterTask(@Nonnull UUID id, @Nullable UUID pattern, @Nonnull Item item, int in_progress, int finished, int required) {
public MatterTask(UUID id, Item item, int in_progress, int finished, int required) { public MatterTask(@Nonnull UUID id, @Nullable UUID pattern, @Nonnull Item item, int in_progress, int finished, int required) {
this.id = id; this.id = id;
this.pattern = pattern;
this.item = item; this.item = item;
this.in_progress = Math.max(0, in_progress); this.in_progress = Math.max(0, in_progress);
this.finished = Math.max(0, finished); this.finished = Math.max(0, finished);
@ -34,11 +38,11 @@ public record MatterTask(UUID id, Item item, int in_progress, int finished, int
} }
public MatterTask shrinkRequired(int amount) { public MatterTask shrinkRequired(int amount) {
return new MatterTask(id, item, in_progress + amount, finished, required - amount); return new MatterTask(id, pattern, item, in_progress + amount, finished, required - amount);
} }
public MatterTask shrinkInProgress(int amount) { public MatterTask shrinkInProgress(int amount) {
return new MatterTask(id, item, in_progress - amount, finished + amount, required); return new MatterTask(id, pattern, item, in_progress - amount, finished + amount, required);
} }
public CompoundTag serializeNBT() { public CompoundTag serializeNBT() {
@ -46,6 +50,12 @@ public record MatterTask(UUID id, Item item, int in_progress, int finished, int
tag.putLong("id_l", id.getLeastSignificantBits()); tag.putLong("id_l", id.getLeastSignificantBits());
tag.putLong("id_u", id.getMostSignificantBits()); tag.putLong("id_u", id.getMostSignificantBits());
if (pattern != null) {
tag.putLong("pattern_l", pattern.getLeastSignificantBits());
tag.putLong("pattern_u", pattern.getMostSignificantBits());
}
tag.putString("item", Objects.requireNonNull(item.getRegistryName()).toString()); tag.putString("item", Objects.requireNonNull(item.getRegistryName()).toString());
tag.putInt("in_progress", in_progress); tag.putInt("in_progress", in_progress);
tag.putInt("finished", finished); tag.putInt("finished", finished);
@ -62,16 +72,42 @@ public record MatterTask(UUID id, Item item, int in_progress, int finished, int
if (nbt instanceof CompoundTag tag) { if (nbt instanceof CompoundTag tag) {
Item get_item = RegistryManager.ACTIVE.getRegistry(Item.class).getValue(new ResourceLocation(tag.getString("item"))); Item get_item = RegistryManager.ACTIVE.getRegistry(Item.class).getValue(new ResourceLocation(tag.getString("item")));
if (get_item != null) if (get_item != null) {
long a = tag.getLong("pattern_u");
long b = tag.getLong("pattern_l");
UUID pattern = a != 0 && b != 0 ? new UUID(a, b) : null;
return new MatterTask( return new MatterTask(
new UUID(tag.getLong("id_u"), tag.getLong("id_l")), new UUID(tag.getLong("id_u"), tag.getLong("id_l")),
pattern,
get_item, get_item,
tag.getInt("in_progress"), tag.getInt("in_progress"),
tag.getInt("finished"), tag.getInt("finished"),
tag.getInt("required") tag.getInt("required")
); );
}
} }
return null; return null;
} }
public void write(FriendlyByteBuf buffer) {
buffer.writeLong(id.getMostSignificantBits());
buffer.writeLong(id.getLeastSignificantBits());
if (pattern != null) {
buffer.writeBoolean(true);
buffer.writeLong(pattern.getMostSignificantBits());
buffer.writeLong(pattern.getLeastSignificantBits());
} else {
buffer.writeBoolean(false);
}
buffer.writeInt(((ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class)).getID(item));
buffer.writeInt(in_progress);
buffer.writeInt(finished);
buffer.writeInt(required);
}
} }

View File

@ -0,0 +1,8 @@
package ru.dbotthepony.mc.otm.capability;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public record MatterTaskAllocation(@Nonnull MatterTask task, @Nullable PatternState pattern) {
}

View File

@ -0,0 +1,36 @@
package ru.dbotthepony.mc.otm.capability;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* status: FAIL, UPDATED or INSERTED
* new_state: null if FAIL, the pattern privided for insertion otherwise (or modified copy of it)
* old_state: on UPDATED, previous state, or null if not UPDATED
*/
public record PatternInsertStatus(@Nonnull Status status, @Nullable PatternState new_state, @Nullable PatternState old_state) {
public enum Status {
FAIL,
UPDATED,
INSERTED,
}
public PatternInsertStatus(@Nonnull Status status, @Nullable PatternState new_state, @Nullable PatternState old_state) {
this.status = status;
this.new_state = new_state;
this.old_state = old_state;
}
public PatternInsertStatus() {
this(Status.FAIL, null, null);
}
public PatternInsertStatus(@Nonnull PatternState new_state) {
this(Status.INSERTED, new_state, null);
}
public PatternInsertStatus(@Nonnull PatternState new_state, @Nonnull PatternState old_state) {
this(Status.UPDATED, new_state, old_state);
}
}

View File

@ -0,0 +1,83 @@
package ru.dbotthepony.mc.otm.capability;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.RegistryManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.UUID;
public record PatternState(@Nonnull UUID id, @Nonnull Item item, double research_percent) {
public PatternState(@Nonnull UUID id, @Nonnull Item item, double research_percent) {
this.id = id;
this.item = item;
this.research_percent = Math.max(0, Math.min(1, research_percent));
}
public boolean equals(PatternState state) {
return state.id.equals(id);
}
public boolean equalsHard(PatternState state) {
return state.id.equals(id) && item == state.item && research_percent == state.research_percent;
}
public CompoundTag serializeNBT() {
var tag = new CompoundTag();
tag.putLong("id_m", id.getMostSignificantBits());
tag.putLong("id_l", id.getLeastSignificantBits());
tag.putString("item", Objects.requireNonNull(item.getRegistryName()).toString());
tag.putDouble("research_percent", research_percent);
return tag;
}
@Nullable
public static PatternState deserializeNBT(Tag nbt) {
if (nbt instanceof CompoundTag tag) {
var item = RegistryManager.ACTIVE.getRegistry(Item.class).getValue(new ResourceLocation(tag.getString("item")));
if (item == null)
return null;
var id = new UUID(tag.getLong("id_m"), tag.getLong("id_l"));
var research_percent = tag.getDouble("research_percent");
return new PatternState(id, item, research_percent);
}
return null;
}
public void write(FriendlyByteBuf buffer) {
buffer.writeLong(id.getMostSignificantBits());
buffer.writeLong(id.getLeastSignificantBits());
buffer.writeInt(((ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class)).getID(item));
buffer.writeDouble(research_percent);
}
@Nullable
public static PatternState read(FriendlyByteBuf buffer) {
long ida = buffer.readLong();
long idb = buffer.readLong();
int item = buffer.readInt();
double percent = buffer.readDouble();
Item get_item = ((ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class)).getValue(item);
if (get_item == null)
return null;
return new PatternState(new UUID(ida, idb), get_item, percent);
}
}

View File

@ -15,10 +15,11 @@ import net.minecraft.world.level.Level;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.RegistryManager; import net.minecraftforge.registries.RegistryManager;
import ru.dbotthepony.mc.otm.capability.IPatternStorage; import ru.dbotthepony.mc.otm.capability.IPatternStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.PatternInsertStatus;
import ru.dbotthepony.mc.otm.capability.PatternState;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -43,7 +44,7 @@ public class ItemPatternStorage extends Item {
p_41421_.getCapability(MatteryCapability.PATTERN).ifPresent(capability -> { p_41421_.getCapability(MatteryCapability.PATTERN).ifPresent(capability -> {
list.add(new TranslatableComponent("otm.item.pattern.stored", capability.getStored(), capability.getCapacity()).withStyle(ChatFormatting.GRAY)); list.add(new TranslatableComponent("otm.item.pattern.stored", capability.getStored(), capability.getCapacity()).withStyle(ChatFormatting.GRAY));
for (IPatternStorage.PatternState state : capability.getStoredPatterns()) { for (PatternState state : capability.getStoredPatterns()) {
list.add(new TranslatableComponent("otm.item.pattern.line", state.item().getName(new ItemStack(state.item(), 1)), String.format("%.2f", state.research_percent() * 100d)).withStyle(ChatFormatting.AQUA)); list.add(new TranslatableComponent("otm.item.pattern.line", state.item().getName(new ItemStack(state.item(), 1)), String.format("%.2f", state.research_percent() * 100d)).withStyle(ChatFormatting.AQUA));
} }
}); });
@ -80,6 +81,7 @@ public class ItemPatternStorage extends Item {
return LazyOptional.empty(); return LazyOptional.empty();
} }
@Nonnull
@Override @Override
public Collection<PatternState> getStoredPatterns() { public Collection<PatternState> getStoredPatterns() {
CompoundTag tag = stack.getOrCreateTag(); CompoundTag tag = stack.getOrCreateTag();
@ -91,21 +93,17 @@ public class ItemPatternStorage extends Item {
ArrayList<PatternState> state_list = new ArrayList<>(); ArrayList<PatternState> state_list = new ArrayList<>();
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
CompoundTag get_tag = list.getCompound(i); var state = PatternState.deserializeNBT(list.getCompound(i));
if (get_tag.get("id") instanceof StringTag id && get_tag.get("progress") instanceof DoubleTag progress) { if (state != null)
Item get_item = RegistryManager.ACTIVE.getRegistry(Item.class).getValue(new ResourceLocation(id.getAsString())); state_list.add(state);
if (get_item != null)
state_list.add(new PatternState(get_item, progress.getAsDouble()));
}
} }
return ImmutableList.copyOf(state_list); return ImmutableList.copyOf(state_list);
} }
@Override @Override
public boolean insertPattern(PatternState pattern, boolean only_update, boolean simulate) { public PatternInsertStatus insertPattern(PatternState pattern, boolean only_update, boolean simulate) {
CompoundTag tag = stack.getOrCreateTag(); CompoundTag tag = stack.getOrCreateTag();
ListTag list; ListTag list;
@ -114,10 +112,14 @@ public class ItemPatternStorage extends Item {
list = list1; list = list1;
} else { } else {
if (only_update) if (only_update)
return false; return new PatternInsertStatus();
if (simulate) if (simulate) {
return capacity > 0; if (capacity > 0)
return new PatternInsertStatus(pattern);
else
return new PatternInsertStatus();
}
list = new ListTag(); list = new ListTag();
tag.put("otm_patterns", list); tag.put("otm_patterns", list);
@ -128,15 +130,15 @@ public class ItemPatternStorage extends Item {
int invalid_entries = 0; int invalid_entries = 0;
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
CompoundTag get_tag = list.getCompound(i); var state = PatternState.deserializeNBT(list.getCompound(i));
if (get_tag.get("id") instanceof StringTag id) { if (state != null) {
if (compare_with.equals(id.getAsString())) { if (state.equals(pattern)) {
if (!simulate) { if (!simulate) {
get_tag.putDouble("progress", pattern.research_percent()); list.set(i, pattern.serializeNBT());
} }
return true; return new PatternInsertStatus(pattern, state);
} }
} else { } else {
invalid_entries++; invalid_entries++;
@ -144,32 +146,26 @@ public class ItemPatternStorage extends Item {
} }
if (only_update || capacity <= list.size() - invalid_entries) if (only_update || capacity <= list.size() - invalid_entries)
return false; return new PatternInsertStatus();
if (invalid_entries > 0) { if (invalid_entries > 0) {
if (simulate) if (simulate)
return true; return new PatternInsertStatus(pattern);
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
CompoundTag get_tag = list.getCompound(i); var state = PatternState.deserializeNBT(list.getCompound(i));
if (!(get_tag.get("id") instanceof StringTag)) { if (state == null) {
get_tag.putString("id", compare_with); list.set(i, pattern.serializeNBT());
get_tag.putDouble("progress", pattern.research_percent()); return new PatternInsertStatus(pattern);
return true;
} }
} }
} }
if (simulate) if (!simulate)
return true; list.add(pattern.serializeNBT());
CompoundTag get_tag = new CompoundTag(); return new PatternInsertStatus(pattern);
get_tag.putString("id", compare_with);
get_tag.putDouble("progress", pattern.research_percent());
list.add(get_tag);
return true;
} }
} }
} }

View File

@ -12,14 +12,12 @@ import ru.dbotthepony.mc.otm.capability.*;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.*;
import java.util.Collection; import java.util.function.Consumer;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
public class MatterGrid { public class MatterGrid implements IMatterGridListener {
public static final Set<MatterGrid> NETWORKS = new HashSet<>(); public static final Set<MatterGrid> NETWORKS = new HashSet<>();
private final Set<IMatterGridCell> cells = new HashSet<>(); private final Set<IMatterGridCell> cells = new HashSet<>();
@ -123,6 +121,8 @@ public class MatterGrid {
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) if (howMuch.compareTo(BigDecimal.ZERO) <= 0)
return BigDecimal.ZERO; return BigDecimal.ZERO;
validate();
BigDecimal extracted = BigDecimal.ZERO; BigDecimal extracted = BigDecimal.ZERO;
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
@ -149,6 +149,8 @@ public class MatterGrid {
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) if (howMuch.compareTo(BigDecimal.ZERO) <= 0)
return BigDecimal.ZERO; return BigDecimal.ZERO;
validate();
BigDecimal received = BigDecimal.ZERO; BigDecimal received = BigDecimal.ZERO;
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
@ -175,6 +177,8 @@ public class MatterGrid {
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) if (howMuch.compareTo(BigDecimal.ZERO) <= 0)
return BigDecimal.ZERO; return BigDecimal.ZERO;
validate();
BigDecimal received = BigDecimal.ZERO; BigDecimal received = BigDecimal.ZERO;
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
@ -197,35 +201,43 @@ public class MatterGrid {
return received; return received;
} }
public boolean insertPattern(IPatternStorage.PatternState state, boolean only_update, boolean simulate) { public PatternInsertStatus insertPattern(PatternState state, boolean only_update, boolean simulate) {
validate();
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage(); IPatternStorage storage = cell.getPatternStorage();
if (storage != null) { if (storage != null) {
if (storage.insertPattern(state, true, simulate)) { var status = storage.insertPattern(state, true, simulate);
return true;
if (status.status() != PatternInsertStatus.Status.FAIL) {
return status;
} }
} }
} }
if (only_update) if (only_update)
return false; return new PatternInsertStatus();
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage(); IPatternStorage storage = cell.getPatternStorage();
if (storage != null) { if (storage != null) {
if (storage.insertPattern(state, false, simulate)) { var status = storage.insertPattern(state, false, simulate);
return true;
if (status.status() != PatternInsertStatus.Status.FAIL) {
return status;
} }
} }
} }
return false; return new PatternInsertStatus();
} }
public Collection<IPatternStorage.PatternState> getStoredPatterns() { public Collection<PatternState> getStoredPatterns() {
ArrayList<IPatternStorage.PatternState> list = new ArrayList<>(); validate();
ArrayList<PatternState> list = new ArrayList<>();
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage(); IPatternStorage storage = cell.getPatternStorage();
@ -238,28 +250,20 @@ public class MatterGrid {
return ImmutableList.copyOf(list); return ImmutableList.copyOf(list);
} }
public Collection<IPatternStorage.PatternState> findPattern(Item item) { public Collection<PatternState> findPatterns(Item item) {
ArrayList<IPatternStorage.PatternState> list = new ArrayList<>(); return findPatterns((patternState -> item == patternState.item()));
for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage();
if (storage != null) {
list.addAll(storage.findPattern(item));
}
}
return ImmutableList.copyOf(list);
} }
public Collection<IPatternStorage.PatternState> findPattern(Predicate<IPatternStorage.PatternState> item) { public Collection<PatternState> findPatterns(Predicate<PatternState> item) {
ArrayList<IPatternStorage.PatternState> list = new ArrayList<>(); validate();
ArrayList<PatternState> list = new ArrayList<>();
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage(); IPatternStorage storage = cell.getPatternStorage();
if (storage != null) { if (storage != null) {
list.addAll(storage.findPattern(item)); list.addAll(storage.findPatterns(item));
} }
} }
@ -267,13 +271,22 @@ public class MatterGrid {
} }
@Nullable @Nullable
public IPatternStorage findExactPatternStorage(IPatternStorage.PatternState state) { public PatternState getPattern(PatternState state) {
return getPattern(state.id());
}
@Nullable
public PatternState getPattern(UUID id) {
validate();
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage(); IPatternStorage storage = cell.getPatternStorage();
if (storage != null) { if (storage != null) {
if (storage.hasExactPattern(state)) { var get = storage.getPattern(id);
return storage;
if (get != null) {
return get;
} }
} }
} }
@ -281,27 +294,19 @@ public class MatterGrid {
return null; return null;
} }
public boolean hasPatternState(IPatternStorage.PatternState state) { public boolean hasPattern(UUID id) {
for (IMatterGridCell cell : cells) { return getPattern(id) != null;
IPatternStorage storage = cell.getPatternStorage();
if (storage != null) {
if (storage.hasExactPattern(state)) {
return true;
}
}
}
return false;
} }
@Nullable @Nullable
public MatterTask allocateTask(boolean simulate) { public MatterTaskAllocation allocateTask(boolean simulate) {
validate();
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IMatterTaskProvider tasks = cell.getTaskProvider(); IMatterTaskProvider tasks = cell.getTaskProvider();
if (tasks != null) { if (tasks != null) {
MatterTask allocated = tasks.allocateTask(simulate); MatterTaskAllocation allocated = tasks.allocateTask(simulate);
if (allocated != null) { if (allocated != null) {
return allocated; return allocated;
@ -313,21 +318,20 @@ public class MatterGrid {
} }
@Nullable @Nullable
public MatterTask notifyTaskCompletion(MatterTask task) { public boolean notifyTaskCompletion(MatterTask task) {
validate();
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IMatterTaskProvider tasks = cell.getTaskProvider(); IMatterTaskProvider tasks = cell.getTaskProvider();
if (tasks != null) { if (tasks != null) {
tasks.notifyTaskCompletion(task); if (tasks.notifyTaskCompletion(task)) {
return true;
}
} }
} }
return null; return false;
}
public void notifyPatternsChanged() {
for (IMatterGridCell cell : cells)
cell.notifyPatternsChanged();
} }
public void track(IMatterGridCell entity) { public void track(IMatterGridCell entity) {
@ -337,7 +341,21 @@ public class MatterGrid {
cells.add(entity); cells.add(entity);
entity.setMatterGrid(this); entity.setMatterGrid(this);
// OverdriveThatMatters.LOGGER.debug("Tracking {} in {}. Tracking {} in total", entity, this, entities.size()); var tasks = entity.getTaskProvider();
if (tasks != null) {
for (var task : tasks.getAllTasks()) {
onMatterTaskCreated(task);
}
}
var patterns = entity.getPatternStorage();
if (patterns != null) {
for (var pattern : patterns.getStoredPatterns()) {
onPatternAdded(pattern);
}
}
} }
public void untrack(IMatterGridCell entity) { public void untrack(IMatterGridCell entity) {
@ -347,10 +365,24 @@ public class MatterGrid {
cells.remove(entity); cells.remove(entity);
entity.setMatterGrid(null); entity.setMatterGrid(null);
var tasks = entity.getTaskProvider();
if (tasks != null) {
for (var task : tasks.getAllTasks()) {
onMatterTaskRemoved(task);
}
}
var patterns = entity.getPatternStorage();
if (patterns != null) {
for (var pattern : patterns.getStoredPatterns()) {
onPatternRemoved(pattern);
}
}
if (cells.size() == 0) if (cells.size() == 0)
NETWORKS.remove(this); NETWORKS.remove(this);
// OverdriveThatMatters.LOGGER.debug("Untracking {} in {}. Tracking {} in total", entity, this, entities.size());
} }
public int networkSize() { public int networkSize() {
@ -400,4 +432,46 @@ public class MatterGrid {
NETWORKS.remove(this); NETWORKS.remove(this);
} }
} }
@Override
public void onPatternAdded(PatternState state) {
// validate();
cells.forEach(cell -> cell.onPatternAdded(state));
}
@Override
public void onPatternRemoved(PatternState state) {
// validate();
cells.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));
}
@Override
public void onMatterTaskCreated(MatterTask task) {
// validate();
cells.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));
}
@Override
public void onMatterTaskFinished(MatterTask state) {
// validate();
cells.forEach(cell -> cell.onMatterTaskFinished(state));
}
@Override
public void onMatterTaskRemoved(MatterTask state) {
// validate();
cells.forEach(cell -> cell.onMatterTaskRemoved(state));
}
} }

View File

@ -20,9 +20,6 @@ public class MatterDecomposerMenu extends PoweredMatteryMenu {
this(containerID, inventory, null); this(containerID, inventory, null);
} }
public MatterLevelWidget<PoweredMatteryMenu> matter_widget;
public ProgressGaugeWidget<PoweredMatteryMenu> progress_widget;
public MatterDecomposerMenu(int containerID, Inventory inventory, @Nullable BlockEntityMatterDecomposer tile) { public MatterDecomposerMenu(int containerID, Inventory inventory, @Nullable BlockEntityMatterDecomposer tile) {
super(Registry.Menus.MATTER_DECOMPOSER, containerID, inventory, tile); super(Registry.Menus.MATTER_DECOMPOSER, containerID, inventory, tile);
Container container = tile != null ? tile.item_container : new SimpleContainer(2); Container container = tile != null ? tile.item_container : new SimpleContainer(2);
@ -39,11 +36,11 @@ public class MatterDecomposerMenu extends PoweredMatteryMenu {
addSlot(new MachineOutputSlot(container, 1, 61 + 18 + 10 + 3 + 22, 36, true, true)); addSlot(new MachineOutputSlot(container, 1, 61 + 18 + 10 + 3 + 22, 36, true, true));
if (tile == null || tile.getCapability(MatteryCapability.MATTER).resolve().isEmpty()) { if (tile == null || tile.getCapability(MatteryCapability.MATTER).resolve().isEmpty()) {
matter_widget = new MatterLevelWidget<>(this, 22, 14); new MatterLevelWidget<>(this, 22, 14);
progress_widget = new ProgressGaugeWidget<>(this, 61 + 18 + 3, 36); new ProgressGaugeWidget<>(this, 61 + 18 + 3, 36);
} else { } else {
matter_widget = new MatterLevelWidget<>(this, 22, 14, tile.getCapability(MatteryCapability.MATTER).resolve().get()); new MatterLevelWidget<>(this, 22, 14, tile.getCapability(MatteryCapability.MATTER).resolve().get());
progress_widget = new ProgressGaugeWidget<>(this, 61 + 18 + 3, 36, () -> (float) tile.getWorkProgress(), tile::cantProcessJob); new ProgressGaugeWidget<>(this, 61 + 18 + 3, 36, () -> (float) tile.getWorkProgress(), tile::cantProcessJob);
} }
addBatterySlot(14); addBatterySlot(14);

View File

@ -2,17 +2,14 @@ package ru.dbotthepony.mc.otm.menu;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.fmllegacy.network.PacketDistributor; import net.minecraftforge.fmllegacy.network.PacketDistributor;
import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterPanel; import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterPanel;
import ru.dbotthepony.mc.otm.capability.IPatternStorage; import ru.dbotthepony.mc.otm.capability.PatternState;
import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.network.MatteryNetworking;
import ru.dbotthepony.mc.otm.network.PatternStateSendListPacket; import ru.dbotthepony.mc.otm.network.PatternStateSendListPacket;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -41,16 +38,16 @@ public class MatterPanelMenu extends MatteryMenu {
sendPatternsToClient(); sendPatternsToClient();
} }
public ArrayList<IPatternStorage.PatternState> patterns = new ArrayList<>(); public ArrayList<PatternState> patterns = new ArrayList<>();
public int changeset = 0; public int changeset = 0;
public void networkStates(List<IPatternStorage.PatternState> list) { public void networkStates(List<PatternState> list) {
changeset++; changeset++;
patterns.clear(); patterns.clear();
patterns.addAll(list); patterns.addAll(list);
} }
public void requestReplication(ServerPlayer ply, IPatternStorage.PatternState state, int how_much) { public void requestReplication(ServerPlayer ply, PatternState state, int how_much) {
if (tile == null) if (tile == null)
return; return;
@ -59,12 +56,14 @@ public class MatterPanelMenu extends MatteryMenu {
if (grid == null) if (grid == null)
return; return;
if (!grid.hasPatternState(state)) { var get_pattern = grid.getPattern(state);
OverdriveThatMatters.LOGGER.error("Received replication request from {} of {}, but can't find it nowhere", ply, state);
if (get_pattern == null) {
OverdriveThatMatters.LOGGER.error("Received replication request from {} of {}, but it is no longer in grid", ply, state);
return; return;
} }
OverdriveThatMatters.LOGGER.debug("add task: {}", ((BlockEntityMatterPanel) tile).addTask(state.item(), how_much)); OverdriveThatMatters.LOGGER.debug("add task: {}", ((BlockEntityMatterPanel) tile).addTask(state, how_much));
} }
public void sendPatternsToClient() { public void sendPatternsToClient() {

View File

@ -13,6 +13,7 @@ import ru.dbotthepony.mc.otm.menu.MatteryMenu;
import ru.dbotthepony.mc.otm.menu.slot.BatterySlot; import ru.dbotthepony.mc.otm.menu.slot.BatterySlot;
import ru.dbotthepony.mc.otm.menu.slot.MachineOutputSlot; import ru.dbotthepony.mc.otm.menu.slot.MachineOutputSlot;
import ru.dbotthepony.mc.otm.menu.slot.SlotAutoRenderable; import ru.dbotthepony.mc.otm.menu.slot.SlotAutoRenderable;
import ru.dbotthepony.mc.otm.menu.widget.MatterLevelWidget;
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget; import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -31,12 +32,14 @@ public class MatterReplicatorMenu extends PoweredMatteryMenu {
addSlot(new MachineOutputSlot(container, i, 64 + 18 * i, 38, true, false)); addSlot(new MachineOutputSlot(container, i, 64 + 18 * i, 38, true, false));
if (tile != null) { if (tile != null) {
new MatterLevelWidget<>(this, 22, 14, tile.matter);
new ProgressGaugeWidget<>(this, 38, 38, () -> (float) tile.getWorkProgress(), tile::cantProcessJob); new ProgressGaugeWidget<>(this, 38, 38, () -> (float) tile.getWorkProgress(), tile::cantProcessJob);
} else { } else {
new MatterLevelWidget<>(this, 22, 14);
new ProgressGaugeWidget<>(this, 38, 38); new ProgressGaugeWidget<>(this, 38, 38);
} }
addBatterySlot(); addBatterySlot(14);
addInventorySlots(); addInventorySlots();
} }
@ -47,6 +50,6 @@ public class MatterReplicatorMenu extends PoweredMatteryMenu {
@Override @Override
protected int getWorkingSlotEnd() { protected int getWorkingSlotEnd() {
return 7; return 5;
} }
} }

View File

@ -1,16 +1,14 @@
package ru.dbotthepony.mc.otm.network; package ru.dbotthepony.mc.otm.network;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fmllegacy.network.NetworkEvent; import net.minecraftforge.fmllegacy.network.NetworkEvent;
import ru.dbotthepony.mc.otm.capability.IPatternStorage; import ru.dbotthepony.mc.otm.capability.PatternState;
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu; import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
import java.util.function.Supplier; import java.util.function.Supplier;
public record PatternReplicationRequestPacket(IPatternStorage.PatternState state, int how_much) { public record PatternReplicationRequestPacket(PatternState state, int how_much) {
public PatternReplicationRequestPacket(IPatternStorage.PatternState state, int how_much) { public PatternReplicationRequestPacket(PatternState state, int how_much) {
this.state = state; this.state = state;
this.how_much = Math.max(1, Math.min(99999, how_much)); this.how_much = Math.max(1, Math.min(99999, how_much));
} }
@ -29,17 +27,14 @@ public record PatternReplicationRequestPacket(IPatternStorage.PatternState state
var ply = context.get().getSender(); var ply = context.get().getSender();
if (ply.containerMenu == null) if (!(ply.containerMenu instanceof MatterPanelMenu menu))
return; return;
if (!(ply.containerMenu instanceof MatterPanelMenu)) menu.requestReplication(ply, state, how_much);
return;
((MatterPanelMenu) ply.containerMenu).requestReplication(ply, state, how_much);
}); });
} }
public static PatternReplicationRequestPacket decodeNetwork(FriendlyByteBuf buffer) { public static PatternReplicationRequestPacket decodeNetwork(FriendlyByteBuf buffer) {
return new PatternReplicationRequestPacket(IPatternStorage.PatternState.read(buffer), buffer.readInt()); return new PatternReplicationRequestPacket(PatternState.read(buffer), buffer.readInt());
} }
} }

View File

@ -4,7 +4,7 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fmllegacy.network.NetworkEvent; import net.minecraftforge.fmllegacy.network.NetworkEvent;
import ru.dbotthepony.mc.otm.capability.IPatternStorage; import ru.dbotthepony.mc.otm.capability.PatternState;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -15,17 +15,17 @@ public class PatternStateSendListPacket {
} }
public PatternStateSendListPacket(Collection<IPatternStorage.PatternState> states) { public PatternStateSendListPacket(Collection<PatternState> states) {
this.states.addAll(states); this.states.addAll(states);
} }
public PatternStateSendListPacket(int container_id, Collection<IPatternStorage.PatternState> states) { public PatternStateSendListPacket(int container_id, Collection<PatternState> states) {
this(states); this(states);
this.container_id = container_id; this.container_id = container_id;
} }
public int container_id; public int container_id;
public ArrayList<IPatternStorage.PatternState> states = new ArrayList<>(); public ArrayList<PatternState> states = new ArrayList<>();
public void encodeNetwork(FriendlyByteBuf buffer) { public void encodeNetwork(FriendlyByteBuf buffer) {
buffer.writeInt(container_id); buffer.writeInt(container_id);
@ -50,7 +50,7 @@ public class PatternStateSendListPacket {
int size = buffer.readInt(); int size = buffer.readInt();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
var state = IPatternStorage.PatternState.read(buffer); var state = PatternState.read(buffer);
if (state != null) { if (state != null) {
packet.states.add(state); packet.states.add(state);

View File

@ -12,15 +12,13 @@ import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.IPatternStorage; import ru.dbotthepony.mc.otm.capability.PatternState;
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu; import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.network.MatteryNetworking;
import ru.dbotthepony.mc.otm.network.PatternReplicationRequestPacket; import ru.dbotthepony.mc.otm.network.PatternReplicationRequestPacket;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.lwjgl.opengl.GL11.GL_ALWAYS; import static org.lwjgl.opengl.GL11.GL_ALWAYS;
@ -45,7 +43,7 @@ public class MatterPanelScreen extends MatteryScreen<MatterPanelMenu> {
titleLabelY = 5; titleLabelY = 5;
} }
private IPatternStorage.PatternState open_pattern; private PatternState open_pattern;
private EditBox input_amount; private EditBox input_amount;
private Button inc_8; private Button inc_8;
private Button inc_64; private Button inc_64;
@ -58,7 +56,7 @@ public class MatterPanelScreen extends MatteryScreen<MatterPanelMenu> {
private Button send; private Button send;
private Button cancel; private Button cancel;
private IPatternStorage.PatternState hovered_pattern; private PatternState hovered_pattern;
private double dragger_position = 0; private double dragger_position = 0;
@ -139,7 +137,10 @@ public class MatterPanelScreen extends MatteryScreen<MatterPanelMenu> {
} }
input_amount.setValue(Integer.toString(Math.max(1, Math.min(99999, value + amount)))); if (value == 1 && amount > 0)
input_amount.setValue(Integer.toString(amount));
else
input_amount.setValue(Integer.toString(Math.max(1, Math.min(99999, value + amount))));
} }
private void onSend() { private void onSend() {
@ -250,7 +251,7 @@ public class MatterPanelScreen extends MatteryScreen<MatterPanelMenu> {
super.renderTooltip(pose, mouseX, mouseY); super.renderTooltip(pose, mouseX, mouseY);
} }
private void openPattern(IPatternStorage.PatternState state) { private void openPattern(PatternState state) {
open_pattern = state; open_pattern = state;
input_amount.setValue("1"); input_amount.setValue("1");
scrolling = false; scrolling = false;