Move energy, matter and storage ImpreciseFraction

those imprecisions will haut me in my dreams
This commit is contained in:
DBotThePony 2022-01-26 09:00:47 +07:00
parent dab5cd6a2b
commit a5e5b928bc
Signed by: DBot
GPG Key ID: DCC23B5715498507
60 changed files with 1054 additions and 663 deletions

View File

@ -30,6 +30,7 @@ import ru.dbotthepony.mc.otm.client.EventHandler;
import ru.dbotthepony.mc.otm.client.model.GravitationStabilizerModel; import ru.dbotthepony.mc.otm.client.model.GravitationStabilizerModel;
import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel; import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import ru.dbotthepony.mc.otm.item.ItemPortableCondensationDrive; import ru.dbotthepony.mc.otm.item.ItemPortableCondensationDrive;
import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.matter.MatterRegistry;
import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.network.MatteryNetworking;
@ -171,7 +172,7 @@ public class OverdriveThatMatters {
MatterRegistry.registerInitialItems(); MatterRegistry.registerInitialItems();
ITEM_STORAGE = StorageObjectRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new Fraction("3.125")); ITEM_STORAGE = StorageObjectRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new ImpreciseFraction("3.125"));
TritaniumArmorModel.register(); TritaniumArmorModel.register();
GravitationStabilizerModel.register(); GravitationStabilizerModel.register();

View File

