Streamline matter and tile worker APIs

This commit is contained in:
DBotThePony 2022-01-30 15:12:22 +07:00
parent 8bd6852d10
commit 75c76af82c
Signed by: DBot
GPG Key ID: DCC23B5715498507
43 changed files with 663 additions and 862 deletions

View File

@ -1,53 +0,0 @@
package ru.dbotthepony.mc.otm.block.entity.worker;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.DoubleTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public record MachineJob(ItemStack stack, double ticks, ImpreciseFraction power, CompoundTag data) {
public MachineJob(ItemStack stack, double ticks, ImpreciseFraction power) {
this(stack, ticks, power, new CompoundTag());
}
public MachineJob(ItemStack stack, double ticks) {
this(stack, ticks, ImpreciseFraction.ZERO);
}
public CompoundTag serializeNBT() {
CompoundTag store_job = new CompoundTag();
store_job.put("data", data);
store_job.put("stack", stack.serializeNBT());
store_job.putDouble("ticks", ticks);
store_job.put("power", power.serializeNBT());
return store_job;
}
@Nullable
public static MachineJob deserializeNBT(@Nullable Tag nbt) {
if (nbt == null)
return null;
if (nbt instanceof CompoundTag tag) {
if (tag.get("stack") instanceof CompoundTag stack_tag && tag.get("ticks") instanceof DoubleTag ticks_processing_time && tag.contains("power")) {
ItemStack stack = ItemStack.of(stack_tag);
if (!stack.isEmpty()) {
return new MachineJob(stack, ticks_processing_time.getAsDouble(), ImpreciseFraction.deserializeNBT(tag.get("power")), tag.getCompound("data"));
}
}
}
return null;
}
}

View File

@ -1,17 +0,0 @@
package ru.dbotthepony.mc.otm.block.entity.worker;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public record MachineJobStatus(boolean valid, int throttle) {
public MachineJobStatus() {
this(true, 0);
}
public MachineJobStatus(boolean finished) {
this(finished, 0);
}
}

View File

@ -1,12 +0,0 @@
package ru.dbotthepony.mc.otm.block.entity.worker;
import net.minecraft.MethodsReturnNonnullByDefault;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public record WorkTickContext(MachineJob job, ImpreciseFraction requiredPower, ImpreciseFraction extractedPower, double ticksAdvanced) {
}

View File

@ -1,25 +0,0 @@
package ru.dbotthepony.mc.otm.block.entity.worker;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public enum WorkerState implements StringRepresentable {
IDLE,
WORKING,
ERROR;
public static final EnumProperty<WorkerState> WORKER_STATE = EnumProperty.create("worker", WorkerState.class);
public static final EnumProperty<WorkerState> SEMI_WORKER_STATE = EnumProperty.create("worker", WorkerState.class, IDLE, WORKING);
@Override
@Nonnull
public String getSerializedName() {
return this == IDLE ? "idle" : this == WORKING ? "working" : "error";
}
}

View File