@ -52,6 +52,7 @@ import ru.dbotthepony.mc.otm.client.render.EnergyCounterRenderer;
import ru.dbotthepony.mc.otm.client.render.GravitationStabilizerRenderer; import ru.dbotthepony.mc.otm.client.render.GravitationStabilizerRenderer;
import ru.dbotthepony.mc.otm.client.render.SkinElement; import ru.dbotthepony.mc.otm.client.render.SkinElement;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import ru.dbotthepony.mc.otm.item.*; import ru.dbotthepony.mc.otm.item.*;
import ru.dbotthepony.mc.otm.menu.*; import ru.dbotthepony.mc.otm.menu.*;
import ru.dbotthepony.mc.otm.client.screen.*; import ru.dbotthepony.mc.otm.client.screen.*;
@ -673,11 +674,11 @@ public class Registry {
public static final ItemPill PILL_OBLIVION = new ItemPill(PillType.OBLIVION); public static final ItemPill PILL_OBLIVION = new ItemPill(PillType.OBLIVION);
public static final ItemPillHeal PILL_HEAL = new ItemPillHeal(); public static final ItemPillHeal PILL_HEAL = new ItemPillHeal();
public static final ItemBattery BATTERY_CRUDE = new ItemBattery(new Fraction(30_000), new Fraction(150), new Fraction(150)); public static final ItemBattery BATTERY_CRUDE = new ItemBattery(new ImpreciseFraction(30_000), new ImpreciseFraction(150), new ImpreciseFraction(150));
public static final ItemBattery BATTERY_BASIC = new ItemBattery(new Fraction(60_000), new Fraction(300), new Fraction(300)); public static final ItemBattery BATTERY_BASIC = new ItemBattery(new ImpreciseFraction(60_000), new ImpreciseFraction(300), new ImpreciseFraction(300));
public static final ItemBattery BATTERY_NORMAL = new ItemBattery(new Fraction(250_000), new Fraction(1000), new Fraction(1000)); public static final ItemBattery BATTERY_NORMAL = new ItemBattery(new ImpreciseFraction(250_000), new ImpreciseFraction(1000), new ImpreciseFraction(1000));
public static final ItemBattery BATTERY_DENSE = new ItemBattery(new Fraction(1_000_000), new Fraction(2000), new Fraction(2000)); public static final ItemBattery BATTERY_DENSE = new ItemBattery(new ImpreciseFraction(1_000_000), new ImpreciseFraction(2000), new ImpreciseFraction(2000));
public static final ItemBattery BATTERY_CAPACITOR = new ItemBattery(new Fraction(150_000), new Fraction(15000), new Fraction(15000)); public static final ItemBattery BATTERY_CAPACITOR = new ItemBattery(new ImpreciseFraction(150_000), new ImpreciseFraction(15000), new ImpreciseFraction(15000));
public static final ItemBattery BATTERY_CREATIVE = new ItemBattery(); public static final ItemBattery BATTERY_CREATIVE = new ItemBattery();
public static final ItemBattery[] BATTERIES = { public static final ItemBattery[] BATTERIES = {
@ -705,9 +706,9 @@ public class Registry {
MATTER_TRANSFORM_MATRIX, MATTER_TRANSFORM_MATRIX,
}; };
public static final ItemMatterCapacitor MATTER_CAPACITOR_BASIC = new ItemMatterCapacitor(new Fraction("4")); public static final ItemMatterCapacitor MATTER_CAPACITOR_BASIC = new ItemMatterCapacitor(new ImpreciseFraction("4"));
public static final ItemMatterCapacitor MATTER_CAPACITOR_NORMAL = new ItemMatterCapacitor(new Fraction("10")); public static final ItemMatterCapacitor MATTER_CAPACITOR_NORMAL = new ItemMatterCapacitor(new ImpreciseFraction("10"));
public static final ItemMatterCapacitor MATTER_CAPACITOR_DENSE = new ItemMatterCapacitor(new Fraction("40")); public static final ItemMatterCapacitor MATTER_CAPACITOR_DENSE = new ItemMatterCapacitor(new ImpreciseFraction("40"));
public static final ItemMatterCapacitor MATTER_CAPACITOR_CREATIVE = new ItemMatterCapacitor(); public static final ItemMatterCapacitor MATTER_CAPACITOR_CREATIVE = new ItemMatterCapacitor();
public static final ItemPatternStorage PATTERN_DRIVE_NORMAL = new ItemPatternStorage(4); public static final ItemPatternStorage PATTERN_DRIVE_NORMAL = new ItemPatternStorage(4);

View File

@ -9,6 +9,7 @@ import ru.dbotthepony.mc.otm.android.AndroidFeatureType;
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -39,8 +40,8 @@ public class AndroidNanobotsArmor extends AndroidFeature {
protected int ticks_passed = 0; protected int ticks_passed = 0;
protected int layers = 0; protected int layers = 0;
protected static final Fraction ENERGY_PER_BUILT = new Fraction(200); protected static final ImpreciseFraction ENERGY_PER_BUILT = new ImpreciseFraction(200);
protected static final Fraction ENERGY_PER_HITPOINT = new Fraction(500); protected static final ImpreciseFraction ENERGY_PER_HITPOINT = new ImpreciseFraction(500);
public static final int[] TICKS = new int[] { public static final int[] TICKS = new int[] {
80, // 4 seconds to build a layer 80, // 4 seconds to build a layer

View File

@ -9,6 +9,7 @@ import ru.dbotthepony.mc.otm.android.AndroidFeatureType;
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -20,7 +21,7 @@ public class AndroidNanobotsRegeneration extends AndroidFeature {
protected int ticks_passed = 0; protected int ticks_passed = 0;
protected int heal_ticks = 0; protected int heal_ticks = 0;
protected static final Fraction ENERGY_PER_HITPOINT = new Fraction(800); protected static final ImpreciseFraction ENERGY_PER_HITPOINT = new ImpreciseFraction(800);
protected static final int[] TICKS_BETWEEN_HEAL = new int[] { protected static final int[] TICKS_BETWEEN_HEAL = new int[] {
100, // 5 seconds 100, // 5 seconds
@ -42,7 +43,7 @@ public class AndroidNanobotsRegeneration extends AndroidFeature {
var missing = Math.min(1, ent.getMaxHealth() - ent.getHealth()); var missing = Math.min(1, ent.getMaxHealth() - ent.getHealth());
var extract = capability.extractEnergyInner(ENERGY_PER_HITPOINT.times(missing), false); var extract = capability.extractEnergyInner(ENERGY_PER_HITPOINT.times(missing), false);
if (extract.compareTo(Fraction.ZERO) > 0) { if (extract.compareTo(ImpreciseFraction.ZERO) > 0) {
heal_ticks = Math.min(heal_ticks + 1, level); heal_ticks = Math.min(heal_ticks + 1, level);
var heal = missing * extract.div(ENERGY_PER_HITPOINT).toFloat(); var heal = missing * extract.div(ENERGY_PER_HITPOINT).toFloat();
ent.heal(heal); ent.heal(heal);

View File

@ -6,19 +6,20 @@ import net.minecraft.nbt.DoubleTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public record MachineJob(ItemStack stack, double ticks, Fraction power, CompoundTag data) { public record MachineJob(ItemStack stack, double ticks, ImpreciseFraction power, CompoundTag data) {
public MachineJob(ItemStack stack, double ticks, Fraction power) { public MachineJob(ItemStack stack, double ticks, ImpreciseFraction power) {
this(stack, ticks, power, new CompoundTag()); this(stack, ticks, power, new CompoundTag());
} }
public MachineJob(ItemStack stack, double ticks) { public MachineJob(ItemStack stack, double ticks) {
this(stack, ticks, Fraction.ZERO); this(stack, ticks, ImpreciseFraction.ZERO);
} }
public CompoundTag serializeNBT() { public CompoundTag serializeNBT() {
@ -42,7 +43,7 @@ public record MachineJob(ItemStack stack, double ticks, Fraction power, Compound
ItemStack stack = ItemStack.of(stack_tag); ItemStack stack = ItemStack.of(stack_tag);
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
return new MachineJob(stack, ticks_processing_time.getAsDouble(), Fraction.deserializeNBT(tag.get("power")), tag.getCompound("data")); return new MachineJob(stack, ticks_processing_time.getAsDouble(), ImpreciseFraction.deserializeNBT(tag.get("power")), tag.getCompound("data"));
} }
} }
} }

View File

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

View File

@ -35,26 +35,4 @@ public class MatteryCapability {
event.register(IStorageGraphNode.class); event.register(IStorageGraphNode.class);
event.register(IMatterGraphNode.class); event.register(IMatterGraphNode.class);
} }
public static final MathContext ROUND_RULES = new MathContext(32, RoundingMode.HALF_DOWN);
public static final Fraction INT_MAX_VALUE = new Fraction(Integer.MAX_VALUE);
public static final Fraction INT_MIN_VALUE = new Fraction(Integer.MIN_VALUE);
public static final Fraction LONG_MAX_VALUE = new Fraction(Long.MAX_VALUE);
public static final Fraction LONG_MIN_VALUE = new Fraction(Long.MIN_VALUE);
public static Fraction drainFE(IEnergyStorage capability, Fraction howMuch, boolean simulate) {
if (howMuch.compareTo(Fraction.ONE) < 0)
return Fraction.ZERO;
return new Fraction(capability.extractEnergy(howMuch.compareTo(INT_MAX_VALUE) > 0 ? Integer.MAX_VALUE : howMuch.toInt(), simulate));
}
public static Fraction floodFE(IEnergyStorage capability, Fraction howMuch, boolean simulate) {
if (howMuch.compareTo(Fraction.ONE) < 0)
return Fraction.ZERO;
return new Fraction(capability.receiveEnergy(howMuch.compareTo(INT_MAX_VALUE) > 0 ? Integer.MAX_VALUE : howMuch.toInt(), simulate));
}
} }

View File

@ -1,11 +1,9 @@
package ru.dbotthepony.mc.otm.capability.matter; package ru.dbotthepony.mc.otm.capability.matter;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
@ -16,18 +14,18 @@ public interface IMatterHandler {
BIDIRECTIONAL // storage BIDIRECTIONAL // storage
} }
Fraction getStoredMatter(); ImpreciseFraction getStoredMatter();
Fraction getMaxStoredMatter(); ImpreciseFraction getMaxStoredMatter();
Fraction receiveMatterOuter(Fraction howMuch, boolean simulate); ImpreciseFraction receiveMatterOuter(ImpreciseFraction howMuch, boolean simulate);
Fraction receiveMatterInner(Fraction howMuch, boolean simulate); ImpreciseFraction receiveMatterInner(ImpreciseFraction howMuch, boolean simulate);
Fraction extractMatterOuter(Fraction howMuch, boolean simulate); ImpreciseFraction extractMatterOuter(ImpreciseFraction howMuch, boolean simulate);
Fraction extractMatterInner(Fraction howMuch, boolean simulate); ImpreciseFraction extractMatterInner(ImpreciseFraction howMuch, boolean simulate);
MatterDirection getDirection(); MatterDirection getDirection();
default Fraction getMissingMatter() { default ImpreciseFraction getMissingMatter() {
return getMaxStoredMatter().minus(getStoredMatter()); return getMaxStoredMatter().minus(getStoredMatter());
} }
} }

View File

@ -4,30 +4,28 @@ import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class MatterHandlerCapability implements IMatterHandler, INBTSerializable<CompoundTag> { public class MatterHandlerCapability implements IMatterHandler, INBTSerializable<CompoundTag> {
protected final Runnable listener; protected final Runnable listener;
protected Fraction stored = Fraction.ZERO; protected ImpreciseFraction stored = ImpreciseFraction.ZERO;
protected MatterDirection direction; protected MatterDirection direction;
protected Fraction max_storage; protected ImpreciseFraction max_storage;
protected Fraction max_receive; protected ImpreciseFraction max_receive;
protected Fraction max_extract; protected ImpreciseFraction max_extract;
public MatterHandlerCapability( public MatterHandlerCapability(
@Nullable Runnable listener, @Nullable Runnable listener,
MatterDirection direction, MatterDirection direction,
Fraction max_storage ImpreciseFraction max_storage
) { ) {
this.listener = listener; this.listener = listener;
this.direction = direction; this.direction = direction;
@ -37,9 +35,9 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable
public MatterHandlerCapability( public MatterHandlerCapability(
@Nullable Runnable listener, @Nullable Runnable listener,
MatterDirection direction, MatterDirection direction,
Fraction max_storage, ImpreciseFraction max_storage,
Fraction max_receive, ImpreciseFraction max_receive,
Fraction max_extract ImpreciseFraction max_extract
) { ) {
this(listener, direction, max_storage); this(listener, direction, max_storage);
@ -63,33 +61,33 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable
@Nonnull @Nonnull
@Override @Override
public Fraction getStoredMatter() { public ImpreciseFraction getStoredMatter() {
return stored; return stored;
} }
@Nonnull @Nonnull
@Override @Override
public Fraction getMaxStoredMatter() { public ImpreciseFraction getMaxStoredMatter() {
return max_storage; return max_storage;
} }
public boolean canReceiveAll(Fraction value) { public boolean canReceiveAll(ImpreciseFraction value) {
return max_storage.compareTo(value) >= 0 && stored.plus(value).compareTo(max_storage) <= 0; return max_storage.compareTo(value) >= 0 && stored.plus(value).compareTo(max_storage) <= 0;
} }
@Nonnull @Nonnull
@Override @Override
public Fraction receiveMatterOuter(Fraction howMuch, boolean simulate) { public ImpreciseFraction receiveMatterOuter(ImpreciseFraction howMuch, boolean simulate) {
if (getDirection() == MatterDirection.EXTRACT) if (getDirection() == MatterDirection.EXTRACT)
return Fraction.ZERO; return ImpreciseFraction.ZERO;
return receiveMatterInner(howMuch, simulate); return receiveMatterInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public Fraction receiveMatterInner(Fraction howMuch, boolean simulate) { public ImpreciseFraction receiveMatterInner(ImpreciseFraction howMuch, boolean simulate) {
Fraction new_matter; ImpreciseFraction new_matter;
if (max_receive == null) { if (max_receive == null) {
new_matter = stored.plus(howMuch).min(max_storage); new_matter = stored.plus(howMuch).min(max_storage);
@ -97,7 +95,7 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable
new_matter = stored.plus(howMuch.min(max_receive)).min(max_storage); new_matter = stored.plus(howMuch.min(max_receive)).min(max_storage);
} }
Fraction diff = new_matter.minus(stored); ImpreciseFraction diff = new_matter.minus(stored);
if (!simulate && new_matter.compareTo(stored) != 0) { if (!simulate && new_matter.compareTo(stored) != 0) {
stored = new_matter; stored = new_matter;
@ -112,17 +110,17 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable
@Nonnull @Nonnull
@Override @Override
public Fraction extractMatterOuter(Fraction howMuch, boolean simulate) { public ImpreciseFraction extractMatterOuter(ImpreciseFraction howMuch, boolean simulate) {
if (getDirection() == MatterDirection.RECEIVE) if (getDirection() == MatterDirection.RECEIVE)
return Fraction.ZERO; return ImpreciseFraction.ZERO;
return extractMatterInner(howMuch, simulate); return extractMatterInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public Fraction extractMatterInner(Fraction howMuch, boolean simulate) { public ImpreciseFraction extractMatterInner(ImpreciseFraction howMuch, boolean simulate) {
Fraction new_matter; ImpreciseFraction new_matter;
if (max_receive == null) { if (max_receive == null) {
new_matter = stored.minus(howMuch).moreThanZero(); new_matter = stored.minus(howMuch).moreThanZero();
@ -130,7 +128,7 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable
new_matter = stored.minus(howMuch.min(max_receive)).moreThanZero(); new_matter = stored.minus(howMuch.min(max_receive)).moreThanZero();
} }
Fraction diff = stored.minus(new_matter); ImpreciseFraction diff = stored.minus(new_matter);
if (!simulate && new_matter.compareTo(stored) != 0) { if (!simulate && new_matter.compareTo(stored) != 0) {
stored = new_matter; stored = new_matter;
@ -167,18 +165,18 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable
@Override @Override
public void deserializeNBT(CompoundTag tag) { public void deserializeNBT(CompoundTag tag) {
if (tag.contains("stored")) if (tag.contains("stored"))
stored = Fraction.deserializeNBT(tag.get("stored")); stored = ImpreciseFraction.deserializeNBT(tag.get("stored"));
if (tag.contains("max_storage")) if (tag.contains("max_storage"))
max_storage = Fraction.deserializeNBT(tag.get("max_storage")); max_storage = ImpreciseFraction.deserializeNBT(tag.get("max_storage"));
if (tag.contains("max_receive")) if (tag.contains("max_receive"))
max_receive = Fraction.deserializeNBT(tag.get("max_receive")); max_receive = ImpreciseFraction.deserializeNBT(tag.get("max_receive"));
else else
max_receive = null; max_receive = null;
if (tag.contains("max_extract")) if (tag.contains("max_extract"))
max_extract = Fraction.deserializeNBT(tag.get("max_extract")); max_extract = ImpreciseFraction.deserializeNBT(tag.get("max_extract"));
else else
max_extract = null; max_extract = null;
} }

View File

@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer;
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import java.util.Optional; import java.util.Optional;
import java.util.Random; import java.util.Random;
@ -160,7 +161,7 @@ public class AndroidGui {
float level; float level;
if (android.getMaxBatteryLevel().compareTo(Fraction.ZERO) == 0) { if (android.getMaxBatteryLevel().isZero()) {
level = 0f; level = 0f;
} else { } else {
level = android.getBatteryLevel().div(android.getMaxBatteryLevel()).toFloat(); level = android.getBatteryLevel().div(android.getMaxBatteryLevel()).toFloat();

View File

@ -20,6 +20,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive; import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import ru.dbotthepony.mc.otm.menu.FormattingHelper; import ru.dbotthepony.mc.otm.menu.FormattingHelper;
import ru.dbotthepony.mc.otm.network.MatterRegistryPacket; import ru.dbotthepony.mc.otm.network.MatterRegistryPacket;
import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.network.MatteryNetworking;
@ -30,11 +31,11 @@ import java.math.MathContext;
import java.util.*; import java.util.*;
public class MatterRegistry { public class MatterRegistry {
public static final Map<Item, Fraction> INITIAL_ITEMS = new HashMap<>(); public static final Map<Item, ImpreciseFraction> INITIAL_ITEMS = new HashMap<>();
public static final Map<Item, Fraction> ITEMS = new HashMap<>(); public static final Map<Item, ImpreciseFraction> ITEMS = new HashMap<>();
public static Fraction getMatterValue(Item item) { public static ImpreciseFraction getMatterValue(Item item) {
return ITEMS.getOrDefault(item, INITIAL_ITEMS.getOrDefault(item, Fraction.ZERO)); return ITEMS.getOrDefault(item, INITIAL_ITEMS.getOrDefault(item, ImpreciseFraction.ZERO));
} }
public static boolean hasMatterValue(Item item) { public static boolean hasMatterValue(Item item) {
@ -49,25 +50,25 @@ public class MatterRegistry {
} }
public static boolean canDecompose(ItemStack stack) { public static boolean canDecompose(ItemStack stack) {
if (stack.getCapability(MatteryCapability.DRIVE).isPresent() && stack.getCapability(MatteryCapability.DRIVE).resolve().get().getStoredCount().compareTo(Fraction.ZERO) > 0) if (stack.getCapability(MatteryCapability.DRIVE).isPresent() && stack.getCapability(MatteryCapability.DRIVE).resolve().get().getStoredCount().compareTo(ImpreciseFraction.ZERO) > 0)
return false; return false;
if (stack.getCapability(MatteryCapability.MATTER).isPresent() && stack.getCapability(MatteryCapability.MATTER).resolve().get().getStoredMatter().compareTo(Fraction.ZERO) > 0) if (stack.getCapability(MatteryCapability.MATTER).isPresent() && stack.getCapability(MatteryCapability.MATTER).resolve().get().getStoredMatter().compareTo(ImpreciseFraction.ZERO) > 0)
return false; return false;
return hasMatterValue(stack.getItem()); return hasMatterValue(stack.getItem());
} }
private static Fraction getMatterValue(ItemStack stack, int level) { private static ImpreciseFraction getMatterValue(ItemStack stack, int level) {
if (level >= 100) { if (level >= 100) {
return Fraction.ZERO; return ImpreciseFraction.ZERO;
} }
Item item = stack.getItem(); Item item = stack.getItem();
var matter = getMatterValue(item); var matter = getMatterValue(item);
if (item.isDamageable(stack)) { if (item.isDamageable(stack)) {
matter = matter.times(Fraction.ONE.minus(new Fraction(item.getDamage(stack)).div(new Fraction(item.getMaxDamage(stack))))); matter = matter.times(ImpreciseFraction.ONE.minus(new ImpreciseFraction(item.getDamage(stack)).div(new ImpreciseFraction(item.getMaxDamage(stack)))));
} }
var cap1 = stack.getCapability(MatteryCapability.DRIVE).resolve(); var cap1 = stack.getCapability(MatteryCapability.DRIVE).resolve();
@ -86,104 +87,104 @@ public class MatterRegistry {
return matter; return matter;
} }
public static Fraction getMatterValue(ItemStack stack) { public static ImpreciseFraction getMatterValue(ItemStack stack) {
return getMatterValue(stack, 0); return getMatterValue(stack, 0);
} }
public static void registerInitialItems() { public static void registerInitialItems() {
// basic things // basic things
INITIAL_ITEMS.put(Items.DIRT, new Fraction("0.0013")); INITIAL_ITEMS.put(Items.DIRT, new ImpreciseFraction("0.0013"));
INITIAL_ITEMS.put(Items.DIRT_PATH, new Fraction("0.0013")); INITIAL_ITEMS.put(Items.DIRT_PATH, new ImpreciseFraction("0.0013"));
INITIAL_ITEMS.put(Items.GRASS_BLOCK, new Fraction("0.0016")); INITIAL_ITEMS.put(Items.GRASS_BLOCK, new ImpreciseFraction("0.0016"));
INITIAL_ITEMS.put(Items.POINTED_DRIPSTONE, new Fraction("0.0007")); INITIAL_ITEMS.put(Items.POINTED_DRIPSTONE, new ImpreciseFraction("0.0007"));
INITIAL_ITEMS.put(Items.STONE, new Fraction("0.001")); INITIAL_ITEMS.put(Items.STONE, new ImpreciseFraction("0.001"));
INITIAL_ITEMS.put(Items.COBBLESTONE, new Fraction("0.001")); INITIAL_ITEMS.put(Items.COBBLESTONE, new ImpreciseFraction("0.001"));
INITIAL_ITEMS.put(Items.MOSSY_COBBLESTONE, new Fraction("0.001")); INITIAL_ITEMS.put(Items.MOSSY_COBBLESTONE, new ImpreciseFraction("0.001"));
INITIAL_ITEMS.put(Items.NETHERRACK, new Fraction("0.00027")); INITIAL_ITEMS.put(Items.NETHERRACK, new ImpreciseFraction("0.00027"));
INITIAL_ITEMS.put(Items.GRANITE, new Fraction("0.0011")); INITIAL_ITEMS.put(Items.GRANITE, new ImpreciseFraction("0.0011"));
INITIAL_ITEMS.put(Items.DIORITE, new Fraction("0.0013")); INITIAL_ITEMS.put(Items.DIORITE, new ImpreciseFraction("0.0013"));
INITIAL_ITEMS.put(Items.ANDESITE, new Fraction("0.0012")); INITIAL_ITEMS.put(Items.ANDESITE, new ImpreciseFraction("0.0012"));
INITIAL_ITEMS.put(Items.BASALT, new Fraction("0.0013")); INITIAL_ITEMS.put(Items.BASALT, new ImpreciseFraction("0.0013"));
INITIAL_ITEMS.put(Items.SOUL_SAND, new Fraction("0.00087")); INITIAL_ITEMS.put(Items.SOUL_SAND, new ImpreciseFraction("0.00087"));
INITIAL_ITEMS.put(Items.SOUL_SOIL, new Fraction("0.00087")); INITIAL_ITEMS.put(Items.SOUL_SOIL, new ImpreciseFraction("0.00087"));
INITIAL_ITEMS.put(Items.ICE, new Fraction("0.0002")); INITIAL_ITEMS.put(Items.ICE, new ImpreciseFraction("0.0002"));
INITIAL_ITEMS.put(Items.GRAVEL, new Fraction("0.001")); INITIAL_ITEMS.put(Items.GRAVEL, new ImpreciseFraction("0.001"));
INITIAL_ITEMS.put(Items.FLINT, new Fraction("0.001")); INITIAL_ITEMS.put(Items.FLINT, new ImpreciseFraction("0.001"));
INITIAL_ITEMS.put(Items.SAND, new Fraction("0.0005")); INITIAL_ITEMS.put(Items.SAND, new ImpreciseFraction("0.0005"));
INITIAL_ITEMS.put(Items.RED_SAND, new Fraction("0.0005")); INITIAL_ITEMS.put(Items.RED_SAND, new ImpreciseFraction("0.0005"));
INITIAL_ITEMS.put(Items.TUFF, new Fraction("0.0007")); INITIAL_ITEMS.put(Items.TUFF, new ImpreciseFraction("0.0007"));
INITIAL_ITEMS.put(Items.DEEPSLATE, new Fraction("0.0014")); INITIAL_ITEMS.put(Items.DEEPSLATE, new ImpreciseFraction("0.0014"));
INITIAL_ITEMS.put(Items.COBBLED_DEEPSLATE, new Fraction("0.0014")); INITIAL_ITEMS.put(Items.COBBLED_DEEPSLATE, new ImpreciseFraction("0.0014"));
INITIAL_ITEMS.put(Items.BLACKSTONE, new Fraction("0.0015")); INITIAL_ITEMS.put(Items.BLACKSTONE, new ImpreciseFraction("0.0015"));
INITIAL_ITEMS.put(Items.INFESTED_STONE, new Fraction("0.063")); INITIAL_ITEMS.put(Items.INFESTED_STONE, new ImpreciseFraction("0.063"));
INITIAL_ITEMS.put(Items.INFESTED_COBBLESTONE, new Fraction("0.063")); INITIAL_ITEMS.put(Items.INFESTED_COBBLESTONE, new ImpreciseFraction("0.063"));
INITIAL_ITEMS.put(Items.INFESTED_STONE_BRICKS, new Fraction("0.063")); INITIAL_ITEMS.put(Items.INFESTED_STONE_BRICKS, new ImpreciseFraction("0.063"));
INITIAL_ITEMS.put(Items.INFESTED_MOSSY_STONE_BRICKS, new Fraction("0.063")); INITIAL_ITEMS.put(Items.INFESTED_MOSSY_STONE_BRICKS, new ImpreciseFraction("0.063"));
INITIAL_ITEMS.put(Items.INFESTED_CRACKED_STONE_BRICKS, new Fraction("0.063")); INITIAL_ITEMS.put(Items.INFESTED_CRACKED_STONE_BRICKS, new ImpreciseFraction("0.063"));
INITIAL_ITEMS.put(Items.INFESTED_CHISELED_STONE_BRICKS, new Fraction("0.063")); INITIAL_ITEMS.put(Items.INFESTED_CHISELED_STONE_BRICKS, new ImpreciseFraction("0.063"));
INITIAL_ITEMS.put(Items.INFESTED_DEEPSLATE, new Fraction("0.067")); INITIAL_ITEMS.put(Items.INFESTED_DEEPSLATE, new ImpreciseFraction("0.067"));
// affected by luck enchantment, thus can be duped // affected by luck enchantment, thus can be duped
// INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new Fraction("0.037")); // INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new ImpreciseFraction("0.037"));
INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new Fraction("0.34")); INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new ImpreciseFraction("0.34"));
// assuming it is very light since it is floating // assuming it is very light since it is floating
INITIAL_ITEMS.put(Items.END_STONE, new Fraction("0.0004")); INITIAL_ITEMS.put(Items.END_STONE, new ImpreciseFraction("0.0004"));
INITIAL_ITEMS.put(Items.OBSIDIAN, new Fraction("0.038")); INITIAL_ITEMS.put(Items.OBSIDIAN, new ImpreciseFraction("0.038"));
// metallic / chemical things // metallic / chemical things
INITIAL_ITEMS.put(Items.COAL, new Fraction("0.005")); INITIAL_ITEMS.put(Items.COAL, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.LAPIS_LAZULI, new Fraction("0.0042")); INITIAL_ITEMS.put(Items.LAPIS_LAZULI, new ImpreciseFraction("0.0042"));
INITIAL_ITEMS.put(Items.REDSTONE, new Fraction("0.004")); INITIAL_ITEMS.put(Items.REDSTONE, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.CHARCOAL, new Fraction("0.005")); INITIAL_ITEMS.put(Items.CHARCOAL, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.DIAMOND, new Fraction("0.5")); INITIAL_ITEMS.put(Items.DIAMOND, new ImpreciseFraction("0.5"));
INITIAL_ITEMS.put(Items.EMERALD, new Fraction("0.46")); INITIAL_ITEMS.put(Items.EMERALD, new ImpreciseFraction("0.46"));
INITIAL_ITEMS.put(Items.IRON_INGOT, new Fraction("0.03")); INITIAL_ITEMS.put(Items.IRON_INGOT, new ImpreciseFraction("0.03"));
INITIAL_ITEMS.put(Items.COPPER_INGOT, new Fraction("0.014")); INITIAL_ITEMS.put(Items.COPPER_INGOT, new ImpreciseFraction("0.014"));
INITIAL_ITEMS.put(Items.GOLD_INGOT, new Fraction("0.32")); INITIAL_ITEMS.put(Items.GOLD_INGOT, new ImpreciseFraction("0.32"));
INITIAL_ITEMS.put(Items.NETHERITE_SCRAP, new Fraction("1.2")); INITIAL_ITEMS.put(Items.NETHERITE_SCRAP, new ImpreciseFraction("1.2"));
INITIAL_ITEMS.put(Items.QUARTZ, new Fraction("0.008")); INITIAL_ITEMS.put(Items.QUARTZ, new ImpreciseFraction("0.008"));
INITIAL_ITEMS.put(Items.GLOWSTONE_DUST, new Fraction("0.007")); INITIAL_ITEMS.put(Items.GLOWSTONE_DUST, new ImpreciseFraction("0.007"));
INITIAL_ITEMS.put(Items.AMETHYST_SHARD, new Fraction("0.034")); INITIAL_ITEMS.put(Items.AMETHYST_SHARD, new ImpreciseFraction("0.034"));
// living things // living things
INITIAL_ITEMS.put(Items.MOSS_BLOCK, new Fraction("0.0012")); INITIAL_ITEMS.put(Items.MOSS_BLOCK, new ImpreciseFraction("0.0012"));
INITIAL_ITEMS.put(Items.OAK_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.OAK_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.SPRUCE_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.SPRUCE_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.BIRCH_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.BIRCH_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.JUNGLE_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.JUNGLE_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.ACACIA_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.ACACIA_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.DARK_OAK_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.DARK_OAK_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.BAMBOO, new Fraction("0.00085")); INITIAL_ITEMS.put(Items.BAMBOO, new ImpreciseFraction("0.00085"));
INITIAL_ITEMS.put(Items.CRIMSON_PLANKS, new Fraction("0.003")); INITIAL_ITEMS.put(Items.CRIMSON_PLANKS, new ImpreciseFraction("0.003"));
INITIAL_ITEMS.put(Items.WARPED_PLANKS, new Fraction("0.003")); INITIAL_ITEMS.put(Items.WARPED_PLANKS, new ImpreciseFraction("0.003"));
INITIAL_ITEMS.put(Items.STRIPPED_OAK_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.STRIPPED_OAK_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.STRIPPED_SPRUCE_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.STRIPPED_SPRUCE_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.STRIPPED_BIRCH_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.STRIPPED_BIRCH_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.STRIPPED_JUNGLE_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.STRIPPED_JUNGLE_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.STRIPPED_ACACIA_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.STRIPPED_ACACIA_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.STRIPPED_DARK_OAK_LOG, new Fraction("0.005")); INITIAL_ITEMS.put(Items.STRIPPED_DARK_OAK_LOG, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.CACTUS, new Fraction("0.0039")); INITIAL_ITEMS.put(Items.CACTUS, new ImpreciseFraction("0.0039"));
INITIAL_ITEMS.put(Items.PUMPKIN, new Fraction("0.005")); INITIAL_ITEMS.put(Items.PUMPKIN, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.MELON, new Fraction("0.005")); INITIAL_ITEMS.put(Items.MELON, new ImpreciseFraction("0.005"));
// flowers! // flowers!
final Fraction flower_value = new Fraction("0.0031"); final ImpreciseFraction flower_value = new ImpreciseFraction("0.0031");
INITIAL_ITEMS.put(Items.DANDELION, flower_value); INITIAL_ITEMS.put(Items.DANDELION, flower_value);
INITIAL_ITEMS.put(Items.POPPY, flower_value); INITIAL_ITEMS.put(Items.POPPY, flower_value);
INITIAL_ITEMS.put(Items.BLUE_ORCHID, flower_value); INITIAL_ITEMS.put(Items.BLUE_ORCHID, flower_value);
@ -197,28 +198,28 @@ public class MatterRegistry {
INITIAL_ITEMS.put(Items.CORNFLOWER, flower_value); INITIAL_ITEMS.put(Items.CORNFLOWER, flower_value);
INITIAL_ITEMS.put(Items.LILY_OF_THE_VALLEY, flower_value); INITIAL_ITEMS.put(Items.LILY_OF_THE_VALLEY, flower_value);
final Fraction big_flower_value = new Fraction("0.0042"); final ImpreciseFraction big_flower_value = new ImpreciseFraction("0.0042");
INITIAL_ITEMS.put(Items.SUNFLOWER, big_flower_value); INITIAL_ITEMS.put(Items.SUNFLOWER, big_flower_value);
INITIAL_ITEMS.put(Items.LILAC, big_flower_value); INITIAL_ITEMS.put(Items.LILAC, big_flower_value);
INITIAL_ITEMS.put(Items.ROSE_BUSH, big_flower_value); INITIAL_ITEMS.put(Items.ROSE_BUSH, big_flower_value);
INITIAL_ITEMS.put(Items.PEONY, big_flower_value); INITIAL_ITEMS.put(Items.PEONY, big_flower_value);
INITIAL_ITEMS.put(Items.SPORE_BLOSSOM, new Fraction("0.0067")); INITIAL_ITEMS.put(Items.SPORE_BLOSSOM, new ImpreciseFraction("0.0067"));
INITIAL_ITEMS.put(Items.BROWN_MUSHROOM, new Fraction("0.0034")); INITIAL_ITEMS.put(Items.BROWN_MUSHROOM, new ImpreciseFraction("0.0034"));
INITIAL_ITEMS.put(Items.RED_MUSHROOM, new Fraction("0.0034")); INITIAL_ITEMS.put(Items.RED_MUSHROOM, new ImpreciseFraction("0.0034"));
INITIAL_ITEMS.put(Items.CRIMSON_FUNGUS, new Fraction("0.004")); INITIAL_ITEMS.put(Items.CRIMSON_FUNGUS, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.WARPED_FUNGUS, new Fraction("0.004")); INITIAL_ITEMS.put(Items.WARPED_FUNGUS, new ImpreciseFraction("0.004"));
// grass // grass
final Fraction grass_value = new Fraction("0.0024"); final ImpreciseFraction grass_value = new ImpreciseFraction("0.0024");
INITIAL_ITEMS.put(Items.CRIMSON_ROOTS, grass_value); INITIAL_ITEMS.put(Items.CRIMSON_ROOTS, grass_value);
INITIAL_ITEMS.put(Items.WARPED_ROOTS, grass_value); INITIAL_ITEMS.put(Items.WARPED_ROOTS, grass_value);
INITIAL_ITEMS.put(Items.NETHER_SPROUTS, new Fraction("0.002")); INITIAL_ITEMS.put(Items.NETHER_SPROUTS, new ImpreciseFraction("0.002"));
INITIAL_ITEMS.put(Items.WEEPING_VINES, grass_value); INITIAL_ITEMS.put(Items.WEEPING_VINES, grass_value);
INITIAL_ITEMS.put(Items.TWISTING_VINES, grass_value); INITIAL_ITEMS.put(Items.TWISTING_VINES, grass_value);
INITIAL_ITEMS.put(Items.HANGING_ROOTS, grass_value); INITIAL_ITEMS.put(Items.HANGING_ROOTS, grass_value);
INITIAL_ITEMS.put(Items.TALL_GRASS, new Fraction("0.0035")); INITIAL_ITEMS.put(Items.TALL_GRASS, new ImpreciseFraction("0.0035"));
INITIAL_ITEMS.put(Items.LARGE_FERN, new Fraction("0.0035")); INITIAL_ITEMS.put(Items.LARGE_FERN, new ImpreciseFraction("0.0035"));
INITIAL_ITEMS.put(Items.GRASS, grass_value); INITIAL_ITEMS.put(Items.GRASS, grass_value);
INITIAL_ITEMS.put(Items.VINE, grass_value); INITIAL_ITEMS.put(Items.VINE, grass_value);
INITIAL_ITEMS.put(Items.LILY_PAD, grass_value); INITIAL_ITEMS.put(Items.LILY_PAD, grass_value);
@ -227,95 +228,95 @@ public class MatterRegistry {
INITIAL_ITEMS.put(Items.SEA_PICKLE, grass_value); INITIAL_ITEMS.put(Items.SEA_PICKLE, grass_value);
INITIAL_ITEMS.put(Items.SEAGRASS, grass_value); INITIAL_ITEMS.put(Items.SEAGRASS, grass_value);
INITIAL_ITEMS.put(Items.FERN, grass_value); INITIAL_ITEMS.put(Items.FERN, grass_value);
INITIAL_ITEMS.put(Items.DEAD_BUSH, new Fraction("0.0017")); INITIAL_ITEMS.put(Items.DEAD_BUSH, new ImpreciseFraction("0.0017"));
INITIAL_ITEMS.put(Items.GLOW_LICHEN, new Fraction("0.0026")); INITIAL_ITEMS.put(Items.GLOW_LICHEN, new ImpreciseFraction("0.0026"));
INITIAL_ITEMS.put(Items.AZALEA, new Fraction("0.0018")); INITIAL_ITEMS.put(Items.AZALEA, new ImpreciseFraction("0.0018"));
INITIAL_ITEMS.put(Items.FLOWERING_AZALEA, grass_value); INITIAL_ITEMS.put(Items.FLOWERING_AZALEA, grass_value);
// living plant (not very blocky) things // living plant (not very blocky) things
// saplings // saplings
INITIAL_ITEMS.put(Items.OAK_SAPLING, new Fraction("0.0035")); INITIAL_ITEMS.put(Items.OAK_SAPLING, new ImpreciseFraction("0.0035"));
INITIAL_ITEMS.put(Items.SPRUCE_SAPLING, new Fraction("0.0045")); INITIAL_ITEMS.put(Items.SPRUCE_SAPLING, new ImpreciseFraction("0.0045"));
INITIAL_ITEMS.put(Items.BIRCH_SAPLING, new Fraction("0.0035")); INITIAL_ITEMS.put(Items.BIRCH_SAPLING, new ImpreciseFraction("0.0035"));
INITIAL_ITEMS.put(Items.JUNGLE_SAPLING, new Fraction("0.0048")); INITIAL_ITEMS.put(Items.JUNGLE_SAPLING, new ImpreciseFraction("0.0048"));
INITIAL_ITEMS.put(Items.ACACIA_SAPLING, new Fraction("0.0033")); INITIAL_ITEMS.put(Items.ACACIA_SAPLING, new ImpreciseFraction("0.0033"));
INITIAL_ITEMS.put(Items.DARK_OAK_SAPLING, new Fraction("0.005")); INITIAL_ITEMS.put(Items.DARK_OAK_SAPLING, new ImpreciseFraction("0.005"));
INITIAL_ITEMS.put(Items.WHEAT_SEEDS, new Fraction("0.0007")); INITIAL_ITEMS.put(Items.WHEAT_SEEDS, new ImpreciseFraction("0.0007"));
INITIAL_ITEMS.put(Items.BEETROOT_SEEDS, new Fraction("0.0007")); INITIAL_ITEMS.put(Items.BEETROOT_SEEDS, new ImpreciseFraction("0.0007"));
// INITIAL_ITEMS.put(Items.MELON_SEEDS, new Fraction("0.0013")); // INITIAL_ITEMS.put(Items.MELON_SEEDS, new ImpreciseFraction("0.0013"));
INITIAL_ITEMS.put(Items.WHEAT, new Fraction("0.0016")); INITIAL_ITEMS.put(Items.WHEAT, new ImpreciseFraction("0.0016"));
INITIAL_ITEMS.put(Items.NETHER_WART, new Fraction("0.0017")); INITIAL_ITEMS.put(Items.NETHER_WART, new ImpreciseFraction("0.0017"));
INITIAL_ITEMS.put(Items.CARROT, new Fraction("0.0019")); INITIAL_ITEMS.put(Items.CARROT, new ImpreciseFraction("0.0019"));
INITIAL_ITEMS.put(Items.POTATO, new Fraction("0.0021")); INITIAL_ITEMS.put(Items.POTATO, new ImpreciseFraction("0.0021"));
INITIAL_ITEMS.put(Items.BEETROOT, new Fraction("0.0021")); INITIAL_ITEMS.put(Items.BEETROOT, new ImpreciseFraction("0.0021"));
INITIAL_ITEMS.put(Items.MELON_SLICE, new Fraction("0.0008")); INITIAL_ITEMS.put(Items.MELON_SLICE, new ImpreciseFraction("0.0008"));
INITIAL_ITEMS.put(Items.COCOA_BEANS, new Fraction("0.00035")); INITIAL_ITEMS.put(Items.COCOA_BEANS, new ImpreciseFraction("0.00035"));
INITIAL_ITEMS.put(Items.HONEYCOMB, new Fraction("0.0014")); INITIAL_ITEMS.put(Items.HONEYCOMB, new ImpreciseFraction("0.0014"));
INITIAL_ITEMS.put(Items.SUGAR_CANE, new Fraction("0.004")); INITIAL_ITEMS.put(Items.SUGAR_CANE, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.APPLE, new Fraction("0.0061")); INITIAL_ITEMS.put(Items.APPLE, new ImpreciseFraction("0.0061"));
INITIAL_ITEMS.put(Items.SWEET_BERRIES, new Fraction("0.0035")); INITIAL_ITEMS.put(Items.SWEET_BERRIES, new ImpreciseFraction("0.0035"));
INITIAL_ITEMS.put(Items.GLOW_BERRIES, new Fraction("0.0041")); INITIAL_ITEMS.put(Items.GLOW_BERRIES, new ImpreciseFraction("0.0041"));
INITIAL_ITEMS.put(Items.KELP, new Fraction("0.0009")); INITIAL_ITEMS.put(Items.KELP, new ImpreciseFraction("0.0009"));
// living animal things // living animal things
INITIAL_ITEMS.put(Items.STRING, new Fraction("0.0006")); INITIAL_ITEMS.put(Items.STRING, new ImpreciseFraction("0.0006"));
INITIAL_ITEMS.put(Items.COBWEB, new Fraction("0.0006")); INITIAL_ITEMS.put(Items.COBWEB, new ImpreciseFraction("0.0006"));
INITIAL_ITEMS.put(Items.INK_SAC, new Fraction("0.0009")); INITIAL_ITEMS.put(Items.INK_SAC, new ImpreciseFraction("0.0009"));
INITIAL_ITEMS.put(Items.SPIDER_EYE, new Fraction("0.001")); INITIAL_ITEMS.put(Items.SPIDER_EYE, new ImpreciseFraction("0.001"));
INITIAL_ITEMS.put(Items.FEATHER, new Fraction("0.0007")); INITIAL_ITEMS.put(Items.FEATHER, new ImpreciseFraction("0.0007"));
INITIAL_ITEMS.put(Items.GUNPOWDER, new Fraction("0.003")); INITIAL_ITEMS.put(Items.GUNPOWDER, new ImpreciseFraction("0.003"));
INITIAL_ITEMS.put(Items.LEATHER, new Fraction("0.0065")); INITIAL_ITEMS.put(Items.LEATHER, new ImpreciseFraction("0.0065"));
INITIAL_ITEMS.put(Items.BONE, new Fraction("0.004")); INITIAL_ITEMS.put(Items.BONE, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.ENDER_PEARL, new Fraction("0.041")); INITIAL_ITEMS.put(Items.ENDER_PEARL, new ImpreciseFraction("0.041"));
INITIAL_ITEMS.put(Items.GHAST_TEAR, new Fraction("0.023")); INITIAL_ITEMS.put(Items.GHAST_TEAR, new ImpreciseFraction("0.023"));
INITIAL_ITEMS.put(Items.BLAZE_ROD, new Fraction("0.02")); INITIAL_ITEMS.put(Items.BLAZE_ROD, new ImpreciseFraction("0.02"));
INITIAL_ITEMS.put(Items.SLIME_BALL, new Fraction("0.0015")); INITIAL_ITEMS.put(Items.SLIME_BALL, new ImpreciseFraction("0.0015"));
INITIAL_ITEMS.put(Items.EGG, new Fraction("0.0011")); INITIAL_ITEMS.put(Items.EGG, new ImpreciseFraction("0.0011"));
INITIAL_ITEMS.put(Items.PORKCHOP, new Fraction("0.0047")); INITIAL_ITEMS.put(Items.PORKCHOP, new ImpreciseFraction("0.0047"));
INITIAL_ITEMS.put(Items.BEEF, new Fraction("0.0047")); INITIAL_ITEMS.put(Items.BEEF, new ImpreciseFraction("0.0047"));
INITIAL_ITEMS.put(Items.MUTTON, new Fraction("0.004")); INITIAL_ITEMS.put(Items.MUTTON, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.PUFFERFISH, new Fraction("0.013")); INITIAL_ITEMS.put(Items.PUFFERFISH, new ImpreciseFraction("0.013"));
INITIAL_ITEMS.put(Items.COD, new Fraction("0.013")); INITIAL_ITEMS.put(Items.COD, new ImpreciseFraction("0.013"));
INITIAL_ITEMS.put(Items.SALMON, new Fraction("0.013")); INITIAL_ITEMS.put(Items.SALMON, new ImpreciseFraction("0.013"));
INITIAL_ITEMS.put(Items.TROPICAL_FISH, new Fraction("0.013")); INITIAL_ITEMS.put(Items.TROPICAL_FISH, new ImpreciseFraction("0.013"));
// building items // building items
INITIAL_ITEMS.put(Items.CLAY_BALL, new Fraction("0.0006")); INITIAL_ITEMS.put(Items.CLAY_BALL, new ImpreciseFraction("0.0006"));
INITIAL_ITEMS.put(Items.SNOWBALL, new Fraction("0.00041")); INITIAL_ITEMS.put(Items.SNOWBALL, new ImpreciseFraction("0.00041"));
// loot // loot
INITIAL_ITEMS.put(Items.TOTEM_OF_UNDYING, new Fraction("1.47")); INITIAL_ITEMS.put(Items.TOTEM_OF_UNDYING, new ImpreciseFraction("1.47"));
INITIAL_ITEMS.put(Items.TRIDENT, new Fraction("1.35")); INITIAL_ITEMS.put(Items.TRIDENT, new ImpreciseFraction("1.35"));
/* /*
INITIAL_ITEMS.put(Items.WHITE_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.WHITE_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.ORANGE_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.ORANGE_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.MAGENTA_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.MAGENTA_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.LIGHT_BLUE_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.LIGHT_BLUE_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.YELLOW_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.YELLOW_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.LIME_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.LIME_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.PINK_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.PINK_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.GRAY_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.GRAY_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.LIGHT_GRAY_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.LIGHT_GRAY_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.CYAN_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.CYAN_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.PURPLE_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.PURPLE_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.BLUE_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.BLUE_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.BROWN_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.BROWN_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.GREEN_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.GREEN_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.RED_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.RED_WOOL, new ImpreciseFraction("0.004"));
INITIAL_ITEMS.put(Items.BLACK_WOOL, new Fraction("0.004")); INITIAL_ITEMS.put(Items.BLACK_WOOL, new ImpreciseFraction("0.004"));
*/ */
// INITIAL_ITEMS.put(Items.CRIMSON_LOG, new Fraction("0.005")); // INITIAL_ITEMS.put(Items.CRIMSON_LOG, new ImpreciseFraction("0.005"));
// INITIAL_ITEMS.put(Items.WARPED_LOG, new Fraction("0.005")); // INITIAL_ITEMS.put(Items.WARPED_LOG, new ImpreciseFraction("0.005"));
} }
private static void registerPostItem(Item item, Item base, Fraction multiplier) { private static void registerPostItem(Item item, Item base, ImpreciseFraction multiplier) {
Fraction value = getMatterValue(base); ImpreciseFraction value = getMatterValue(base);
if (!value.equals(Fraction.ZERO)) { if (!value.equals(Fraction.ZERO)) {
ITEMS.put(item, value.times(multiplier)); ITEMS.put(item, value.times(multiplier));
@ -323,12 +324,10 @@ public class MatterRegistry {
} }
public static void registerPostItems() { public static void registerPostItems() {
registerPostItem(Items.CHIPPED_ANVIL, Items.ANVIL, new Fraction("0.8")); registerPostItem(Items.CHIPPED_ANVIL, Items.ANVIL, new ImpreciseFraction("0.8"));
registerPostItem(Items.DAMAGED_ANVIL, Items.ANVIL, new Fraction("0.5")); registerPostItem(Items.DAMAGED_ANVIL, Items.ANVIL, new ImpreciseFraction("0.5"));
} }
public static final MathContext ROUND_RULES = MatteryCapability.ROUND_RULES;
private static final HashMap<Item, ArrayList<Recipe<?>>> usages = new HashMap<>(); private static final HashMap<Item, ArrayList<Recipe<?>>> usages = new HashMap<>();
private static final HashMap<Item, ArrayList<Recipe<?>>> results = new HashMap<>(); private static final HashMap<Item, ArrayList<Recipe<?>>> results = new HashMap<>();
private static final HashMap<Item, Integer> seen_items = new HashMap<>(); private static final HashMap<Item, Integer> seen_items = new HashMap<>();
@ -341,8 +340,8 @@ public class MatterRegistry {
private static final Item[] scan_stack = new Item[1000]; private static final Item[] scan_stack = new Item[1000];
@Nullable @Nullable
private static Fraction determineValue(Item item) { private static ImpreciseFraction determineValue(Item item) {
Fraction _get = ITEMS.get(item); ImpreciseFraction _get = ITEMS.get(item);
if (_get != null) { if (_get != null) {
return _get; return _get;
@ -379,13 +378,13 @@ public class MatterRegistry {
} }
} }
return Fraction.ZERO; return ImpreciseFraction.ZERO;
} }
seen_items.put(item, 0); seen_items.put(item, 0);
if (!results.containsKey(item)) { if (!results.containsKey(item)) {
return Fraction.ZERO; return ImpreciseFraction.ZERO;
} }
scan_stack[stack_index] = item; scan_stack[stack_index] = item;
@ -393,32 +392,32 @@ public class MatterRegistry {
boolean defer_occured = false; boolean defer_occured = false;
Fraction smallest_possible_total = null; ImpreciseFraction smallest_possible_total = null;
for (Recipe<?> recipe : results.get(item)) { for (Recipe<?> recipe : results.get(item)) {
ItemStack self = recipe.getResultItem(); ItemStack self = recipe.getResultItem();
Fraction recipe_summ = Fraction.ZERO; ImpreciseFraction recipe_summ = ImpreciseFraction.ZERO;
boolean this_defered = false; boolean this_defered = false;
for (Ingredient ingredient : recipe.getIngredients()) { for (Ingredient ingredient : recipe.getIngredients()) {
ItemStack[] items = ingredient.getItems(); ItemStack[] items = ingredient.getItems();
Fraction smallest_possible = null; ImpreciseFraction smallest_possible = null;
for (ItemStack stack : items) { for (ItemStack stack : items) {
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
Fraction determine = determineValue(stack.getItem()); ImpreciseFraction determine = determineValue(stack.getItem());
// if we hit an recursive recipe, defer it // if we hit an recursive recipe, defer it
if (determine != null) { if (determine != null) {
if (determine.compareTo(Fraction.ZERO) == 0) { if (determine.isZero()) {
// farewell // farewell
OverdriveThatMatters.LOGGER.debug("Cannot determine matter value for {} because value of {} is unknown", item, stack.getItem()); OverdriveThatMatters.LOGGER.debug("Cannot determine matter value for {} because value of {} is unknown", item, stack.getItem());
seen_items_child.put(item, stack.getItem()); seen_items_child.put(item, stack.getItem());
scan_stack[stack_index] = null; scan_stack[stack_index] = null;
stack_index--; stack_index--;
return Fraction.ZERO; return ImpreciseFraction.ZERO;
} }
if (smallest_possible == null || smallest_possible.compareTo(determine) > 0) if (smallest_possible == null || smallest_possible.compareTo(determine) > 0)
@ -444,7 +443,7 @@ public class MatterRegistry {
if (this_defered) if (this_defered)
continue; continue;
recipe_summ = recipe_summ.div(new Fraction(self.getCount())); recipe_summ = recipe_summ.div(self.getCount());
if (smallest_possible_total == null || smallest_possible_total.compareTo(recipe_summ) > 0) if (smallest_possible_total == null || smallest_possible_total.compareTo(recipe_summ) > 0)
smallest_possible_total = recipe_summ; smallest_possible_total = recipe_summ;
@ -469,7 +468,7 @@ public class MatterRegistry {
scan_stack[stack_index] = null; scan_stack[stack_index] = null;
stack_index--; stack_index--;
return Fraction.ZERO; return ImpreciseFraction.ZERO;
} }
private static void flood(List<? extends Recipe<?>> recipe_type) { private static void flood(List<? extends Recipe<?>> recipe_type) {
@ -564,9 +563,9 @@ public class MatterRegistry {
@SubscribeEvent @SubscribeEvent
public static void attachItemStackTextEvent(ItemTooltipEvent event) { public static void attachItemStackTextEvent(ItemTooltipEvent event) {
if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 340) || InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 344)) { if (InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 340) || InputConstants.isKeyDown(Minecraft.getInstance().getWindow().getWindow(), 344)) {
Fraction matter_value = getMatterValue(event.getItemStack()); ImpreciseFraction matter_value = getMatterValue(event.getItemStack());
if (!matter_value.equals(Fraction.ZERO)) { if (!matter_value.isZero()) {
event.getToolTip().add(FormattingHelper.formatMatterValue(matter_value).withStyle(ChatFormatting.AQUA)); event.getToolTip().add(FormattingHelper.formatMatterValue(matter_value).withStyle(ChatFormatting.AQUA));
} }
} }

View File

@ -7,6 +7,7 @@ import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.chat.TranslatableComponent;
import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -122,6 +123,17 @@ public class FormattingHelper {
Fraction.fromString("1000000000000000000000000"), // "otm.suffix.yotta": "Y%s", Fraction.fromString("1000000000000000000000000"), // "otm.suffix.yotta": "Y%s",
}; };
public static final ImpreciseFraction[] SUFFIX_ABOVE_ONE_IM_FRAC = new ImpreciseFraction[] {
new ImpreciseFraction("1000"), // "otm.suffix.kilo": "k%s",
new ImpreciseFraction("1000000"), // "otm.suffix.mega": "M%s",
new ImpreciseFraction("1000000000"), // "otm.suffix.giga": "G%s",
new ImpreciseFraction("1000000000000"), // "otm.suffix.tera": "T%s",
new ImpreciseFraction("1000000000000000"), // "otm.suffix.peta": "P%s",
new ImpreciseFraction("1000000000000000000"), // "otm.suffix.exa": "E%s",
new ImpreciseFraction("1000000000000000000000"), // "otm.suffix.zetta": "Z%s",
new ImpreciseFraction("1000000000000000000000000"), // "otm.suffix.yotta": "Y%s",
};
public static final String[] SUFFIX_COMPONENTS_BELOW_ONE = new String[] { public static final String[] SUFFIX_COMPONENTS_BELOW_ONE = new String[] {
"otm.suffix.deci", "otm.suffix.deci",
"otm.suffix.centi", "otm.suffix.centi",
@ -161,6 +173,19 @@ public class FormattingHelper {
Fraction.fromString("0.000000000000000000000001"), // "otm.suffix.yocto": "y%s", Fraction.fromString("0.000000000000000000000001"), // "otm.suffix.yocto": "y%s",
}; };
public static final ImpreciseFraction[] SUFFIX_BELOW_ONE_IM_FRAC = new ImpreciseFraction[] {
new ImpreciseFraction("0.1"), // "otm.suffix.milli": "d%s",
new ImpreciseFraction("0.01"), // "otm.suffix.milli": "c%s",
new ImpreciseFraction("0.001"), // "otm.suffix.milli": "m%s",
new ImpreciseFraction("0.000001"), // "otm.suffix.micro": "μ%s",
new ImpreciseFraction("0.000000001"), // "otm.suffix.nano": "n%s",
new ImpreciseFraction("0.000000000001"), // "otm.suffix.pico": "p%s",
new ImpreciseFraction("0.000000000000001"), // "otm.suffix.femto": "f%s",
new ImpreciseFraction("0.000000000000000001"), // "otm.suffix.atto": "a%s",
new ImpreciseFraction("0.000000000000000000001"), // "otm.suffix.zepto": "z%s",
new ImpreciseFraction("0.000000000000000000000001"), // "otm.suffix.yocto": "y%s",
};
public static String formatDecimal(BigDecimal value, int decimals) { public static String formatDecimal(BigDecimal value, int decimals) {
return value.setScale(decimals, RoundingMode.HALF_UP).toString(); return value.setScale(decimals, RoundingMode.HALF_UP).toString();
} }
@ -176,6 +201,10 @@ public class FormattingHelper {
return new TranslatableComponent("otm.gui.level", formatSI(power, POWER_NAME), formatSI(max_power, POWER_NAME)); return new TranslatableComponent("otm.gui.level", formatSI(power, POWER_NAME), formatSI(max_power, POWER_NAME));
} }
public static Component formatPowerLevel(ImpreciseFraction power, ImpreciseFraction max_power) {
return new TranslatableComponent("otm.gui.level", formatSI(power, POWER_NAME), formatSI(max_power, POWER_NAME));
}
public static Component formatMatterLevel(BigDecimal power, BigDecimal max_power) { public static Component formatMatterLevel(BigDecimal power, BigDecimal max_power) {
return new TranslatableComponent("otm.gui.level", formatMatterValuePlain(power), formatMatterValuePlain(max_power)); return new TranslatableComponent("otm.gui.level", formatMatterValuePlain(power), formatMatterValuePlain(max_power));
} }
@ -184,6 +213,10 @@ public class FormattingHelper {
return new TranslatableComponent("otm.gui.level", formatMatterValuePlain(power), formatMatterValuePlain(max_power)); return new TranslatableComponent("otm.gui.level", formatMatterValuePlain(power), formatMatterValuePlain(max_power));
} }
public static Component formatMatterLevel(ImpreciseFraction power, ImpreciseFraction max_power) {
return new TranslatableComponent("otm.gui.level", formatMatterValuePlain(power), formatMatterValuePlain(max_power));
}
public static TranslatableComponent formatMatterValue(BigDecimal matter) { public static TranslatableComponent formatMatterValue(BigDecimal matter) {
return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME)); return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME));
} }
@ -192,6 +225,10 @@ public class FormattingHelper {
return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME)); return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME));
} }
public static TranslatableComponent formatMatterValue(ImpreciseFraction matter) {
return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME));
}
public static Component formatMatterValuePlain(BigDecimal matter) { public static Component formatMatterValuePlain(BigDecimal matter) {
return formatSI(matter, MATTER_NAME); return formatSI(matter, MATTER_NAME);
} }
@ -200,6 +237,10 @@ public class FormattingHelper {
return formatSI(matter, MATTER_NAME); return formatSI(matter, MATTER_NAME);
} }
public static Component formatMatterValuePlain(ImpreciseFraction matter) {
return formatSI(matter, MATTER_NAME);
}
public static Component formatPower(BigDecimal power) { public static Component formatPower(BigDecimal power) {
return formatSI(power, POWER_NAME); return formatSI(power, POWER_NAME);
} }
@ -208,6 +249,10 @@ public class FormattingHelper {
return formatSI(power, POWER_NAME); return formatSI(power, POWER_NAME);
} }
public static Component formatPower(ImpreciseFraction power) {
return formatSI(power, POWER_NAME);
}
public static Component formatSI(BigDecimal value) { public static Component formatSI(BigDecimal value) {
return formatSI(value, ""); return formatSI(value, "");
} }
@ -303,4 +348,48 @@ public class FormattingHelper {
return new TranslatableComponent("otm.suffix.merge", value.decimalString(2, true), end_suffix); return new TranslatableComponent("otm.suffix.merge", value.decimalString(2, true), end_suffix);
} }
} }
public static Component formatSI(ImpreciseFraction value, Object end_suffix) {
if (value.compareTo(ImpreciseFraction.ZERO) == 0) {
if ("".equals(end_suffix)) {
return new TextComponent("0.00");
} else {
return new TranslatableComponent("otm.suffix.merge", "0.00", end_suffix);
}
}
int compare = value.compareTo(ImpreciseFraction.ONE);
if (compare == 0) {
if ("".equals(end_suffix)) {
return new TextComponent("1.00");
} else {
return new TranslatableComponent("otm.suffix.merge", "1.00", end_suffix);
}
} else if (compare > 0) {
for (int i = SUFFIX_ABOVE_ONE_IM_FRAC.length - 1; i >= 0; i--) {
if (value.compareTo(SUFFIX_ABOVE_ONE_IM_FRAC[i]) >= 0) {
return new TranslatableComponent(SUFFIX_COMPONENTS_ABOVE_ONE[i], value.div(SUFFIX_ABOVE_ONE_IM_FRAC[i]).toString(2), end_suffix);
}
}
if ("".equals(end_suffix)) {
return new TextComponent(value.toString(2));
} else {
return new TranslatableComponent("otm.suffix.merge", value.toString(2), end_suffix);
}
}
for (int i = SUFFIX_BELOW_ONE_IM_FRAC.length - 1; i >= 0; i--) {
if (value.compareTo(SUFFIX_BELOW_ONE_IM_FRAC[i]) < 0) {
return new TranslatableComponent(SUFFIX_COMPONENTS_BELOW_ONE[i], value.div(SUFFIX_BELOW_ONE_IM_FRAC[i]).toString(2), end_suffix);
}
}
if ("".equals(end_suffix)) {
return new TextComponent(value.toString(2));
} else {
return new TranslatableComponent("otm.suffix.merge", value.toString(2), end_suffix);
}
}
} }

View File

@ -8,6 +8,7 @@ import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.registries.ForgeRegistry; import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.RegistryManager; import net.minecraftforge.registries.RegistryManager;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.matter.MatterRegistry;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -15,7 +16,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Supplier; import java.util.function.Supplier;
public record MatterRegistryPacket(Map<Item, Fraction> list) { public record MatterRegistryPacket(Map<Item, ImpreciseFraction> list) {
public void write(FriendlyByteBuf buffer) { public void write(FriendlyByteBuf buffer) {
buffer.writeInt(list.size()); buffer.writeInt(list.size());
var registry = (ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class); var registry = (ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class);
@ -30,10 +31,10 @@ public record MatterRegistryPacket(Map<Item, Fraction> list) {
var size = buffer.readInt(); var size = buffer.readInt();
var registry = (ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class); var registry = (ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class);
var map = new HashMap<Item, Fraction>(); var map = new HashMap<Item, ImpreciseFraction>();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
map.put(registry.getValue(buffer.readInt()), Fraction.read(buffer)); map.put(registry.getValue(buffer.readInt()), ImpreciseFraction.read(buffer));
} }
return new MatterRegistryPacket(map); return new MatterRegistryPacket(map);

View File

@ -7,12 +7,13 @@ import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.NetworkEvent;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import ru.dbotthepony.mc.otm.network.NetworkHelper; import ru.dbotthepony.mc.otm.network.NetworkHelper;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.function.Supplier; import java.util.function.Supplier;
public record AndroidEnergyPacket(boolean is_maximal, Fraction energy) { public record AndroidEnergyPacket(boolean is_maximal, ImpreciseFraction energy) {
public void write(FriendlyByteBuf buffer) { public void write(FriendlyByteBuf buffer) {
buffer.writeBoolean(is_maximal); buffer.writeBoolean(is_maximal);
energy.write(buffer); energy.write(buffer);
@ -40,6 +41,6 @@ public record AndroidEnergyPacket(boolean is_maximal, Fraction energy) {
} }
public static AndroidEnergyPacket read(FriendlyByteBuf buffer) { public static AndroidEnergyPacket read(FriendlyByteBuf buffer) {
return new AndroidEnergyPacket(buffer.readBoolean(), Fraction.read(buffer)); return new AndroidEnergyPacket(buffer.readBoolean(), ImpreciseFraction.read(buffer));
} }
} }

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.storage;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -14,7 +15,7 @@ import java.util.Objects;
public class StorageObjectRegistry { public class StorageObjectRegistry {
private static final HashMap<Class<? extends IStorageStack>, StorageObjectTuple<? extends IStorageStack>> REGISTRY = new HashMap<>(); private static final HashMap<Class<? extends IStorageStack>, StorageObjectTuple<? extends IStorageStack>> REGISTRY = new HashMap<>();
public static <T extends IStorageStack> StorageObjectTuple<T> register(Class<T> identity, T empty, Fraction energyPerOperation) { public static <T extends IStorageStack> StorageObjectTuple<T> register(Class<T> identity, T empty, ImpreciseFraction energyPerOperation) {
final var tuple = new StorageObjectTuple<>(identity, empty, energyPerOperation); final var tuple = new StorageObjectTuple<>(identity, empty, energyPerOperation);
REGISTRY.put(identity, tuple); REGISTRY.put(identity, tuple);
return tuple; return tuple;

View File

@ -1,10 +1,11 @@
package ru.dbotthepony.mc.otm.storage; package ru.dbotthepony.mc.otm.storage;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public record StorageObjectTuple<T extends IStorageStack>(@Nonnull Class<T> identity, @Nonnull T empty, @Nonnull Fraction energyPerOperation) { public record StorageObjectTuple<T extends IStorageStack>(@Nonnull Class<T> identity, @Nonnull T empty, @Nonnull ImpreciseFraction energyPerOperation) {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj instanceof StorageObjectTuple tuple) if (obj instanceof StorageObjectTuple tuple)

View File

@ -14,6 +14,7 @@ import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
class BlockEntityAndroidStation(p_155229_: BlockPos, p_155230_: BlockState) : class BlockEntityAndroidStation(p_155229_: BlockPos, p_155230_: BlockState) :
@ -31,9 +32,9 @@ class BlockEntityAndroidStation(p_155229_: BlockPos, p_155230_: BlockState) :
energy = MatteryMachineEnergyStorage( energy = MatteryMachineEnergyStorage(
this, this,
MatteryMachineEnergyStorage.MachineType.WORKER, MatteryMachineEnergyStorage.MachineType.WORKER,
Fraction(100000), ImpreciseFraction(100000),
Fraction(250), ImpreciseFraction(250),
Fraction(250) ImpreciseFraction(250)
) )
} }
@ -53,10 +54,10 @@ class BlockEntityAndroidStation(p_155229_: BlockPos, p_155230_: BlockState) :
val missing = it.missingPower val missing = it.missingPower
if (missing > Fraction.ZERO) { if (missing > ImpreciseFraction.ZERO) {
val extract = energy.extractEnergyInner(missing, true) val extract = energy.extractEnergyInner(missing, true)
if (extract > Fraction.ZERO) { if (extract > ImpreciseFraction.ZERO) {
val received = it.receiveEnergyOuter(extract, false) val received = it.receiveEnergyOuter(extract, false)
energy.extractEnergyInner(received, false) energy.extractEnergyInner(received, false)
} }

View File

@ -28,6 +28,7 @@ import ru.dbotthepony.mc.otm.capability.extractEnergy
import ru.dbotthepony.mc.otm.capability.receiveEnergy import ru.dbotthepony.mc.otm.capability.receiveEnergy
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.MenuBatteryBank import ru.dbotthepony.mc.otm.menu.MenuBatteryBank
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
import ru.dbotthepony.mc.otm.unaryMinus import ru.dbotthepony.mc.otm.unaryMinus
@ -61,16 +62,16 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block
{ slot: Int, amount: Int, stack: ItemStack? -> true } { slot: Int, amount: Int, stack: ItemStack? -> true }
) )
private data class BatteryBankDistribution(val distribution: Array<Fraction>, val maxThroughput: Fraction) private data class BatteryBankDistribution(val distribution: Array<ImpreciseFraction>, val maxThroughput: ImpreciseFraction)
private enum class BankMode { RECEIVE, EXTRACT, BIDIRECTIONAL } private enum class BankMode { RECEIVE, EXTRACT, BIDIRECTIONAL }
private inner class BatteryBankEnergy(private val mode: BankMode) : IMatteryEnergyStorage { private inner class BatteryBankEnergy(private val mode: BankMode) : IMatteryEnergyStorage {
override fun canExtract() = mode != BankMode.RECEIVE override fun canExtract() = mode != BankMode.RECEIVE
override fun canReceive() = mode != BankMode.EXTRACT override fun canReceive() = mode != BankMode.EXTRACT
override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (mode == BankMode.RECEIVE) if (mode == BankMode.RECEIVE)
return Fraction.ZERO return ImpreciseFraction.ZERO
return extractEnergyInner(howMuch, simulate) return extractEnergyInner(howMuch, simulate)
} }
@ -79,8 +80,8 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block
* [mode] = true на приём, false на отдачу * [mode] = true на приём, false на отдачу
*/ */
fun getDistribution(mode: Boolean): BatteryBankDistribution { fun getDistribution(mode: Boolean): BatteryBankDistribution {
val distribution = Array(container.containerSize) { Fraction.ZERO } val distribution = Array(container.containerSize) { ImpreciseFraction.ZERO }
var summ = Fraction.ZERO var summ = ImpreciseFraction.ZERO
for (i in 0 until container.containerSize) { for (i in 0 until container.containerSize) {
val stack = container.getItem(i) val stack = container.getItem(i)
@ -88,12 +89,12 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block
if (!stack.isEmpty) { if (!stack.isEmpty) {
stack.getCapability(CapabilityEnergy.ENERGY).ifPresent { stack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
if (it is IMatteryEnergyStorage) { if (it is IMatteryEnergyStorage) {
val diff: Fraction val diff: ImpreciseFraction
if (mode) { if (mode) {
diff = it.receiveEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true) diff = it.receiveEnergyOuter(ImpreciseFraction.LONG_MAX_VALUE, true)
} else { } else {
diff = it.extractEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true) diff = it.extractEnergyOuter(ImpreciseFraction.LONG_MAX_VALUE, true)
} }
distribution[i] = diff distribution[i] = diff
@ -102,19 +103,19 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block
val diff: Int val diff: Int
if (mode) { if (mode) {
diff = it.receiveEnergy(MatteryCapability.LONG_MAX_VALUE, true) diff = it.receiveEnergy(ImpreciseFraction.LONG_MAX_VALUE, true)
} else { } else {
diff = it.extractEnergy(MatteryCapability.LONG_MAX_VALUE, true) diff = it.extractEnergy(ImpreciseFraction.LONG_MAX_VALUE, true)
} }
distribution[i] = Fraction(diff) distribution[i] = ImpreciseFraction(diff)
summ += distribution[i] summ += distribution[i]
} }
} }
} }
} }
if (!summ.isZero()) { if (!summ.isZero) {
for (i in 0 until container.containerSize) { for (i in 0 until container.containerSize) {
distribution[i] = distribution[i] / summ distribution[i] = distribution[i] / summ
} }
@ -123,23 +124,23 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block
return BatteryBankDistribution(distribution, summ) return BatteryBankDistribution(distribution, summ)
} }
private fun distributeEnergy(mode: Boolean, howMuch: Fraction, simulate: Boolean): Fraction { private fun distributeEnergy(mode: Boolean, howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
val distribution = getDistribution(mode) val distribution = getDistribution(mode)
if (distribution.maxThroughput.isZero()) if (distribution.maxThroughput.isZero)
return Fraction.ZERO return ImpreciseFraction.ZERO
val distList: Array<Fraction> = distribution.distribution val distList = distribution.distribution
var summ = Fraction.ZERO var summ = ImpreciseFraction.ZERO
for (i in 0 until container.containerSize) { for (i in 0 until container.containerSize) {
if (!distList[i].isZero()) { if (!distList[i].isZero) {
val stack = container.getItem(i) val stack = container.getItem(i)
if (!stack.isEmpty) { if (!stack.isEmpty) {
stack.getCapability(CapabilityEnergy.ENERGY).ifPresent { stack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
if (it is IMatteryEnergyStorage) { if (it is IMatteryEnergyStorage) {
val diff: Fraction val diff: ImpreciseFraction
if (mode) { if (mode) {
diff = it.receiveEnergyOuter(howMuch * distList[i], simulate) diff = it.receiveEnergyOuter(howMuch * distList[i], simulate)
@ -157,37 +158,37 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block
diff = it.extractEnergy(howMuch * distList[i], simulate) diff = it.extractEnergy(howMuch * distList[i], simulate)
} }
summ += Fraction(diff) summ += ImpreciseFraction(diff)
} }
} }
} }
} }
} }
if (!simulate && !summ.isZero()) { if (!simulate && !summ.isZero) {
setChangedLight() setChangedLight()
} }
return summ return summ
} }
override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return distributeEnergy(false, howMuch, simulate) return distributeEnergy(false, howMuch, simulate)
} }
override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (mode == BankMode.EXTRACT) if (mode == BankMode.EXTRACT)
return Fraction.ZERO return ImpreciseFraction.ZERO
return receiveEnergyInner(howMuch, simulate) return receiveEnergyInner(howMuch, simulate)
} }
override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return distributeEnergy(true, howMuch, simulate) return distributeEnergy(true, howMuch, simulate)
} }
override val batteryLevel: Fraction get() { override val batteryLevel: ImpreciseFraction get() {
var result = Fraction.ZERO var result = ImpreciseFraction.ZERO
for (i in 0 until container.containerSize) { for (i in 0 until container.containerSize) {
val stack = container.getItem(i) val stack = container.getItem(i)
@ -206,8 +207,8 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block
return result return result
} }
override val maxBatteryLevel: Fraction get() { override val maxBatteryLevel: ImpreciseFraction get() {
var result = Fraction.ZERO var result = ImpreciseFraction.ZERO
for (i in 0 until container.containerSize) { for (i in 0 until container.containerSize) {
val stack = container.getItem(i) val stack = container.getItem(i)
@ -329,13 +330,13 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block
outputCapability.ifPresent { outputCapability.ifPresent {
val (_, maxThroughput) = energy.getDistribution(false) val (_, maxThroughput) = energy.getDistribution(false)
if (maxThroughput.isZero()) if (maxThroughput.isZero)
return@ifPresent return@ifPresent
if (it is IMatteryEnergyStorage) { if (it is IMatteryEnergyStorage) {
val diff = it.receiveEnergyOuter(maxThroughput, false) val diff = it.receiveEnergyOuter(maxThroughput, false)
if (!diff.isZero()) { if (!diff.isZero) {
energy.extractEnergyInner(diff, false) energy.extractEnergyInner(diff, false)
} }
} else { } else {

View File

@ -29,6 +29,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.capability.receiveEnergy import ru.dbotthepony.mc.otm.capability.receiveEnergy
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.plus import ru.dbotthepony.mc.otm.core.plus
import ru.dbotthepony.mc.otm.menu.MenuChemicalGenerator import ru.dbotthepony.mc.otm.menu.MenuChemicalGenerator
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ -181,7 +182,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
val extracted = energy.extractEnergyInner(demand, true) val extracted = energy.extractEnergyInner(demand, true)
val received = it.receiveEnergyOuter(extracted, false) val received = it.receiveEnergyOuter(extracted, false)
if (!received.isZero()) { if (!received.isZero) {
energy.extractEnergyInner(received, false) energy.extractEnergyInner(received, false)
} }
} else { } else {
@ -218,7 +219,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
val residue = container[SLOT_INPUT].item.getContainerItem(container[SLOT_INPUT].copy().also { it.count = 1 }) val residue = container[SLOT_INPUT].item.getContainerItem(container[SLOT_INPUT].copy().also { it.count = 1 })
val canPutResidue = residue.isEmpty || container[SLOT_RESIDUE].isEmpty || ItemStack.isSameItemSameTags(container[SLOT_RESIDUE], residue) && container[SLOT_RESIDUE].count < container[2].maxStackSize val canPutResidue = residue.isEmpty || container[SLOT_RESIDUE].isEmpty || ItemStack.isSameItemSameTags(container[SLOT_RESIDUE], residue) && container[SLOT_RESIDUE].count < container[2].maxStackSize
if (canPutResidue && ticks >= 4 && (energy.batteryLevel < Fraction.ONE || GENERATION_SPEED * (ticks / 4) + energy.batteryLevel <= energy.maxBatteryLevel)) { if (canPutResidue && ticks >= 4 && (energy.batteryLevel < ImpreciseFraction.ONE || GENERATION_SPEED * (ticks / 4) + energy.batteryLevel <= energy.maxBatteryLevel)) {
workingTicksTotal = ticks / 4 workingTicksTotal = ticks / 4
workingTicks = ticks / 4 workingTicks = ticks / 4
container[SLOT_INPUT].shrink(1) container[SLOT_INPUT].shrink(1)
@ -238,13 +239,13 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
check = false check = false
} }
if (energy.batteryLevel.isZero()) return if (energy.batteryLevel.isZero) return
val item = container[SLOT_BATTERY] val item = container[SLOT_BATTERY]
if (!item.isEmpty) { if (!item.isEmpty) {
item.getCapability(CapabilityEnergy.ENERGY).ifPresent(this::workWithPower) item.getCapability(CapabilityEnergy.ENERGY).ifPresent(this::workWithPower)
if (energy.batteryLevel.isZero()) return if (energy.batteryLevel.isZero) return
} }
for (consumer in consumers) { for (consumer in consumers) {
@ -253,10 +254,10 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti
} }
companion object { companion object {
private val THROUGHPUT = Fraction(160) private val THROUGHPUT = ImpreciseFraction(160)
private const val THROUGHPUT_INT = 160 private const val THROUGHPUT_INT = 160
private val GENERATION_SPEED = Fraction(40) private val GENERATION_SPEED = ImpreciseFraction(40)
private val MAX_ENERGY = Fraction(24_000) private val MAX_ENERGY = ImpreciseFraction(24_000)
private val NAME = TranslatableComponent("block.overdrive_that_matters.chemical_generator") private val NAME = TranslatableComponent("block.overdrive_that_matters.chemical_generator")
const val SLOT_INPUT = 0 const val SLOT_INPUT = 0

View File

@ -20,6 +20,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction 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.ifHas
import ru.dbotthepony.mc.otm.menu.MenuDriveRack import ru.dbotthepony.mc.otm.menu.MenuDriveRack
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
@ -67,7 +68,7 @@ class BlockEntityDriveRack(p_155229_: BlockPos, p_155230_: BlockState) :
} }
init { init {
energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, Fraction(80000)) energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, ImpreciseFraction(80000))
} }
fun tick() { fun tick() {

View File

@ -19,6 +19,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction 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.menu.MenuDriveViewer
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
import javax.annotation.ParametersAreNonnullByDefault import javax.annotation.ParametersAreNonnullByDefault
@ -77,7 +78,7 @@ class BlockEntityDriveViewer(p_155229_: BlockPos, p_155230_: BlockState) : Block
} }
init { init {
energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, Fraction(30000)) energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, ImpreciseFraction(30000))
} }
override fun getDefaultDisplayName(): Component { override fun getDefaultDisplayName(): Component {

View File

@ -29,12 +29,13 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.capability.extractEnergy
import ru.dbotthepony.mc.otm.capability.receiveEnergy import ru.dbotthepony.mc.otm.capability.receiveEnergy
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.MenuEnergyCounter import ru.dbotthepony.mc.otm.menu.MenuEnergyCounter
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.MatteryNetworking
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.function.Supplier import java.util.function.Supplier
data class EnergyCounterPacket(val pos: BlockPos, val thisTick: Fraction, val total: Fraction, val index: Int, val value: Fraction) { data class EnergyCounterPacket(val pos: BlockPos, val thisTick: ImpreciseFraction, val total: ImpreciseFraction, val index: Int, val value: ImpreciseFraction) {
fun write(buff: FriendlyByteBuf) { fun write(buff: FriendlyByteBuf) {
buff.writeBlockPos(pos) buff.writeBlockPos(pos)
thisTick.write(buff) thisTick.write(buff)
@ -60,35 +61,35 @@ data class EnergyCounterPacket(val pos: BlockPos, val thisTick: Fraction, val to
companion object { companion object {
fun read(buff: FriendlyByteBuf): EnergyCounterPacket { fun read(buff: FriendlyByteBuf): EnergyCounterPacket {
val pos = buff.readBlockPos() val pos = buff.readBlockPos()
val thisTick = Fraction.read(buff) val thisTick = ImpreciseFraction.read(buff)
val total = Fraction.read(buff) val total = ImpreciseFraction.read(buff)
val index = buff.readInt() val index = buff.readInt()
val value = Fraction.read(buff) val value = ImpreciseFraction.read(buff)
return EnergyCounterPacket(pos, thisTick, total, index, value) return EnergyCounterPacket(pos, thisTick, total, index, value)
} }
} }
} }
class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(Registry.BlockEntities.ENERGY_COUNTER, p_155229_, p_155230_) { class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(Registry.BlockEntities.ENERGY_COUNTER, p_155229_, p_155230_) {
var passed = Fraction.ZERO var passed = ImpreciseFraction.ZERO
internal set internal set
private val history = Array(10 * 20) { Fraction.ZERO } private val history = Array(10 * 20) { ImpreciseFraction.ZERO }
private var historyTick = 0 private var historyTick = 0
fun size() = history.size fun size() = history.size
operator fun get(i: Int) = history[i] operator fun get(i: Int) = history[i]
internal operator fun set(i: Int, value: Fraction) { internal operator fun set(i: Int, value: ImpreciseFraction) {
history[i] = value history[i] = value
} }
var lastTick: Fraction = Fraction.ZERO var lastTick = ImpreciseFraction.ZERO
internal set internal set
fun getHistory(ticks: Int): Array<Fraction> { fun getHistory(ticks: Int): Array<ImpreciseFraction> {
require(!(ticks < 1 || ticks >= history.size)) { "Invalid history length provided" } require(!(ticks < 1 || ticks >= history.size)) { "Invalid history length provided" }
val history = Array(ticks) { Fraction.ZERO } val history = Array(ticks) { ImpreciseFraction.ZERO }
for (i in 0 until ticks) { for (i in 0 until ticks) {
var index = (historyTick - i) % this.history.size var index = (historyTick - i) % this.history.size
@ -99,14 +100,14 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return history return history
} }
fun calcAverage(ticks: Int): Fraction { fun calcAverage(ticks: Int): ImpreciseFraction {
return sumHistory(ticks) / ticks return sumHistory(ticks) / ticks
} }
fun sumHistory(ticks: Int): Fraction { fun sumHistory(ticks: Int): ImpreciseFraction {
require(!(ticks < 1 || ticks >= history.size)) { "Invalid history length provided" } require(!(ticks < 1 || ticks >= history.size)) { "Invalid history length provided" }
var value = Fraction.ZERO var value = ImpreciseFraction.ZERO
for (i in 0 until ticks) { for (i in 0 until ticks) {
var index = (historyTick - i) % history.size var index = (historyTick - i) % history.size
@ -133,7 +134,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
super.load(nbt) super.load(nbt)
nbt.ifHas(("passed")) { nbt.ifHas(("passed")) {
passed = Fraction.deserializeNBT(it) passed = ImpreciseFraction.deserializeNBT(it)
} }
nbt.ifHas(("history_tick"), IntTag::class.java) { nbt.ifHas(("history_tick"), IntTag::class.java) {
@ -143,7 +144,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
nbt.ifHas("history", ListTag::class.java) { nbt.ifHas("history", ListTag::class.java) {
for (i in it.indices) { for (i in it.indices) {
val bytes = it[i] as? ByteArrayTag val bytes = it[i] as? ByteArrayTag
history[i] = if (bytes != null) Fraction.deserializeNBT(bytes) else Fraction.ZERO history[i] = if (bytes != null) ImpreciseFraction.deserializeNBT(bytes) else ImpreciseFraction.ZERO
} }
} }
} }
@ -172,23 +173,23 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
} }
private inner class EnergyCounterCap(val is_input: Boolean) : IMatteryEnergyStorage { private inner class EnergyCounterCap(val is_input: Boolean) : IMatteryEnergyStorage {
override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return extractEnergyInner(howMuch, simulate) return extractEnergyInner(howMuch, simulate)
} }
override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (is_input) if (is_input)
return Fraction.ZERO return ImpreciseFraction.ZERO
if (inputCapability.isPresent) { if (inputCapability.isPresent) {
val it = inputCapability.resolve().get() val it = inputCapability.resolve().get()
val diff: Fraction val diff: ImpreciseFraction
if (it is IMatteryEnergyStorage) { if (it is IMatteryEnergyStorage) {
diff = it.extractEnergyOuter(howMuch, simulate) diff = it.extractEnergyOuter(howMuch, simulate)
} else { } else {
diff = Fraction(it.extractEnergy(howMuch, simulate)) diff = ImpreciseFraction(it.extractEnergy(howMuch, simulate))
} }
if (!simulate) { if (!simulate) {
@ -199,26 +200,26 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return diff return diff
} }
return Fraction.ZERO return ImpreciseFraction.ZERO
} }
override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return receiveEnergyInner(howMuch, simulate) return receiveEnergyInner(howMuch, simulate)
} }
override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (!is_input) if (!is_input)
return Fraction.ZERO return ImpreciseFraction.ZERO
if (outputCapability.isPresent) { if (outputCapability.isPresent) {
val it = outputCapability.resolve().get() val it = outputCapability.resolve().get()
val diff: Fraction val diff: ImpreciseFraction
if (it is IMatteryEnergyStorage) { if (it is IMatteryEnergyStorage) {
diff = it.receiveEnergyOuter(howMuch, simulate) diff = it.receiveEnergyOuter(howMuch, simulate)
} else { } else {
diff = Fraction(it.receiveEnergy(howMuch, simulate)) diff = ImpreciseFraction(it.receiveEnergy(howMuch, simulate))
} }
if (!simulate) { if (!simulate) {
@ -229,10 +230,10 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return diff return diff
} }
return Fraction.ZERO return ImpreciseFraction.ZERO
} }
override val batteryLevel: Fraction override val batteryLevel: ImpreciseFraction
get() { get() {
if (is_input) { if (is_input) {
if (outputCapability.isPresent) { if (outputCapability.isPresent) {
@ -242,7 +243,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return it.batteryLevel return it.batteryLevel
} }
return Fraction(it.energyStored) return ImpreciseFraction(it.energyStored)
} }
} else { } else {
if (inputCapability.isPresent) { if (inputCapability.isPresent) {
@ -252,14 +253,14 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return it.batteryLevel return it.batteryLevel
} }
return Fraction(it.energyStored) return ImpreciseFraction(it.energyStored)
} }
} }
return Fraction.ZERO return ImpreciseFraction.ZERO
} }
override val maxBatteryLevel: Fraction override val maxBatteryLevel: ImpreciseFraction
get() { get() {
if (is_input) { if (is_input) {
if (outputCapability.isPresent) { if (outputCapability.isPresent) {
@ -269,7 +270,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return it.maxBatteryLevel return it.maxBatteryLevel
} }
return Fraction(it.maxEnergyStored) return ImpreciseFraction(it.maxEnergyStored)
} }
} else { } else {
if (inputCapability.isPresent) { if (inputCapability.isPresent) {
@ -279,14 +280,14 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return it.maxBatteryLevel return it.maxBatteryLevel
} }
return Fraction(it.maxEnergyStored) return ImpreciseFraction(it.maxEnergyStored)
} }
} }
return Fraction.ZERO return ImpreciseFraction.ZERO
} }
override val missingPower: Fraction override val missingPower: ImpreciseFraction
get() { get() {
if (is_input) { if (is_input) {
if (outputCapability.isPresent) { if (outputCapability.isPresent) {
@ -296,7 +297,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return it.missingPower return it.missingPower
} }
return Fraction((it.maxEnergyStored - it.energyStored).coerceAtLeast(0)) return ImpreciseFraction((it.maxEnergyStored - it.energyStored).coerceAtLeast(0))
} }
} else { } else {
if (inputCapability.isPresent) { if (inputCapability.isPresent) {
@ -306,11 +307,11 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return it.missingPower return it.missingPower
} }
return Fraction((it.maxEnergyStored - it.energyStored).coerceAtLeast(0)) return ImpreciseFraction((it.maxEnergyStored - it.energyStored).coerceAtLeast(0))
} }
} }
return Fraction.ZERO return ImpreciseFraction.ZERO
} }
override fun canExtract() = !is_input override fun canExtract() = !is_input
@ -423,7 +424,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
val index = historyTick val index = historyTick
historyTick = (historyTick + 1) % history.size historyTick = (historyTick + 1) % history.size
val accumulated = history[historyTick] val accumulated = history[historyTick]
history[historyTick] = Fraction.ZERO history[historyTick] = ImpreciseFraction.ZERO
MatteryNetworking.CHANNEL.send(PacketDistributor.NEAR.with(this::distributor), EnergyCounterPacket(blockPos, lastTick, passed, index, accumulated)) MatteryNetworking.CHANNEL.send(PacketDistributor.NEAR.with(this::distributor), EnergyCounterPacket(blockPos, lastTick, passed, index, accumulated))
} }

View File

@ -17,6 +17,7 @@ import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.MenuItemMonitor import ru.dbotthepony.mc.otm.menu.MenuItemMonitor
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
@ -27,7 +28,7 @@ class BlockEntityItemMonitor(p_155229_: BlockPos, p_155230_: BlockState) :
val cell = BasicStorageGraphNode() val cell = BasicStorageGraphNode()
init { init {
energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, Fraction(80_000)) energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, ImpreciseFraction(80_000))
} }
fun tick() { fun tick() {

View File

@ -26,6 +26,7 @@ import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction 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.Graph6Node
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
@ -106,13 +107,13 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
@JvmField @JvmField
val matter: MatterHandlerCapability = val matter: MatterHandlerCapability =
object : MatterHandlerCapability(this::setChangedLight, MatterDirection.BIDIRECTIONAL, Fraction(4)) { object : MatterHandlerCapability(this::setChangedLight, MatterDirection.BIDIRECTIONAL, CAPACITY) {
override fun getDirection(): MatterDirection { override fun getDirection(): MatterDirection {
return if (this@BlockEntityMatterBottler.workFlow) MatterDirection.RECEIVE else MatterDirection.EXTRACT return if (this@BlockEntityMatterBottler.workFlow) MatterDirection.RECEIVE else MatterDirection.EXTRACT
} }
} }
private var initialCapacity: Fraction? = null private var initialCapacity: ImpreciseFraction? = null
private var lastWorkStack: ItemStack? = null private var lastWorkStack: ItemStack? = null
override fun getMatterHandler(): IMatterHandler { override fun getMatterHandler(): IMatterHandler {
@ -200,18 +201,18 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
val cap = resolver.get() val cap = resolver.get()
if (this.workFlow) { if (this.workFlow) {
if (cap.maxStoredMatter - initialCapacity!! <= Fraction.ZERO) { if (cap.maxStoredMatter - initialCapacity!! <= ImpreciseFraction.ZERO) {
return 0f return 0f
} }
return ((cap.storedMatter - initialCapacity!!) / (cap.maxStoredMatter - initialCapacity!!)).toFloat() return ((cap.storedMatter - initialCapacity!!) / (cap.maxStoredMatter - initialCapacity!!)).toFloat()
} }
if (initialCapacity!! <= Fraction.ZERO) { if (initialCapacity!! <= ImpreciseFraction.ZERO) {
return 0f return 0f
} }
return (Fraction.ONE - cap.storedMatter / initialCapacity!!).toFloat() return (ImpreciseFraction.ONE - cap.storedMatter / initialCapacity!!).toFloat()
} }
override fun setRemoved() { override fun setRemoved() {
@ -224,7 +225,7 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
if (isBlockedByRedstone) { if (isBlockedByRedstone) {
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.IDLE) { if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.IDLE) {
level!!.setBlock( level?.setBlock(
blockPos, blockPos,
blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE),
Block.UPDATE_CLIENTS Block.UPDATE_CLIENTS
@ -247,7 +248,7 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
val cap = itemStack.getCapability(MatteryCapability.MATTER).resolve() val cap = itemStack.getCapability(MatteryCapability.MATTER).resolve()
if (cap.isPresent && cap.get().direction !== unexpectedDirection) { if (cap.isPresent && cap.get().direction !== unexpectedDirection) {
if (this.workFlow && cap.get().missingMatter > Fraction.ZERO || !this.workFlow && cap.get().storedMatter > Fraction.ZERO) { if (this.workFlow && cap.get().missingMatter > ImpreciseFraction.ZERO || !this.workFlow && cap.get().storedMatter > ImpreciseFraction.ZERO) {
work_stack = itemStack work_stack = itemStack
capability = cap.get() capability = cap.get()
work_slot = i work_slot = i
@ -269,7 +270,7 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
if (capability != null) { if (capability != null) {
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.WORKING) { if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.WORKING) {
level!!.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS)
} }
if (workFlow) { if (workFlow) {
@ -278,25 +279,25 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
matter.missingMatter.min(MATTER_EXCHANGE_RATE * EXTRACTION_TICKS, capability.missingMatter - matter.storedMatter), true matter.missingMatter.min(MATTER_EXCHANGE_RATE * EXTRACTION_TICKS, capability.missingMatter - matter.storedMatter), true
) )
if (extracted > Fraction.ZERO) { if (extracted > ImpreciseFraction.ZERO) {
val received = matter.receiveMatterOuter(extracted, false) val received = matter.receiveMatterOuter(extracted, false)
graph.extractMatter(received, false) graph.extractMatter(received, false)
} }
} }
if (matter.storedMatter > Fraction.ZERO) { if (matter.storedMatter > ImpreciseFraction.ZERO) {
val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true) val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true)
if (!energyExtracted.isZero()) { if (!energyExtracted.isZero) {
val matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(matter.storedMatter) * (energyExtracted / ENERGY_CONSUMPTION), true) val matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(matter.storedMatter) * energyExtracted / ENERGY_CONSUMPTION, true)
if (!matter.isZero()) { if (!matter.isZero) {
energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE,false) energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE, false)
capability.receiveMatterOuter(matter, false) capability.receiveMatterOuter(matter, false)
this.matter.extractMatterInner(matter, false) this.matter.extractMatterInner(matter, false)
if (capability.missingMatter.isZero()) { if (capability.missingMatter.isZero) {
for (i in 3..5) { for (i in 3..5) {
if (container.getItem(i).isEmpty) { if (container.getItem(i).isEmpty) {
container.setItem(work_slot, ItemStack.EMPTY) container.setItem(work_slot, ItemStack.EMPTY)
@ -311,16 +312,16 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
} else { } else {
val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true) val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true)
if (!energyExtracted.isZero()) { if (!energyExtracted.isZero) {
val matter = capability.extractMatterOuter(MATTER_EXCHANGE_RATE.min(matter.missingMatter) * energyExtracted / ENERGY_CONSUMPTION, true) val matter = capability.extractMatterOuter(MATTER_EXCHANGE_RATE.min(matter.missingMatter) * energyExtracted / ENERGY_CONSUMPTION, true)
if (!matter.isZero()) { if (!matter.isZero) {
this.energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE,false) this.energy.extractEnergyInner(ENERGY_CONSUMPTION * (matter / MATTER_EXCHANGE_RATE).toDouble(),false)
capability.extractMatterOuter(matter, false) capability.extractMatterOuter(matter, false)
this.matter.receiveMatterInner(matter, false) this.matter.receiveMatterInner(matter, false)
if (capability.storedMatter.isZero()) { if (capability.storedMatter.isZero) {
for (i in 2 downTo 0) { for (i in 2 downTo 0) {
if (container.getItem(i).isEmpty) { if (container.getItem(i).isEmpty) {
container.setItem(work_slot, ItemStack.EMPTY) container.setItem(work_slot, ItemStack.EMPTY)
@ -336,7 +337,7 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
level!!.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS) level!!.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
} }
if (!workFlow && !matter.storedMatter.isZero() && graph != null) { if (!workFlow && !matter.storedMatter.isZero && graph != null) {
val diff = matter.extractMatterInner(matter.storedMatter, true) val diff = matter.extractMatterInner(matter.storedMatter, true)
val diff2 = graph.receiveMatter(diff, true) val diff2 = graph.receiveMatter(diff, true)
matter.extractMatterInner(diff2, false) matter.extractMatterInner(diff2, false)
@ -346,8 +347,9 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
companion object { companion object {
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_bottler") private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_bottler")
private val MATTER_EXCHANGE_RATE = Fraction("0.04") private val MATTER_EXCHANGE_RATE = ImpreciseFraction("0.04")
private val ENERGY_CONSUMPTION = Fraction(20) private val ENERGY_CONSUMPTION = ImpreciseFraction(20)
private val EXTRACTION_TICKS = Fraction(200) private val EXTRACTION_TICKS = ImpreciseFraction(200)
private val CAPACITY = ImpreciseFraction(4)
} }
} }

View File

@ -23,6 +23,7 @@ import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction 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.Graph6Node
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
@ -42,8 +43,8 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState)
return node return node
} }
override fun getStoredMatter(): Fraction { override fun getStoredMatter(): ImpreciseFraction {
var summ = Fraction.ZERO var summ = ImpreciseFraction.ZERO
for (stack in container) for (stack in container)
if (!stack.isEmpty) if (!stack.isEmpty)
@ -54,8 +55,8 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState)
return summ return summ
} }
override fun getMaxStoredMatter(): Fraction { override fun getMaxStoredMatter(): ImpreciseFraction {
var summ = Fraction.ZERO var summ = ImpreciseFraction.ZERO
for (stack in container) for (stack in container)
if (!stack.isEmpty) if (!stack.isEmpty)
@ -66,13 +67,13 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState)
return summ return summ
} }
override fun receiveMatterOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return receiveMatterInner(howMuch, simulate) return receiveMatterInner(howMuch, simulate)
} }
override fun receiveMatterInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
var howMuch = howMuch var howMuch = howMuch
var summ = Fraction.ZERO var summ = ImpreciseFraction.ZERO
for (stack in container) { for (stack in container) {
if (!stack.isEmpty) { if (!stack.isEmpty) {
@ -82,7 +83,7 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState)
howMuch -= diff howMuch -= diff
} }
if (howMuch.isZero()) { if (howMuch.isZero) {
break break
} }
} }
@ -91,13 +92,13 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState)
return summ return summ
} }
override fun extractMatterOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return extractMatterInner(howMuch, simulate) return extractMatterInner(howMuch, simulate)
} }
override fun extractMatterInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
var howMuch = howMuch var howMuch = howMuch
var summ = Fraction.ZERO var summ = ImpreciseFraction.ZERO
for (stack in container) { for (stack in container) {
if (!stack.isEmpty) { if (!stack.isEmpty) {
@ -107,7 +108,7 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState)
howMuch -= diff howMuch -= diff
} }
if (howMuch.isZero()) { if (howMuch.isZero) {
break break
} }
} }

View File

@ -26,6 +26,7 @@ import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction 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.Graph6Node
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
@ -37,18 +38,13 @@ import ru.dbotthepony.mc.otm.set
class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState) class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
: BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_DECOMPOSER, pos, state), IMatterGraphNode { : BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_DECOMPOSER, pos, state), IMatterGraphNode {
companion object {
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_decomposer")
private val BASE_CONSUMPTION = Fraction(240)
}
init { init {
energy = MatteryMachineEnergyStorage( energy = MatteryMachineEnergyStorage(
this, this,
MatteryMachineEnergyStorage.MachineType.WORKER, MatteryMachineEnergyStorage.MachineType.WORKER,
Fraction(400000), ImpreciseFraction(400000),
Fraction(2000), ImpreciseFraction(2000),
Fraction(2000) ImpreciseFraction(2000)
) )
} }
@ -60,7 +56,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
} }
@JvmField @JvmField
val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.EXTRACT, Fraction("20")) val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.EXTRACT, CAPACITY)
private var resolverMatter = LazyOptional.of { matter } private var resolverMatter = LazyOptional.of { matter }
private var resolverNode = LazyOptional.of { this } private var resolverNode = LazyOptional.of { this }
@ -136,7 +132,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
if (MatterRegistry.canDecompose(copy)) { if (MatterRegistry.canDecompose(copy)) {
val value = MatterRegistry.getMatterValue(copy) val value = MatterRegistry.getMatterValue(copy)
if (value != Fraction.ZERO && matter.canReceiveAll(value)) { if (!value.isZero && matter.canReceiveAll(value)) {
stack.shrink(1) stack.shrink(1)
return MachineJob(copy, value.toDouble() * 12500.0, BASE_CONSUMPTION) return MachineJob(copy, value.toDouble() * 12500.0, BASE_CONSUMPTION)
} }
@ -168,7 +164,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
val grid = node.graph as MatterNetworkGraph? val grid = node.graph as MatterNetworkGraph?
if (!matter.storedMatter.isZero() && grid != null) { if (!matter.storedMatter.isZero && grid != null) {
val diff = matter.extractMatterInner(matter.getStoredMatter(), true) val diff = matter.extractMatterInner(matter.getStoredMatter(), true)
val diff2 = grid.receiveMatter(diff, true) val diff2 = grid.receiveMatter(diff, true)
@ -176,4 +172,10 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
grid.receiveMatter(diff2, false) grid.receiveMatter(diff2, false)
} }
} }
companion object {
private val CAPACITY = ImpreciseFraction("20")
private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_decomposer")
private val BASE_CONSUMPTION = ImpreciseFraction(240)
}
} }

View File

@ -29,6 +29,7 @@ import ru.dbotthepony.mc.otm.capability.matter.MatterTask
import ru.dbotthepony.mc.otm.capability.matter.PatternState import ru.dbotthepony.mc.otm.capability.matter.PatternState
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction 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.Graph6Node
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
@ -51,7 +52,7 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
} }
@JvmField @JvmField
val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.RECEIVE, Fraction(2)) val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.RECEIVE, ImpreciseFraction(2))
// обычные запросы // обычные запросы
@JvmField @JvmField
@ -144,7 +145,7 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
val drain = graph.extractMatter(toExtract, true) val drain = graph.extractMatter(toExtract, true)
if (drain.isZero()) { if (drain.isZero) {
// в сети нет материи // в сети нет материи
return MachineJobStatus(false, 200) return MachineJobStatus(false, 200)
} }
@ -209,19 +210,19 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
energy = MatteryMachineEnergyStorage( energy = MatteryMachineEnergyStorage(
this, this,
MatteryMachineEnergyStorage.MachineType.WORKER, MatteryMachineEnergyStorage.MachineType.WORKER,
Fraction(200000), ImpreciseFraction(200000),
Fraction(4000), ImpreciseFraction(4000),
Fraction(4000) ImpreciseFraction(4000)
) )
} }
companion object { companion object {
private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_replicator") private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_replicator")
private val BASE_CONSUMPTION = Fraction(400) private val BASE_CONSUMPTION = ImpreciseFraction(400)
private const val TICKS_PER_MTU = 20000.0 private const val TICKS_PER_MTU = 20000.0
private val TICKS_PER_MTU_BD = Fraction(20000) private val TICKS_PER_MTU_BD = ImpreciseFraction(20000)
private const val MTU_PER_TICK = 1.0 / 20000.0 private const val MTU_PER_TICK = 1.0 / 20000.0
private val MTU_PER_TICK_BD = Fraction.ONE.div(TICKS_PER_MTU_BD) private val MTU_PER_TICK_BD = ImpreciseFraction.ONE.div(TICKS_PER_MTU_BD)
private val DRAIN_MULT = Fraction(200) private val DRAIN_MULT = ImpreciseFraction(200)
} }
} }

View File

@ -25,6 +25,7 @@ import ru.dbotthepony.mc.otm.capability.matter.PatternInsertStatus
import ru.dbotthepony.mc.otm.capability.matter.PatternState import ru.dbotthepony.mc.otm.capability.matter.PatternState
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction 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.Graph6Node
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
@ -184,9 +185,9 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
energy = MatteryMachineEnergyStorage( energy = MatteryMachineEnergyStorage(
this, this,
MatteryMachineEnergyStorage.MachineType.WORKER, MatteryMachineEnergyStorage.MachineType.WORKER,
Fraction(40000), ImpreciseFraction(40000),
Fraction(400), ImpreciseFraction(400),
Fraction(400) ImpreciseFraction(400)
) )
} }
@ -200,6 +201,6 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
companion object { companion object {
private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_scanner") private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_scanner")
private val BASE_CONSUMPTION = Fraction("40") private val BASE_CONSUMPTION = ImpreciseFraction("40")
} }
} }

View File

@ -14,6 +14,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.capability.extractEnergy
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.Fraction 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.ifHas
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
@ -25,7 +26,7 @@ abstract class BlockEntityMatteryPowered(p_155228_: BlockEntityType<*>, p_155229
protected fun batteryChargeLoop() { protected fun batteryChargeLoop() {
var demand = energy.receiveEnergyOuter(energy.missingPower, true) var demand = energy.receiveEnergyOuter(energy.missingPower, true)
if (demand.isZero()) return if (demand.isZero) return
for (stack in batteryContainer) { for (stack in batteryContainer) {
if (!stack.isEmpty) { if (!stack.isEmpty) {
@ -41,7 +42,7 @@ abstract class BlockEntityMatteryPowered(p_155228_: BlockEntityType<*>, p_155229
} }
} }
if (demand <= Fraction.ZERO) if (demand <= ImpreciseFraction.ZERO)
return return
} }
} }

View File

@ -16,6 +16,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
import ru.dbotthepony.mc.otm.core.Fraction 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.menu.MenuPlatePress
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
@ -81,7 +82,7 @@ class BlockEntityPlatePress(p_155229_: BlockPos, p_155230_: BlockState) : BlockE
} }
companion object { companion object {
private val BASELINE_CONSUMPTION = Fraction(15) private val BASELINE_CONSUMPTION = ImpreciseFraction(15)
private val NAME = TranslatableComponent("block.overdrive_that_matters.plate_press") private val NAME = TranslatableComponent("block.overdrive_that_matters.plate_press")
const val SLOT_INPUT = 0 const val SLOT_INPUT = 0
const val SLOT_OUTPUT = 1 const val SLOT_OUTPUT = 1

View File

@ -26,6 +26,7 @@ import ru.dbotthepony.mc.otm.block.BlockBlackHole
import ru.dbotthepony.mc.otm.block.entity.BlockEntityGravitationStabilizer import ru.dbotthepony.mc.otm.block.entity.BlockEntityGravitationStabilizer
import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue.Companion.queueForLevel import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue.Companion.queueForLevel
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.plus import ru.dbotthepony.mc.otm.core.plus
import ru.dbotthepony.mc.otm.matter.MatterRegistry import ru.dbotthepony.mc.otm.matter.MatterRegistry
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
@ -35,7 +36,7 @@ import kotlin.math.sqrt
class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(Registry.BlockEntities.BLACK_HOLE, p_155229_, p_155230_) { class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(Registry.BlockEntities.BLACK_HOLE, p_155229_, p_155230_) {
var mass = BASELINE_MASS var mass = BASELINE_MASS
set(mass) { set(mass) {
if (mass <= Fraction.ZERO) { if (mass <= ImpreciseFraction.ZERO) {
collapse() collapse()
return return
} }
@ -156,7 +157,7 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn
fun readBlackHoleData(tag: CompoundTag) { fun readBlackHoleData(tag: CompoundTag) {
tag["mass"]?.let { tag["mass"]?.let {
mass = Fraction.deserializeNBT(it) mass = ImpreciseFraction.deserializeNBT(it)
} }
spin_direction = tag.getBoolean("spin_direction") spin_direction = tag.getBoolean("spin_direction")
@ -280,7 +281,7 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn
} else { } else {
val mass = MatterRegistry.getMatterValue(item.item) val mass = MatterRegistry.getMatterValue(item.item)
if (mass > Fraction.ZERO) if (mass > ImpreciseFraction.ZERO)
this.mass += mass * item.item.count this.mass += mass * item.item.count
} }
} }
@ -351,8 +352,8 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn
companion object { companion object {
const val ITERATIONS = 30_000 const val ITERATIONS = 30_000
val BASELINE_MASS = Fraction(1_000) val BASELINE_MASS = ImpreciseFraction(1_000)
val HAWKING_MASS_LOSE_STEP = Fraction("-0.1") val HAWKING_MASS_LOSE_STEP = ImpreciseFraction("-0.1")
private val blockShapeCache = HashMap<Int, Array<BlockPos>>() private val blockShapeCache = HashMap<Int, Array<BlockPos>>()

View File

@ -8,6 +8,7 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.DoubleTag import net.minecraft.nbt.DoubleTag
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import ru.dbotthepony.mc.otm.core.Fraction 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.ifHas
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
@ -139,7 +140,7 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
return return
} }
if (!currentJob.power.isZero() && energy.batteryLevel.isZero()) { if (!currentJob.power.isZero && energy.batteryLevel.isZero) {
idleTicksAnim++ idleTicksAnim++
if (idleTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) { if (idleTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) {
@ -152,7 +153,7 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
idleTicksAnim = 0 idleTicksAnim = 0
if (workTicks < currentJob.ticks) { if (workTicks < currentJob.ticks) {
if (!currentJob.power.isZero()) { if (!currentJob.power.isZero) {
val extractedPower = energy.extractEnergyInner(currentJob.power, true) val extractedPower = energy.extractEnergyInner(currentJob.power, true)
val workSpeed = extractedPower.div(currentJob.power) val workSpeed = extractedPower.div(currentJob.power)
@ -191,7 +192,7 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
} }
} }
} else { } else {
val status = onWorkTick(WorkTickContext(currentJob, Fraction.ZERO, Fraction.ZERO, Fraction.ONE)) val status = onWorkTick(WorkTickContext(currentJob, ImpreciseFraction.ZERO, ImpreciseFraction.ZERO, ImpreciseFraction.ONE))
if (!status.valid) { if (!status.valid) {
throttleTicks += status.throttle() throttleTicks += status.throttle()

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.capability
import net.minecraftforge.energy.IEnergyStorage import net.minecraftforge.energy.IEnergyStorage
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
fun IEnergyStorage.receiveEnergy(amount: Fraction, simulate: Boolean): Int { fun IEnergyStorage.receiveEnergy(amount: Fraction, simulate: Boolean): Int {
if (amount.isZero()) if (amount.isZero())
@ -22,3 +23,23 @@ fun IEnergyStorage.extractEnergy(amount: Fraction, simulate: Boolean): Int {
return extractEnergy(amount.wholePart().toInt(), simulate) return extractEnergy(amount.wholePart().toInt(), simulate)
} }
fun IEnergyStorage.receiveEnergy(amount: ImpreciseFraction, simulate: Boolean): Int {
if (amount.isZero)
return 0
if (amount > ImpreciseFraction.INT_MAX_VALUE)
return receiveEnergy(Int.MAX_VALUE, simulate)
return receiveEnergy(amount.toInt(), simulate)
}
fun IEnergyStorage.extractEnergy(amount: ImpreciseFraction, simulate: Boolean): Int {
if (amount.isZero)
return 0
if (amount > ImpreciseFraction.INT_MAX_VALUE)
return extractEnergy(Int.MAX_VALUE, simulate)
return extractEnergy(amount.toInt(), simulate)
}

View File

@ -2,58 +2,59 @@ package ru.dbotthepony.mc.otm.capability
import net.minecraftforge.energy.IEnergyStorage import net.minecraftforge.energy.IEnergyStorage
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
// IEnergyStorage for direct compat with Forge Energy // IEnergyStorage for direct compat with Forge Energy
interface IMatteryEnergyStorage : IEnergyStorage { interface IMatteryEnergyStorage : IEnergyStorage {
// such as cables. This is something that would work only with energy storage // such as cables. This is something that would work only with energy storage
fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
// for internal needs, e.g. for work // for internal needs, e.g. for work
// CAN also be used by something that does evil // CAN also be used by something that does evil
// e.g. sucking out energy anomaly should use this // e.g. sucking out energy anomaly should use this
fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
// energy is received from outside, e.g. cables // energy is received from outside, e.g. cables
fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
// energy is received from inside, e.g. generator generates power // energy is received from inside, e.g. generator generates power
fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
fun extractEnergyOuter(howMuch: Long, simulate: Boolean): Fraction { fun extractEnergyOuter(howMuch: Long, simulate: Boolean): ImpreciseFraction {
return extractEnergyOuter(Fraction(howMuch), simulate) return extractEnergyOuter(ImpreciseFraction(howMuch), simulate)
} }
fun extractEnergyOuter(howMuch: Int, simulate: Boolean): Fraction { fun extractEnergyOuter(howMuch: Int, simulate: Boolean): ImpreciseFraction {
return extractEnergyOuter(Fraction(howMuch), simulate) return extractEnergyOuter(ImpreciseFraction(howMuch), simulate)
} }
fun receiveEnergyOuter(howMuch: Long, simulate: Boolean): Fraction { fun receiveEnergyOuter(howMuch: Long, simulate: Boolean): ImpreciseFraction {
return receiveEnergyOuter(Fraction(howMuch), simulate) return receiveEnergyOuter(ImpreciseFraction(howMuch), simulate)
} }
fun receiveEnergyOuter(howMuch: Int, simulate: Boolean): Fraction { fun receiveEnergyOuter(howMuch: Int, simulate: Boolean): ImpreciseFraction {
return receiveEnergyOuter(Fraction(howMuch), simulate) return receiveEnergyOuter(ImpreciseFraction(howMuch), simulate)
} }
fun extractEnergyInner(howMuch: Long, simulate: Boolean): Fraction { fun extractEnergyInner(howMuch: Long, simulate: Boolean): ImpreciseFraction {
return extractEnergyInner(Fraction(howMuch), simulate) return extractEnergyInner(ImpreciseFraction(howMuch), simulate)
} }
fun extractEnergyInner(howMuch: Int, simulate: Boolean): Fraction { fun extractEnergyInner(howMuch: Int, simulate: Boolean): ImpreciseFraction {
return extractEnergyInner(Fraction(howMuch), simulate) return extractEnergyInner(ImpreciseFraction(howMuch), simulate)
} }
fun receiveEnergyInner(howMuch: Long, simulate: Boolean): Fraction { fun receiveEnergyInner(howMuch: Long, simulate: Boolean): ImpreciseFraction {
return receiveEnergyInner(Fraction(howMuch), simulate) return receiveEnergyInner(ImpreciseFraction(howMuch), simulate)
} }
fun receiveEnergyInner(howMuch: Int, simulate: Boolean): Fraction { fun receiveEnergyInner(howMuch: Int, simulate: Boolean): ImpreciseFraction {
return receiveEnergyInner(Fraction(howMuch), simulate) return receiveEnergyInner(ImpreciseFraction(howMuch), simulate)
} }
val batteryLevel: Fraction val batteryLevel: ImpreciseFraction
val maxBatteryLevel: Fraction val maxBatteryLevel: ImpreciseFraction
val missingPower: Fraction val missingPower: ImpreciseFraction
get() = (maxBatteryLevel - batteryLevel).moreThanZero() get() = (maxBatteryLevel - batteryLevel).moreThanZero()
override fun receiveEnergy(maxReceive: Int, simulate: Boolean): Int { override fun receiveEnergy(maxReceive: Int, simulate: Boolean): Int {
@ -63,7 +64,7 @@ interface IMatteryEnergyStorage : IEnergyStorage {
if (received == 0) if (received == 0)
return 0 return 0
return receiveEnergyOuter(Fraction(received), simulate).toInt() return receiveEnergyOuter(ImpreciseFraction(received), simulate).toInt()
} }
override fun extractEnergy(maxReceive: Int, simulate: Boolean): Int { override fun extractEnergy(maxReceive: Int, simulate: Boolean): Int {
@ -73,32 +74,22 @@ interface IMatteryEnergyStorage : IEnergyStorage {
if (extracted == 0) if (extracted == 0)
return 0 return 0
return extractEnergyOuter(Fraction(extracted), simulate).toInt() return extractEnergyOuter(ImpreciseFraction(extracted), simulate).toInt()
} }
override fun getEnergyStored(): Int { override fun getEnergyStored(): Int {
val level = batteryLevel return batteryLevel.toInt()
if (level < MatteryCapability.INT_MAX_VALUE)
return level.toInt()
return Int.MAX_VALUE
} }
override fun getMaxEnergyStored(): Int { override fun getMaxEnergyStored(): Int {
val level = maxBatteryLevel return maxBatteryLevel.toInt()
if (level < MatteryCapability.INT_MAX_VALUE)
return level.toInt()
return Int.MAX_VALUE
} }
override fun canExtract(): Boolean { override fun canExtract(): Boolean {
return extractEnergyOuter(Fraction.ONE, true) > Fraction.ZERO return extractEnergyOuter(ImpreciseFraction.ONE, true) > ImpreciseFraction.ZERO
} }
override fun canReceive(): Boolean { override fun canReceive(): Boolean {
return receiveEnergyOuter(Fraction.ONE, true) > Fraction.ZERO return receiveEnergyOuter(ImpreciseFraction.ONE, true) > ImpreciseFraction.ZERO
} }
} }

View File

@ -3,41 +3,40 @@ package ru.dbotthepony.mc.otm.capability
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraftforge.common.util.INBTSerializable import net.minecraftforge.common.util.INBTSerializable
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.Fraction.Companion.deserializeNBT
import ru.dbotthepony.mc.otm.ifHas import ru.dbotthepony.mc.otm.ifHas
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
open class MatteryMachineEnergyStorage @JvmOverloads constructor( open class MatteryMachineEnergyStorage @JvmOverloads constructor(
protected val listener: () -> Unit, protected val listener: () -> Unit,
val type: MachineType, val type: MachineType,
override var maxBatteryLevel: Fraction = DEFAULT_MAX_CAPACITY, override var maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
protected var maxInput: Fraction = DEFAULT_MAX_RECEIVE, protected var maxInput: ImpreciseFraction = DEFAULT_MAX_RECEIVE,
protected var maxOutput: Fraction = maxInput protected var maxOutput: ImpreciseFraction = maxInput
) : IMatteryEnergyStorage, INBTSerializable<CompoundTag> { ) : IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
@JvmOverloads @JvmOverloads
constructor( constructor(
listener: BlockEntity, listener: BlockEntity,
type: MachineType, type: MachineType,
maxBatteryLevel: Fraction = DEFAULT_MAX_CAPACITY, maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: Fraction = DEFAULT_MAX_RECEIVE, maxInput: ImpreciseFraction = DEFAULT_MAX_RECEIVE,
maxOutput: Fraction = DEFAULT_MAX_EXTRACT) : this({listener.setChanged()}, type, maxBatteryLevel, maxInput, maxOutput) maxOutput: ImpreciseFraction = DEFAULT_MAX_EXTRACT) : this({listener.setChanged()}, type, maxBatteryLevel, maxInput, maxOutput)
enum class MachineType { enum class MachineType {
WORKER, GENERATOR, CAPACITOR WORKER, GENERATOR, CAPACITOR
} }
override var batteryLevel = Fraction.ZERO override var batteryLevel = ImpreciseFraction.ZERO
protected set protected set
override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (type == MachineType.WORKER) if (type == MachineType.WORKER)
return Fraction.ZERO return ImpreciseFraction.ZERO
return extractEnergyInner(howMuch, simulate) return extractEnergyInner(howMuch, simulate)
} }
override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
val new = batteryLevel.minus(howMuch.min(maxOutput)).moreThanZero() val new = batteryLevel.minus(howMuch.min(maxOutput)).moreThanZero()
val diff = batteryLevel.minus(new) val diff = batteryLevel.minus(new)
@ -49,14 +48,14 @@ open class MatteryMachineEnergyStorage @JvmOverloads constructor(
return diff return diff
} }
override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (type == MachineType.GENERATOR) if (type == MachineType.GENERATOR)
return Fraction.ZERO return ImpreciseFraction.ZERO
return receiveEnergyInner(howMuch, simulate) return receiveEnergyInner(howMuch, simulate)
} }
override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
val new = batteryLevel.plus(howMuch.min(maxInput)).min(maxBatteryLevel) val new = batteryLevel.plus(howMuch.min(maxInput)).min(maxBatteryLevel)
val diff = new.minus(batteryLevel) val diff = new.minus(batteryLevel)
@ -89,15 +88,15 @@ open class MatteryMachineEnergyStorage @JvmOverloads constructor(
} }
override fun deserializeNBT(nbt: CompoundTag) { override fun deserializeNBT(nbt: CompoundTag) {
nbt.ifHas("energy_stored") { batteryLevel = deserializeNBT(it) } nbt.ifHas("energy_stored") { batteryLevel = ImpreciseFraction.deserializeNBT(it) }
// nbt.ifHas("energy_stored_max") { maxBatteryLevel = deserializeNBT(it) } // nbt.ifHas("energy_stored_max") { maxBatteryLevel = deserializeNBT(it) }
// nbt.ifHas("max_input") { maxInput = deserializeNBT(it) } // nbt.ifHas("max_input") { maxInput = deserializeNBT(it) }
// nbt.ifHas("max_output") { maxOutput = deserializeNBT(it) } // nbt.ifHas("max_output") { maxOutput = deserializeNBT(it) }
} }
companion object { companion object {
val DEFAULT_MAX_RECEIVE = Fraction(200) val DEFAULT_MAX_RECEIVE = ImpreciseFraction(200)
val DEFAULT_MAX_EXTRACT = DEFAULT_MAX_RECEIVE val DEFAULT_MAX_EXTRACT = DEFAULT_MAX_RECEIVE
val DEFAULT_MAX_CAPACITY = Fraction(60000) val DEFAULT_MAX_CAPACITY = ImpreciseFraction(60000)
} }
} }

View File

@ -36,6 +36,7 @@ import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.capability.extractEnergy
import ru.dbotthepony.mc.otm.capability.receiveEnergy import ru.dbotthepony.mc.otm.capability.receiveEnergy
import ru.dbotthepony.mc.otm.core.Fraction 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.ifHas
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
import java.util.* import java.util.*
@ -43,13 +44,13 @@ import java.util.*
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapabilityProvider, IAndroidCapability, INBTSerializable<CompoundTag?> { open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapabilityProvider, IAndroidCapability, INBTSerializable<CompoundTag?> {
@JvmField protected var battery = Fraction.ZERO @JvmField protected var battery = ImpreciseFraction.ZERO
@JvmField protected var maxBattery = Fraction(60000) @JvmField protected var maxBattery = ImpreciseFraction(60000)
override var batteryItemStack = ItemStack.EMPTY override var batteryItemStack = ItemStack.EMPTY
private var remoteBattery = Fraction(-1) private var remoteBattery = ImpreciseFraction(-1)
private var remoteMaxBattery = Fraction(-1) private var remoteMaxBattery = ImpreciseFraction(-1)
private var remoteBatteryStack = ItemStack.EMPTY private var remoteBatteryStack = ItemStack.EMPTY
@JvmField protected val features: MutableMap<AndroidFeatureType<*>, AndroidFeature> = HashMap() @JvmField protected val features: MutableMap<AndroidFeatureType<*>, AndroidFeature> = HashMap()
@ -119,8 +120,8 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
} }
override fun invalidateNetworkState() { override fun invalidateNetworkState() {
remoteBattery = Fraction.MINUS_ONE remoteBattery = ImpreciseFraction.MINUS_ONE
remoteMaxBattery = Fraction.MINUS_ONE remoteMaxBattery = ImpreciseFraction.MINUS_ONE
remoteBatteryStack = ItemStack.EMPTY remoteBatteryStack = ItemStack.EMPTY
if (ent is ServerPlayer) { if (ent is ServerPlayer) {
@ -131,11 +132,11 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
} }
} }
override fun setEnergy(value: Fraction) { override fun setEnergy(value: ImpreciseFraction) {
battery = value battery = value
} }
override fun setMaxEnergy(value: Fraction) { override fun setMaxEnergy(value: ImpreciseFraction) {
maxBattery = value maxBattery = value
} }
@ -170,11 +171,11 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
compound!! compound!!
compound.ifHas("energy_stored") { compound.ifHas("energy_stored") {
battery = Fraction.deserializeNBT(it) battery = ImpreciseFraction.deserializeNBT(it)
} }
compound.ifHas("energy_stored_max") { compound.ifHas("energy_stored_max") {
maxBattery = Fraction.deserializeNBT(it) maxBattery = ImpreciseFraction.deserializeNBT(it)
} }
compound.ifHas("battery", CompoundTag::class.java) { compound.ifHas("battery", CompoundTag::class.java) {
@ -300,13 +301,13 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
} }
} }
override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return Fraction.ZERO return ImpreciseFraction.ZERO
} }
override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
var howMuch = howMuch var howMuch = howMuch
var drained = Fraction.ZERO var drained = ImpreciseFraction.ZERO
if (!batteryItemStack.isEmpty) { if (!batteryItemStack.isEmpty) {
batteryItemStack.getCapability(CapabilityEnergy.ENERGY).ifPresent { batteryItemStack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
@ -321,7 +322,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
} }
} }
if (howMuch.isZero()) { if (howMuch.isZero) {
if (!simulate && ent is ServerPlayer) { if (!simulate && ent is ServerPlayer) {
ent.awardStat(Registry.Names.POWER_CONSUMED, drained.toInt() * 10) ent.awardStat(Registry.Names.POWER_CONSUMED, drained.toInt() * 10)
} }
@ -344,9 +345,9 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
return drained return drained
} }
override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
var howMuch = howMuch var howMuch = howMuch
var received = Fraction.ZERO var received = ImpreciseFraction.ZERO
if (!batteryItemStack.isEmpty) { if (!batteryItemStack.isEmpty) {
batteryItemStack.getCapability(CapabilityEnergy.ENERGY).ifPresent { batteryItemStack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
@ -361,7 +362,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
} }
} }
if (howMuch.isZero()) { if (howMuch.isZero) {
return received return received
} }
} }
@ -376,7 +377,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
return received return received
} }
override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return receiveEnergyOuter(howMuch, simulate) return receiveEnergyOuter(howMuch, simulate)
} }
@ -384,7 +385,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
return ent return ent
} }
override val batteryLevel: Fraction get() { override val batteryLevel: ImpreciseFraction get() {
if (!batteryItemStack.isEmpty) { if (!batteryItemStack.isEmpty) {
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve() val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()
@ -402,7 +403,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab
return battery return battery
} }
override val maxBatteryLevel: Fraction get() { override val maxBatteryLevel: ImpreciseFraction get() {
if (batteryItemStack != ItemStack.EMPTY) { if (batteryItemStack != ItemStack.EMPTY) {
val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve() val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve()

View File

@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.android.AndroidResearch
import ru.dbotthepony.mc.otm.android.AndroidResearchType import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.network.android.AndroidResearchPacket import ru.dbotthepony.mc.otm.network.android.AndroidResearchPacket
import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
@ -58,8 +59,8 @@ class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply
isAndroid = true isAndroid = true
willBecomeAndroid = false willBecomeAndroid = false
battery = Fraction(60000) battery = ImpreciseFraction(60000)
maxBattery = Fraction(60000) maxBattery = ImpreciseFraction(60000)
} }
fun becomeAndroidAndKill() { fun becomeAndroidAndKill() {
@ -74,8 +75,8 @@ class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply
if (!isAndroid) return if (!isAndroid) return
isAndroid = false isAndroid = false
battery = Fraction(0) battery = ImpreciseFraction(0)
maxBattery = Fraction(60000) maxBattery = ImpreciseFraction(60000)
dropBattery() dropBattery()
} }
@ -296,7 +297,7 @@ class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply
} }
} }
val ENERGY_FOR_HUNGER_POINT = Fraction(1000) val ENERGY_FOR_HUNGER_POINT = ImpreciseFraction(1000)
const val SLEEP_TICKS_LIMIT = 80 const val SLEEP_TICKS_LIMIT = 80
} }
} }

View File

@ -8,7 +8,7 @@ import net.minecraftforge.event.entity.living.LivingHurtEvent
import ru.dbotthepony.mc.otm.android.AndroidFeature import ru.dbotthepony.mc.otm.android.AndroidFeature
import ru.dbotthepony.mc.otm.android.AndroidFeatureType import ru.dbotthepony.mc.otm.android.AndroidFeatureType
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import java.util.* import java.util.*
interface IAndroidCapability : IMatteryEnergyStorage, INBTSerializable<CompoundTag?> { interface IAndroidCapability : IMatteryEnergyStorage, INBTSerializable<CompoundTag?> {
@ -40,6 +40,6 @@ interface IAndroidCapability : IMatteryEnergyStorage, INBTSerializable<CompoundT
fun onHurt(event: LivingHurtEvent) {} fun onHurt(event: LivingHurtEvent) {}
var batteryItemStack: ItemStack var batteryItemStack: ItemStack
fun invalidateNetworkState() // tell capability that player forgot everything, and everything needs to be re-networked fun invalidateNetworkState() // tell capability that player forgot everything, and everything needs to be re-networked
fun setEnergy(value: Fraction) fun setEnergy(value: ImpreciseFraction)
fun setMaxEnergy(value: Fraction) fun setMaxEnergy(value: ImpreciseFraction)
} }