@ -1,19 +1,14 @@
package ru.dbotthepony.mc.otm.capability;
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.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 ru.dbotthepony.mc.otm.graph.storage.IStorageGraphNode;
import java.math.MathContext;
import java.math.RoundingMode;
public class MatteryCapability {
public static final Capability<IMatteryEnergyStorage> ENERGY = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<IAndroidCapability> ANDROID = CapabilityManager.get(new CapabilityToken<>() {});

View File

@ -1,31 +0,0 @@
package ru.dbotthepony.mc.otm.capability.matter;
import net.minecraft.MethodsReturnNonnullByDefault;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public interface IMatterHandler {
enum MatterDirection {
RECEIVE, // consumer
EXTRACT, // producer
BIDIRECTIONAL // storage
}
ImpreciseFraction getStoredMatter();
ImpreciseFraction getMaxStoredMatter();
ImpreciseFraction receiveMatterOuter(ImpreciseFraction howMuch, boolean simulate);
ImpreciseFraction receiveMatterInner(ImpreciseFraction howMuch, boolean simulate);
ImpreciseFraction extractMatterOuter(ImpreciseFraction howMuch, boolean simulate);
ImpreciseFraction extractMatterInner(ImpreciseFraction howMuch, boolean simulate);
MatterDirection getDirection();
default ImpreciseFraction getMissingMatter() {
return getMaxStoredMatter().minus(getStoredMatter()).moreThanZero();
}
}

View File

@ -1,56 +0,0 @@
package ru.dbotthepony.mc.otm.capability.matter;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Collection;
import java.util.UUID;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public interface IMatterTaskProvider {
/**
* @return immutable collection of tasks that can be allocated by a worker
*/
Collection<MatterTask> getTasks();
/**
* @return immutable collection of all stored tasks, even fully allocated by workers
*/
Collection<MatterTask> getAllTasks();
/**
* Allocates (marks as work-in-progress) a task
* by incrementing it's in_progress by 1
* and shrinking required by 1
*
* If required == 0, it should not be returned by this method
* @param simulate whenever to change internal state
* @return MatterTaskAllocation(task, pattern) that should be performed, or null if no work is available
*/
@Nullable
MatterTaskAllocation allocateTask(boolean simulate);
/**
* Notify about task completion. If this provider indeed contain this task, it should
* shrink in_progress by 1
* 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.
* @return whenever task indeed belong to this provider and internal state was updated
*/
boolean notifyTaskCompletion(MatterTask task);
/**
* @param id uuid of task
* @return MatterTask that this capability holds with this id, or null
*/
@Nullable
MatterTask getTask(UUID id);
/**
* Destroys all tasks this capability contains
*/
void dropAllTasks();
}

View File

@ -1,91 +0,0 @@
package ru.dbotthepony.mc.otm.capability.matter;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.world.item.Item;
import ru.dbotthepony.mc.otm.capability.matter.PatternInsertStatus;
import ru.dbotthepony.mc.otm.capability.matter.PatternState;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Collection;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public interface IPatternStorage {
/**
* @return unmodifiable collection of stored patterns
*/
Collection<PatternState> getStoredPatterns();
default Collection<PatternState> findPatterns(Item item) {
return findPatterns((item2) -> item.equals(item2.item()));
}
default Collection<PatternState> findPatterns(Predicate<PatternState> predicate) {
return getStoredPatterns().stream().filter(predicate).collect(Collectors.toList());
}
@Nullable
default PatternState findPattern(Item item) {
return findPattern((item2) -> item.equals(item2.item()));
}
@Nullable
default PatternState findPattern(Predicate<PatternState> predicate) {
for (var pattern : getStoredPatterns()) {
if (predicate.test(pattern)) {
return pattern;
}
}
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(PatternState state) {
return getPattern(state.id()) != null;
}
default boolean hasPattern(@Nullable UUID id) {
return getPattern(id) != null;
}
int getCapacity();
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 only_update do not insert new pattern if this pattern's UUID is not matched
* @param simulate whenever to affect state
* @return record of status of the operation (at status() FAIL, UPDATED, INSERTED) as well as new_state and old_state
*/
PatternInsertStatus insertPattern(PatternState pattern, boolean only_update, boolean simulate);
default PatternInsertStatus insertPattern(PatternState pattern, boolean simulate) {
return insertPattern(pattern, false, simulate);
}
default PatternInsertStatus updatePattern(PatternState pattern, boolean simulate) {
return insertPattern(pattern, true, simulate);
}
}

View File

@ -1,183 +0,0 @@
package ru.dbotthepony.mc.otm.capability.matter;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.nbt.CompoundTag;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.common.util.LazyOptional;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class MatterHandlerCapability implements IMatterHandler, INBTSerializable<CompoundTag> {
protected final Runnable listener;
protected ImpreciseFraction stored = ImpreciseFraction.ZERO;
protected MatterDirection direction;
protected ImpreciseFraction max_storage;
protected ImpreciseFraction max_receive;
protected ImpreciseFraction max_extract;
public MatterHandlerCapability(
@Nullable Runnable listener,
MatterDirection direction,
ImpreciseFraction max_storage
) {
this.listener = listener;
this.direction = direction;
this.max_storage = max_storage;
}
public MatterHandlerCapability(
@Nullable Runnable listener,
MatterDirection direction,
ImpreciseFraction max_storage,
ImpreciseFraction max_receive,
ImpreciseFraction max_extract
) {
this(listener, direction, max_storage);
this.max_receive = max_receive;
this.max_extract = max_extract;
}
private LazyOptional<IMatterHandler> handler = LazyOptional.of(() -> this);
public void invalidate() {
handler.invalidate();
}
public void revive() {
handler = LazyOptional.of(() -> this);
}
public LazyOptional<IMatterHandler> get() {
return handler;
}
@Nonnull
@Override
public ImpreciseFraction getStoredMatter() {
return stored;
}
@Nonnull
@Override
public ImpreciseFraction getMaxStoredMatter() {
return max_storage;
}
public boolean canReceiveAll(ImpreciseFraction value) {
return max_storage.compareTo(value) >= 0 && stored.plus(value).compareTo(max_storage) <= 0;
}
@Nonnull
@Override
public ImpreciseFraction receiveMatterOuter(ImpreciseFraction howMuch, boolean simulate) {
if (getDirection() == MatterDirection.EXTRACT)
return ImpreciseFraction.ZERO;
return receiveMatterInner(howMuch, simulate);
}
@Nonnull
@Override
public ImpreciseFraction receiveMatterInner(ImpreciseFraction howMuch, boolean simulate) {
ImpreciseFraction new_matter;
if (max_receive == null) {
new_matter = stored.plus(howMuch).min(max_storage);
} else {
new_matter = stored.plus(howMuch.min(max_receive)).min(max_storage);
}
ImpreciseFraction diff = new_matter.minus(stored);
if (!simulate && new_matter.compareTo(stored) != 0) {
stored = new_matter;
if (listener != null) {
listener.run();
}
}
return diff;
}
@Nonnull
@Override
public ImpreciseFraction extractMatterOuter(ImpreciseFraction howMuch, boolean simulate) {
if (getDirection() == MatterDirection.RECEIVE)
return ImpreciseFraction.ZERO;
return extractMatterInner(howMuch, simulate);
}
@Nonnull
@Override
public ImpreciseFraction extractMatterInner(ImpreciseFraction howMuch, boolean simulate) {
ImpreciseFraction new_matter;
if (max_receive == null) {
new_matter = stored.minus(howMuch).moreThanZero();
} else {
new_matter = stored.minus(howMuch.min(max_receive)).moreThanZero();
}
ImpreciseFraction diff = stored.minus(new_matter);
if (!simulate && new_matter.compareTo(stored) != 0) {
stored = new_matter;
if (listener != null) {
listener.run();
}
}
return diff;
}
@Nonnull
@Override
public MatterDirection getDirection() {
return direction;
}
@Override
public CompoundTag serializeNBT() {
CompoundTag tag = new CompoundTag();
tag.put("stored", stored.serializeNBT());
tag.put("max_storage", max_storage.serializeNBT());
if (max_receive != null)
tag.put("max_receive", max_receive.serializeNBT());
if (max_extract != null)
tag.put("max_extract", max_extract.serializeNBT());
return tag;
}
@Override
public void deserializeNBT(CompoundTag tag) {
if (tag.contains("stored"))
stored = ImpreciseFraction.deserializeNBT(tag.get("stored"));
if (tag.contains("max_storage"))
max_storage = ImpreciseFraction.deserializeNBT(tag.get("max_storage"));
if (tag.contains("max_receive"))
max_receive = ImpreciseFraction.deserializeNBT(tag.get("max_receive"));
else
max_receive = null;
if (tag.contains("max_extract"))
max_extract = ImpreciseFraction.deserializeNBT(tag.get("max_extract"));
else
max_extract = null;
}
}

View File

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

View File

@ -1,39 +0,0 @@
package ru.dbotthepony.mc.otm.capability.matter;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
/**
* 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

@ -14,11 +14,11 @@ 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) {
public record PatternState(@Nonnull UUID id, @Nonnull Item item, double research) {
public PatternState(@Nonnull UUID id, @Nonnull Item item, double research) {
this.id = id;
this.item = item;
this.research_percent = Math.max(0, Math.min(1, research_percent));
this.research = Math.max(0, Math.min(1, research));
}
@Override
@ -38,17 +38,13 @@ public record PatternState(@Nonnull UUID id, @Nonnull Item item, double research
return id.hashCode();
}
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);
tag.putDouble("research_percent", research);
return tag;
}
@ -76,7 +72,7 @@ public record PatternState(@Nonnull UUID id, @Nonnull Item item, double research
buffer.writeInt(((ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class)).getID(item));
buffer.writeDouble(research_percent);
buffer.writeDouble(research);
}
@Nullable

View File

@ -5,10 +5,8 @@ import net.minecraft.client.gui.components.EditBox;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.matter.MatterTask;
import ru.dbotthepony.mc.otm.capability.matter.PatternState;
import ru.dbotthepony.mc.otm.menu.MenuMatterPanel;
@ -199,7 +197,7 @@ public class MatterPanelScreen extends MatteryScreen<MenuMatterPanel> {
}
private List<Component> getPatternTooltip(List<Component> input, PatternState pattern) {
input.add(new TranslatableComponent("otm.item.pattern.research", String.format("%.2f", pattern.research_percent() * 100d)).withStyle(ChatFormatting.AQUA));
input.add(new TranslatableComponent("otm.item.pattern.research", String.format("%.2f", pattern.research() * 100d)).withStyle(ChatFormatting.AQUA));
return input;
}

View File

@ -19,17 +19,18 @@ operator fun Direction.unaryMinus(): Direction = this.opposite
operator fun Vec3i.unaryMinus(): Vec3i = Vec3i(-x, -y, -z)
operator fun BlockPos.unaryMinus(): BlockPos = BlockPos(-x, -y, -z)
operator fun CompoundTag.set(s: String, value: Tag) = put(s, value)
operator fun CompoundTag.set(s: String, value: Int) = putInt(s, value)
operator fun CompoundTag.set(s: String, value: Byte) = putByte(s, value)
operator fun CompoundTag.set(s: String, value: Short) = putShort(s, value)
operator fun CompoundTag.set(s: String, value: Long) = putLong(s, value)
operator fun CompoundTag.set(s: String, value: Float) = putFloat(s, value)
operator fun CompoundTag.set(s: String, value: Double) = putDouble(s, value)
operator fun CompoundTag.set(s: String, value: String) = putString(s, value)
operator fun CompoundTag.set(s: String, value: Boolean) = putBoolean(s, value)
operator fun CompoundTag.set(s: String, value: ByteArray) = putByteArray(s, value)
operator fun CompoundTag.set(s: String, value: LongArray) = putLongArray(s, value)
operator fun CompoundTag.set(index: String, value: Tag) = put(index, value)
operator fun CompoundTag.set(index: String, value: Int) = putInt(index, value)
operator fun CompoundTag.set(index: String, value: Byte) = putByte(index, value)
operator fun CompoundTag.set(index: String, value: Short) = putShort(index, value)
operator fun CompoundTag.set(index: String, value: Long) = putLong(index, value)
operator fun CompoundTag.set(index: String, value: Float) = putFloat(index, value)
operator fun CompoundTag.set(index: String, value: Double) = putDouble(index, value)
operator fun CompoundTag.set(index: String, value: String) = putString(index, value)
operator fun CompoundTag.set(index: String, value: Boolean) = putBoolean(index, value)
operator fun CompoundTag.set(index: String, value: ByteArray) = putByteArray(index, value)
operator fun CompoundTag.set(index: String, value: IntArray) = putIntArray(index, value)
operator fun CompoundTag.set(index: String, value: LongArray) = putLongArray(index, value)
operator fun Container.set(index: Int, value: ItemStack) = setItem(index, value)
operator fun Container.get(index: Int): ItemStack = getItem(index)

View File

@ -12,8 +12,7 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.AABB
import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
@ -28,15 +27,7 @@ class BlockEntityAndroidStation(p_155229_: BlockPos, p_155230_: BlockState) :
return MACHINE_NAME
}
init {
energy = MatteryMachineEnergyStorage(
this,
MatteryMachineEnergyStorage.MachineType.WORKER,
ImpreciseFraction(100000),
ImpreciseFraction(250),
ImpreciseFraction(250)
)
}
override val energy = WorkerEnergyStorage(this, STORAGE, MAX_IO)
fun tick() {
batteryChargeLoop()
@ -68,5 +59,7 @@ class BlockEntityAndroidStation(p_155229_: BlockPos, p_155230_: BlockState) :
companion object {
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.android_station")
private val STORAGE = ImpreciseFraction(100_000)
private val MAX_IO = ImpreciseFraction(250)
}
}

View File

@ -23,10 +23,7 @@ import net.minecraftforge.items.CapabilityItemHandler
import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.capability.receiveEnergy
import ru.dbotthepony.mc.otm.capability.*
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
@ -47,7 +44,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
private var resolver = LazyOptional.of {energy}
@JvmField
val energy = MatteryMachineEnergyStorage(this::setChangedLight, MatteryMachineEnergyStorage.MachineType.GENERATOR, MAX_ENERGY, THROUGHPUT)
val energy = GeneratorEnergyStorage(this::setChangedLight, MAX_ENERGY, THROUGHPUT)
override fun setChangedLight() {
super.setChangedLight()

View File

@ -17,9 +17,8 @@ import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.ifHas
import ru.dbotthepony.mc.otm.menu.MenuDriveRack
@ -29,6 +28,7 @@ import ru.dbotthepony.mc.otm.storage.PoweredVirtualComponent
class BlockEntityDriveRack(p_155229_: BlockPos, p_155230_: BlockState) :
BlockEntityMatteryPowered(Registry.BlockEntities.DRIVE_RACK, p_155229_, p_155230_) {
override val energy = WorkerEnergyStorage(this, STORAGE)
@JvmField
val drives: MatteryContainer = object : MatteryContainer(this::setChanged, 4) {
@ -67,10 +67,6 @@ class BlockEntityDriveRack(p_155229_: BlockPos, p_155230_: BlockState) :
StorageNetworkGraph.discoverFull(this, cell.getAsStorageNode())
}
init {
energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, ImpreciseFraction(80000))
}
fun tick() {
batteryChargeLoop()
}
@ -101,5 +97,6 @@ class BlockEntityDriveRack(p_155229_: BlockPos, p_155230_: BlockState) :
companion object {
private val NAME = TranslatableComponent("block.overdrive_that_matters.drive_rack")
private val STORAGE = ImpreciseFraction(80_000)
}
}

View File

@ -16,9 +16,8 @@ import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.BlockDriveViewer
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.MenuDriveViewer
import ru.dbotthepony.mc.otm.set
@ -51,6 +50,8 @@ class BlockEntityDriveViewer(p_155229_: BlockPos, p_155230_: BlockState) : Block
}
}
override val energy = WorkerEnergyStorage(this)
@JvmField
val container: MatteryContainer = object : MatteryContainer(this::setChanged, 1) {
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
@ -77,10 +78,6 @@ class BlockEntityDriveViewer(p_155229_: BlockPos, p_155230_: BlockState) : Block
}
}
init {
energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, ImpreciseFraction(30000))
}
override fun getDefaultDisplayName(): Component {
return NAME
}

View File

@ -13,23 +13,19 @@ 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.graph.storage.BasicStorageGraphNode
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.MenuItemMonitor
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
import ru.dbotthepony.mc.otm.menu.MenuItemMonitor
class BlockEntityItemMonitor(p_155229_: BlockPos, p_155230_: BlockState) :
BlockEntityMatteryPowered(Registry.BlockEntities.ITEM_MONITOR, p_155229_, p_155230_) {
@JvmField
val cell = BasicStorageGraphNode()
init {
energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, ImpreciseFraction(80_000))
}
override val energy = WorkerEnergyStorage(this)
fun tick() {
batteryChargeLoop()

View File

@ -20,18 +20,18 @@ import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.BlockMatterBottler
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
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.menu.MenuMatterBottler
import ru.dbotthepony.mc.otm.orNull
import ru.dbotthepony.mc.otm.set
class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
@ -39,6 +39,7 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
private val node = Graph6Node<IMatterGraphNode>(this)
private val resolverNode = LazyOptional.of { this }
override val energy = WorkerEnergyStorage(this)
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
return node
@ -106,9 +107,9 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
})
@JvmField
val matter: MatterHandlerCapability =
object : MatterHandlerCapability(this::setChangedLight, MatterDirection.BIDIRECTIONAL, CAPACITY) {
override fun getDirection(): MatterDirection {
val matter: MatterHandlerImpl =
object : MatterHandlerImpl(this::setChangedLight, MatterDirection.BIDIRECTIONAL, CAPACITY) {
override val direction: MatterDirection get() {
return if (this@BlockEntityMatterBottler.workFlow) MatterDirection.RECEIVE else MatterDirection.EXTRACT
}
}
@ -183,20 +184,10 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
nbt.ifHas("matter", CompoundTag::class.java, matter::deserializeNBT)
}
init {
energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER)
}
fun getWorkProgress(): Float {
val lastWorkStack = lastWorkStack ?: return 0f
val initialCapacity = initialCapacity ?: return 0f
val resolver = lastWorkStack.getCapability(MatteryCapability.MATTER).resolve()
if (resolver.isEmpty) {
return 0f
}
val cap = resolver.get()
val cap = lastWorkStack.getCapability(MatteryCapability.MATTER).orNull() ?: return 0f
if (this.workFlow) {
if (cap.maxStoredMatter - initialCapacity <= ImpreciseFraction.ZERO) {
@ -243,12 +234,12 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
val itemStack = container.getItem(i)
if (!itemStack.isEmpty) {
val cap = itemStack.getCapability(MatteryCapability.MATTER).resolve()
val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: continue
if (cap.isPresent && cap.get().direction !== unexpectedDirection) {
if (this.workFlow && cap.get().missingMatter > ImpreciseFraction.ZERO || !this.workFlow && cap.get().storedMatter > ImpreciseFraction.ZERO) {
if (cap.direction !== unexpectedDirection) {
if (this.workFlow && cap.missingMatter > ImpreciseFraction.ZERO || !this.workFlow && cap.storedMatter > ImpreciseFraction.ZERO) {
work_stack = itemStack
capability = cap.get()
capability = cap
work_slot = i
break
}

View File

@ -20,9 +20,8 @@ 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.capability.matter.MatterDirection
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.graph.Graph6Node
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
@ -43,7 +42,7 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState)
return node
}
override fun getStoredMatter(): ImpreciseFraction {
override val storedMatter: ImpreciseFraction get() {
var summ = ImpreciseFraction.ZERO
for (stack in container)
@ -55,7 +54,7 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState)
return summ
}
override fun getMaxStoredMatter(): ImpreciseFraction {
override val maxStoredMatter: ImpreciseFraction get() {
var summ = ImpreciseFraction.ZERO
for (stack in container)
@ -116,7 +115,7 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState)
return summ
}
override fun getDirection(): MatterDirection {
override val direction: MatterDirection get() {
return MatterDirection.BIDIRECTIONAL
}

View File

@ -18,12 +18,13 @@ 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.block.entity.worker.WorkerJob
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJobStatus
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.graph.Graph6Node
@ -39,16 +40,7 @@ import ru.dbotthepony.mc.otm.set
class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
: BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_DECOMPOSER, pos, state), IMatterGraphNode {
init {
energy = MatteryMachineEnergyStorage(
this,
MatteryMachineEnergyStorage.MachineType.WORKER,
ENERGY_STORAGE,
MAX_IO,
MAX_IO
)
}
override val energy = WorkerEnergyStorage(this, ENERGY_STORAGE, MAX_IO)
private var valid = true
private val node = Graph6Node<IMatterGraphNode>(this)
@ -57,7 +49,11 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
}
@JvmField
val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.EXTRACT, CAPACITY)
val matter = MatterHandlerImpl(
this::setChangedLight,
MatterDirection.EXTRACT,
CAPACITY
)
private var resolverMatter = LazyOptional.of { matter }
private var resolverNode = LazyOptional.of { this }
@ -118,7 +114,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
return super.getCapability(cap, side)
}
override fun onJobFinish(job: MachineJob): MachineJobStatus {
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
var matterValue = ImpreciseFraction.deserializeNBT(job.data["value"])
if (job.data.getBoolean("to_dust")) {
@ -149,7 +145,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
} else if (!item.isFull(stack2)) {
if (stack2.count != 1) {
job.data["value"] = matterValue.serializeNBT()
return MachineJobStatus(false, 20)
return WorkerJobStatus(false, 20)
}
matterValue -= item.addMatterValue(stack2, matterValue, false)
@ -166,26 +162,26 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
container.setChanged(OUTPUT_DUST_STACKING)
} else {
job.data["value"] = matterValue.serializeNBT()
return MachineJobStatus(false, 20)
return WorkerJobStatus(false, 20)
}
}
}
}
return MachineJobStatus()
return WorkerJobStatus()
}
matterValue -= matter.receiveMatterInner(matterValue, false)
if (matterValue.isPositive) {
job.data["value"] = matterValue.serializeNBT()
return MachineJobStatus(false, 20)
return WorkerJobStatus(false, 20)
}
return MachineJobStatus()
return WorkerJobStatus()
}
override fun computeNextJob(): MachineJob? {
override fun computeNextJob(): WorkerJob? {
val stack = container[INPUT_SLOT]
if (!stack.isEmpty) {
@ -198,7 +194,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
if (!matter.isZero) {
stack.count--
return MachineJob(copy, matter.complexity * baselineComplexityDecomposeTicks, BASE_CONSUMPTION, CompoundTag().also {
return WorkerJob(copy, matter.complexity * baselineComplexityDecomposeTicks, BASE_CONSUMPTION, CompoundTag().also {
it["to_dust"] = (level?.random?.nextDouble() ?: 1.0) <= 1.0
it["value"] = matter.value.serializeNBT()
})

View File

@ -33,8 +33,6 @@ import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
import java.util.ArrayList
import java.util.List
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
class BlockEntityMatterPanel(p_155229_: BlockPos, p_155230_: BlockState) :
BlockEntityMattery(Registry.BlockEntities.MATTER_PANEL, p_155229_, p_155230_), IMatterGraphNode, IMatterTaskProvider {
@ -100,27 +98,27 @@ class BlockEntityMatterPanel(p_155229_: BlockPos, p_155230_: BlockState) :
return this
}
private val tasks = HashMap<UUID, MatterTask?>()
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 val tasks: Collection<MatterTask> get() {
return _tasks.values.stream().filter { task: MatterTask? -> task!!.required() > 0 }.collect(Collectors.toList()) as Collection<MatterTask>
}
override fun getAllTasks(): Collection<MatterTask> {
return List.copyOf(tasks.values) as Collection<MatterTask>
override val allTasks: Collection<MatterTask> get() {
return List.copyOf(_tasks.values) as Collection<MatterTask>
}
override fun allocateTask(simulate: Boolean): MatterTaskAllocation? {
val graph = node.graph as MatterNetworkGraph? ?: return null
for ((key, task) in tasks) {
if (task!!.required > 0) {
for ((key, task) in _tasks) {
if (task.required > 0) {
val getPattern = graph.getPattern(task.pattern!!)
if (getPattern != null) {
if (!simulate) {
val new = task.shrinkRequired(1)
tasks[key] = new
_tasks[key] = new
listeners.forEach { menu: MenuMatterPanel -> menu.taskUpdated(new) }
graph.onMatterTaskUpdated(new, task)
setChanged()
@ -135,7 +133,7 @@ class BlockEntityMatterPanel(p_155229_: BlockPos, p_155230_: BlockState) :
}
override fun notifyTaskCompletion(task: MatterTask): Boolean {
var localTask = tasks[task.id] ?: return false
var localTask = _tasks[task.id] ?: return false
val oldTask = localTask
localTask = localTask.shrinkInProgress(1)
@ -143,12 +141,12 @@ class BlockEntityMatterPanel(p_155229_: BlockPos, p_155230_: BlockState) :
// Задача полностью выполнена
if (localTask.required <= 0 && localTask.in_progress <= 0) {
tasks.remove(task.id)
_tasks.remove(task.id)
graph?.onMatterTaskCreated(task)
listeners.forEach { menu: MenuMatterPanel -> menu.taskRemoved(localTask) }
} else {
// Задача обновлена
tasks[task.id()] = localTask
_tasks[task.id()] = localTask
graph?.onMatterTaskUpdated(localTask, oldTask)
listeners.forEach { menu: MenuMatterPanel -> menu.taskUpdated(localTask) }
}
@ -162,7 +160,7 @@ class BlockEntityMatterPanel(p_155229_: BlockPos, p_155230_: BlockState) :
val list = ListTag()
for (task in tasks.values) {
for (task in _tasks.values) {
list.add(task!!.serializeNBT())
}
@ -171,25 +169,25 @@ class BlockEntityMatterPanel(p_155229_: BlockPos, p_155230_: BlockState) :
override fun load(nbt: CompoundTag) {
super.load(nbt)
tasks.clear()
_tasks.clear()
val list = nbt.getList("tasks", Tag.TAG_COMPOUND.toInt())
for (tag in list) {
val task = MatterTask.deserializeNBT(tag)
if (task != null) {
tasks[task.id()] = task
_tasks[task.id()] = task
}
}
}
override fun getTask(id: UUID): MatterTask? {
return tasks[id]
return _tasks[id]
}
fun removeTask(id: UUID) {
val task = tasks[id] ?: return
tasks.remove(id)
val task = _tasks[id] ?: return
_tasks.remove(id)
(node.graph as MatterNetworkGraph?)?.onMatterTaskRemoved(task)
@ -201,7 +199,7 @@ class BlockEntityMatterPanel(p_155229_: BlockPos, p_155230_: BlockState) :
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
_tasks[task.id()] = task
(node.graph as MatterNetworkGraph?)?.onMatterTaskCreated(task)
@ -214,12 +212,12 @@ class BlockEntityMatterPanel(p_155229_: BlockPos, p_155230_: BlockState) :
override fun dropAllTasks() {
val graph = node.graph as MatterNetworkGraph?
for (task in tasks.values) {
graph?.onMatterTaskRemoved(task!!)
listeners.forEach { menu: MenuMatterPanel -> menu.taskUpdated(task!!) }
for (task in _tasks.values) {
graph?.onMatterTaskRemoved(task)
listeners.forEach { menu: MenuMatterPanel -> menu.taskUpdated(task) }
}
tasks.clear()
_tasks.clear()
}
companion object {

View File

@ -16,13 +16,14 @@ 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.block.entity.worker.WorkerJob
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJobStatus
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerTickContext
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerImpl
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
@ -36,11 +37,16 @@ import ru.dbotthepony.mc.otm.set
class BlockEntityMatterRecycler(blockPos: BlockPos, blockState: BlockState)
: BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_RECYCLER, blockPos, blockState), IMatterGraphNode {
val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.EXTRACT, STORAGE)
val matter = MatterHandlerImpl(
this::setChangedLight,
MatterDirection.EXTRACT,
STORAGE
)
val container = MatteryContainer(this::setChangedLight, 1)
private val node = Graph6Node<IMatterGraphNode>(this)
private var resolverNode = LazyOptional.of { this }
private var valid = true
override val energy = WorkerEnergyStorage(this, MAX_POWER)
override fun getAsMatterNode(): Graph6Node<IMatterGraphNode> {
return node
@ -50,10 +56,6 @@ class BlockEntityMatterRecycler(blockPos: BlockPos, blockState: BlockState)
return matter
}
init {
energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, MAX_POWER)
}
private val itemHandler = container.handler(object : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
return stack.item is ItemMatterDust
@ -123,12 +125,12 @@ class BlockEntityMatterRecycler(blockPos: BlockPos, blockState: BlockState)
return MenuMatterRecycler(containerID, inventory, this)
}
override fun onJobFinish(job: MachineJob): MachineJobStatus {
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
// вся логика в onWorkTick
return MachineJobStatus()
return WorkerJobStatus()
}
override fun computeNextJob(): MachineJob? {
override fun computeNextJob(): WorkerJob? {
if (matter.missingMatter.isZero)
return null
@ -143,21 +145,21 @@ class BlockEntityMatterRecycler(blockPos: BlockPos, blockState: BlockState)
val dustMatter = (stack.item as ItemMatterDust).getMatterValue(copy) ?: return null
stack.shrink(1)
return MachineJob(copy, dustMatter.value.toDouble() * MATTER_TICKS, POWER_CONSUMPTION)
return WorkerJob(copy, dustMatter.value.toDouble() * MATTER_TICKS, POWER_CONSUMPTION)
}
override fun onWorkTick(context: WorkTickContext): MachineJobStatus {
override fun onWorkTick(context: WorkerTickContext): WorkerJobStatus {
if ((level?.random?.nextDouble() ?: 1.0) <= 0.4)
return MachineJobStatus()
return WorkerJobStatus()
val receive = if (context.ticksAdvanced == 1.0) MATTER_PER_TICK else MATTER_PER_TICK * context.ticksAdvanced
val received = matter.receiveMatterInner(receive, true)
if (receive != received)
return MachineJobStatus(false, 20)
return WorkerJobStatus(false, 20)
matter.receiveMatterInner(receive, false)
return MachineJobStatus()
return WorkerJobStatus()
}
fun tick() {

View File

@ -1,6 +1,5 @@
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
@ -18,15 +17,12 @@ 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.block.entity.worker.WorkerJob
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJobStatus
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerTickContext
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.capability.matter.MatterTask
import ru.dbotthepony.mc.otm.capability.matter.PatternState
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.*
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.graph.Graph6Node
@ -37,13 +33,11 @@ import ru.dbotthepony.mc.otm.matter.baselineComplexityReplicateTicks
import ru.dbotthepony.mc.otm.matter.getMatterValue
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu
import ru.dbotthepony.mc.otm.set
import javax.annotation.ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_), IMatterGraphNode {
override val energy = WorkerEnergyStorage(this, STORAGE, MAX_IO)
private val node = Graph6Node<IMatterGraphNode>(this)
private val resolverNode = LazyOptional.of { this }
@ -52,7 +46,11 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
}
@JvmField
val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.RECEIVE, ImpreciseFraction(2))
val matter = MatterHandlerImpl(
this::setChangedLight,
MatterDirection.RECEIVE,
ImpreciseFraction(2)
)
// обычные запросы
@JvmField
@ -68,13 +66,13 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
return MatterReplicatorMenu(containerID, inventory, this)
}
override fun onJobFinish(job: MachineJob): MachineJobStatus {
if (!regularSlots.fullyAddItem(job.stack())) {
return MachineJobStatus(false, 20)
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
if (!regularSlots.fullyAddItem(job.stack)) {
return WorkerJobStatus(false, 20)
}
(node.graph as MatterNetworkGraph?)?.notifyTaskCompletion(MatterTask.deserializeNBT(job.data["task"])!!)
return MachineJobStatus()
return WorkerJobStatus()
}
override fun onMatterTaskCreated(task: MatterTask) {
@ -101,10 +99,10 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
MatterNetworkGraph.discoverFull(this, node)
}
override fun computeNextJob(): MachineJob? {
override fun computeNextJob(): WorkerJob? {
val graph = node.graph as MatterNetworkGraph? ?: return null
val allocation = graph.allocateTask(false) ?: return null
val stack = allocation.task().stack(1)
val stack = allocation.task.stack(1)
val matter = getMatterValue(stack)
// ????????
@ -112,7 +110,7 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
val ticks = matter.complexity * baselineComplexityReplicateTicks
return MachineJob(stack, ticks, BASE_CONSUMPTION, CompoundTag().also {
return WorkerJob(stack, ticks, BASE_CONSUMPTION, CompoundTag().also {
it["matter_per_tick"] = (matter.value / ticks).serializeNBT()
it["task"] = allocation.task.serializeNBT()
@ -121,9 +119,9 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
})
}
override fun onWorkTick(context: WorkTickContext): MachineJobStatus {
override fun onWorkTick(context: WorkerTickContext): WorkerJobStatus {
val drainPerTick = ImpreciseFraction.deserializeNBT(context.job.data["matter_per_tick"])
val graph = node.graph as MatterNetworkGraph? ?: return MachineJobStatus(false, 20)
val graph = node.graph as MatterNetworkGraph? ?: return WorkerJobStatus(false, 20)
if (matter.extractMatterInner(drainPerTick, true) < drainPerTick) {
// в машине недостаточно материи
@ -135,13 +133,13 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
if (drain < toExtract) {
// недостаточно материи в сети
return MachineJobStatus(false, 200)
return WorkerJobStatus(false, 200)
}
// достаточно материи в сети + внутри машины
matter.extractMatterInner(drainPerTick, false)
graph.extractMatter(drain, false)
return MachineJobStatus()
return WorkerJobStatus()
} else {
// в тик требуется меньше материи, чем её может хранить репликатор
// примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше
@ -152,7 +150,7 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
if (drain.isZero) {
// в сети нет материи
return MachineJobStatus(false, 200)
return WorkerJobStatus(false, 200)
}
val received = matter.receiveMatterOuter(drain, false)
@ -160,17 +158,17 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
// получили материю, проверяем возможность работы
if (matter.extractMatterInner(drainPerTick, false) >= drainPerTick) {
return MachineJobStatus()
return WorkerJobStatus()
} else {
// :(
return MachineJobStatus(false, 200)
return WorkerJobStatus(false, 200)
}
}
}
// в машине достаточно материи
matter.extractMatterInner(drainPerTick, false)
return MachineJobStatus()
return WorkerJobStatus()
}
override fun saveAdditional(nbt: CompoundTag) {
@ -211,19 +209,11 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
return super.getCapability(cap, side)
}
init {
energy = MatteryMachineEnergyStorage(
this,
MatteryMachineEnergyStorage.MachineType.WORKER,
ImpreciseFraction(200000),
ImpreciseFraction(4000),
ImpreciseFraction(4000)
)
}
companion object {
private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_replicator")
private val BASE_CONSUMPTION = ImpreciseFraction(400)
private val DRAIN_MULT = ImpreciseFraction(200)
private val STORAGE = ImpreciseFraction(200_000)
private val MAX_IO = ImpreciseFraction(4_000)
}
}

View File

@ -17,11 +17,10 @@ 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.WorkerJob
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJobStatus
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.PatternInsertStatus
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.PatternState
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
@ -35,9 +34,9 @@ import java.util.*
class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_SCANNER, p_155229_, p_155230_), IMatterGraphNode {
val input_slot = MatteryContainer(this::setChanged, 1)
private val inputHandler = input_slot.handler(
val container = MatteryContainer(this::setChanged, 1)
override val energy = WorkerEnergyStorage(this, STORAGE, MAX_IO)
private val itemHandler = container.handler(
{ _: Int, stack: ItemStack -> canDecompose(stack) },
{ _: Int, _: Int, _: ItemStack -> isIdling }
)
@ -66,8 +65,7 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
if (valid) {
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return inputHandler.get().cast()
//if (cap === MatteryCapability.MATTER_CELL) return resolver_grid.cast()
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.get().cast()
if (cap == MatteryCapability.MATTER_NODE) return resolverNode.cast()
}
@ -77,7 +75,7 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
override fun invalidateCaps() {
super.invalidateCaps()
valid = false
inputHandler.invalidate()
itemHandler.invalidate()
resolverNode.invalidate()
matterNode.destroy(::MatterNetworkGraph)
}
@ -85,7 +83,7 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
override fun reviveCaps() {
super.reviveCaps()
valid = true
inputHandler.revive()
itemHandler.revive()
resolverNode = LazyOptional.of { this }
}
@ -98,98 +96,88 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
return NAME
}
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? {
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return MenuMatterScanner(containerID, inventory, this)
}
override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt)
nbt.put("container", input_slot.serializeNBT())
nbt.put("container", container.serializeNBT())
}
override fun load(nbt: CompoundTag) {
input_slot.deserializeNBT(nbt["container"])
container.deserializeNBT(nbt["container"])
super.load(nbt)
}
override fun onJobFinish(job: MachineJob): MachineJobStatus {
val grid = matterNode.graph as MatterNetworkGraph? ?: return MachineJobStatus(false, 100)
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
val grid = matterNode.graph as MatterNetworkGraph? ?: return WorkerJobStatus(false, 100)
val stack = job.stack()
if (stack.isEmpty || !hasMatterValue(stack)) return MachineJobStatus()
val stack = job.stack
if (stack.isEmpty || !hasMatterValue(stack)) return WorkerJobStatus()
val getState = grid.findPatterns(stack.item)
var findState: PatternState? = null
for (state in getState) {
if (state.item() === stack.item) {
if (findState == null && state.research_percent() < 1.0) {
if (findState == null && state.research() < 1.0) {
findState = state
} else if (findState != null && findState.research_percent() < state.research_percent()) {
} else if (findState != null && findState.research() < state.research()) {
findState = state
}
}
}
val new_state =
val new =
if (findState != null) {
PatternState(findState.id(), stack.item, findState.research_percent() + 0.2)
PatternState(findState.id(), stack.item, findState.research() + 0.2)
} else {
PatternState(UUID.randomUUID(), stack.item, 0.2)
}
if (grid.insertPattern(new_state, onlyUpdate = false, simulate = false).status != PatternInsertStatus.Status.FAIL) {
return MachineJobStatus()
if (!grid.insertPattern(new, onlyUpdate = false, simulate = false).isFailed) {
return WorkerJobStatus()
} else {
return MachineJobStatus(false, 200)
return WorkerJobStatus(false, 200)
}
}
override fun computeNextJob(): MachineJob? {
override fun computeNextJob(): WorkerJob? {
val grid = matterNode.graph as MatterNetworkGraph? ?: return null
val stack = input_slot.getItem(0)
val stack = container.getItem(0)
if (stack.isEmpty || !canDecompose(stack)) return null
val getState = grid.findPatterns(stack.item)
var findState: PatternState? = null
for (state in getState) {
if (state.item() === stack.item && state.research_percent() < 1.0) {
if (state.item() === stack.item && state.research() < 1.0) {
findState = state
} else if (state.item() === stack.item && state.research_percent() >= 1.0) {
} else if (state.item() === stack.item && state.research() >= 1.0) {
return null
}
}
val new_state: PatternState =
val new: PatternState =
if (findState != null) {
PatternState(findState.id, stack.item, findState.research_percent + 0.2)
} else {
PatternState(UUID.randomUUID(), stack.item, 0.2)
}
if (grid.insertPattern(new_state, false, true).status != PatternInsertStatus.Status.FAIL) {
if (!grid.insertPattern(new, onlyUpdate = false, simulate = true).isFailed) {
val copy = stack.copy()
copy.count = 1
stack.shrink(1)
input_slot.setChanged()
return MachineJob(copy, getMatterValue(copy).complexity * baselineComplexityScanTicks, BASE_CONSUMPTION)
container.setChanged()
return WorkerJob(copy, getMatterValue(copy).complexity * baselineComplexityScanTicks, BASE_CONSUMPTION)
}
return null
}
init {
energy = MatteryMachineEnergyStorage(
this,
MatteryMachineEnergyStorage.MachineType.WORKER,
ImpreciseFraction(40000),
ImpreciseFraction(400),
ImpreciseFraction(400)
)
}
override fun setLevel(p_155231_: Level) {
super.setLevel(p_155231_)
@ -201,5 +189,7 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
companion object {
private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_scanner")
private val BASE_CONSUMPTION = ImpreciseFraction("40")
private val STORAGE = ImpreciseFraction(80_000)
private val MAX_IO = ImpreciseFraction(400)
}
}

View File

@ -8,10 +8,7 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.energy.CapabilityEnergy
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.capability.extractEnergy
import ru.dbotthepony.mc.otm.capability.*
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
@ -19,7 +16,7 @@ import ru.dbotthepony.mc.otm.ifHas
import ru.dbotthepony.mc.otm.set
abstract class BlockEntityMatteryPowered(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(p_155228_, p_155229_, p_155230_) {
protected lateinit var energy: MatteryMachineEnergyStorage
abstract val energy: EnergyStorageImpl
private var resolverEnergy = LazyOptional.of { energy }
private var valid = true
val batteryContainer = MatteryContainer(this::setChangedLight, 1)

View File

@ -3,11 +3,9 @@ package ru.dbotthepony.mc.otm.block.entity
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 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
@ -19,13 +17,13 @@ import ru.dbotthepony.mc.otm.menu.MenuPatternStorage
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.capability.matter.*
import ru.dbotthepony.mc.otm.graph.Graph6Node
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
@ -152,13 +150,13 @@ class BlockEntityPatternStorage(p_155229_: BlockPos, p_155230_: BlockState) :
return MenuPatternStorage(containerID, inventory, this)
}
override fun getStoredPatterns(): Collection<PatternState> {
override val storedPatterns: Collection<PatternState> get() {
val list = ArrayList<PatternState>()
patterns.consumeCapability(MatteryCapability.PATTERN) { capability: IPatternStorage -> list.addAll(capability.storedPatterns) }
return list
}
override fun getCapacity(): Int {
override val capacity: Int get() {
var stored = 0L
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
@ -167,7 +165,7 @@ class BlockEntityPatternStorage(p_155229_: BlockPos, p_155230_: BlockState) :
return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt()
}
override fun getStored(): Int {
override val stored: Int get() {
var stored = 0L
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
@ -185,17 +183,17 @@ class BlockEntityPatternStorage(p_155229_: BlockPos, p_155230_: BlockState) :
for (storage in patterns.capabilityIterator(MatteryCapability.PATTERN)) {
val status = storage.insertPattern(pattern, only_update, simulate)
if (status.status() != PatternInsertStatus.Status.FAIL) {
if (!status.isFailed) {
if (!simulate) {
setChanged()
val graph = node.graph as MatterNetworkGraph?
if (graph != null) {
if (status.status() == PatternInsertStatus.Status.INSERTED) {
graph.onPatternAdded(status.new_state()!!)
if (status.isInserted) {
graph.onPatternAdded(status.newState!!)
} else {
graph.onPatternUpdated(status.new_state()!!, status.old_state()!!)
graph.onPatternUpdated(status.newState!!, status.oldState!!)
}
}
}
@ -204,7 +202,7 @@ class BlockEntityPatternStorage(p_155229_: BlockPos, p_155230_: BlockState) :
}
}
return PatternInsertStatus()
return PatternInsertFailure
}
companion object {

View File

@ -1,6 +1,7 @@
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.TranslatableComponent
import net.minecraft.world.entity.player.Inventory
@ -8,22 +9,25 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
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.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJob
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerJobStatus
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.MenuPlatePress
import ru.dbotthepony.mc.otm.set
class BlockEntityPlatePress(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMatteryWorker(Registry.BlockEntities.PLATE_PRESS, p_155229_, p_155230_) {
val container = MatteryContainer(this::setChangedLight, 2)
override val energy = WorkerEnergyStorage(this::setChangedLight)
val handler = container.handler(object : MatteryContainerFilter {
val itemHandler = container.handler(object : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
return slot != SLOT_OUTPUT
}
@ -33,8 +37,21 @@ class BlockEntityPlatePress(p_155229_: BlockPos, p_155230_: BlockState) : BlockE
}
})
init {
energy = MatteryMachineEnergyStorage(this::setChangedLight, MatteryMachineEnergyStorage.MachineType.WORKER)
override fun invalidateCaps() {
super.invalidateCaps()
itemHandler.invalidate()
}
override fun reviveCaps() {
super.reviveCaps()
itemHandler.revive()
}
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
return itemHandler.get().cast()
return super.getCapability(cap, side)
}
override fun saveAdditional(nbt: CompoundTag) {
@ -53,21 +70,21 @@ class BlockEntityPlatePress(p_155229_: BlockPos, p_155230_: BlockState) : BlockE
return MenuPlatePress(containerID, inventory, this)
}
override fun onJobFinish(job: MachineJob): MachineJobStatus {
val resultTag = job.data["result"] as? CompoundTag ?: return MachineJobStatus()
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
val resultTag = job.data["result"] as? CompoundTag ?: return WorkerJobStatus()
val result = ItemStack.of(resultTag)
if (result.isEmpty)
return MachineJobStatus()
return WorkerJobStatus()
if (!container.fullyAddItem(result, start = SLOT_OUTPUT, end = SLOT_OUTPUT)) {
return MachineJobStatus(false, 20)
return WorkerJobStatus(false, 20)
}
return MachineJobStatus()
return WorkerJobStatus()
}
override fun computeNextJob(): MachineJob? {
override fun computeNextJob(): WorkerJob? {
val level = level ?: return null
val recipe = level.recipeManager.getRecipeFor(Registry.Recipes.PLATE_PRESS, container, level).orElse(null) ?: return null
@ -76,7 +93,7 @@ class BlockEntityPlatePress(p_155229_: BlockPos, p_155230_: BlockState) : BlockE
container.setChanged(SLOT_INPUT)
copy.count = 1
return MachineJob(copy, recipe.workTime.toDouble(), BASELINE_CONSUMPTION, CompoundTag().also {
return WorkerJob(copy, recipe.workTime.toDouble(), BASELINE_CONSUMPTION, CompoundTag().also {
it["result"] = recipe.resultItem.serializeNBT()
})
}

View File

@ -19,7 +19,7 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
var throttleTicks = 0
protected set
var currentJob: MachineJob? = null
var currentJob: WorkerJob? = null
protected set
// если isIdling То ничего не делать
@ -48,7 +48,8 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
workTicks = it.asDouble
}
currentJob = MachineJob.deserializeNBT(nbt["current_job"])
currentJob = WorkerJob.deserializeNBT(nbt["current_job"])
if (currentJob == null)
workTicks = 0.0
}
@ -68,14 +69,14 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
* @return whenever machine can finish it's job. return false if machine for whatever reason can't finish it's job,
* waiting on conditions to be met
*/
protected abstract fun onJobFinish(job: MachineJob): MachineJobStatus
protected abstract fun onJobFinish(job: WorkerJob): WorkerJobStatus
/**
* @param context context for current job
* @return whenever machine can perform it
*/
protected open fun onWorkTick(context: WorkTickContext): MachineJobStatus {
return MachineJobStatus()
protected open fun onWorkTick(context: WorkerTickContext): WorkerJobStatus {
return WorkerJobStatus()
}
private var idleTicksAnim = 0
@ -170,9 +171,9 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
// может быть меньше, чем единица, если недостаточно питания или мы завершаем работу,
// для которой осталось дробное количество тиков
val ticksAdvanced = (extractedPower / requiredPower).toDouble().coerceAtMost(ticksLeft)
val status = onWorkTick(WorkTickContext(currentJob, requiredPower, extractedPower, ticksAdvanced))
val status = onWorkTick(WorkerTickContext(currentJob, requiredPower, extractedPower, ticksAdvanced))
if (!status.valid()) {
if (!status.valid) {
throttleTicks += status.throttle
return
}
@ -200,10 +201,10 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
}
} else {
val ticksLeft = (currentJob.ticks - workTicks).coerceAtMost(1.0)
val status = onWorkTick(WorkTickContext(currentJob, ImpreciseFraction.ZERO, ImpreciseFraction.ZERO, ticksLeft))
val status = onWorkTick(WorkerTickContext(currentJob, ImpreciseFraction.ZERO, ImpreciseFraction.ZERO, ticksLeft))
if (!status.valid) {
throttleTicks += status.throttle()
throttleTicks += status.throttle
return
}
@ -214,7 +215,7 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
if (workTicks >= currentJob.ticks) {
val finish = onJobFinish(currentJob)
if (finish.valid()) {
if (finish.valid) {
this.currentJob = null
workTicks = 0.0
} else {
@ -225,7 +226,7 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
} else {
val finish = onJobFinish(currentJob)
if (finish.valid()) {
if (finish.valid) {
this.currentJob = null
workTicks = 0.0
errorTicksAnim = 0
@ -248,7 +249,7 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
* Determine which item can be processed from input slots if idling
* @return any item in input slots. null if no work is available
*/
protected abstract fun computeNextJob(): MachineJob?
protected abstract fun computeNextJob(): WorkerJob?
fun basicTicker() {
batteryChargeLoop()

View File

@ -0,0 +1,83 @@
package ru.dbotthepony.mc.otm.block.entity.worker
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.DoubleTag
import net.minecraft.nbt.Tag
import net.minecraft.util.StringRepresentable
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.state.properties.EnumProperty
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.set
@JvmRecord
data class WorkerTickContext(
val job: WorkerJob,
val requiredPower: ImpreciseFraction,
val extractedPower: ImpreciseFraction,
val ticksAdvanced: Double
)
enum class WorkerState : StringRepresentable {
IDLE,
WORKING,
ERROR;
companion object {
@JvmField
val WORKER_STATE: EnumProperty<WorkerState> = EnumProperty.create("worker", WorkerState::class.java)
@JvmField
val SEMI_WORKER_STATE: EnumProperty<WorkerState> = EnumProperty.create("worker", WorkerState::class.java, IDLE, WORKING)
}
override fun getSerializedName(): String {
return if (this == IDLE) "idle" else if (this == WORKING) "working" else "error"
}
}
@JvmRecord
data class WorkerJobStatus @JvmOverloads constructor(val valid: Boolean = true, val throttle: Int = 0)
@JvmRecord
data class WorkerJob @JvmOverloads constructor(
val stack: ItemStack,
val ticks: Double,
val power: ImpreciseFraction = ImpreciseFraction.ZERO,
val data: CompoundTag = CompoundTag()) {
fun serializeNBT(): CompoundTag {
return CompoundTag().also {
it["stack"] = stack.serializeNBT()
it["ticks"] = ticks
it["power"] = power.serializeNBT()
it["data"] = data
}
}
operator fun get(index: String) = data[index]
operator fun set(index: String, value: Tag) { data[index] = value }
operator fun set(index: String, value: Int) { data[index] = value }
operator fun set(index: String, value: Byte) { data[index] = value }
operator fun set(index: String, value: Short) { data[index] = value }
operator fun set(index: String, value: Long) { data[index] = value }
operator fun set(index: String, value: Float) { data[index] = value }
operator fun set(index: String, value: Double) { data[index] = value }
operator fun set(index: String, value: String) { data[index] = value }
operator fun set(index: String, value: Boolean) { data[index] = value }
operator fun set(index: String, value: ByteArray) { data[index] = value }
operator fun set(index: String, value: IntArray) { data[index] = value }
operator fun set(index: String, value: LongArray) { data[index] = value }
companion object {
@JvmStatic
fun deserializeNBT(tag: Tag?): WorkerJob? {
val nbt = tag as? CompoundTag ?: return null
return WorkerJob(
ItemStack.of(nbt["stack"] as? CompoundTag ?: return null),
(nbt["ticks"] as? DoubleTag ?: return null).asDouble,
ImpreciseFraction.deserializeNBT(nbt["power"]),
nbt["data"] as? CompoundTag ?: return null
)
}
}
}

View File

@ -7,25 +7,17 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.ifHas
import ru.dbotthepony.mc.otm.set
open class MatteryMachineEnergyStorage @JvmOverloads constructor(
private enum class MachineType {
WORKER, GENERATOR, CAPACITOR
}
sealed class EnergyStorageImpl constructor(
protected val listener: () -> Unit,
val type: MachineType,
override var maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
protected var maxInput: ImpreciseFraction = DEFAULT_MAX_RECEIVE,
protected var maxOutput: ImpreciseFraction = maxInput
private val type: MachineType,
override var maxBatteryLevel: ImpreciseFraction,
protected var maxInput: ImpreciseFraction,
protected var maxOutput: ImpreciseFraction
) : IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
@JvmOverloads
constructor(
listener: BlockEntity,
type: MachineType,
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction = DEFAULT_MAX_RECEIVE,
maxOutput: ImpreciseFraction = DEFAULT_MAX_EXTRACT) : this({listener.setChanged()}, type, maxBatteryLevel, maxInput, maxOutput)
enum class MachineType {
WORKER, GENERATOR, CAPACITOR
}
override var batteryLevel = ImpreciseFraction.ZERO
protected set
@ -95,8 +87,46 @@ open class MatteryMachineEnergyStorage @JvmOverloads constructor(
}
companion object {
val DEFAULT_MAX_RECEIVE = ImpreciseFraction(200)
val DEFAULT_MAX_EXTRACT = DEFAULT_MAX_RECEIVE
val DEFAULT_MAX_CAPACITY = ImpreciseFraction(60000)
val DEFAULT_MAX_IO = ImpreciseFraction(200)
val DEFAULT_MAX_CAPACITY = ImpreciseFraction(60_000)
}
}
}
open class WorkerEnergyStorage(
listener: () -> Unit,
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction = maxInput
) : EnergyStorageImpl(listener, MachineType.WORKER, maxBatteryLevel, maxInput, maxOutput) {
constructor(
listener: BlockEntity,
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction = maxInput) : this({listener.setChanged()}, maxBatteryLevel, maxInput, maxOutput)
}
open class GeneratorEnergyStorage(
listener: () -> Unit,
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction = maxInput
) : EnergyStorageImpl(listener, MachineType.GENERATOR, maxBatteryLevel, maxInput, maxOutput) {
constructor(
listener: BlockEntity,
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction = maxInput) : this({listener.setChanged()}, maxBatteryLevel, maxInput, maxOutput)
}
open class CapacitorEnergyStorage(
listener: () -> Unit,
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction = maxInput
) : EnergyStorageImpl(listener, MachineType.CAPACITOR, maxBatteryLevel, maxInput, maxOutput) {
constructor(
listener: BlockEntity,
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction = maxInput) : this({listener.setChanged()}, maxBatteryLevel, maxInput, maxOutput)
}

View File

@ -0,0 +1,136 @@
package ru.dbotthepony.mc.otm.capability.matter
import net.minecraft.world.item.Item
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import java.util.*
import java.util.function.Predicate
import java.util.stream.Collectors
interface IMatterHandler {
val storedMatter: ImpreciseFraction
val maxStoredMatter: ImpreciseFraction
fun receiveMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
fun extractMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
val direction: MatterDirection
val missingMatter: ImpreciseFraction
get() = maxStoredMatter.minus(storedMatter).moreThanZero()
}
enum class MatterDirection { RECEIVE, EXTRACT, BIDIRECTIONAL }
interface IMatterTaskProvider {
/**
* @return immutable collection of tasks that can be allocated by a worker
*/
val tasks: Collection<MatterTask>
/**
* @return immutable collection of all stored tasks, even fully allocated by workers
*/
val allTasks: Collection<MatterTask>
/**
* Allocates (marks as work-in-progress) a task
* by incrementing it's in_progress by 1
* and shrinking required by 1
*
* If required == 0, it should not be returned by this method
* @param simulate whenever to change internal state
* @return MatterTaskAllocation(task, pattern) that should be performed, or null if no work is available
*/
fun allocateTask(simulate: Boolean): MatterTaskAllocation?
/**
* Notify about task completion. If this provider indeed contain this task, it should
* shrink in_progress by 1
* 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.
* @return whenever task indeed belong to this provider and internal state was updated
*/
fun notifyTaskCompletion(task: MatterTask): Boolean
/**
* @param id uuid of task
* @return MatterTask that this capability holds with this id, or null
*/
fun getTask(id: UUID): MatterTask?
/**
* Destroys all tasks this capability contains
*/
fun dropAllTasks()
}
interface IPatternStorage {
/**
* @return unmodifiable collection of stored patterns
*/
val storedPatterns: Collection<PatternState>
fun findPatterns(item: Item): Collection<PatternState> {
return findPatterns { item2: PatternState -> item == item2.item() }
}
fun findPatterns(predicate: Predicate<PatternState>?): Collection<PatternState> {
return storedPatterns.stream().filter(predicate).collect(Collectors.toList())
}
fun findPattern(item: Item): PatternState? {
return findPattern { item2: PatternState -> item == item2.item() }
}
fun findPattern(predicate: Predicate<PatternState>): PatternState? {
for (pattern in storedPatterns) {
if (predicate.test(pattern)) {
return pattern
}
}
return null
}
fun getPattern(id: UUID?): PatternState? {
id ?: return null
for (pattern in storedPatterns) {
if (pattern.id == id) {
return pattern
}
}
return null
}
fun hasPattern(state: PatternState): Boolean {
return getPattern(state.id) != null
}
fun hasPattern(id: UUID?): Boolean {
return getPattern(id) != null
}
val capacity: Int
val stored: Int
/**
* 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 only_update do not insert new pattern if this pattern's UUID is not matched
* @param simulate whenever to affect state
* @return record of status of the operation (at status() FAIL, UPDATED, INSERTED) as well as new_state and old_state
*/
fun insertPattern(pattern: PatternState, only_update: Boolean, simulate: Boolean): PatternInsertStatus
fun insertPattern(pattern: PatternState, simulate: Boolean): PatternInsertStatus {
return insertPattern(pattern, false, simulate)
}
fun updatePattern(pattern: PatternState, simulate: Boolean): PatternInsertStatus {
return insertPattern(pattern, true, simulate)
}
}

View File

@ -0,0 +1,24 @@
package ru.dbotthepony.mc.otm.capability.matter
private enum class PatternInsertResult {
FAIL,
UPDATED,
INSERTED;
}
sealed class PatternInsertStatus(
private val status: PatternInsertResult,
val newState: PatternState?,
val oldState: PatternState?
) {
val isFailed get() = status === PatternInsertResult.FAIL
val isUpdated get() = status === PatternInsertResult.UPDATED
val isInserted get() = status === PatternInsertResult.INSERTED
}
object PatternInsertFailure : PatternInsertStatus(PatternInsertResult.FAIL, null, null)
class PatternInsertUpdated(new: PatternState, old: PatternState) : PatternInsertStatus(PatternInsertResult.UPDATED, new, old)
class PatternInsertInserted(new: PatternState) : PatternInsertStatus(PatternInsertResult.INSERTED, new, null)
@JvmRecord
data class MatterTaskAllocation(val task: MatterTask, val pattern: PatternState?)

View File

@ -0,0 +1,104 @@
package ru.dbotthepony.mc.otm.capability.matter
import net.minecraft.nbt.CompoundTag
import net.minecraftforge.common.util.INBTSerializable
import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.set
open class MatterHandlerImpl @JvmOverloads constructor(
protected val listener: Runnable?,
override val direction: MatterDirection,
override val maxStoredMatter: ImpreciseFraction,
val maxReceive: ImpreciseFraction? = null,
val maxExtract: ImpreciseFraction? = maxReceive
) : IMatterHandler, INBTSerializable<CompoundTag> {
override var storedMatter = ImpreciseFraction.ZERO
protected set
private var handler = LazyOptional.of<IMatterHandler> { this }
fun invalidate() {
handler.invalidate()
}
fun revive() {
handler = LazyOptional.of { this }
}
fun get(): LazyOptional<IMatterHandler> {
return handler
}
open fun canReceiveAll(value: ImpreciseFraction): Boolean {
return maxStoredMatter >= value && storedMatter + value <= maxStoredMatter
}
override fun receiveMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (direction === MatterDirection.EXTRACT)
return ImpreciseFraction.ZERO
return receiveMatterInner(howMuch, simulate)
}
override fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
val new: ImpreciseFraction
if (maxReceive == null) {
new = (storedMatter + howMuch).min(maxStoredMatter)
} else {
new = (storedMatter + howMuch.min(maxReceive)).min(maxStoredMatter)
}
val diff = new - storedMatter
if (!simulate && new != storedMatter) {
storedMatter = new
listener?.run()
}
return diff
}
override fun extractMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (direction === MatterDirection.RECEIVE)
return ImpreciseFraction.ZERO
return extractMatterInner(howMuch, simulate)
}
override fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
val new: ImpreciseFraction
if (maxExtract == null) {
new = (storedMatter - howMuch).moreThanZero()
} else {
new = (storedMatter - howMuch.min(maxExtract)).moreThanZero()
}
val diff = storedMatter - new
if (!simulate && new != storedMatter) {
storedMatter = new
listener?.run()
}
return diff
}
override fun serializeNBT(): CompoundTag {
return CompoundTag().also {
it["stored"] = storedMatter.serializeNBT()
//it["max_storage"] = maxStoredMatter.serializeNBT()
//if (maxReceive != null) it["max_receive"] = maxReceive.serializeNBT()
//if (maxExtract != null) it["max_extract"] = maxExtract.serializeNBT()
}
}
override fun deserializeNBT(tag: CompoundTag) {
storedMatter = ImpreciseFraction.deserializeNBT(tag["stored"])
//maxStoredMatter = ImpreciseFraction.deserializeNBT(tag["max_storage"])
//maxReceive = if (tag.contains("max_receive")) ImpreciseFraction.deserializeNBT(tag["max_receive"]) else null
//maxExtract = if (tag.contains("max_extract")) ImpreciseFraction.deserializeNBT(tag["max_extract"]) else null
}
}

View File

@ -5,7 +5,6 @@ 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.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.graph.Abstract6Graph
import ru.dbotthepony.mc.otm.graph.Graph6Node
@ -78,7 +77,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
for (node in _nodes) {
val matter = node.value.getMatterHandler()
if (matter != null && matter.direction == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
if (matter != null && matter.direction == MatterDirection.BIDIRECTIONAL) {
level += matter.storedMatter
}
}
@ -92,7 +91,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
for (node in _nodes) {
val matter = node.value.getMatterHandler()
if (matter != null && matter.direction == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
if (matter != null && matter.direction == MatterDirection.BIDIRECTIONAL) {
level += matter.maxStoredMatter
}
}
@ -133,7 +132,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
for (node in _nodes) {
val matter = node.value.getMatterHandler()
if (matter != null && matter.direction == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
if (matter != null && matter.direction == MatterDirection.BIDIRECTIONAL) {
val value = matter.receiveMatterOuter(howMuch, simulate)
howMuch -= value
received += value
@ -156,7 +155,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
for (node in _nodes) {
val matter = node.value.getMatterHandler()
if (matter != null && matter.direction != IMatterHandler.MatterDirection.EXTRACT) {
if (matter != null && matter.direction != MatterDirection.EXTRACT) {
val value = matter.receiveMatterOuter(howMuch, simulate)
howMuch -= value
received += value
@ -176,19 +175,19 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
if (storage != null) {
val status = storage.insertPattern(state, onlyUpdate, simulate)
if (status.status != PatternInsertStatus.Status.FAIL) {
if (!status.isFailed) {
return status
}
}
}
return PatternInsertStatus()
return PatternInsertFailure
}
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
if (!status.isFailed) return status
return _insertPattern(state, false, simulate)
}

View File

@ -17,9 +17,7 @@ import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.OverdriveThatMatters
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.core.Fraction
import ru.dbotthepony.mc.otm.core.Fraction.Companion.deserializeNBT
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.FormattingHelper
import javax.annotation.ParametersAreNonnullByDefault
@ -45,16 +43,16 @@ class ItemMatterCapacitor : Item {
stack.getOrCreateTag().put("matter", value.serializeNBT())
}
override fun getStoredMatter(): ImpreciseFraction {
override val storedMatter: ImpreciseFraction get() {
return if (isCreative) ImpreciseFraction.LONG_MAX_VALUE else matter()
}
override fun getMaxStoredMatter(): ImpreciseFraction {
override val maxStoredMatter: ImpreciseFraction get() {
return storage
}
override fun getMissingMatter(): ImpreciseFraction {
return if (isCreative) ImpreciseFraction.LONG_MAX_VALUE else super.getMissingMatter()
override val missingMatter: ImpreciseFraction get() {
return if (isCreative) ImpreciseFraction.LONG_MAX_VALUE else super.missingMatter
}
override fun receiveMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
@ -89,9 +87,7 @@ class ItemMatterCapacitor : Item {
return diff
}
override fun getDirection(): MatterDirection {
return MatterDirection.BIDIRECTIONAL
}
override val direction = MatterDirection.BIDIRECTIONAL
}
val storage: ImpreciseFraction

View File

@ -5,19 +5,17 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.nbt.CompoundTag
import net.minecraftforge.common.capabilities.ICapabilityProvider
import net.minecraft.world.item.TooltipFlag
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import net.minecraft.network.chat.TranslatableComponent
import net.minecraft.ChatFormatting
import ru.dbotthepony.mc.otm.capability.matter.PatternState
import net.minecraftforge.common.util.LazyOptional
import net.minecraft.nbt.ListTag
import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import ru.dbotthepony.mc.otm.capability.matter.PatternInsertStatus
import net.minecraft.world.item.Item
import net.minecraft.world.level.Level
import net.minecraftforge.common.capabilities.Capability
import ru.dbotthepony.mc.otm.capability.matter.*
import ru.dbotthepony.mc.otm.ifHas
import java.util.*
@ -56,7 +54,7 @@ class ItemPatternStorage : Item {
TranslatableComponent(
"otm.item.pattern.line",
state.item().getName(ItemStack(state.item(), 1)),
String.format("%.2f", state.research_percent() * 100.0)
String.format("%.2f", state.research() * 100.0)
).withStyle(ChatFormatting.AQUA)
)
}
@ -68,11 +66,11 @@ class ItemPatternStorage : Item {
private inner class ItemPatternStorageCapability(val stack: ItemStack) : IPatternStorage, ICapabilityProvider {
private val resolver = LazyOptional.of<IPatternStorage> { this }
override fun getCapacity(): Int {
override val capacity: Int get() {
return this@ItemPatternStorage.capacity
}
override fun getStored(): Int {
override val stored: Int get() {
return storedPatterns.size
}
@ -80,7 +78,7 @@ class ItemPatternStorage : Item {
return if (cap === MatteryCapability.PATTERN) resolver.cast() else LazyOptional.empty()
}
override fun getStoredPatterns(): Collection<PatternState> {
override val storedPatterns: Collection<PatternState> get() {
stack.tag?.ifHas("otm_patterns", ListTag::class.java) {
val list = ArrayList<PatternState>()
@ -109,13 +107,13 @@ class ItemPatternStorage : Item {
if (list !is ListTag) {
if (only_update)
return PatternInsertStatus()
return PatternInsertFailure
if (simulate) {
if (capacity > 0)
return PatternInsertStatus(pattern)
return PatternInsertInserted(pattern)
else
return PatternInsertStatus()
return PatternInsertFailure
}
list = ListTag()
@ -133,7 +131,7 @@ class ItemPatternStorage : Item {
list[i] = pattern.serializeNBT()
}
return PatternInsertStatus(pattern, state)
return PatternInsertUpdated(pattern, state)
}
} else {
invalidCounter++
@ -141,18 +139,18 @@ class ItemPatternStorage : Item {
}
if (only_update || capacity <= list.size - invalidCounter)
return PatternInsertStatus()
return PatternInsertFailure
if (invalidCounter > 0) {
if (simulate)
return PatternInsertStatus(pattern)
return PatternInsertInserted(pattern)
for (i in list.indices) {
val state = PatternState.deserializeNBT(list.getCompound(i))
if (state == null) {
list[i] = pattern.serializeNBT()
return PatternInsertStatus(pattern)
return PatternInsertInserted(pattern)
}
}
}
@ -160,7 +158,7 @@ class ItemPatternStorage : Item {
if (!simulate)
list.add(pattern.serializeNBT())
return PatternInsertStatus(pattern)
return PatternInsertInserted(pattern)
}
}
}

View File

@ -6,7 +6,7 @@ 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.capability.matter.MatterDirection
import ru.dbotthepony.mc.otm.menu.data.BooleanDataContainer
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
@ -44,9 +44,9 @@ class MenuMatterBottler @JvmOverloads constructor(
if (!cap.isPresent) return false
if (workFlow.value) {
return index < 3 && cap.get().direction != IMatterHandler.MatterDirection.EXTRACT
return index < 3 && cap.get().direction != MatterDirection.EXTRACT
} else {
return index >= 3 && cap.get().direction != IMatterHandler.MatterDirection.RECEIVE
return index >= 3 && cap.get().direction != MatterDirection.RECEIVE
}
}
}

View File

@ -24,7 +24,7 @@ class MenuMatterScanner @JvmOverloads constructor(
val patterns: LevelGaugeWidget
init {
val container = tile?.input_slot ?: SimpleContainer(1)
val container = tile?.container ?: SimpleContainer(1)
input = object : MatterySlot(container, 0, 64, 38) {
override fun mayPlace(p_40231_: ItemStack): Boolean {

View File

@ -17,11 +17,11 @@ abstract class MenuMatteryPowered protected constructor(
@JvmField val batterySlot: BatterySlot
init {
if (tile == null || tile.getCapability(MatteryCapability.ENERGY).resolve().isEmpty) {
if (tile == null) {
powerWidget = LevelGaugeWidget(this)
batterySlot = BatterySlot(SimpleContainer(1), 0)
} else {
powerWidget = LevelGaugeWidget(this, tile.getCapability(MatteryCapability.ENERGY).resolve().get())
powerWidget = LevelGaugeWidget(this, tile.energy)
batterySlot = BatterySlot(tile.batteryContainer, 0)
}

View File

@ -5,7 +5,7 @@ import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack
import net.minecraftforge.energy.CapabilityEnergy
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
import ru.dbotthepony.mc.otm.capability.matter.MatterDirection
open class MatterySlot @JvmOverloads constructor(p_40223_: Container, index: Int, x: Int = 0, y: Int = 0) : Slot(p_40223_, index, x, y)
@ -27,13 +27,13 @@ open class MatterContainerInputSlot @JvmOverloads constructor(
index: Int,
x: Int = 0,
y: Int = 0,
val direction: IMatterHandler.MatterDirection = IMatterHandler.MatterDirection.BIDIRECTIONAL
val direction: MatterDirection = MatterDirection.BIDIRECTIONAL
) : MatterySlot(p_40223_, index, x, y) {
override fun mayPlace(p_40231_: ItemStack): Boolean {
val handler = p_40231_.getCapability(MatteryCapability.MATTER).resolve()
if (handler.isEmpty) return false
val direction = handler.get().direction
return direction == IMatterHandler.MatterDirection.BIDIRECTIONAL || this.direction == direction
return direction == MatterDirection.BIDIRECTIONAL || this.direction == direction
}
}

View File

@ -33,8 +33,8 @@ class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) {
) : this(menu) {
if (matter == null) return
this.level = matter::getStoredMatter
this.maxLevel = matter::getMaxStoredMatter
this.level = matter::storedMatter
this.maxLevel = matter::maxStoredMatter
}
constructor(