View File

@ -4,6 +4,7 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.storage.IStorageComponent import ru.dbotthepony.mc.otm.storage.IStorageComponent
import ru.dbotthepony.mc.otm.storage.IStorageStack import ru.dbotthepony.mc.otm.storage.IStorageStack
import ru.dbotthepony.mc.otm.storage.IStorageTuple import ru.dbotthepony.mc.otm.storage.IStorageTuple
@ -35,8 +36,8 @@ interface IMatteryDrive<T : IStorageStack> : IStorageComponent<T> {
var isDirty: Boolean var isDirty: Boolean
val storedCount: Fraction val storedCount: ImpreciseFraction
val driveCapacity: Fraction val driveCapacity: ImpreciseFraction
// not extending INBTSerializable to avoid serializing it as forgecaps // not extending INBTSerializable to avoid serializing it as forgecaps
fun serializeNBT(): CompoundTag fun serializeNBT(): CompoundTag

View File

@ -13,6 +13,7 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag import net.minecraft.nbt.ListTag
import net.minecraft.nbt.Tag import net.minecraft.nbt.Tag
import ru.dbotthepony.mc.otm.core.Fraction 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.ifHas
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
import java.util.ArrayList import java.util.ArrayList
@ -20,7 +21,7 @@ import java.util.HashSet
abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor( abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor(
override var driveCapacity: Fraction, override var driveCapacity: ImpreciseFraction,
override val uuid: UUID = UUID.randomUUID(), override val uuid: UUID = UUID.randomUUID(),
var maxDifferentStacks: Int = 0xFFFF var maxDifferentStacks: Int = 0xFFFF
) : IMatteryDrive<T> { ) : IMatteryDrive<T> {
@ -42,12 +43,12 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
var storedDifferentStacks = 0 var storedDifferentStacks = 0
override var storedCount = Fraction.ZERO override var storedCount = ImpreciseFraction.ZERO
protected set protected set
override fun insertStack(stack: T, simulate: Boolean): T { override fun insertStack(stack: T, simulate: Boolean): T {
val maxInsert = driveCapacity.minus(storedCount).min(stack.count) val maxInsert = driveCapacity.minus(storedCount).min(stack.count)
if (maxInsert <= Fraction.ZERO) return stack if (maxInsert <= ImpreciseFraction.ZERO) return stack
val listing = storedStacks.computeIfAbsent(stack.partitionKey()) { ArrayList() } val listing = storedStacks.computeIfAbsent(stack.partitionKey()) { ArrayList() }
@ -97,16 +98,16 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
return copy return copy
} }
override fun extractStack(id: UUID, amount: Fraction, simulate: Boolean): T { override fun extractStack(id: UUID, amount: ImpreciseFraction, simulate: Boolean): T {
var amount = amount var amount = amount
val get = storedByID[id] ?: return identity().empty() val get = storedByID[id] ?: return identity().empty()
if (amount <= Fraction.ZERO) if (amount <= ImpreciseFraction.ZERO)
amount = get.stack.getMaxStackSize().orElse(get.stack.count) amount = get.stack.getMaxStackSize().orElse(get.stack.count)
amount = amount.min(get.stack.count) amount = amount.min(get.stack.count)
if (amount <= Fraction.ZERO) if (amount <= ImpreciseFraction.ZERO)
return identity().empty() return identity().empty()
val copy = get.stack.copy() as T val copy = get.stack.copy() as T
@ -130,7 +131,7 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
storedCount = storedCount.minus(amount) storedCount = storedCount.minus(amount)
get.stack.shrink(amount) get.stack.shrink(amount)
if (get.stack.count.compareTo(Fraction.ZERO) != 0) { if (!get.stack.count.isZero) {
for (listener in listeners) { for (listener in listeners) {
listener.changeObject(get.id(), get.stack.count) listener.changeObject(get.id(), get.stack.count)
} }
@ -170,11 +171,11 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
override fun deserializeNBT(nbt: CompoundTag) { override fun deserializeNBT(nbt: CompoundTag) {
storedStacks.clear() storedStacks.clear()
storedByID.clear() storedByID.clear()
storedCount = Fraction.ZERO storedCount = ImpreciseFraction.ZERO
storedDifferentStacks = 0 storedDifferentStacks = 0
nbt.ifHas("capacity") { nbt.ifHas("capacity") {
driveCapacity = deserializeNBT(it) driveCapacity = ImpreciseFraction.deserializeNBT(it)
} }
maxDifferentStacks = nbt.getInt("max_different_stacks") maxDifferentStacks = nbt.getInt("max_different_stacks")

View File

@ -7,6 +7,7 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items import net.minecraft.world.item.Items
import net.minecraftforge.registries.RegistryManager import net.minecraftforge.registries.RegistryManager
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
import ru.dbotthepony.mc.otm.storage.IStorageTuple import ru.dbotthepony.mc.otm.storage.IStorageTuple
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
@ -14,10 +15,10 @@ import ru.dbotthepony.mc.otm.storage.StorageObjectRegistry
import java.util.* import java.util.*
class ItemMatteryDrive : AbstractMatteryDrive<ItemStackWrapper>, IItemMatteryDrive { class ItemMatteryDrive : AbstractMatteryDrive<ItemStackWrapper>, IItemMatteryDrive {
constructor(capacity: Fraction, max_different_stacks: Int) : super(capacity, maxDifferentStacks = max_different_stacks) constructor(capacity: ImpreciseFraction, max_different_stacks: Int) : super(capacity, maxDifferentStacks = max_different_stacks)
constructor(capacity: Fraction, uuid: UUID, max_different_stacks: Int) : super(capacity, uuid, max_different_stacks) constructor(capacity: ImpreciseFraction, uuid: UUID, max_different_stacks: Int) : super(capacity, uuid, max_different_stacks)
constructor(capacity: Fraction, uuid: UUID) : super(capacity, uuid) constructor(capacity: ImpreciseFraction, uuid: UUID) : super(capacity, uuid)
constructor(capacity: Fraction) : super(capacity) constructor(capacity: ImpreciseFraction) : super(capacity)
private val identity = StorageObjectRegistry.getOrError(ItemStackWrapper::class.java) private val identity = StorageObjectRegistry.getOrError(ItemStackWrapper::class.java)
override fun identity() = identity override fun identity() = identity
@ -86,6 +87,6 @@ class ItemMatteryDrive : AbstractMatteryDrive<ItemStackWrapper>, IItemMatteryDri
companion object { companion object {
@JvmField @JvmField
val DUMMY = ItemMatteryDrive(Fraction(0), UUID(0L, 0L), 0) val DUMMY = ItemMatteryDrive(ImpreciseFraction(0), UUID(0L, 0L), 0)
} }
} }

View File

@ -51,8 +51,8 @@ class EnergyCounterRenderer(private val context: BlockEntityRendererProvider.Con
poseStack.pushPose() poseStack.pushPose()
poseStack.translate(-0.1, -0.1, -0.1) poseStack.translate(-0.1, -0.1, -0.1)
font.drawAligned(poseStack, tile.lastTick.decimalString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y, 0xFFFFFF) font.drawAligned(poseStack, tile.lastTick.toString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y, 0xFFFFFF)
font.drawAligned(poseStack, tile.sumHistory(20).decimalString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y + font.lineHeight, 0xFFFFFF) font.drawAligned(poseStack, tile.sumHistory(20).toString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y + font.lineHeight, 0xFFFFFF)
poseStack.popPose() poseStack.popPose()
y += font.lineHeight * 3 y += font.lineHeight * 3

View File

@ -105,7 +105,7 @@ open class PatternGaugePanel @JvmOverloads constructor(
protected open fun makeTooltip(): MutableList<Component> { protected open fun makeTooltip(): MutableList<Component> {
return mutableListOf( return mutableListOf(
TranslatableComponent("otm.gui.pattern.percentage_level", String.format("%.2f", widget.percentage() * 100.0)), TranslatableComponent("otm.gui.pattern.percentage_level", String.format("%.2f", widget.percentage() * 100.0)),
TranslatableComponent("otm.gui.pattern.format", widget.level().decimalString(), widget.maxLevel().decimalString()) TranslatableComponent("otm.gui.pattern.format", widget.level().toString(2), widget.maxLevel().toString(2))
) )
} }

View File

@ -10,6 +10,8 @@ import java.math.BigInteger
import java.math.MathContext import java.math.MathContext
import java.math.RoundingMode import java.math.RoundingMode
private val IMPRECISE_CONTEXT = MathContext(17)
private fun powScale(int: Int): BigInteger { private fun powScale(int: Int): BigInteger {
if (int <= 0) if (int <= 0)
return BigInteger.ONE return BigInteger.ONE
@ -597,6 +599,27 @@ data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @
return (value / divisor).toDouble() + ((value % divisor).toDouble() / divisor.toDouble()) return (value / divisor).toDouble() + ((value % divisor).toDouble() / divisor.toDouble())
} }
fun toImpreciseFraction(): ImpreciseFraction {
if (isNaN())
return ImpreciseFraction.NaN
val div = value.divideAndRemainder(divisor)
val a = divisor.toDouble()
val b = div[1].toDouble()
if (b == 0.0 || b == -0.0 || !a.isFinite() || !b.isFinite()) {
return ImpreciseFraction(div[0])
}
val div2 = a / b
if (div2.isFinite() && !div2.isNaN()) {
return ImpreciseFraction(div[0], div2)
}
return ImpreciseFraction(div[0])
}
fun toByteArray(): ByteArray { fun toByteArray(): ByteArray {
if (isNaN()) { if (isNaN()) {
return byteArrayOf(1, 0, 0, 0, 0, 1, 0, 0, 0, 0) return byteArrayOf(1, 0, 0, 0, 0, 1, 0, 0, 0, 0)

View File

@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.core
import net.minecraft.nbt.ByteArrayTag import net.minecraft.nbt.ByteArrayTag
import net.minecraft.nbt.StringTag import net.minecraft.nbt.StringTag
import net.minecraft.nbt.Tag import net.minecraft.nbt.Tag
import net.minecraft.network.FriendlyByteBuf
import java.math.BigDecimal import java.math.BigDecimal
import java.math.BigInteger import java.math.BigInteger
import java.math.MathContext import java.math.MathContext
@ -13,6 +14,14 @@ private fun isZero(value: BigInteger) = value == BigInteger.ZERO
private val LONG_BUFF = ByteBuffer.allocate(8) private val LONG_BUFF = ByteBuffer.allocate(8)
private fun byteToInt(value: Byte): Int {
if (value < 0) {
return 256 + value
}
return value.toInt()
}
private fun longToBytes(value: Long): ByteArray { private fun longToBytes(value: Long): ByteArray {
LONG_BUFF.position(0) LONG_BUFF.position(0)
LONG_BUFF.putLong(value) LONG_BUFF.putLong(value)
@ -33,6 +42,29 @@ private fun bytesToLong(value: ByteArray, from: Int = 0): Long {
return LONG_BUFF.long return LONG_BUFF.long
} }
private fun bytesToLong(
value0: Byte,
value1: Byte,
value2: Byte,
value3: Byte,
value4: Byte,
value5: Byte,
value6: Byte,
value7: Byte,
): Long {
val arr = LONG_BUFF.array()
arr[0] = value0
arr[1] = value1
arr[2] = value2
arr[3] = value3
arr[4] = value4
arr[5] = value5
arr[6] = value6
arr[7] = value7
LONG_BUFF.position(0)
return LONG_BUFF.long
}
const val EPSILON = 0.0000001 const val EPSILON = 0.0000001
private fun cmpDouble(a: Double, b: Double): Boolean { private fun cmpDouble(a: Double, b: Double): Boolean {
@ -42,6 +74,18 @@ private fun cmpDouble(a: Double, b: Double): Boolean {
return (a - b).absoluteValue <= EPSILON return (a - b).absoluteValue <= EPSILON
} }
private val BI_INT_MAX = BigInteger.valueOf(Int.MAX_VALUE.toLong())
private val BI_INT_MIN = BigInteger.valueOf(Int.MIN_VALUE.toLong())
private val BI_LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE)
private val BI_LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE)
private val BI_FLOAT_MAX = BigDecimal(Float.MAX_VALUE.toString()).toBigInteger()
private val BI_FLOAT_MIN = BigDecimal(Float.MIN_VALUE.toString()).toBigInteger()
private val BI_DOUBLE_MAX = BigDecimal(Double.MAX_VALUE.toString()).toBigInteger()
private val BI_DOUBLE_MIN = BigDecimal(Double.MIN_VALUE.toString()).toBigInteger()
private val PERCENTAGE_CONTEXT = MathContext(6)
@Suppress("unused") @Suppress("unused")
class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Double = 0.0) : Comparable<ImpreciseFraction> { class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Double = 0.0) : Comparable<ImpreciseFraction> {
@JvmOverloads constructor(whole: Byte, decimal: Double = 0.0) : this(BigInteger.valueOf(whole.toLong()), decimal) @JvmOverloads constructor(whole: Byte, decimal: Double = 0.0) : this(BigInteger.valueOf(whole.toLong()), decimal)
@ -49,8 +93,8 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
@JvmOverloads constructor(whole: Int, decimal: Double = 0.0) : this(BigInteger.valueOf(whole.toLong()), decimal) @JvmOverloads constructor(whole: Int, decimal: Double = 0.0) : this(BigInteger.valueOf(whole.toLong()), decimal)
@JvmOverloads constructor(whole: Long, decimal: Double = 0.0) : this(BigInteger.valueOf(whole), decimal) @JvmOverloads constructor(whole: Long, decimal: Double = 0.0) : this(BigInteger.valueOf(whole), decimal)
constructor(value: BigDecimal) : this(value.toBigInteger(), value.remainder(BigDecimal.ONE).toDouble()) // TODO constructor(value: BigDecimal) : this(value.toBigInteger(), value.remainder(BigDecimal.ONE).toDouble()) // TODO
constructor(value: Float) : this(BigDecimal(value.toString())) constructor(value: Float) : this(BigInteger.valueOf((value - value % 1.0).toLong()), value % 1.0)
constructor(value: Double) : this(BigDecimal(value.toString())) constructor(value: Double) : this(BigInteger.valueOf((value - value % 1.0).toLong()), value % 1.0)
constructor(value: String) : this(BigDecimal(value)) constructor(value: String) : this(BigDecimal(value))
val decimal: Double val decimal: Double
@ -95,7 +139,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
} }
} }
fun isNaN() = decimal.isNaN() val isNaN get() = decimal.isNaN()
operator fun plus(other: ImpreciseFraction) = ImpreciseFraction(whole + other.whole, decimal + other.decimal) operator fun plus(other: ImpreciseFraction) = ImpreciseFraction(whole + other.whole, decimal + other.decimal)
operator fun minus(other: ImpreciseFraction) = ImpreciseFraction(whole - other.whole, decimal - other.decimal) operator fun minus(other: ImpreciseFraction) = ImpreciseFraction(whole - other.whole, decimal - other.decimal)
@ -133,12 +177,32 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
return ImpreciseFraction(div[0].toBigInteger(), div[1].toDouble() / bD) return ImpreciseFraction(div[0].toBigInteger(), div[1].toDouble() / bD)
} }
operator fun plus(other: Float): ImpreciseFraction = plus(ImpreciseFraction(other))
operator fun minus(other: Float): ImpreciseFraction = minus(ImpreciseFraction(other))
operator fun times(other: Float): ImpreciseFraction = times(ImpreciseFraction(other))
operator fun div(other: Float): ImpreciseFraction = div(ImpreciseFraction(other))
operator fun plus(other: Double): ImpreciseFraction = plus(ImpreciseFraction(other))
operator fun minus(other: Double): ImpreciseFraction = minus(ImpreciseFraction(other))
operator fun times(other: Double): ImpreciseFraction = times(ImpreciseFraction(other))
operator fun div(other: Double): ImpreciseFraction = div(ImpreciseFraction(other))
operator fun plus(other: Int): ImpreciseFraction = plus(ImpreciseFraction(other))
operator fun minus(other: Int): ImpreciseFraction = minus(ImpreciseFraction(other))
operator fun times(other: Int): ImpreciseFraction = times(ImpreciseFraction(other))
operator fun div(other: Int): ImpreciseFraction = div(ImpreciseFraction(other))
operator fun plus(other: Long): ImpreciseFraction = plus(ImpreciseFraction(other))
operator fun minus(other: Long): ImpreciseFraction = minus(ImpreciseFraction(other))
operator fun times(other: Long): ImpreciseFraction = times(ImpreciseFraction(other))
operator fun div(other: Long): ImpreciseFraction = div(ImpreciseFraction(other))
operator fun unaryMinus(): ImpreciseFraction { operator fun unaryMinus(): ImpreciseFraction {
return ImpreciseFraction(-whole, decimal) return ImpreciseFraction(-whole, decimal)
} }
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (isNaN()) if (isNaN)
return false return false
if (other is ImpreciseFraction) { if (other is ImpreciseFraction) {
@ -149,7 +213,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
} }
fun equalsStrict(other: Any?): Boolean { fun equalsStrict(other: Any?): Boolean {
if (isNaN()) if (isNaN)
return false return false
if (other is ImpreciseFraction) { if (other is ImpreciseFraction) {
@ -160,16 +224,36 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
} }
override fun hashCode(): Int { override fun hashCode(): Int {
if (isNaN()) if (isNaN)
return Double.NaN.hashCode() return Double.NaN.hashCode()
return 31 * decimal.hashCode() + whole.hashCode() return 31 * decimal.hashCode() + whole.hashCode()
} }
override fun toString(): String { fun toString(decimals: Int): String {
if (isNaN()) if (isNaN)
return "NaN" return "NaN"
if (decimals == 0) {
return whole.toString()
} else if (decimals > 0) {
val strDecimal = if (decimal == 0.0 || decimal == -0.0) {
"0"
} else if (decimal > 0.0) {
decimal.toString().substring(2)
} else {
decimal.toString().substring(3)
}
if (strDecimal.length < decimals) {
return "$whole.${strDecimal + "0".repeat(decimals - strDecimal.length)}"
} else if (strDecimal.length > decimals) {
return "$whole.${strDecimal.substring(0, decimals)}"
} else {
return "$whole.$strDecimal"
}
}
return when (signum()) { return when (signum()) {
1 -> "$whole.${decimal.toString().substring(2)}" 1 -> "$whole.${decimal.toString().substring(2)}"
0 -> "0.0" 0 -> "0.0"
@ -178,9 +262,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
} }
} }
fun toDouble(): Double { override fun toString() = toString(-1)
return java.lang.Double.parseDouble(toString())
}
fun toBigDecmial(): BigDecimal { fun toBigDecmial(): BigDecimal {
return BigDecimal(whole) + BigDecimal(decimal) return BigDecimal(whole) + BigDecimal(decimal)
@ -197,9 +279,9 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
} }
override fun compareTo(other: ImpreciseFraction): Int { override fun compareTo(other: ImpreciseFraction): Int {
if (isNaN()) if (isNaN)
return 1 return 1
else if (other.isNaN()) else if (other.isNaN)
return -1 return -1
val a = signum() val a = signum()
@ -222,9 +304,9 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
} }
fun compareToStrict(other: ImpreciseFraction): Int { fun compareToStrict(other: ImpreciseFraction): Int {
if (isNaN()) if (isNaN)
return 1 return 1
else if (other.isNaN()) else if (other.isNaN)
return -1 return -1
val a = signum() val a = signum()
@ -246,16 +328,16 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
return whole.compareTo(other.whole) return whole.compareTo(other.whole)
} }
fun toBytesArray(): ByteArray { fun toByteArray(): ByteArray {
val whole = whole.toByteArray() val whole = whole.toByteArray()
return byteArrayOf(whole.size.toByte(), *whole, *longToBytes(decimal.toBits())) return byteArrayOf(whole.size.toByte(), *whole, *longToBytes(decimal.toBits()))
} }
fun serializeNBT(): Tag { fun serializeNBT(): Tag {
return ByteArrayTag(toBytesArray()) return ByteArrayTag(toByteArray())
} }
fun isZero() = cmpDouble(decimal, 0.0) && isZero(whole) val isZero get() = cmpDouble(decimal, 0.0) && isZero(whole)
fun moreThanZero(): ImpreciseFraction { fun moreThanZero(): ImpreciseFraction {
if (signum() >= 0) if (signum() >= 0)
@ -295,28 +377,105 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
return min return min
} }
fun toInt(): Int {
if (whole > BI_INT_MAX) {
return Int.MAX_VALUE
} else if (whole < BI_INT_MIN) {
return Int.MIN_VALUE
}
return whole.toInt()
}
fun write(buff: FriendlyByteBuf) {
buff.writeBytes(toByteArray())
}
fun toFloat(): Float {
return whole.toFloat() + decimal.toFloat()
}
fun toDouble(): Double {
return whole.toDouble() + decimal
}
fun toFraction(): Fraction {
if (isZero) {
return Fraction.ZERO
}
if (cmpDouble(decimal, 0.0)) {
return Fraction(whole)
}
return Fraction(toBigDecmial())
}
fun percentage(divisor: ImpreciseFraction, zeroing: Boolean = true): Float {
if ((isZero || divisor.isZero) && zeroing) return 0f
if (isNaN || divisor.isNaN || divisor.isZero) return Float.NaN
if (this >= divisor)
return 1f
if (this <= FLOAT_MAX_VALUE && divisor <= FLOAT_MAX_VALUE)
return (toDouble() / divisor.toDouble()).toFloat()
return toBigDecmial().divide(divisor.toBigDecmial(), PERCENTAGE_CONTEXT).toFloat()
}
companion object { companion object {
@JvmField val MINUS_ZERO = ImpreciseFraction(0, -0.0) @JvmField val MINUS_ZERO = ImpreciseFraction(0, -0.0)
@JvmField val ZERO = ImpreciseFraction(BigInteger.ZERO) @JvmField val ZERO = ImpreciseFraction(BigInteger.ZERO)
@JvmField val ONE = ImpreciseFraction(BigInteger.ONE) @JvmField val ONE = ImpreciseFraction(BigInteger.ONE)
@JvmField val MINUS_ONE = ImpreciseFraction(-BigInteger.ONE)
@JvmField val TWO = ImpreciseFraction(BigInteger.TWO) @JvmField val TWO = ImpreciseFraction(BigInteger.TWO)
@JvmField val TEN = ImpreciseFraction(BigInteger.TEN) @JvmField val TEN = ImpreciseFraction(BigInteger.TEN)
fun fromBytesArray(input: ByteArray): ImpreciseFraction { @JvmField val INT_MAX_VALUE = ImpreciseFraction(BI_INT_MAX)
val size = if (input[0] < 0) input[0].toInt() + 256 else input[0].toInt() @JvmField val INT_MIN_VALUE = ImpreciseFraction(BI_INT_MIN)
@JvmField val LONG_MAX_VALUE = ImpreciseFraction(BI_LONG_MAX)
@JvmField val LONG_MIN_VALUE = ImpreciseFraction(BI_LONG_MIN)
@JvmField val FLOAT_MAX_VALUE = ImpreciseFraction(BI_FLOAT_MAX)
@JvmField val FLOAT_MIN_VALUE = ImpreciseFraction(BI_FLOAT_MIN)
@JvmField val DOUBLE_MAX_VALUE = ImpreciseFraction(BI_DOUBLE_MAX)
@JvmField val DOUBLE_MIN_VALUE = ImpreciseFraction(BI_DOUBLE_MIN)
@JvmField val NaN = ImpreciseFraction(0, Double.NaN)
@JvmStatic
fun fromByteArray(input: ByteArray): ImpreciseFraction {
val size = byteToInt(input[0])
val slice = input.copyOfRange(1, 1 + size) val slice = input.copyOfRange(1, 1 + size)
val bits = bytesToLong(input, 1 + size) val bits = bytesToLong(input, 1 + size)
return ImpreciseFraction(BigInteger(slice), Double.fromBits(bits)) return ImpreciseFraction(BigInteger(slice), Double.fromBits(bits))
} }
@JvmStatic
fun deserializeNBT(input: Tag?): ImpreciseFraction { fun deserializeNBT(input: Tag?): ImpreciseFraction {
if (input is ByteArrayTag) { if (input is ByteArrayTag) {
return fromBytesArray(input.asByteArray) return fromByteArray(input.asByteArray)
} else if (input is StringTag) { } else if (input is StringTag) {
return ImpreciseFraction(input.asString) return ImpreciseFraction(input.asString)
} }
return ZERO return ZERO
} }
@JvmStatic
fun read(buff: FriendlyByteBuf): ImpreciseFraction {
val len = byteToInt(buff.readByte())
val slice = ByteArray(len)
for (i in 0 until len)
slice[i] = buff.readByte()
val bits = bytesToLong(buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte(), buff.readByte())
return ImpreciseFraction(BigInteger(slice), Double.fromBits(bits))
}
} }
} }
fun FriendlyByteBuf.readImpreciseFraction() = ImpreciseFraction.read(this)
fun FriendlyByteBuf.writeImpreciseFraction(value: ImpreciseFraction) = value.write(this)

View File

@ -6,6 +6,7 @@ import net.minecraft.world.level.block.entity.BlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.matter.* import ru.dbotthepony.mc.otm.capability.matter.*
import ru.dbotthepony.mc.otm.core.Fraction 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.Abstract6Graph
import ru.dbotthepony.mc.otm.graph.Graph6Node import ru.dbotthepony.mc.otm.graph.Graph6Node
import java.util.* import java.util.*
@ -71,8 +72,8 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
} }
} }
fun getMatterStorageLevel(): Fraction { fun getMatterStorageLevel(): ImpreciseFraction {
var level = Fraction.ZERO var level = ImpreciseFraction.ZERO
for (node in _nodes) { for (node in _nodes) {
val matter = node.value.getMatterHandler() val matter = node.value.getMatterHandler()
@ -85,8 +86,8 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
return level return level
} }
fun getMatterStorageMaxLevel(): Fraction { fun getMatterStorageMaxLevel(): ImpreciseFraction {
var level = Fraction.ZERO var level = ImpreciseFraction.ZERO
for (node in _nodes) { for (node in _nodes) {
val matter = node.value.getMatterHandler() val matter = node.value.getMatterHandler()
@ -99,12 +100,12 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
return level return level
} }
fun extractMatter(howMuch: Fraction, simulate: Boolean): Fraction { fun extractMatter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (howMuch <= Fraction.ZERO) if (howMuch <= ImpreciseFraction.ZERO)
return Fraction.ZERO return ImpreciseFraction.ZERO
var howMuch = howMuch var howMuch = howMuch
var extracted = Fraction.ZERO var extracted = ImpreciseFraction.ZERO
for (node in _nodes) { for (node in _nodes) {
val matter = node.value.getMatterHandler() val matter = node.value.getMatterHandler()
@ -114,7 +115,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
howMuch -= value howMuch -= value
extracted += value extracted += value
if (howMuch <= Fraction.ZERO) if (howMuch <= ImpreciseFraction.ZERO)
return extracted return extracted
} }
} }
@ -122,12 +123,12 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
return extracted return extracted
} }
fun receiveMatter(howMuch: Fraction, simulate: Boolean): Fraction { fun receiveMatter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (howMuch <= Fraction.ZERO) if (howMuch <= ImpreciseFraction.ZERO)
return Fraction.ZERO return ImpreciseFraction.ZERO
var howMuch = howMuch var howMuch = howMuch
var received = Fraction.ZERO var received = ImpreciseFraction.ZERO
for (node in _nodes) { for (node in _nodes) {
val matter = node.value.getMatterHandler() val matter = node.value.getMatterHandler()
@ -137,7 +138,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
howMuch -= value howMuch -= value
received += value received += value
if (howMuch <= Fraction.ZERO) if (howMuch <= ImpreciseFraction.ZERO)
return received return received
} }
} }
@ -145,12 +146,12 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
return received return received
} }
fun receiveMatterForce(howMuch: Fraction, simulate: Boolean): Fraction { fun receiveMatterForce(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (howMuch <= Fraction.ZERO) if (howMuch <= ImpreciseFraction.ZERO)
return Fraction.ZERO return ImpreciseFraction.ZERO
var howMuch = howMuch var howMuch = howMuch
var received = Fraction.ZERO var received = ImpreciseFraction.ZERO
for (node in _nodes) { for (node in _nodes) {
val matter = node.value.getMatterHandler() val matter = node.value.getMatterHandler()
@ -160,7 +161,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
howMuch -= value howMuch -= value
received += value received += value
if (howMuch <= Fraction.ZERO) if (howMuch <= ImpreciseFraction.ZERO)
return received return received
} }
} }

View File

@ -20,25 +20,26 @@ import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
class ItemBattery : Item { class ItemBattery : Item {
private inner class BatteryMatteryCapability(private val stack: ItemStack) : IMatteryEnergyStorage, ICapabilityProvider { private inner class BatteryMatteryCapability(private val stack: ItemStack) : IMatteryEnergyStorage, ICapabilityProvider {
private fun energy(): Fraction { private fun energy(): ImpreciseFraction {
val tag = stack.orCreateTag val tag = stack.orCreateTag
return if (tag.contains("otm_energy")) { return if (tag.contains("otm_energy")) {
deserializeNBT(tag["otm_energy"]) ImpreciseFraction.deserializeNBT(tag["otm_energy"])
} else Fraction.ZERO } else ImpreciseFraction.ZERO
} }
private fun energy(value: Fraction) { private fun energy(value: ImpreciseFraction) {
stack.getOrCreateTag().put("otm_energy", value.serializeNBT()) stack.getOrCreateTag().put("otm_energy", value.serializeNBT())
} }
override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return extractEnergyInner(howMuch, simulate) return extractEnergyInner(howMuch, simulate)
} }
override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (isCreative) return howMuch if (isCreative) return howMuch
val new = energy().minus(howMuch.min(extract)).moreThanZero() val new = energy().minus(howMuch.min(extract)).moreThanZero()
val diff = energy().minus(new) val diff = energy().minus(new)
@ -50,11 +51,11 @@ class ItemBattery : Item {
return diff return diff
} }
override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return receiveEnergyInner(howMuch, simulate) return receiveEnergyInner(howMuch, simulate)
} }
override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (isCreative) return howMuch if (isCreative) return howMuch
val new = energy().plus(howMuch.min(receive)).min(storage) val new = energy().plus(howMuch.min(receive)).min(storage)
val diff = new.minus(energy()) val diff = new.minus(energy())
@ -66,15 +67,15 @@ class ItemBattery : Item {
return diff return diff
} }
override val missingPower: Fraction get() { override val missingPower: ImpreciseFraction get() {
return if (isCreative) MatteryCapability.LONG_MAX_VALUE else super.missingPower return if (isCreative) ImpreciseFraction.LONG_MAX_VALUE else super.missingPower
} }
override val batteryLevel: Fraction get() { override val batteryLevel: ImpreciseFraction get() {
return if (isCreative) MatteryCapability.LONG_MAX_VALUE else energy() return if (isCreative) ImpreciseFraction.LONG_MAX_VALUE else energy()
} }
override val maxBatteryLevel: Fraction get() { override val maxBatteryLevel: ImpreciseFraction get() {
return storage return storage
} }
@ -94,12 +95,12 @@ class ItemBattery : Item {
} }
private val isCreative: Boolean private val isCreative: Boolean
val storage: Fraction val storage: ImpreciseFraction
val receive: Fraction val receive: ImpreciseFraction
val extract: Fraction val extract: ImpreciseFraction
private val throughputText: Component private val throughputText: Component
constructor(storage: Fraction, receive: Fraction, extract: Fraction) : super( constructor(storage: ImpreciseFraction, receive: ImpreciseFraction, extract: ImpreciseFraction) : super(
Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB) Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)
) { ) {
isCreative = false isCreative = false
@ -115,9 +116,9 @@ class ItemBattery : Item {
constructor() : super(Properties().stacksTo(1).rarity(Rarity.EPIC).tab(OverdriveThatMatters.CREATIVE_TAB)) { constructor() : super(Properties().stacksTo(1).rarity(Rarity.EPIC).tab(OverdriveThatMatters.CREATIVE_TAB)) {
isCreative = true isCreative = true
storage = MatteryCapability.LONG_MAX_VALUE storage = ImpreciseFraction.LONG_MAX_VALUE
receive = MatteryCapability.LONG_MAX_VALUE receive = ImpreciseFraction.LONG_MAX_VALUE
extract = MatteryCapability.LONG_MAX_VALUE extract = ImpreciseFraction.LONG_MAX_VALUE
throughputText = TranslatableComponent("otm.item.power.infinite.throughput").withStyle(ChatFormatting.GRAY) throughputText = TranslatableComponent("otm.item.power.infinite.throughput").withStyle(ChatFormatting.GRAY)
} }

View File

@ -20,6 +20,7 @@ import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.Fraction.Companion.deserializeNBT import ru.dbotthepony.mc.otm.core.Fraction.Companion.deserializeNBT
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.FormattingHelper import ru.dbotthepony.mc.otm.menu.FormattingHelper
import javax.annotation.ParametersAreNonnullByDefault import javax.annotation.ParametersAreNonnullByDefault
@ -33,34 +34,34 @@ class ItemMatterCapacitor : Item {
return if (cap === MatteryCapability.MATTER) resolver.cast() else LazyOptional.empty() return if (cap === MatteryCapability.MATTER) resolver.cast() else LazyOptional.empty()
} }
private fun matter(): Fraction { private fun matter(): ImpreciseFraction {
val tag = stack.orCreateTag val tag = stack.orCreateTag
return if (tag.contains("otm_matter")) { return if (tag.contains("matter")) {
deserializeNBT(tag["otm_matter"]) ImpreciseFraction.deserializeNBT(tag["matter"])
} else Fraction.ZERO } else ImpreciseFraction.ZERO
} }
private fun matter(value: Fraction) { private fun matter(value: ImpreciseFraction) {
stack.getOrCreateTag().put("otm_matter", value.serializeNBT()) stack.getOrCreateTag().put("matter", value.serializeNBT())
} }
override fun getStoredMatter(): Fraction { override fun getStoredMatter(): ImpreciseFraction {
return if (isCreative) Fraction.LONG_MAX_VALUE else matter() return if (isCreative) ImpreciseFraction.LONG_MAX_VALUE else matter()
} }
override fun getMaxStoredMatter(): Fraction { override fun getMaxStoredMatter(): ImpreciseFraction {
return storage return storage
} }
override fun getMissingMatter(): Fraction { override fun getMissingMatter(): ImpreciseFraction {
return if (isCreative) Fraction.LONG_MAX_VALUE else super.getMissingMatter() return if (isCreative) ImpreciseFraction.LONG_MAX_VALUE else super.getMissingMatter()
} }
override fun receiveMatterOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return receiveMatterInner(howMuch, simulate) return receiveMatterInner(howMuch, simulate)
} }
override fun receiveMatterInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (isCreative) return howMuch if (isCreative) return howMuch
val new = matter().plus(howMuch.min(maxInput)).min(storage) val new = matter().plus(howMuch.min(maxInput)).min(storage)
val diff = new.minus(matter()) val diff = new.minus(matter())
@ -72,11 +73,11 @@ class ItemMatterCapacitor : Item {
return diff return diff
} }
override fun extractMatterOuter(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return extractMatterInner(howMuch, simulate) return extractMatterInner(howMuch, simulate)
} }
override fun extractMatterInner(howMuch: Fraction, simulate: Boolean): Fraction { override fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (isCreative) return howMuch if (isCreative) return howMuch
val new = matter().minus(howMuch.min(maxOutput)).moreThanZero() val new = matter().minus(howMuch.min(maxOutput)).moreThanZero()
val diff = matter().minus(new) val diff = matter().minus(new)
@ -93,17 +94,17 @@ class ItemMatterCapacitor : Item {
} }
} }
val storage: Fraction val storage: ImpreciseFraction
private val isCreative: Boolean private val isCreative: Boolean
constructor(storage: Fraction) : super(Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)) { constructor(storage: ImpreciseFraction) : super(Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)) {
isCreative = false isCreative = false
this.storage = storage this.storage = storage
} }
constructor() : super(Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB).rarity(Rarity.EPIC)) { constructor() : super(Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB).rarity(Rarity.EPIC)) {
isCreative = true isCreative = true
storage = MatteryCapability.LONG_MAX_VALUE storage = ImpreciseFraction.LONG_MAX_VALUE
} }
override fun appendHoverText( override fun appendHoverText(
@ -133,8 +134,8 @@ class ItemMatterCapacitor : Item {
} }
companion object { companion object {
private val maxInput = MatteryCapability.LONG_MAX_VALUE private val maxInput = ImpreciseFraction.LONG_MAX_VALUE
private val maxOutput = MatteryCapability.LONG_MAX_VALUE private val maxOutput = ImpreciseFraction.LONG_MAX_VALUE
private val INFINITE_STORAGE: Component = private val INFINITE_STORAGE: Component =
TranslatableComponent("otm.item.matter.infinite").withStyle(ChatFormatting.GRAY) TranslatableComponent("otm.item.matter.infinite").withStyle(ChatFormatting.GRAY)

View File

@ -25,15 +25,16 @@ import net.minecraftforge.eventbus.api.SubscribeEvent
import net.minecraftforge.event.entity.player.EntityItemPickupEvent import net.minecraftforge.event.entity.player.EntityItemPickupEvent
import ru.dbotthepony.mc.otm.capability.drive.DrivePool import ru.dbotthepony.mc.otm.capability.drive.DrivePool
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
import java.util.* import java.util.*
class ItemPortableCondensationDrive(capacity: Int) : class ItemPortableCondensationDrive(capacity: Int) :
Item(Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)) { Item(Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)) {
val capacity: Fraction val capacity: ImpreciseFraction
init { init {
this.capacity = Fraction(capacity) this.capacity = ImpreciseFraction(capacity)
} }
private inner class DriveCapability(private val stack: ItemStack) : ICapabilityProvider { private inner class DriveCapability(private val stack: ItemStack) : ICapabilityProvider {

View File

@ -5,16 +5,17 @@ import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.Registry import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter
import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer
import ru.dbotthepony.mc.otm.menu.data.ImpreciseFractionDataContainer
class MenuEnergyCounter @JvmOverloads constructor( class MenuEnergyCounter @JvmOverloads constructor(
p_38852_: Int, p_38852_: Int,
inventory: Inventory, inventory: Inventory,
tile: BlockEntityEnergyCounter? = null tile: BlockEntityEnergyCounter? = null
) : MatteryMenu(Registry.Menus.ENERGY_COUNTER, p_38852_, inventory, tile) { ) : MatteryMenu(Registry.Menus.ENERGY_COUNTER, p_38852_, inventory, tile) {
@JvmField val passed = FractionDataContainer() @JvmField val passed = ImpreciseFractionDataContainer()
@JvmField val average = FractionDataContainer() @JvmField val average = ImpreciseFractionDataContainer()
@JvmField val last20Ticks = FractionDataContainer() @JvmField val last20Ticks = ImpreciseFractionDataContainer()
@JvmField val lastTick = FractionDataContainer() @JvmField val lastTick = ImpreciseFractionDataContainer()
// TODO: Graph and proper networking for it // TODO: Graph and proper networking for it
private var ticksPassed = 0 private var ticksPassed = 0

View File

@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.Registry import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCapacitorBank import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCapacitorBank
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
@ -26,9 +27,9 @@ class MenuMatterCapacitor @JvmOverloads constructor(
} else { } else {
matterGauge = LevelGaugeWidget(this, tile) matterGauge = LevelGaugeWidget(this, tile)
totalMatterGauge = LevelGaugeWidget(this, { totalMatterGauge = LevelGaugeWidget(this, {
(tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getMatterStorageLevel() ?: Fraction.ZERO (tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getMatterStorageLevel() ?: ImpreciseFraction.ZERO
}, { }, {
(tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getMatterStorageMaxLevel() ?: Fraction.ZERO (tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getMatterStorageMaxLevel() ?: ImpreciseFraction.ZERO
}) })
} }

View File

@ -9,6 +9,7 @@ import net.minecraft.world.SimpleContainer
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.Registry import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.matter.MatterRegistry import ru.dbotthepony.mc.otm.matter.MatterRegistry
import java.math.BigInteger import java.math.BigInteger
@ -37,8 +38,8 @@ class MenuMatterScanner @JvmOverloads constructor(
if (tile != null) { if (tile != null) {
progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }, tile::isUnableToProcess) progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }, tile::isUnableToProcess)
patterns = LevelGaugeWidget(this, patterns = LevelGaugeWidget(this,
{ Fraction(tile.getAsMatterGraph()?.getPatternCount()?.toBigInteger() ?: BigInteger.ZERO) }, { ImpreciseFraction(tile.getAsMatterGraph()?.getPatternCount()?.toBigInteger() ?: BigInteger.ZERO) },
{ Fraction(tile.getAsMatterGraph()?.getPatternCapacity()?.toBigInteger() ?: BigInteger.ZERO) }) { ImpreciseFraction(tile.getAsMatterGraph()?.getPatternCapacity()?.toBigInteger() ?: BigInteger.ZERO) })
} else { } else {
progress = ProgressGaugeWidget(this) progress = ProgressGaugeWidget(this)
patterns = LevelGaugeWidget(this) patterns = LevelGaugeWidget(this)

View File

@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.Registry import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.entity.BlockEntityPatternStorage import ru.dbotthepony.mc.otm.block.entity.BlockEntityPatternStorage
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
@ -26,9 +27,9 @@ class MenuPatternStorage @JvmOverloads constructor(
} else { } else {
stored_this = LevelGaugeWidget(this, tile) stored_this = LevelGaugeWidget(this, tile)
stored_grid = LevelGaugeWidget(this, { stored_grid = LevelGaugeWidget(this, {
Fraction((tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getPatternCount() ?: 0) ImpreciseFraction((tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getPatternCount() ?: 0)
}, { }, {
Fraction((tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getPatternCapacity() ?: 0) ImpreciseFraction((tile.getAsMatterNode().graph as MatterNetworkGraph?)?.getPatternCapacity() ?: 0)
}) })
} }

View File

@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.menu.data
import net.minecraft.world.inventory.ContainerData import net.minecraft.world.inventory.ContainerData
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.network.NetworkHelper import ru.dbotthepony.mc.otm.network.NetworkHelper
import java.util.zip.CRC32 import java.util.zip.CRC32
@ -47,6 +48,7 @@ class FractionDataContainer : ContainerData {
set(value) { set(value) {
_value = value _value = value
val _value = _value
if (_value == null) { if (_value == null) {
buffer.fill(0) buffer.fill(0)
return return
@ -54,7 +56,95 @@ class FractionDataContainer : ContainerData {
try { try {
val bytes = ByteArray(128) {0} val bytes = ByteArray(128) {0}
_value!!.toByteArray().copyInto(bytes) _value.toByteArray().copyInto(bytes)
val crc = CRC32()
crc.update(bytes)
val crcValue = crc.value
val a = (crcValue and 0xFFFF).toShort()
val b = ((crcValue and 0xFFFF0000) ushr 16).toShort()
buffer[0] = a
buffer[1] = b
NetworkHelper.bytesToShorts(bytes).copyInto(buffer, destinationOffset = 2)
} catch(err: Throwable) {
if (!mute) {
LOGGER.error("Unable to serialize value $value for network transportation", err)
mute = true
}
buffer.fill(0)
}
}
val buffer = ShortArray(NETWORK_PAYLOAD_SIZE)
override operator fun get(p_39284_: Int): Int {
return buffer[p_39284_].toInt()
}
override operator fun set(p_39285_: Int, p_39286_: Int) {
buffer[p_39285_] = p_39286_.toShort()
if (_value != null) _value2 = _value
_value = null
}
override fun getCount(): Int {
return buffer.size
}
}
class ImpreciseFractionDataContainer : ContainerData {
companion object {
// CRC32 + Данные
const val NETWORK_PAYLOAD_SIZE = 64 + 2
private val LOGGER = LogManager.getLogger()
}
private var _value: ImpreciseFraction? = ImpreciseFraction.ZERO
private var _value2: ImpreciseFraction? = ImpreciseFraction.ZERO
fun hasComputedValue(): Boolean {
return _value != null
}
private var mute = false
var value: ImpreciseFraction
get() {
if (_value != null)
return _value!!
val bytes = NetworkHelper.shortsToBytes(buffer, 2)
val crc = CRC32()
crc.update(bytes)
val crcValue = crc.value
val a = (crcValue and 0xFFFF).toShort()
val b = ((crcValue and 0xFFFF0000) ushr 16).toShort()
if (a == buffer[0] && b == buffer[1]) {
_value = ImpreciseFraction.fromByteArray(bytes)
} else {
_value = _value2
}
return _value!!
}
set(value) {
_value = value
val _value = _value
if (_value == null) {
buffer.fill(0)
return
}
try {
val bytes = ByteArray(128) {0}
_value.toByteArray().copyInto(bytes)
val crc = CRC32() val crc = CRC32()
crc.update(bytes) crc.update(bytes)

View File

@ -8,7 +8,7 @@ import net.minecraft.world.inventory.ClickAction
import net.minecraft.world.inventory.ClickType import net.minecraft.world.inventory.ClickType
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraftforge.network.PacketDistributor import net.minecraftforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.MatteryNetworking
import ru.dbotthepony.mc.otm.network.SetCarriedPacket import ru.dbotthepony.mc.otm.network.SetCarriedPacket
@ -78,7 +78,7 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
} }
override fun addObject(stack: ItemStackWrapper, id: UUID, provider: IStorageView<ItemStackWrapper>) = addObject(stack.stack, id) override fun addObject(stack: ItemStackWrapper, id: UUID, provider: IStorageView<ItemStackWrapper>) = addObject(stack.stack, id)
override fun changeObject(id: UUID, newCount: Fraction) = changeObject(id, newCount.toInt()) override fun changeObject(id: UUID, newCount: ImpreciseFraction) = changeObject(id, newCount.toInt())
protected fun network(fn: () -> Any) { protected fun network(fn: () -> Any) {
if (!remote) { if (!remote) {

View File

@ -4,16 +4,18 @@ import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer
import ru.dbotthepony.mc.otm.menu.data.ImpreciseFractionDataContainer
@Suppress("unused") @Suppress("unused")
class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) { class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) {
@JvmField var level = {Fraction.ONE} @JvmField var level = { ImpreciseFraction.ONE}
@JvmField var maxLevel = {Fraction.ONE} @JvmField var maxLevel = {ImpreciseFraction.ONE}
@JvmField val levelContainer = FractionDataContainer() @JvmField val levelContainer = ImpreciseFractionDataContainer()
@JvmField val maxLevelContainer = FractionDataContainer() @JvmField val maxLevelContainer = ImpreciseFractionDataContainer()
constructor( constructor(
menu: MatteryMenu, menu: MatteryMenu,
@ -41,14 +43,14 @@ class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) {
) : this(menu) { ) : this(menu) {
if (patterns == null) return if (patterns == null) return
this.level = {Fraction(patterns.stored)} this.level = {ImpreciseFraction(patterns.stored)}
this.maxLevel = {Fraction(patterns.capacity)} this.maxLevel = {ImpreciseFraction(patterns.capacity)}
} }
constructor( constructor(
menu: MatteryMenu, menu: MatteryMenu,
level: () -> Fraction, level: () -> ImpreciseFraction,
maxLevel: () -> Fraction, maxLevel: () -> ImpreciseFraction,
) : this(menu) { ) : this(menu) {
this.level = level this.level = level
this.maxLevel = maxLevel this.maxLevel = maxLevel
@ -64,7 +66,7 @@ class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) {
maxLevelContainer.value = maxLevel.invoke() maxLevelContainer.value = maxLevel.invoke()
} }
fun level(): Fraction = levelContainer.value fun level(): ImpreciseFraction = levelContainer.value
fun maxLevel(): Fraction = maxLevelContainer.value fun maxLevel(): ImpreciseFraction = maxLevelContainer.value
fun percentage(): Float = levelContainer.value.percentage(maxLevelContainer.value) fun percentage(): Float = levelContainer.value.percentage(maxLevelContainer.value)
} }

View File

@ -1,19 +1,19 @@
package ru.dbotthepony.mc.otm.storage package ru.dbotthepony.mc.otm.storage
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import java.util.* import java.util.*
interface IStorageStack { interface IStorageStack {
fun copy(): IStorageStack fun copy(): IStorageStack
var count: Fraction var count: ImpreciseFraction
fun isEmpty(): Boolean fun isEmpty(): Boolean
/** /**
* @return max stack size for this stack object * @return max stack size for this stack object
* [Optional.empty()] if unlimited (default) * [Optional.empty()] if unlimited (default)
*/ */
fun getMaxStackSize(): Optional<Fraction> = Optional.empty() fun getMaxStackSize(): Optional<ImpreciseFraction> = Optional.empty()
/** /**
* Returns Identity utilized to partition view table (if it has any). * Returns Identity utilized to partition view table (if it has any).
@ -38,11 +38,11 @@ interface IStorageStack {
*/ */
fun sameItem(other: IStorageStack): Boolean fun sameItem(other: IStorageStack): Boolean
fun grow(amount: Fraction) { fun grow(amount: ImpreciseFraction) {
count += amount count += amount
} }
fun shrink(amount: Fraction) { fun shrink(amount: ImpreciseFraction) {
count -= amount count -= amount
} }
} }
@ -83,9 +83,9 @@ interface IStorageView<T : IStorageStack> : IStorageTrigger<T> {
* @param simulate whenever to simulate the action or not * @param simulate whenever to simulate the action or not
* @return copy of object, with amount of units actually extracted * @return copy of object, with amount of units actually extracted
*/ */
fun extractStack(id: UUID, amount: Fraction, simulate: Boolean): T fun extractStack(id: UUID, amount: ImpreciseFraction, simulate: Boolean): T
fun extractStack(id: UUID, amount: Int, simulate: Boolean): T = extractStack(id, Fraction(amount), simulate) fun extractStack(id: UUID, amount: Int, simulate: Boolean): T = extractStack(id, ImpreciseFraction(amount), simulate)
fun extractStack(id: UUID, amount: Long, simulate: Boolean): T = extractStack(id, Fraction(amount), simulate) fun extractStack(id: UUID, amount: Long, simulate: Boolean): T = extractStack(id, ImpreciseFraction(amount), simulate)
/** /**
* Designed for views, for extraction with less computation overhead caused by * Designed for views, for extraction with less computation overhead caused by
@ -96,12 +96,12 @@ interface IStorageView<T : IStorageStack> : IStorageTrigger<T> {
* @param simulate whenever to simulate the action or not * @param simulate whenever to simulate the action or not
* @return amount extracted * @return amount extracted
*/ */
fun extractStackCount(id: UUID, amount: Fraction, simulate: Boolean): Fraction { fun extractStackCount(id: UUID, amount: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return extractStack(id, amount, simulate).count return extractStack(id, amount, simulate).count
} }
fun extractStackCount(id: UUID, amount: Int, simulate: Boolean): Fraction = extractStackCount(id, Fraction(amount), simulate) fun extractStackCount(id: UUID, amount: Int, simulate: Boolean): ImpreciseFraction = extractStackCount(id, ImpreciseFraction(amount), simulate)
fun extractStackCount(id: UUID, amount: Long, simulate: Boolean): Fraction = extractStackCount(id, Fraction(amount), simulate) fun extractStackCount(id: UUID, amount: Long, simulate: Boolean): ImpreciseFraction = extractStackCount(id, ImpreciseFraction(amount), simulate)
fun getStacks(): Collection<IStorageTuple<T>> fun getStacks(): Collection<IStorageTuple<T>>
@ -139,7 +139,7 @@ interface IStorageListener<T : IStorageStack> {
/** /**
* Fired on whenever an object is changes on listener we subscribed to * Fired on whenever an object is changes on listener we subscribed to
*/ */
fun changeObject(id: UUID, newCount: Fraction) fun changeObject(id: UUID, newCount: ImpreciseFraction)
/** /**
* Fired on whenever an object is removed from listener we subscribed to * Fired on whenever an object is removed from listener we subscribed to

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.storage
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import java.util.* import java.util.*
@JvmRecord @JvmRecord
@ -14,14 +15,14 @@ data class ItemStackWrapper(val stack: ItemStack) : IStorageStack {
stack.count = Math.max(value, 0) stack.count = Math.max(value, 0)
} }
override var count: Fraction override var count: ImpreciseFraction
get() = Fraction(stack.count) get() = ImpreciseFraction(stack.count)
set(value) = setCount(value.toInt()) set(value) = setCount(value.toInt())
fun getCountInt() = stack.count fun getCountInt() = stack.count
override fun getMaxStackSize(): Optional<Fraction> { override fun getMaxStackSize(): Optional<ImpreciseFraction> {
return Optional.of(Fraction(stack.maxStackSize)) return Optional.of(ImpreciseFraction(stack.maxStackSize))
} }
override fun isEmpty(): Boolean = stack.isEmpty override fun isEmpty(): Boolean = stack.isEmpty

View File

@ -2,14 +2,15 @@ package ru.dbotthepony.mc.otm.storage
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import java.util.* import java.util.*
class RemoteTuple<T : IStorageStack>(val obj: T, val remote_id: UUID, val provider: IStorageView<T>, val local: LocalTuple<T>) { class RemoteTuple<T : IStorageStack>(val obj: T, val remote_id: UUID, val provider: IStorageView<T>, val local: LocalTuple<T>) {
fun extract(amount: Fraction, simulate: Boolean): T { fun extract(amount: ImpreciseFraction, simulate: Boolean): T {
return provider.extractStack(remote_id, amount, simulate) return provider.extractStack(remote_id, amount, simulate)
} }
fun extractCount(amount: Fraction, simulate: Boolean): Fraction { fun extractCount(amount: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
return provider.extractStackCount(remote_id, amount, simulate) return provider.extractStackCount(remote_id, amount, simulate)
} }
@ -145,8 +146,8 @@ open class VirtualComponent<T : IStorageStack>(identity: Class<T>) : IStorageCom
} }
} }
override fun changeObject(id: UUID, newCount: Fraction) { override fun changeObject(id: UUID, newCount: ImpreciseFraction) {
assert(newCount > Fraction.ZERO) assert(newCount > ImpreciseFraction.ZERO)
val tuple = remoteByUUID[id] ?: throw IllegalStateException("No such tuple with id $id") val tuple = remoteByUUID[id] ?: throw IllegalStateException("No such tuple with id $id")
val diff = newCount - tuple.obj.count val diff = newCount - tuple.obj.count
@ -167,7 +168,7 @@ open class VirtualComponent<T : IStorageStack>(identity: Class<T>) : IStorageCom
remoteByUUID.remove(id) remoteByUUID.remove(id)
val a = tuple.local.stack.count <= Fraction.ZERO val a = tuple.local.stack.count <= ImpreciseFraction.ZERO
val b = tuple.local.tuples.size == 0 val b = tuple.local.tuples.size == 0
if (a || b) { if (a || b) {
@ -195,21 +196,21 @@ open class VirtualComponent<T : IStorageStack>(identity: Class<T>) : IStorageCom
return leftover return leftover
} }
override fun extractStack(id: UUID, amount: Fraction, simulate: Boolean): T { override fun extractStack(id: UUID, amount: ImpreciseFraction, simulate: Boolean): T {
if (amount.isZero()) if (amount.isZero)
return identity.empty return identity.empty
var amount = amount var amount = amount
val tuple: LocalTuple<T>? = localByUUID[id] val tuple: LocalTuple<T>? = localByUUID[id]
if (tuple == null || amount.isZero()) if (tuple == null || amount.isZero)
return identity.empty return identity.empty
if (amount <= Fraction.MINUS_ONE) if (amount <= ImpreciseFraction.MINUS_ONE)
amount = tuple.stack.getMaxStackSize().orElse(tuple.stack.count) amount = tuple.stack.getMaxStackSize().orElse(tuple.stack.count)
val toExtract = tuple.stack.count.min(amount) val toExtract = tuple.stack.count.min(amount)
var extracted = Fraction.ZERO var extracted = ImpreciseFraction.ZERO
val copy = tuple.stack.copy() as T val copy = tuple.stack.copy() as T
for (remote_tuple in tuple.tuples) { for (remote_tuple in tuple.tuples) {
@ -219,7 +220,7 @@ open class VirtualComponent<T : IStorageStack>(identity: Class<T>) : IStorageCom
break break
} }
if (extracted > Fraction.ZERO) { if (extracted > ImpreciseFraction.ZERO) {
copy.count = extracted copy.count = extracted
return copy return copy
} }
@ -235,11 +236,11 @@ open class PoweredVirtualComponent<T : IStorageStack>(identity: Class<T>, @JvmFi
} }
override fun insertStack(stack: T, simulate: Boolean): T { override fun insertStack(stack: T, simulate: Boolean): T {
val required = stack.count * identity.energyPerOperation val required = identity.energyPerOperation * stack.count
val energy = energyProvider() val energy = energyProvider()
val extracted = energy.extractEnergyInner(required, true) val extracted = energy.extractEnergyInner(required, true)
if (extracted.isZero()) { if (extracted.isZero) {
return stack.copy() as T return stack.copy() as T
} }
@ -255,7 +256,7 @@ open class PoweredVirtualComponent<T : IStorageStack>(identity: Class<T>, @JvmFi
} }
if (!simulate) { if (!simulate) {
val requiredNew = (stack.count - leftover.count) * identity.energyPerOperation val requiredNew = identity.energyPerOperation * stack.count - leftover.count
energy.extractEnergyInner(requiredNew, false) energy.extractEnergyInner(requiredNew, false)
} }
@ -266,7 +267,7 @@ open class PoweredVirtualComponent<T : IStorageStack>(identity: Class<T>, @JvmFi
val oldCount = stack.count val oldCount = stack.count
stack.count = extracted / identity.energyPerOperation stack.count = extracted / identity.energyPerOperation
val diff = oldCount - stack.count val diff = oldCount - stack.count
val newRequired = stack.count * identity.energyPerOperation val newRequired = identity.energyPerOperation * stack.count
val newExtracted = energy.extractEnergyInner(newRequired, true) val newExtracted = energy.extractEnergyInner(newRequired, true)
if (newExtracted == newRequired) { if (newExtracted == newRequired) {
@ -293,12 +294,12 @@ open class PoweredVirtualComponent<T : IStorageStack>(identity: Class<T>, @JvmFi
return stack return stack
} }
override fun extractStack(id: UUID, amount: Fraction, simulate: Boolean): T { override fun extractStack(id: UUID, amount: ImpreciseFraction, simulate: Boolean): T {
val required = amount * identity.energyPerOperation val required = identity.energyPerOperation * amount
val energy = energyProvider() val energy = energyProvider()
val extracted = energy.extractEnergyInner(required, true) val extracted = energy.extractEnergyInner(required, true)
if (extracted.isZero()) { if (extracted.isZero) {
return identity.empty return identity.empty
} }

View File

@ -37,7 +37,7 @@ object ImpreciseFractionTests {
@DisplayName("ImpreciseFraction store/load") @DisplayName("ImpreciseFraction store/load")
fun storeLoad() { fun storeLoad() {
val f = ImpreciseFraction(4, 0.28) val f = ImpreciseFraction(4, 0.28)
val loaded = ImpreciseFraction.fromBytesArray(f.toBytesArray()) val loaded = ImpreciseFraction.fromByteArray(f.toByteArray())
check(f == loaded) { "$f != $loaded" } check(f == loaded) { "$f != $loaded" }
} }
} }