diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index 4e7a782e6..d6fed7fa2 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -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.TritaniumArmorModel; 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.matter.MatterRegistry; import ru.dbotthepony.mc.otm.network.MatteryNetworking; @@ -171,7 +172,7 @@ public class OverdriveThatMatters { 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(); GravitationStabilizerModel.register(); diff --git a/src/main/java/ru/dbotthepony/mc/otm/Registry.java b/src/main/java/ru/dbotthepony/mc/otm/Registry.java index 7e5e4bab9..63a9eace1 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/Registry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/Registry.java @@ -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.SkinElement; 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.menu.*; 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 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_BASIC = new ItemBattery(new Fraction(60_000), new Fraction(300), new Fraction(300)); - public static final ItemBattery BATTERY_NORMAL = new ItemBattery(new Fraction(250_000), new Fraction(1000), new Fraction(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_CAPACITOR = new ItemBattery(new Fraction(150_000), new Fraction(15000), new Fraction(15000)); + 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 ImpreciseFraction(60_000), new ImpreciseFraction(300), new ImpreciseFraction(300)); + 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 ImpreciseFraction(1_000_000), new ImpreciseFraction(2000), new ImpreciseFraction(2000)); + 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[] BATTERIES = { @@ -705,9 +706,9 @@ public class Registry { MATTER_TRANSFORM_MATRIX, }; - public static final ItemMatterCapacitor MATTER_CAPACITOR_BASIC = new ItemMatterCapacitor(new Fraction("4")); - public static final ItemMatterCapacitor MATTER_CAPACITOR_NORMAL = new ItemMatterCapacitor(new Fraction("10")); - public static final ItemMatterCapacitor MATTER_CAPACITOR_DENSE = new ItemMatterCapacitor(new Fraction("40")); + public static final ItemMatterCapacitor MATTER_CAPACITOR_BASIC = new ItemMatterCapacitor(new ImpreciseFraction("4")); + public static final ItemMatterCapacitor MATTER_CAPACITOR_NORMAL = new ItemMatterCapacitor(new ImpreciseFraction("10")); + public static final ItemMatterCapacitor MATTER_CAPACITOR_DENSE = new ItemMatterCapacitor(new ImpreciseFraction("40")); public static final ItemMatterCapacitor MATTER_CAPACITOR_CREATIVE = new ItemMatterCapacitor(); public static final ItemPatternStorage PATTERN_DRIVE_NORMAL = new ItemPatternStorage(4); diff --git a/src/main/java/ru/dbotthepony/mc/otm/android/feature/AndroidNanobotsArmor.java b/src/main/java/ru/dbotthepony/mc/otm/android/feature/AndroidNanobotsArmor.java index c4fcbd88a..ab47835b8 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/android/feature/AndroidNanobotsArmor.java +++ b/src/main/java/ru/dbotthepony/mc/otm/android/feature/AndroidNanobotsArmor.java @@ -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.MatteryCapability; import ru.dbotthepony.mc.otm.core.Fraction; +import ru.dbotthepony.mc.otm.core.ImpreciseFraction; import java.math.BigDecimal; @@ -39,8 +40,8 @@ public class AndroidNanobotsArmor extends AndroidFeature { protected int ticks_passed = 0; protected int layers = 0; - protected static final Fraction ENERGY_PER_BUILT = new Fraction(200); - protected static final Fraction ENERGY_PER_HITPOINT = new Fraction(500); + protected static final ImpreciseFraction ENERGY_PER_BUILT = new ImpreciseFraction(200); + protected static final ImpreciseFraction ENERGY_PER_HITPOINT = new ImpreciseFraction(500); public static final int[] TICKS = new int[] { 80, // 4 seconds to build a layer diff --git a/src/main/java/ru/dbotthepony/mc/otm/android/feature/AndroidNanobotsRegeneration.java b/src/main/java/ru/dbotthepony/mc/otm/android/feature/AndroidNanobotsRegeneration.java index c7db98957..01ba93927 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/android/feature/AndroidNanobotsRegeneration.java +++ b/src/main/java/ru/dbotthepony/mc/otm/android/feature/AndroidNanobotsRegeneration.java @@ -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.MatteryCapability; import ru.dbotthepony.mc.otm.core.Fraction; +import ru.dbotthepony.mc.otm.core.ImpreciseFraction; import java.math.BigDecimal; @@ -20,7 +21,7 @@ public class AndroidNanobotsRegeneration extends AndroidFeature { protected int ticks_passed = 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[] { 100, // 5 seconds @@ -42,7 +43,7 @@ public class AndroidNanobotsRegeneration extends AndroidFeature { var missing = Math.min(1, ent.getMaxHealth() - ent.getHealth()); 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); var heal = missing * extract.div(ENERGY_PER_HITPOINT).toFloat(); ent.heal(heal); diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/MachineJob.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/MachineJob.java index 67be2b48a..149cd6b2a 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/MachineJob.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/MachineJob.java @@ -6,19 +6,20 @@ import net.minecraft.nbt.DoubleTag; import net.minecraft.nbt.Tag; import net.minecraft.world.item.ItemStack; import ru.dbotthepony.mc.otm.core.Fraction; +import ru.dbotthepony.mc.otm.core.ImpreciseFraction; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -public record MachineJob(ItemStack stack, double ticks, Fraction power, CompoundTag data) { - public MachineJob(ItemStack stack, double ticks, Fraction power) { +public record MachineJob(ItemStack stack, double ticks, ImpreciseFraction power, CompoundTag data) { + public MachineJob(ItemStack stack, double ticks, ImpreciseFraction power) { this(stack, ticks, power, new CompoundTag()); } public MachineJob(ItemStack stack, double ticks) { - this(stack, ticks, Fraction.ZERO); + this(stack, ticks, ImpreciseFraction.ZERO); } public CompoundTag serializeNBT() { @@ -42,7 +43,7 @@ public record MachineJob(ItemStack stack, double ticks, Fraction power, Compound ItemStack stack = ItemStack.of(stack_tag); 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")); } } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/WorkTickContext.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/WorkTickContext.java index 55cb029df..30524cc95 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/WorkTickContext.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/WorkTickContext.java @@ -2,11 +2,12 @@ package ru.dbotthepony.mc.otm.block.entity.worker; import net.minecraft.MethodsReturnNonnullByDefault; import ru.dbotthepony.mc.otm.core.Fraction; +import ru.dbotthepony.mc.otm.core.ImpreciseFraction; import javax.annotation.ParametersAreNonnullByDefault; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -public record WorkTickContext(MachineJob job, Fraction requiredPower, Fraction extractedPower, Fraction workSpeed) { +public record WorkTickContext(MachineJob job, ImpreciseFraction requiredPower, ImpreciseFraction extractedPower, ImpreciseFraction workSpeed) { } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java index ee58d1b4f..e567e8d9c 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java @@ -35,26 +35,4 @@ public class MatteryCapability { event.register(IStorageGraphNode.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)); - } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/matter/IMatterHandler.java b/src/main/java/ru/dbotthepony/mc/otm/capability/matter/IMatterHandler.java index e4a2cd68a..359f8ed32 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/matter/IMatterHandler.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/matter/IMatterHandler.java @@ -1,11 +1,9 @@ package ru.dbotthepony.mc.otm.capability.matter; 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 java.math.BigDecimal; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault @@ -16,18 +14,18 @@ public interface IMatterHandler { BIDIRECTIONAL // storage } - Fraction getStoredMatter(); - Fraction getMaxStoredMatter(); + ImpreciseFraction getStoredMatter(); + ImpreciseFraction getMaxStoredMatter(); - Fraction receiveMatterOuter(Fraction howMuch, boolean simulate); - Fraction receiveMatterInner(Fraction howMuch, boolean simulate); + ImpreciseFraction receiveMatterOuter(ImpreciseFraction howMuch, boolean simulate); + ImpreciseFraction receiveMatterInner(ImpreciseFraction howMuch, boolean simulate); - Fraction extractMatterOuter(Fraction howMuch, boolean simulate); - Fraction extractMatterInner(Fraction howMuch, boolean simulate); + ImpreciseFraction extractMatterOuter(ImpreciseFraction howMuch, boolean simulate); + ImpreciseFraction extractMatterInner(ImpreciseFraction howMuch, boolean simulate); MatterDirection getDirection(); - default Fraction getMissingMatter() { + default ImpreciseFraction getMissingMatter() { return getMaxStoredMatter().minus(getStoredMatter()); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterHandlerCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterHandlerCapability.java index 3d994615c..8c2c5d51c 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterHandlerCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterHandlerCapability.java @@ -4,30 +4,28 @@ import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.nbt.CompoundTag; import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.LazyOptional; -import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; 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.Nullable; import javax.annotation.ParametersAreNonnullByDefault; -import java.math.BigDecimal; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault public class MatterHandlerCapability implements IMatterHandler, INBTSerializable { protected final Runnable listener; - protected Fraction stored = Fraction.ZERO; + protected ImpreciseFraction stored = ImpreciseFraction.ZERO; protected MatterDirection direction; - protected Fraction max_storage; + protected ImpreciseFraction max_storage; - protected Fraction max_receive; - protected Fraction max_extract; + protected ImpreciseFraction max_receive; + protected ImpreciseFraction max_extract; public MatterHandlerCapability( @Nullable Runnable listener, MatterDirection direction, - Fraction max_storage + ImpreciseFraction max_storage ) { this.listener = listener; this.direction = direction; @@ -37,9 +35,9 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable public MatterHandlerCapability( @Nullable Runnable listener, MatterDirection direction, - Fraction max_storage, - Fraction max_receive, - Fraction max_extract + ImpreciseFraction max_storage, + ImpreciseFraction max_receive, + ImpreciseFraction max_extract ) { this(listener, direction, max_storage); @@ -63,33 +61,33 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable @Nonnull @Override - public Fraction getStoredMatter() { + public ImpreciseFraction getStoredMatter() { return stored; } @Nonnull @Override - public Fraction getMaxStoredMatter() { + public ImpreciseFraction getMaxStoredMatter() { 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; } @Nonnull @Override - public Fraction receiveMatterOuter(Fraction howMuch, boolean simulate) { + public ImpreciseFraction receiveMatterOuter(ImpreciseFraction howMuch, boolean simulate) { if (getDirection() == MatterDirection.EXTRACT) - return Fraction.ZERO; + return ImpreciseFraction.ZERO; return receiveMatterInner(howMuch, simulate); } @Nonnull @Override - public Fraction receiveMatterInner(Fraction howMuch, boolean simulate) { - Fraction new_matter; + public ImpreciseFraction receiveMatterInner(ImpreciseFraction howMuch, boolean simulate) { + ImpreciseFraction new_matter; if (max_receive == null) { 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); } - Fraction diff = new_matter.minus(stored); + ImpreciseFraction diff = new_matter.minus(stored); if (!simulate && new_matter.compareTo(stored) != 0) { stored = new_matter; @@ -112,17 +110,17 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable @Nonnull @Override - public Fraction extractMatterOuter(Fraction howMuch, boolean simulate) { + public ImpreciseFraction extractMatterOuter(ImpreciseFraction howMuch, boolean simulate) { if (getDirection() == MatterDirection.RECEIVE) - return Fraction.ZERO; + return ImpreciseFraction.ZERO; return extractMatterInner(howMuch, simulate); } @Nonnull @Override - public Fraction extractMatterInner(Fraction howMuch, boolean simulate) { - Fraction new_matter; + public ImpreciseFraction extractMatterInner(ImpreciseFraction howMuch, boolean simulate) { + ImpreciseFraction new_matter; if (max_receive == null) { 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(); } - Fraction diff = stored.minus(new_matter); + ImpreciseFraction diff = stored.minus(new_matter); if (!simulate && new_matter.compareTo(stored) != 0) { stored = new_matter; @@ -167,18 +165,18 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable @Override public void deserializeNBT(CompoundTag tag) { if (tag.contains("stored")) - stored = Fraction.deserializeNBT(tag.get("stored")); + stored = ImpreciseFraction.deserializeNBT(tag.get("stored")); 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")) - max_receive = Fraction.deserializeNBT(tag.get("max_receive")); + max_receive = ImpreciseFraction.deserializeNBT(tag.get("max_receive")); else max_receive = null; if (tag.contains("max_extract")) - max_extract = Fraction.deserializeNBT(tag.get("max_extract")); + max_extract = ImpreciseFraction.deserializeNBT(tag.get("max_extract")); else max_extract = null; } diff --git a/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java b/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java index 86a5b839d..846c8a47f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java +++ b/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java @@ -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.MatteryCapability; import ru.dbotthepony.mc.otm.core.Fraction; +import ru.dbotthepony.mc.otm.core.ImpreciseFraction; import java.util.Optional; import java.util.Random; @@ -160,7 +161,7 @@ public class AndroidGui { float level; - if (android.getMaxBatteryLevel().compareTo(Fraction.ZERO) == 0) { + if (android.getMaxBatteryLevel().isZero()) { level = 0f; } else { level = android.getBatteryLevel().div(android.getMaxBatteryLevel()).toFloat(); diff --git a/src/main/java/ru/dbotthepony/mc/otm/matter/MatterRegistry.java b/src/main/java/ru/dbotthepony/mc/otm/matter/MatterRegistry.java index 58bf2b752..0baf42759 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/matter/MatterRegistry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/matter/MatterRegistry.java @@ -20,6 +20,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive; 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.network.MatterRegistryPacket; import ru.dbotthepony.mc.otm.network.MatteryNetworking; @@ -30,11 +31,11 @@ import java.math.MathContext; import java.util.*; public class MatterRegistry { - public static final Map INITIAL_ITEMS = new HashMap<>(); - public static final Map ITEMS = new HashMap<>(); + public static final Map INITIAL_ITEMS = new HashMap<>(); + public static final Map ITEMS = new HashMap<>(); - public static Fraction getMatterValue(Item item) { - return ITEMS.getOrDefault(item, INITIAL_ITEMS.getOrDefault(item, Fraction.ZERO)); + public static ImpreciseFraction getMatterValue(Item item) { + return ITEMS.getOrDefault(item, INITIAL_ITEMS.getOrDefault(item, ImpreciseFraction.ZERO)); } public static boolean hasMatterValue(Item item) { @@ -49,25 +50,25 @@ public class MatterRegistry { } 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; - 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 hasMatterValue(stack.getItem()); } - private static Fraction getMatterValue(ItemStack stack, int level) { + private static ImpreciseFraction getMatterValue(ItemStack stack, int level) { if (level >= 100) { - return Fraction.ZERO; + return ImpreciseFraction.ZERO; } Item item = stack.getItem(); var matter = getMatterValue(item); 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(); @@ -86,104 +87,104 @@ public class MatterRegistry { return matter; } - public static Fraction getMatterValue(ItemStack stack) { + public static ImpreciseFraction getMatterValue(ItemStack stack) { return getMatterValue(stack, 0); } public static void registerInitialItems() { // basic things - INITIAL_ITEMS.put(Items.DIRT, new Fraction("0.0013")); - INITIAL_ITEMS.put(Items.DIRT_PATH, new Fraction("0.0013")); - INITIAL_ITEMS.put(Items.GRASS_BLOCK, new Fraction("0.0016")); + INITIAL_ITEMS.put(Items.DIRT, new ImpreciseFraction("0.0013")); + INITIAL_ITEMS.put(Items.DIRT_PATH, new ImpreciseFraction("0.0013")); + 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.COBBLESTONE, new Fraction("0.001")); - INITIAL_ITEMS.put(Items.MOSSY_COBBLESTONE, new Fraction("0.001")); - INITIAL_ITEMS.put(Items.NETHERRACK, new Fraction("0.00027")); - INITIAL_ITEMS.put(Items.GRANITE, new Fraction("0.0011")); - INITIAL_ITEMS.put(Items.DIORITE, new Fraction("0.0013")); - INITIAL_ITEMS.put(Items.ANDESITE, new Fraction("0.0012")); - INITIAL_ITEMS.put(Items.BASALT, new Fraction("0.0013")); + INITIAL_ITEMS.put(Items.STONE, new ImpreciseFraction("0.001")); + INITIAL_ITEMS.put(Items.COBBLESTONE, new ImpreciseFraction("0.001")); + INITIAL_ITEMS.put(Items.MOSSY_COBBLESTONE, new ImpreciseFraction("0.001")); + INITIAL_ITEMS.put(Items.NETHERRACK, new ImpreciseFraction("0.00027")); + INITIAL_ITEMS.put(Items.GRANITE, new ImpreciseFraction("0.0011")); + INITIAL_ITEMS.put(Items.DIORITE, new ImpreciseFraction("0.0013")); + INITIAL_ITEMS.put(Items.ANDESITE, new ImpreciseFraction("0.0012")); + INITIAL_ITEMS.put(Items.BASALT, new ImpreciseFraction("0.0013")); - INITIAL_ITEMS.put(Items.SOUL_SAND, new Fraction("0.00087")); - INITIAL_ITEMS.put(Items.SOUL_SOIL, new Fraction("0.00087")); + INITIAL_ITEMS.put(Items.SOUL_SAND, new ImpreciseFraction("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.FLINT, new Fraction("0.001")); + INITIAL_ITEMS.put(Items.GRAVEL, new ImpreciseFraction("0.001")); + INITIAL_ITEMS.put(Items.FLINT, new ImpreciseFraction("0.001")); - INITIAL_ITEMS.put(Items.SAND, new Fraction("0.0005")); - INITIAL_ITEMS.put(Items.RED_SAND, new Fraction("0.0005")); + INITIAL_ITEMS.put(Items.SAND, new ImpreciseFraction("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.DEEPSLATE, new Fraction("0.0014")); - INITIAL_ITEMS.put(Items.COBBLED_DEEPSLATE, new Fraction("0.0014")); + INITIAL_ITEMS.put(Items.TUFF, new ImpreciseFraction("0.0007")); + INITIAL_ITEMS.put(Items.DEEPSLATE, new ImpreciseFraction("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_COBBLESTONE, new Fraction("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_STONE_BRICKS, new Fraction("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_MOSSY_STONE_BRICKS, new Fraction("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_CRACKED_STONE_BRICKS, new Fraction("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_CHISELED_STONE_BRICKS, new Fraction("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_DEEPSLATE, new Fraction("0.067")); + INITIAL_ITEMS.put(Items.INFESTED_STONE, new ImpreciseFraction("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_COBBLESTONE, new ImpreciseFraction("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_STONE_BRICKS, new ImpreciseFraction("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_MOSSY_STONE_BRICKS, new ImpreciseFraction("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_CRACKED_STONE_BRICKS, new ImpreciseFraction("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_CHISELED_STONE_BRICKS, new ImpreciseFraction("0.063")); + INITIAL_ITEMS.put(Items.INFESTED_DEEPSLATE, new ImpreciseFraction("0.067")); // 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 Fraction("0.34")); + // INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new ImpreciseFraction("0.037")); + INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new ImpreciseFraction("0.34")); // 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 - INITIAL_ITEMS.put(Items.COAL, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.LAPIS_LAZULI, new Fraction("0.0042")); - INITIAL_ITEMS.put(Items.REDSTONE, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.CHARCOAL, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.DIAMOND, new Fraction("0.5")); - INITIAL_ITEMS.put(Items.EMERALD, new Fraction("0.46")); - INITIAL_ITEMS.put(Items.IRON_INGOT, new Fraction("0.03")); - INITIAL_ITEMS.put(Items.COPPER_INGOT, new Fraction("0.014")); - INITIAL_ITEMS.put(Items.GOLD_INGOT, new Fraction("0.32")); - INITIAL_ITEMS.put(Items.NETHERITE_SCRAP, new Fraction("1.2")); - INITIAL_ITEMS.put(Items.QUARTZ, new Fraction("0.008")); - INITIAL_ITEMS.put(Items.GLOWSTONE_DUST, new Fraction("0.007")); - INITIAL_ITEMS.put(Items.AMETHYST_SHARD, new Fraction("0.034")); + INITIAL_ITEMS.put(Items.COAL, new ImpreciseFraction("0.005")); + INITIAL_ITEMS.put(Items.LAPIS_LAZULI, new ImpreciseFraction("0.0042")); + INITIAL_ITEMS.put(Items.REDSTONE, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.CHARCOAL, new ImpreciseFraction("0.005")); + INITIAL_ITEMS.put(Items.DIAMOND, new ImpreciseFraction("0.5")); + INITIAL_ITEMS.put(Items.EMERALD, new ImpreciseFraction("0.46")); + INITIAL_ITEMS.put(Items.IRON_INGOT, new ImpreciseFraction("0.03")); + INITIAL_ITEMS.put(Items.COPPER_INGOT, new ImpreciseFraction("0.014")); + INITIAL_ITEMS.put(Items.GOLD_INGOT, new ImpreciseFraction("0.32")); + INITIAL_ITEMS.put(Items.NETHERITE_SCRAP, new ImpreciseFraction("1.2")); + INITIAL_ITEMS.put(Items.QUARTZ, new ImpreciseFraction("0.008")); + INITIAL_ITEMS.put(Items.GLOWSTONE_DUST, new ImpreciseFraction("0.007")); + INITIAL_ITEMS.put(Items.AMETHYST_SHARD, new ImpreciseFraction("0.034")); // 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.SPRUCE_LOG, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.BIRCH_LOG, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.JUNGLE_LOG, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.ACACIA_LOG, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.DARK_OAK_LOG, new Fraction("0.005")); + INITIAL_ITEMS.put(Items.OAK_LOG, new ImpreciseFraction("0.005")); + INITIAL_ITEMS.put(Items.SPRUCE_LOG, new ImpreciseFraction("0.005")); + INITIAL_ITEMS.put(Items.BIRCH_LOG, new ImpreciseFraction("0.005")); + INITIAL_ITEMS.put(Items.JUNGLE_LOG, new ImpreciseFraction("0.005")); + INITIAL_ITEMS.put(Items.ACACIA_LOG, new ImpreciseFraction("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.WARPED_PLANKS, new Fraction("0.003")); + INITIAL_ITEMS.put(Items.CRIMSON_PLANKS, new ImpreciseFraction("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_SPRUCE_LOG, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.STRIPPED_BIRCH_LOG, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.STRIPPED_JUNGLE_LOG, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.STRIPPED_ACACIA_LOG, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.STRIPPED_DARK_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 ImpreciseFraction("0.005")); + INITIAL_ITEMS.put(Items.STRIPPED_BIRCH_LOG, new ImpreciseFraction("0.005")); + INITIAL_ITEMS.put(Items.STRIPPED_JUNGLE_LOG, new ImpreciseFraction("0.005")); + INITIAL_ITEMS.put(Items.STRIPPED_ACACIA_LOG, new ImpreciseFraction("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.PUMPKIN, new Fraction("0.005")); - INITIAL_ITEMS.put(Items.MELON, new Fraction("0.005")); + INITIAL_ITEMS.put(Items.CACTUS, new ImpreciseFraction("0.0039")); + INITIAL_ITEMS.put(Items.PUMPKIN, new ImpreciseFraction("0.005")); + INITIAL_ITEMS.put(Items.MELON, new ImpreciseFraction("0.005")); // 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.POPPY, 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.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.LILAC, big_flower_value); INITIAL_ITEMS.put(Items.ROSE_BUSH, 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.BROWN_MUSHROOM, new Fraction("0.0034")); - INITIAL_ITEMS.put(Items.RED_MUSHROOM, new Fraction("0.0034")); - INITIAL_ITEMS.put(Items.CRIMSON_FUNGUS, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.WARPED_FUNGUS, new Fraction("0.004")); + INITIAL_ITEMS.put(Items.SPORE_BLOSSOM, new ImpreciseFraction("0.0067")); + INITIAL_ITEMS.put(Items.BROWN_MUSHROOM, new ImpreciseFraction("0.0034")); + INITIAL_ITEMS.put(Items.RED_MUSHROOM, new ImpreciseFraction("0.0034")); + INITIAL_ITEMS.put(Items.CRIMSON_FUNGUS, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.WARPED_FUNGUS, new ImpreciseFraction("0.004")); // 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.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.TWISTING_VINES, grass_value); INITIAL_ITEMS.put(Items.HANGING_ROOTS, grass_value); - INITIAL_ITEMS.put(Items.TALL_GRASS, new Fraction("0.0035")); - INITIAL_ITEMS.put(Items.LARGE_FERN, new Fraction("0.0035")); + INITIAL_ITEMS.put(Items.TALL_GRASS, new ImpreciseFraction("0.0035")); + INITIAL_ITEMS.put(Items.LARGE_FERN, new ImpreciseFraction("0.0035")); INITIAL_ITEMS.put(Items.GRASS, grass_value); INITIAL_ITEMS.put(Items.VINE, 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.SEAGRASS, grass_value); INITIAL_ITEMS.put(Items.FERN, grass_value); - INITIAL_ITEMS.put(Items.DEAD_BUSH, new Fraction("0.0017")); - INITIAL_ITEMS.put(Items.GLOW_LICHEN, new Fraction("0.0026")); - INITIAL_ITEMS.put(Items.AZALEA, new Fraction("0.0018")); + INITIAL_ITEMS.put(Items.DEAD_BUSH, new ImpreciseFraction("0.0017")); + INITIAL_ITEMS.put(Items.GLOW_LICHEN, new ImpreciseFraction("0.0026")); + INITIAL_ITEMS.put(Items.AZALEA, new ImpreciseFraction("0.0018")); INITIAL_ITEMS.put(Items.FLOWERING_AZALEA, grass_value); // living plant (not very blocky) things // saplings - INITIAL_ITEMS.put(Items.OAK_SAPLING, new Fraction("0.0035")); - INITIAL_ITEMS.put(Items.SPRUCE_SAPLING, new Fraction("0.0045")); - INITIAL_ITEMS.put(Items.BIRCH_SAPLING, new Fraction("0.0035")); - INITIAL_ITEMS.put(Items.JUNGLE_SAPLING, new Fraction("0.0048")); - INITIAL_ITEMS.put(Items.ACACIA_SAPLING, new Fraction("0.0033")); - INITIAL_ITEMS.put(Items.DARK_OAK_SAPLING, new Fraction("0.005")); + INITIAL_ITEMS.put(Items.OAK_SAPLING, new ImpreciseFraction("0.0035")); + INITIAL_ITEMS.put(Items.SPRUCE_SAPLING, new ImpreciseFraction("0.0045")); + INITIAL_ITEMS.put(Items.BIRCH_SAPLING, new ImpreciseFraction("0.0035")); + INITIAL_ITEMS.put(Items.JUNGLE_SAPLING, new ImpreciseFraction("0.0048")); + INITIAL_ITEMS.put(Items.ACACIA_SAPLING, new ImpreciseFraction("0.0033")); + 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.BEETROOT_SEEDS, new Fraction("0.0007")); - // INITIAL_ITEMS.put(Items.MELON_SEEDS, new Fraction("0.0013")); - INITIAL_ITEMS.put(Items.WHEAT, new Fraction("0.0016")); - INITIAL_ITEMS.put(Items.NETHER_WART, new Fraction("0.0017")); - INITIAL_ITEMS.put(Items.CARROT, new Fraction("0.0019")); - INITIAL_ITEMS.put(Items.POTATO, new Fraction("0.0021")); - INITIAL_ITEMS.put(Items.BEETROOT, new Fraction("0.0021")); - INITIAL_ITEMS.put(Items.MELON_SLICE, new Fraction("0.0008")); + INITIAL_ITEMS.put(Items.WHEAT_SEEDS, new ImpreciseFraction("0.0007")); + INITIAL_ITEMS.put(Items.BEETROOT_SEEDS, new ImpreciseFraction("0.0007")); + // INITIAL_ITEMS.put(Items.MELON_SEEDS, new ImpreciseFraction("0.0013")); + INITIAL_ITEMS.put(Items.WHEAT, new ImpreciseFraction("0.0016")); + INITIAL_ITEMS.put(Items.NETHER_WART, new ImpreciseFraction("0.0017")); + INITIAL_ITEMS.put(Items.CARROT, new ImpreciseFraction("0.0019")); + INITIAL_ITEMS.put(Items.POTATO, new ImpreciseFraction("0.0021")); + INITIAL_ITEMS.put(Items.BEETROOT, new ImpreciseFraction("0.0021")); + INITIAL_ITEMS.put(Items.MELON_SLICE, new ImpreciseFraction("0.0008")); - INITIAL_ITEMS.put(Items.COCOA_BEANS, new Fraction("0.00035")); - INITIAL_ITEMS.put(Items.HONEYCOMB, new Fraction("0.0014")); - INITIAL_ITEMS.put(Items.SUGAR_CANE, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.APPLE, new Fraction("0.0061")); - INITIAL_ITEMS.put(Items.SWEET_BERRIES, new Fraction("0.0035")); - INITIAL_ITEMS.put(Items.GLOW_BERRIES, new Fraction("0.0041")); - INITIAL_ITEMS.put(Items.KELP, new Fraction("0.0009")); + INITIAL_ITEMS.put(Items.COCOA_BEANS, new ImpreciseFraction("0.00035")); + INITIAL_ITEMS.put(Items.HONEYCOMB, new ImpreciseFraction("0.0014")); + INITIAL_ITEMS.put(Items.SUGAR_CANE, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.APPLE, new ImpreciseFraction("0.0061")); + INITIAL_ITEMS.put(Items.SWEET_BERRIES, new ImpreciseFraction("0.0035")); + INITIAL_ITEMS.put(Items.GLOW_BERRIES, new ImpreciseFraction("0.0041")); + INITIAL_ITEMS.put(Items.KELP, new ImpreciseFraction("0.0009")); // living animal things - INITIAL_ITEMS.put(Items.STRING, new Fraction("0.0006")); - INITIAL_ITEMS.put(Items.COBWEB, new Fraction("0.0006")); - INITIAL_ITEMS.put(Items.INK_SAC, new Fraction("0.0009")); - INITIAL_ITEMS.put(Items.SPIDER_EYE, new Fraction("0.001")); - INITIAL_ITEMS.put(Items.FEATHER, new Fraction("0.0007")); - INITIAL_ITEMS.put(Items.GUNPOWDER, new Fraction("0.003")); - INITIAL_ITEMS.put(Items.LEATHER, new Fraction("0.0065")); - INITIAL_ITEMS.put(Items.BONE, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.ENDER_PEARL, new Fraction("0.041")); - INITIAL_ITEMS.put(Items.GHAST_TEAR, new Fraction("0.023")); - INITIAL_ITEMS.put(Items.BLAZE_ROD, new Fraction("0.02")); - INITIAL_ITEMS.put(Items.SLIME_BALL, new Fraction("0.0015")); - INITIAL_ITEMS.put(Items.EGG, new Fraction("0.0011")); + INITIAL_ITEMS.put(Items.STRING, new ImpreciseFraction("0.0006")); + INITIAL_ITEMS.put(Items.COBWEB, new ImpreciseFraction("0.0006")); + INITIAL_ITEMS.put(Items.INK_SAC, new ImpreciseFraction("0.0009")); + INITIAL_ITEMS.put(Items.SPIDER_EYE, new ImpreciseFraction("0.001")); + INITIAL_ITEMS.put(Items.FEATHER, new ImpreciseFraction("0.0007")); + INITIAL_ITEMS.put(Items.GUNPOWDER, new ImpreciseFraction("0.003")); + INITIAL_ITEMS.put(Items.LEATHER, new ImpreciseFraction("0.0065")); + INITIAL_ITEMS.put(Items.BONE, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.ENDER_PEARL, new ImpreciseFraction("0.041")); + INITIAL_ITEMS.put(Items.GHAST_TEAR, new ImpreciseFraction("0.023")); + INITIAL_ITEMS.put(Items.BLAZE_ROD, new ImpreciseFraction("0.02")); + INITIAL_ITEMS.put(Items.SLIME_BALL, new ImpreciseFraction("0.0015")); + INITIAL_ITEMS.put(Items.EGG, new ImpreciseFraction("0.0011")); - INITIAL_ITEMS.put(Items.PORKCHOP, new Fraction("0.0047")); - INITIAL_ITEMS.put(Items.BEEF, new Fraction("0.0047")); - INITIAL_ITEMS.put(Items.MUTTON, new Fraction("0.004")); + INITIAL_ITEMS.put(Items.PORKCHOP, new ImpreciseFraction("0.0047")); + INITIAL_ITEMS.put(Items.BEEF, new ImpreciseFraction("0.0047")); + INITIAL_ITEMS.put(Items.MUTTON, new ImpreciseFraction("0.004")); - INITIAL_ITEMS.put(Items.PUFFERFISH, new Fraction("0.013")); - INITIAL_ITEMS.put(Items.COD, new Fraction("0.013")); - INITIAL_ITEMS.put(Items.SALMON, new Fraction("0.013")); - INITIAL_ITEMS.put(Items.TROPICAL_FISH, new Fraction("0.013")); + INITIAL_ITEMS.put(Items.PUFFERFISH, new ImpreciseFraction("0.013")); + INITIAL_ITEMS.put(Items.COD, new ImpreciseFraction("0.013")); + INITIAL_ITEMS.put(Items.SALMON, new ImpreciseFraction("0.013")); + INITIAL_ITEMS.put(Items.TROPICAL_FISH, new ImpreciseFraction("0.013")); // building items - INITIAL_ITEMS.put(Items.CLAY_BALL, new Fraction("0.0006")); - INITIAL_ITEMS.put(Items.SNOWBALL, new Fraction("0.00041")); + INITIAL_ITEMS.put(Items.CLAY_BALL, new ImpreciseFraction("0.0006")); + INITIAL_ITEMS.put(Items.SNOWBALL, new ImpreciseFraction("0.00041")); // loot - INITIAL_ITEMS.put(Items.TOTEM_OF_UNDYING, new Fraction("1.47")); - INITIAL_ITEMS.put(Items.TRIDENT, new Fraction("1.35")); + INITIAL_ITEMS.put(Items.TOTEM_OF_UNDYING, new ImpreciseFraction("1.47")); + INITIAL_ITEMS.put(Items.TRIDENT, new ImpreciseFraction("1.35")); /* - INITIAL_ITEMS.put(Items.WHITE_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.ORANGE_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.MAGENTA_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.LIGHT_BLUE_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.YELLOW_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.LIME_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.PINK_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.GRAY_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.LIGHT_GRAY_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.CYAN_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.PURPLE_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.BLUE_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.BROWN_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.GREEN_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.RED_WOOL, new Fraction("0.004")); - INITIAL_ITEMS.put(Items.BLACK_WOOL, new Fraction("0.004")); + INITIAL_ITEMS.put(Items.WHITE_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.ORANGE_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.MAGENTA_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.LIGHT_BLUE_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.YELLOW_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.LIME_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.PINK_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.GRAY_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.LIGHT_GRAY_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.CYAN_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.PURPLE_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.BLUE_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.BROWN_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.GREEN_WOOL, new ImpreciseFraction("0.004")); + INITIAL_ITEMS.put(Items.RED_WOOL, new ImpreciseFraction("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.WARPED_LOG, new Fraction("0.005")); + // INITIAL_ITEMS.put(Items.CRIMSON_LOG, new ImpreciseFraction("0.005")); + // INITIAL_ITEMS.put(Items.WARPED_LOG, new ImpreciseFraction("0.005")); } - private static void registerPostItem(Item item, Item base, Fraction multiplier) { - Fraction value = getMatterValue(base); + private static void registerPostItem(Item item, Item base, ImpreciseFraction multiplier) { + ImpreciseFraction value = getMatterValue(base); if (!value.equals(Fraction.ZERO)) { ITEMS.put(item, value.times(multiplier)); @@ -323,12 +324,10 @@ public class MatterRegistry { } public static void registerPostItems() { - registerPostItem(Items.CHIPPED_ANVIL, Items.ANVIL, new Fraction("0.8")); - registerPostItem(Items.DAMAGED_ANVIL, Items.ANVIL, new Fraction("0.5")); + registerPostItem(Items.CHIPPED_ANVIL, Items.ANVIL, new ImpreciseFraction("0.8")); + registerPostItem(Items.DAMAGED_ANVIL, Items.ANVIL, new ImpreciseFraction("0.5")); } - public static final MathContext ROUND_RULES = MatteryCapability.ROUND_RULES; - private static final HashMap>> usages = new HashMap<>(); private static final HashMap>> results = new HashMap<>(); private static final HashMap seen_items = new HashMap<>(); @@ -341,8 +340,8 @@ public class MatterRegistry { private static final Item[] scan_stack = new Item[1000]; @Nullable - private static Fraction determineValue(Item item) { - Fraction _get = ITEMS.get(item); + private static ImpreciseFraction determineValue(Item item) { + ImpreciseFraction _get = ITEMS.get(item); if (_get != null) { return _get; @@ -379,13 +378,13 @@ public class MatterRegistry { } } - return Fraction.ZERO; + return ImpreciseFraction.ZERO; } seen_items.put(item, 0); if (!results.containsKey(item)) { - return Fraction.ZERO; + return ImpreciseFraction.ZERO; } scan_stack[stack_index] = item; @@ -393,32 +392,32 @@ public class MatterRegistry { boolean defer_occured = false; - Fraction smallest_possible_total = null; + ImpreciseFraction smallest_possible_total = null; for (Recipe recipe : results.get(item)) { ItemStack self = recipe.getResultItem(); - Fraction recipe_summ = Fraction.ZERO; + ImpreciseFraction recipe_summ = ImpreciseFraction.ZERO; boolean this_defered = false; for (Ingredient ingredient : recipe.getIngredients()) { ItemStack[] items = ingredient.getItems(); - Fraction smallest_possible = null; + ImpreciseFraction smallest_possible = null; for (ItemStack stack : items) { if (!stack.isEmpty()) { - Fraction determine = determineValue(stack.getItem()); + ImpreciseFraction determine = determineValue(stack.getItem()); // if we hit an recursive recipe, defer it if (determine != null) { - if (determine.compareTo(Fraction.ZERO) == 0) { + if (determine.isZero()) { // farewell OverdriveThatMatters.LOGGER.debug("Cannot determine matter value for {} because value of {} is unknown", item, stack.getItem()); seen_items_child.put(item, stack.getItem()); scan_stack[stack_index] = null; stack_index--; - return Fraction.ZERO; + return ImpreciseFraction.ZERO; } if (smallest_possible == null || smallest_possible.compareTo(determine) > 0) @@ -444,7 +443,7 @@ public class MatterRegistry { if (this_defered) 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) smallest_possible_total = recipe_summ; @@ -469,7 +468,7 @@ public class MatterRegistry { scan_stack[stack_index] = null; stack_index--; - return Fraction.ZERO; + return ImpreciseFraction.ZERO; } private static void flood(List> recipe_type) { @@ -564,9 +563,9 @@ public class MatterRegistry { @SubscribeEvent public static void attachItemStackTextEvent(ItemTooltipEvent event) { 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)); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java b/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java index ca913c54b..ccc543bd4 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java @@ -7,6 +7,7 @@ import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.core.Fraction; +import ru.dbotthepony.mc.otm.core.ImpreciseFraction; import javax.annotation.ParametersAreNonnullByDefault; import java.math.BigDecimal; @@ -122,6 +123,17 @@ public class FormattingHelper { 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[] { "otm.suffix.deci", "otm.suffix.centi", @@ -161,6 +173,19 @@ public class FormattingHelper { 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) { 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)); } + 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) { 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)); } + 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) { 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)); } + public static TranslatableComponent formatMatterValue(ImpreciseFraction matter) { + return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME)); + } + public static Component formatMatterValuePlain(BigDecimal matter) { return formatSI(matter, MATTER_NAME); } @@ -200,6 +237,10 @@ public class FormattingHelper { return formatSI(matter, MATTER_NAME); } + public static Component formatMatterValuePlain(ImpreciseFraction matter) { + return formatSI(matter, MATTER_NAME); + } + public static Component formatPower(BigDecimal power) { return formatSI(power, POWER_NAME); } @@ -208,6 +249,10 @@ public class FormattingHelper { return formatSI(power, POWER_NAME); } + public static Component formatPower(ImpreciseFraction power) { + return formatSI(power, POWER_NAME); + } + public static Component formatSI(BigDecimal value) { return formatSI(value, ""); } @@ -303,4 +348,48 @@ public class FormattingHelper { 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); + } + } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/MatterRegistryPacket.java b/src/main/java/ru/dbotthepony/mc/otm/network/MatterRegistryPacket.java index a074963bd..8c5ff967e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/network/MatterRegistryPacket.java +++ b/src/main/java/ru/dbotthepony/mc/otm/network/MatterRegistryPacket.java @@ -8,6 +8,7 @@ import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.registries.ForgeRegistry; import net.minecraftforge.registries.RegistryManager; import ru.dbotthepony.mc.otm.core.Fraction; +import ru.dbotthepony.mc.otm.core.ImpreciseFraction; import ru.dbotthepony.mc.otm.matter.MatterRegistry; import java.math.BigDecimal; @@ -15,7 +16,7 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; -public record MatterRegistryPacket(Map list) { +public record MatterRegistryPacket(Map list) { public void write(FriendlyByteBuf buffer) { buffer.writeInt(list.size()); var registry = (ForgeRegistry) RegistryManager.ACTIVE.getRegistry(Item.class); @@ -30,10 +31,10 @@ public record MatterRegistryPacket(Map list) { var size = buffer.readInt(); var registry = (ForgeRegistry) RegistryManager.ACTIVE.getRegistry(Item.class); - var map = new HashMap(); + var map = new HashMap(); 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); diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidEnergyPacket.java b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidEnergyPacket.java index 5206da01f..96c185fc0 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidEnergyPacket.java +++ b/src/main/java/ru/dbotthepony/mc/otm/network/android/AndroidEnergyPacket.java @@ -7,12 +7,13 @@ import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.network.NetworkEvent; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.core.Fraction; +import ru.dbotthepony.mc.otm.core.ImpreciseFraction; import ru.dbotthepony.mc.otm.network.NetworkHelper; import java.math.BigDecimal; 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) { buffer.writeBoolean(is_maximal); energy.write(buffer); @@ -40,6 +41,6 @@ public record AndroidEnergyPacket(boolean is_maximal, Fraction energy) { } public static AndroidEnergyPacket read(FriendlyByteBuf buffer) { - return new AndroidEnergyPacket(buffer.readBoolean(), Fraction.read(buffer)); + return new AndroidEnergyPacket(buffer.readBoolean(), ImpreciseFraction.read(buffer)); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/storage/StorageObjectRegistry.java b/src/main/java/ru/dbotthepony/mc/otm/storage/StorageObjectRegistry.java index 9111b1f5f..a7c83e017 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/storage/StorageObjectRegistry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/storage/StorageObjectRegistry.java @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.storage; 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.Nullable; @@ -14,7 +15,7 @@ import java.util.Objects; public class StorageObjectRegistry { private static final HashMap, StorageObjectTuple> REGISTRY = new HashMap<>(); - public static StorageObjectTuple register(Class identity, T empty, Fraction energyPerOperation) { + public static StorageObjectTuple register(Class identity, T empty, ImpreciseFraction energyPerOperation) { final var tuple = new StorageObjectTuple<>(identity, empty, energyPerOperation); REGISTRY.put(identity, tuple); return tuple; diff --git a/src/main/java/ru/dbotthepony/mc/otm/storage/StorageObjectTuple.java b/src/main/java/ru/dbotthepony/mc/otm/storage/StorageObjectTuple.java index 6edc70d33..1279153b0 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/storage/StorageObjectTuple.java +++ b/src/main/java/ru/dbotthepony/mc/otm/storage/StorageObjectTuple.java @@ -1,10 +1,11 @@ package ru.dbotthepony.mc.otm.storage; import ru.dbotthepony.mc.otm.core.Fraction; +import ru.dbotthepony.mc.otm.core.ImpreciseFraction; import javax.annotation.Nonnull; -public record StorageObjectTuple(@Nonnull Class identity, @Nonnull T empty, @Nonnull Fraction energyPerOperation) { +public record StorageObjectTuple(@Nonnull Class identity, @Nonnull T empty, @Nonnull ImpreciseFraction energyPerOperation) { @Override public boolean equals(Object obj) { if (obj instanceof StorageObjectTuple tuple) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.kt index 16c0994fe..42e142060 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.kt @@ -14,6 +14,7 @@ import ru.dbotthepony.mc.otm.Registry import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.menu.AndroidStationMenu class BlockEntityAndroidStation(p_155229_: BlockPos, p_155230_: BlockState) : @@ -31,9 +32,9 @@ class BlockEntityAndroidStation(p_155229_: BlockPos, p_155230_: BlockState) : energy = MatteryMachineEnergyStorage( this, MatteryMachineEnergyStorage.MachineType.WORKER, - Fraction(100000), - Fraction(250), - Fraction(250) + ImpreciseFraction(100000), + ImpreciseFraction(250), + ImpreciseFraction(250) ) } @@ -53,10 +54,10 @@ class BlockEntityAndroidStation(p_155229_: BlockPos, p_155230_: BlockState) : val missing = it.missingPower - if (missing > Fraction.ZERO) { + if (missing > ImpreciseFraction.ZERO) { val extract = energy.extractEnergyInner(missing, true) - if (extract > Fraction.ZERO) { + if (extract > ImpreciseFraction.ZERO) { val received = it.receiveEnergyOuter(extract, false) energy.extractEnergyInner(received, false) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.kt index b374bf3d8..a44bcc156 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.kt @@ -28,6 +28,7 @@ import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.capability.receiveEnergy import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.menu.MenuBatteryBank import ru.dbotthepony.mc.otm.set 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 } ) - private data class BatteryBankDistribution(val distribution: Array, val maxThroughput: Fraction) + private data class BatteryBankDistribution(val distribution: Array, val maxThroughput: ImpreciseFraction) private enum class BankMode { RECEIVE, EXTRACT, BIDIRECTIONAL } private inner class BatteryBankEnergy(private val mode: BankMode) : IMatteryEnergyStorage { override fun canExtract() = mode != BankMode.RECEIVE 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) - return Fraction.ZERO + return ImpreciseFraction.ZERO return extractEnergyInner(howMuch, simulate) } @@ -79,8 +80,8 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block * [mode] = true на приём, false на отдачу */ fun getDistribution(mode: Boolean): BatteryBankDistribution { - val distribution = Array(container.containerSize) { Fraction.ZERO } - var summ = Fraction.ZERO + val distribution = Array(container.containerSize) { ImpreciseFraction.ZERO } + var summ = ImpreciseFraction.ZERO for (i in 0 until container.containerSize) { val stack = container.getItem(i) @@ -88,12 +89,12 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block if (!stack.isEmpty) { stack.getCapability(CapabilityEnergy.ENERGY).ifPresent { if (it is IMatteryEnergyStorage) { - val diff: Fraction + val diff: ImpreciseFraction if (mode) { - diff = it.receiveEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true) + diff = it.receiveEnergyOuter(ImpreciseFraction.LONG_MAX_VALUE, true) } else { - diff = it.extractEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true) + diff = it.extractEnergyOuter(ImpreciseFraction.LONG_MAX_VALUE, true) } distribution[i] = diff @@ -102,19 +103,19 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block val diff: Int if (mode) { - diff = it.receiveEnergy(MatteryCapability.LONG_MAX_VALUE, true) + diff = it.receiveEnergy(ImpreciseFraction.LONG_MAX_VALUE, true) } 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] } } } } - if (!summ.isZero()) { + if (!summ.isZero) { for (i in 0 until container.containerSize) { distribution[i] = distribution[i] / summ } @@ -123,23 +124,23 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block 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) - if (distribution.maxThroughput.isZero()) - return Fraction.ZERO + if (distribution.maxThroughput.isZero) + return ImpreciseFraction.ZERO - val distList: Array = distribution.distribution - var summ = Fraction.ZERO + val distList = distribution.distribution + var summ = ImpreciseFraction.ZERO for (i in 0 until container.containerSize) { - if (!distList[i].isZero()) { + if (!distList[i].isZero) { val stack = container.getItem(i) if (!stack.isEmpty) { stack.getCapability(CapabilityEnergy.ENERGY).ifPresent { if (it is IMatteryEnergyStorage) { - val diff: Fraction + val diff: ImpreciseFraction if (mode) { 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) } - summ += Fraction(diff) + summ += ImpreciseFraction(diff) } } } } } - if (!simulate && !summ.isZero()) { + if (!simulate && !summ.isZero) { setChangedLight() } return summ } - override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { 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) - return Fraction.ZERO + return ImpreciseFraction.ZERO 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) } - override val batteryLevel: Fraction get() { - var result = Fraction.ZERO + override val batteryLevel: ImpreciseFraction get() { + var result = ImpreciseFraction.ZERO for (i in 0 until container.containerSize) { val stack = container.getItem(i) @@ -206,8 +207,8 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block return result } - override val maxBatteryLevel: Fraction get() { - var result = Fraction.ZERO + override val maxBatteryLevel: ImpreciseFraction get() { + var result = ImpreciseFraction.ZERO for (i in 0 until container.containerSize) { val stack = container.getItem(i) @@ -329,13 +330,13 @@ class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : Block outputCapability.ifPresent { val (_, maxThroughput) = energy.getDistribution(false) - if (maxThroughput.isZero()) + if (maxThroughput.isZero) return@ifPresent if (it is IMatteryEnergyStorage) { val diff = it.receiveEnergyOuter(maxThroughput, false) - if (!diff.isZero()) { + if (!diff.isZero) { energy.extractEnergyInner(diff, false) } } else { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityChemicalGenerator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityChemicalGenerator.kt index 6f32c69a7..4f8c977ae 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityChemicalGenerator.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityChemicalGenerator.kt @@ -29,6 +29,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.capability.receiveEnergy import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.plus import ru.dbotthepony.mc.otm.menu.MenuChemicalGenerator import java.lang.ref.WeakReference @@ -181,7 +182,7 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti val extracted = energy.extractEnergyInner(demand, true) val received = it.receiveEnergyOuter(extracted, false) - if (!received.isZero()) { + if (!received.isZero) { energy.extractEnergyInner(received, false) } } 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 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 workingTicks = ticks / 4 container[SLOT_INPUT].shrink(1) @@ -238,13 +239,13 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti check = false } - if (energy.batteryLevel.isZero()) return + if (energy.batteryLevel.isZero) return val item = container[SLOT_BATTERY] if (!item.isEmpty) { item.getCapability(CapabilityEnergy.ENERGY).ifPresent(this::workWithPower) - if (energy.batteryLevel.isZero()) return + if (energy.batteryLevel.isZero) return } for (consumer in consumers) { @@ -253,10 +254,10 @@ class BlockEntityChemicalGenerator(pos: BlockPos, state: BlockState) : BlockEnti } companion object { - private val THROUGHPUT = Fraction(160) + private val THROUGHPUT = ImpreciseFraction(160) private const val THROUGHPUT_INT = 160 - private val GENERATION_SPEED = Fraction(40) - private val MAX_ENERGY = Fraction(24_000) + private val GENERATION_SPEED = ImpreciseFraction(40) + private val MAX_ENERGY = ImpreciseFraction(24_000) private val NAME = TranslatableComponent("block.overdrive_that_matters.chemical_generator") const val SLOT_INPUT = 0 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveRack.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveRack.kt index 3c134f411..c7000a7b3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveRack.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveRack.kt @@ -20,6 +20,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.ifHas import ru.dbotthepony.mc.otm.menu.MenuDriveRack import ru.dbotthepony.mc.otm.set @@ -67,7 +68,7 @@ class BlockEntityDriveRack(p_155229_: BlockPos, p_155230_: BlockState) : } init { - energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, Fraction(80000)) + energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, ImpreciseFraction(80000)) } fun tick() { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveViewer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveViewer.kt index afbbda55e..141b285f9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveViewer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveViewer.kt @@ -19,6 +19,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.menu.MenuDriveViewer import ru.dbotthepony.mc.otm.set import javax.annotation.ParametersAreNonnullByDefault @@ -77,7 +78,7 @@ class BlockEntityDriveViewer(p_155229_: BlockPos, p_155230_: BlockState) : Block } init { - energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, Fraction(30000)) + energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, ImpreciseFraction(30000)) } override fun getDefaultDisplayName(): Component { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.kt index de63a6613..8fd3a2514 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.kt @@ -29,12 +29,13 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.capability.receiveEnergy 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.network.MatteryNetworking import java.lang.ref.WeakReference 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) { buff.writeBlockPos(pos) thisTick.write(buff) @@ -60,35 +61,35 @@ data class EnergyCounterPacket(val pos: BlockPos, val thisTick: Fraction, val to companion object { fun read(buff: FriendlyByteBuf): EnergyCounterPacket { val pos = buff.readBlockPos() - val thisTick = Fraction.read(buff) - val total = Fraction.read(buff) + val thisTick = ImpreciseFraction.read(buff) + val total = ImpreciseFraction.read(buff) val index = buff.readInt() - val value = Fraction.read(buff) + val value = ImpreciseFraction.read(buff) return EnergyCounterPacket(pos, thisTick, total, index, value) } } } 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 - private val history = Array(10 * 20) { Fraction.ZERO } + private val history = Array(10 * 20) { ImpreciseFraction.ZERO } private var historyTick = 0 fun size() = history.size 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 } - var lastTick: Fraction = Fraction.ZERO + var lastTick = ImpreciseFraction.ZERO internal set - fun getHistory(ticks: Int): Array { + fun getHistory(ticks: Int): Array { 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) { var index = (historyTick - i) % this.history.size @@ -99,14 +100,14 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo return history } - fun calcAverage(ticks: Int): Fraction { + fun calcAverage(ticks: Int): ImpreciseFraction { return sumHistory(ticks) / ticks } - fun sumHistory(ticks: Int): Fraction { + fun sumHistory(ticks: Int): ImpreciseFraction { require(!(ticks < 1 || ticks >= history.size)) { "Invalid history length provided" } - var value = Fraction.ZERO + var value = ImpreciseFraction.ZERO for (i in 0 until ticks) { var index = (historyTick - i) % history.size @@ -133,7 +134,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo super.load(nbt) nbt.ifHas(("passed")) { - passed = Fraction.deserializeNBT(it) + passed = ImpreciseFraction.deserializeNBT(it) } 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) { for (i in it.indices) { 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 { - override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { + override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { return extractEnergyInner(howMuch, simulate) } - override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { if (is_input) - return Fraction.ZERO + return ImpreciseFraction.ZERO if (inputCapability.isPresent) { val it = inputCapability.resolve().get() - val diff: Fraction + val diff: ImpreciseFraction if (it is IMatteryEnergyStorage) { diff = it.extractEnergyOuter(howMuch, simulate) } else { - diff = Fraction(it.extractEnergy(howMuch, simulate)) + diff = ImpreciseFraction(it.extractEnergy(howMuch, simulate)) } if (!simulate) { @@ -199,26 +200,26 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo 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) } - override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { if (!is_input) - return Fraction.ZERO + return ImpreciseFraction.ZERO if (outputCapability.isPresent) { val it = outputCapability.resolve().get() - val diff: Fraction + val diff: ImpreciseFraction if (it is IMatteryEnergyStorage) { diff = it.receiveEnergyOuter(howMuch, simulate) } else { - diff = Fraction(it.receiveEnergy(howMuch, simulate)) + diff = ImpreciseFraction(it.receiveEnergy(howMuch, simulate)) } if (!simulate) { @@ -229,10 +230,10 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo return diff } - return Fraction.ZERO + return ImpreciseFraction.ZERO } - override val batteryLevel: Fraction + override val batteryLevel: ImpreciseFraction get() { if (is_input) { if (outputCapability.isPresent) { @@ -242,7 +243,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo return it.batteryLevel } - return Fraction(it.energyStored) + return ImpreciseFraction(it.energyStored) } } else { if (inputCapability.isPresent) { @@ -252,14 +253,14 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo 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() { if (is_input) { if (outputCapability.isPresent) { @@ -269,7 +270,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo return it.maxBatteryLevel } - return Fraction(it.maxEnergyStored) + return ImpreciseFraction(it.maxEnergyStored) } } else { if (inputCapability.isPresent) { @@ -279,14 +280,14 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo 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() { if (is_input) { if (outputCapability.isPresent) { @@ -296,7 +297,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo return it.missingPower } - return Fraction((it.maxEnergyStored - it.energyStored).coerceAtLeast(0)) + return ImpreciseFraction((it.maxEnergyStored - it.energyStored).coerceAtLeast(0)) } } else { if (inputCapability.isPresent) { @@ -306,11 +307,11 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo 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 @@ -423,7 +424,7 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo val index = historyTick historyTick = (historyTick + 1) % history.size 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)) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityItemMonitor.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityItemMonitor.kt index 8b24b1bb9..d78658ada 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityItemMonitor.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityItemMonitor.kt @@ -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.MatteryMachineEnergyStorage 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.graph.storage.StorageNetworkGraph @@ -27,7 +28,7 @@ class BlockEntityItemMonitor(p_155229_: BlockPos, p_155230_: BlockState) : val cell = BasicStorageGraphNode() init { - energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, Fraction(80_000)) + energy = MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, ImpreciseFraction(80_000)) } fun tick() { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.kt index 434262dfa..9cbc6155e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.kt @@ -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.container.MatteryContainer import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.graph.Graph6Node import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph @@ -106,13 +107,13 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) : @JvmField val matter: MatterHandlerCapability = - object : MatterHandlerCapability(this::setChangedLight, MatterDirection.BIDIRECTIONAL, Fraction(4)) { + object : MatterHandlerCapability(this::setChangedLight, MatterDirection.BIDIRECTIONAL, CAPACITY) { override fun getDirection(): MatterDirection { 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 override fun getMatterHandler(): IMatterHandler { @@ -200,18 +201,18 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) : val cap = resolver.get() if (this.workFlow) { - if (cap.maxStoredMatter - initialCapacity!! <= Fraction.ZERO) { + if (cap.maxStoredMatter - initialCapacity!! <= ImpreciseFraction.ZERO) { return 0f } return ((cap.storedMatter - initialCapacity!!) / (cap.maxStoredMatter - initialCapacity!!)).toFloat() } - if (initialCapacity!! <= Fraction.ZERO) { + if (initialCapacity!! <= ImpreciseFraction.ZERO) { return 0f } - return (Fraction.ONE - cap.storedMatter / initialCapacity!!).toFloat() + return (ImpreciseFraction.ONE - cap.storedMatter / initialCapacity!!).toFloat() } override fun setRemoved() { @@ -224,7 +225,7 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) : if (isBlockedByRedstone) { if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.IDLE) { - level!!.setBlock( + level?.setBlock( blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS @@ -247,7 +248,7 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) : val cap = itemStack.getCapability(MatteryCapability.MATTER).resolve() if (cap.isPresent && cap.get().direction !== unexpectedDirection) { - if (this.workFlow && cap.get().missingMatter > Fraction.ZERO || !this.workFlow && cap.get().storedMatter > Fraction.ZERO) { + if (this.workFlow && cap.get().missingMatter > ImpreciseFraction.ZERO || !this.workFlow && cap.get().storedMatter > ImpreciseFraction.ZERO) { work_stack = itemStack capability = cap.get() work_slot = i @@ -269,7 +270,7 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) : if (capability != null) { if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.WORKING) { - level!!.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) + level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) } 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 ) - if (extracted > Fraction.ZERO) { + if (extracted > ImpreciseFraction.ZERO) { val received = matter.receiveMatterOuter(extracted, false) graph.extractMatter(received, false) } } - if (matter.storedMatter > Fraction.ZERO) { + if (matter.storedMatter > ImpreciseFraction.ZERO) { val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true) - if (!energyExtracted.isZero()) { - val matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(matter.storedMatter) * (energyExtracted / ENERGY_CONSUMPTION), true) + if (!energyExtracted.isZero) { + val matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(matter.storedMatter) * energyExtracted / ENERGY_CONSUMPTION, true) - if (!matter.isZero()) { - energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE,false) + if (!matter.isZero) { + energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE, false) capability.receiveMatterOuter(matter, false) this.matter.extractMatterInner(matter, false) - if (capability.missingMatter.isZero()) { + if (capability.missingMatter.isZero) { for (i in 3..5) { if (container.getItem(i).isEmpty) { container.setItem(work_slot, ItemStack.EMPTY) @@ -311,16 +312,16 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) : } else { 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) - if (!matter.isZero()) { - this.energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE,false) + if (!matter.isZero) { + this.energy.extractEnergyInner(ENERGY_CONSUMPTION * (matter / MATTER_EXCHANGE_RATE).toDouble(),false) capability.extractMatterOuter(matter, false) this.matter.receiveMatterInner(matter, false) - if (capability.storedMatter.isZero()) { + if (capability.storedMatter.isZero) { for (i in 2 downTo 0) { if (container.getItem(i).isEmpty) { 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) } - if (!workFlow && !matter.storedMatter.isZero() && graph != null) { + if (!workFlow && !matter.storedMatter.isZero && graph != null) { val diff = matter.extractMatterInner(matter.storedMatter, true) val diff2 = graph.receiveMatter(diff, true) matter.extractMatterInner(diff2, false) @@ -346,8 +347,9 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) : companion object { private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_bottler") - private val MATTER_EXCHANGE_RATE = Fraction("0.04") - private val ENERGY_CONSUMPTION = Fraction(20) - private val EXTRACTION_TICKS = Fraction(200) + private val MATTER_EXCHANGE_RATE = ImpreciseFraction("0.04") + private val ENERGY_CONSUMPTION = ImpreciseFraction(20) + private val EXTRACTION_TICKS = ImpreciseFraction(200) + private val CAPACITY = ImpreciseFraction(4) } } \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.kt index 138447777..a7da22cd7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.kt @@ -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.container.MatteryContainer import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.graph.Graph6Node import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph @@ -42,8 +43,8 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState) return node } - override fun getStoredMatter(): Fraction { - var summ = Fraction.ZERO + override fun getStoredMatter(): ImpreciseFraction { + var summ = ImpreciseFraction.ZERO for (stack in container) if (!stack.isEmpty) @@ -54,8 +55,8 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState) return summ } - override fun getMaxStoredMatter(): Fraction { - var summ = Fraction.ZERO + override fun getMaxStoredMatter(): ImpreciseFraction { + var summ = ImpreciseFraction.ZERO for (stack in container) if (!stack.isEmpty) @@ -66,13 +67,13 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState) return summ } - override fun receiveMatterOuter(howMuch: Fraction, simulate: Boolean): Fraction { + override fun receiveMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { return receiveMatterInner(howMuch, simulate) } - override fun receiveMatterInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { var howMuch = howMuch - var summ = Fraction.ZERO + var summ = ImpreciseFraction.ZERO for (stack in container) { if (!stack.isEmpty) { @@ -82,7 +83,7 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState) howMuch -= diff } - if (howMuch.isZero()) { + if (howMuch.isZero) { break } } @@ -91,13 +92,13 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState) return summ } - override fun extractMatterOuter(howMuch: Fraction, simulate: Boolean): Fraction { + override fun extractMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { return extractMatterInner(howMuch, simulate) } - override fun extractMatterInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { var howMuch = howMuch - var summ = Fraction.ZERO + var summ = ImpreciseFraction.ZERO for (stack in container) { if (!stack.isEmpty) { @@ -107,7 +108,7 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState) howMuch -= diff } - if (howMuch.isZero()) { + if (howMuch.isZero) { break } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.kt index 42f1b59b4..362af67a3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.kt @@ -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.container.MatteryContainer import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.graph.Graph6Node import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph @@ -37,18 +38,13 @@ import ru.dbotthepony.mc.otm.set class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState) : BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_DECOMPOSER, pos, state), IMatterGraphNode { - companion object { - private val MACHINE_NAME = TranslatableComponent("block.overdrive_that_matters.matter_decomposer") - private val BASE_CONSUMPTION = Fraction(240) - } - init { energy = MatteryMachineEnergyStorage( this, MatteryMachineEnergyStorage.MachineType.WORKER, - Fraction(400000), - Fraction(2000), - Fraction(2000) + ImpreciseFraction(400000), + ImpreciseFraction(2000), + ImpreciseFraction(2000) ) } @@ -60,7 +56,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState) } @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 resolverNode = LazyOptional.of { this } @@ -136,7 +132,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState) if (MatterRegistry.canDecompose(copy)) { val value = MatterRegistry.getMatterValue(copy) - if (value != Fraction.ZERO && matter.canReceiveAll(value)) { + if (!value.isZero && matter.canReceiveAll(value)) { stack.shrink(1) 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? - if (!matter.storedMatter.isZero() && grid != null) { + if (!matter.storedMatter.isZero && grid != null) { val diff = matter.extractMatterInner(matter.getStoredMatter(), true) val diff2 = grid.receiveMatter(diff, true) @@ -176,4 +172,10 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState) 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) + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.kt index ccb01cefe..500c290e0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.kt @@ -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.container.MatteryContainer import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.graph.Graph6Node import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph @@ -51,7 +52,7 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) : } @JvmField - val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.RECEIVE, Fraction(2)) + val matter = MatterHandlerCapability(this::setChangedLight, IMatterHandler.MatterDirection.RECEIVE, ImpreciseFraction(2)) // обычные запросы @JvmField @@ -144,7 +145,7 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) : val drain = graph.extractMatter(toExtract, true) - if (drain.isZero()) { + if (drain.isZero) { // в сети нет материи return MachineJobStatus(false, 200) } @@ -209,19 +210,19 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) : energy = MatteryMachineEnergyStorage( this, MatteryMachineEnergyStorage.MachineType.WORKER, - Fraction(200000), - Fraction(4000), - Fraction(4000) + ImpreciseFraction(200000), + ImpreciseFraction(4000), + ImpreciseFraction(4000) ) } companion object { 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 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 val MTU_PER_TICK_BD = Fraction.ONE.div(TICKS_PER_MTU_BD) - private val DRAIN_MULT = Fraction(200) + private val MTU_PER_TICK_BD = ImpreciseFraction.ONE.div(TICKS_PER_MTU_BD) + private val DRAIN_MULT = ImpreciseFraction(200) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.kt index ca4bda7e8..249ec842f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.kt @@ -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.container.MatteryContainer import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.graph.Graph6Node import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph @@ -184,9 +185,9 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) : energy = MatteryMachineEnergyStorage( this, MatteryMachineEnergyStorage.MachineType.WORKER, - Fraction(40000), - Fraction(400), - Fraction(400) + ImpreciseFraction(40000), + ImpreciseFraction(400), + ImpreciseFraction(400) ) } @@ -200,6 +201,6 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) : companion object { private val NAME = TranslatableComponent("block.overdrive_that_matters.matter_scanner") - private val BASE_CONSUMPTION = Fraction("40") + private val BASE_CONSUMPTION = ImpreciseFraction("40") } } \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.kt index 66a9be330..f04df100b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.kt @@ -14,6 +14,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.ifHas import ru.dbotthepony.mc.otm.set @@ -25,7 +26,7 @@ abstract class BlockEntityMatteryPowered(p_155228_: BlockEntityType<*>, p_155229 protected fun batteryChargeLoop() { var demand = energy.receiveEnergyOuter(energy.missingPower, true) - if (demand.isZero()) return + if (demand.isZero) return for (stack in batteryContainer) { if (!stack.isEmpty) { @@ -41,7 +42,7 @@ abstract class BlockEntityMatteryPowered(p_155228_: BlockEntityType<*>, p_155229 } } - if (demand <= Fraction.ZERO) + if (demand <= ImpreciseFraction.ZERO) return } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityPlatePress.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityPlatePress.kt index dfea60ecd..47b21ce0b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityPlatePress.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityPlatePress.kt @@ -16,6 +16,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.container.MatteryContainerFilter import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.menu.MenuPlatePress import ru.dbotthepony.mc.otm.set @@ -81,7 +82,7 @@ class BlockEntityPlatePress(p_155229_: BlockPos, p_155230_: BlockState) : BlockE } companion object { - private val BASELINE_CONSUMPTION = Fraction(15) + private val BASELINE_CONSUMPTION = ImpreciseFraction(15) private val NAME = TranslatableComponent("block.overdrive_that_matters.plate_press") const val SLOT_INPUT = 0 const val SLOT_OUTPUT = 1 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlockEntityBlackHole.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlockEntityBlackHole.kt index 4679c98e6..222e332a3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlockEntityBlackHole.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlockEntityBlackHole.kt @@ -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.blackhole.ExplosionQueue.Companion.queueForLevel 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.matter.MatterRegistry 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_) { var mass = BASELINE_MASS set(mass) { - if (mass <= Fraction.ZERO) { + if (mass <= ImpreciseFraction.ZERO) { collapse() return } @@ -156,7 +157,7 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn fun readBlackHoleData(tag: CompoundTag) { tag["mass"]?.let { - mass = Fraction.deserializeNBT(it) + mass = ImpreciseFraction.deserializeNBT(it) } spin_direction = tag.getBoolean("spin_direction") @@ -280,7 +281,7 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn } else { val mass = MatterRegistry.getMatterValue(item.item) - if (mass > Fraction.ZERO) + if (mass > ImpreciseFraction.ZERO) this.mass += mass * item.item.count } } @@ -351,8 +352,8 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn companion object { const val ITERATIONS = 30_000 - val BASELINE_MASS = Fraction(1_000) - val HAWKING_MASS_LOSE_STEP = Fraction("-0.1") + val BASELINE_MASS = ImpreciseFraction(1_000) + val HAWKING_MASS_LOSE_STEP = ImpreciseFraction("-0.1") private val blockShapeCache = HashMap>() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.kt index 94dcd6de8..a22bb60da 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.kt @@ -8,6 +8,7 @@ import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.DoubleTag import net.minecraft.world.level.block.Block 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.set @@ -139,7 +140,7 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_ return } - if (!currentJob.power.isZero() && energy.batteryLevel.isZero()) { + if (!currentJob.power.isZero && energy.batteryLevel.isZero) { idleTicksAnim++ 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 if (workTicks < currentJob.ticks) { - if (!currentJob.power.isZero()) { + if (!currentJob.power.isZero) { val extractedPower = energy.extractEnergyInner(currentJob.power, true) val workSpeed = extractedPower.div(currentJob.power) @@ -191,7 +192,7 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_ } } } 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) { throttleTicks += status.throttle() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt index df6168a09..5301e7bc0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/Ext.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.capability import net.minecraftforge.energy.IEnergyStorage import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction fun IEnergyStorage.receiveEnergy(amount: Fraction, simulate: Boolean): Int { if (amount.isZero()) @@ -22,3 +23,23 @@ fun IEnergyStorage.extractEnergy(amount: Fraction, simulate: Boolean): Int { 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) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.kt index ba9cfddc3..99f35728a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.kt @@ -2,58 +2,59 @@ package ru.dbotthepony.mc.otm.capability import net.minecraftforge.energy.IEnergyStorage import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction // IEnergyStorage for direct compat with Forge Energy interface IMatteryEnergyStorage : IEnergyStorage { // 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 // CAN also be used by something that does evil // 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 - fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction + fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction // 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 { - return extractEnergyOuter(Fraction(howMuch), simulate) + fun extractEnergyOuter(howMuch: Long, simulate: Boolean): ImpreciseFraction { + return extractEnergyOuter(ImpreciseFraction(howMuch), simulate) } - fun extractEnergyOuter(howMuch: Int, simulate: Boolean): Fraction { - return extractEnergyOuter(Fraction(howMuch), simulate) + fun extractEnergyOuter(howMuch: Int, simulate: Boolean): ImpreciseFraction { + return extractEnergyOuter(ImpreciseFraction(howMuch), simulate) } - fun receiveEnergyOuter(howMuch: Long, simulate: Boolean): Fraction { - return receiveEnergyOuter(Fraction(howMuch), simulate) + fun receiveEnergyOuter(howMuch: Long, simulate: Boolean): ImpreciseFraction { + return receiveEnergyOuter(ImpreciseFraction(howMuch), simulate) } - fun receiveEnergyOuter(howMuch: Int, simulate: Boolean): Fraction { - return receiveEnergyOuter(Fraction(howMuch), simulate) + fun receiveEnergyOuter(howMuch: Int, simulate: Boolean): ImpreciseFraction { + return receiveEnergyOuter(ImpreciseFraction(howMuch), simulate) } - fun extractEnergyInner(howMuch: Long, simulate: Boolean): Fraction { - return extractEnergyInner(Fraction(howMuch), simulate) + fun extractEnergyInner(howMuch: Long, simulate: Boolean): ImpreciseFraction { + return extractEnergyInner(ImpreciseFraction(howMuch), simulate) } - fun extractEnergyInner(howMuch: Int, simulate: Boolean): Fraction { - return extractEnergyInner(Fraction(howMuch), simulate) + fun extractEnergyInner(howMuch: Int, simulate: Boolean): ImpreciseFraction { + return extractEnergyInner(ImpreciseFraction(howMuch), simulate) } - fun receiveEnergyInner(howMuch: Long, simulate: Boolean): Fraction { - return receiveEnergyInner(Fraction(howMuch), simulate) + fun receiveEnergyInner(howMuch: Long, simulate: Boolean): ImpreciseFraction { + return receiveEnergyInner(ImpreciseFraction(howMuch), simulate) } - fun receiveEnergyInner(howMuch: Int, simulate: Boolean): Fraction { - return receiveEnergyInner(Fraction(howMuch), simulate) + fun receiveEnergyInner(howMuch: Int, simulate: Boolean): ImpreciseFraction { + return receiveEnergyInner(ImpreciseFraction(howMuch), simulate) } - val batteryLevel: Fraction - val maxBatteryLevel: Fraction - val missingPower: Fraction + val batteryLevel: ImpreciseFraction + val maxBatteryLevel: ImpreciseFraction + val missingPower: ImpreciseFraction get() = (maxBatteryLevel - batteryLevel).moreThanZero() override fun receiveEnergy(maxReceive: Int, simulate: Boolean): Int { @@ -63,7 +64,7 @@ interface IMatteryEnergyStorage : IEnergyStorage { if (received == 0) return 0 - return receiveEnergyOuter(Fraction(received), simulate).toInt() + return receiveEnergyOuter(ImpreciseFraction(received), simulate).toInt() } override fun extractEnergy(maxReceive: Int, simulate: Boolean): Int { @@ -73,32 +74,22 @@ interface IMatteryEnergyStorage : IEnergyStorage { if (extracted == 0) return 0 - return extractEnergyOuter(Fraction(extracted), simulate).toInt() + return extractEnergyOuter(ImpreciseFraction(extracted), simulate).toInt() } override fun getEnergyStored(): Int { - val level = batteryLevel - - if (level < MatteryCapability.INT_MAX_VALUE) - return level.toInt() - - return Int.MAX_VALUE + return batteryLevel.toInt() } override fun getMaxEnergyStored(): Int { - val level = maxBatteryLevel - - if (level < MatteryCapability.INT_MAX_VALUE) - return level.toInt() - - return Int.MAX_VALUE + return maxBatteryLevel.toInt() } override fun canExtract(): Boolean { - return extractEnergyOuter(Fraction.ONE, true) > Fraction.ZERO + return extractEnergyOuter(ImpreciseFraction.ONE, true) > ImpreciseFraction.ZERO } override fun canReceive(): Boolean { - return receiveEnergyOuter(Fraction.ONE, true) > Fraction.ZERO + return receiveEnergyOuter(ImpreciseFraction.ONE, true) > ImpreciseFraction.ZERO } } \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.kt index 3b689efec..f7a64e47b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.kt @@ -3,41 +3,40 @@ package ru.dbotthepony.mc.otm.capability import net.minecraft.nbt.CompoundTag import net.minecraft.world.level.block.entity.BlockEntity import net.minecraftforge.common.util.INBTSerializable -import ru.dbotthepony.mc.otm.core.Fraction -import ru.dbotthepony.mc.otm.core.Fraction.Companion.deserializeNBT +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.ifHas import ru.dbotthepony.mc.otm.set open class MatteryMachineEnergyStorage @JvmOverloads constructor( protected val listener: () -> Unit, val type: MachineType, - override var maxBatteryLevel: Fraction = DEFAULT_MAX_CAPACITY, - protected var maxInput: Fraction = DEFAULT_MAX_RECEIVE, - protected var maxOutput: Fraction = maxInput + override var maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY, + protected var maxInput: ImpreciseFraction = DEFAULT_MAX_RECEIVE, + protected var maxOutput: ImpreciseFraction = maxInput ) : IMatteryEnergyStorage, INBTSerializable { @JvmOverloads constructor( listener: BlockEntity, type: MachineType, - maxBatteryLevel: Fraction = DEFAULT_MAX_CAPACITY, - maxInput: Fraction = DEFAULT_MAX_RECEIVE, - maxOutput: Fraction = DEFAULT_MAX_EXTRACT) : this({listener.setChanged()}, type, maxBatteryLevel, maxInput, maxOutput) + maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY, + maxInput: ImpreciseFraction = DEFAULT_MAX_RECEIVE, + maxOutput: ImpreciseFraction = DEFAULT_MAX_EXTRACT) : this({listener.setChanged()}, type, maxBatteryLevel, maxInput, maxOutput) enum class MachineType { WORKER, GENERATOR, CAPACITOR } - override var batteryLevel = Fraction.ZERO + override var batteryLevel = ImpreciseFraction.ZERO protected set - override fun extractEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { + override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { if (type == MachineType.WORKER) - return Fraction.ZERO + return ImpreciseFraction.ZERO 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 diff = batteryLevel.minus(new) @@ -49,14 +48,14 @@ open class MatteryMachineEnergyStorage @JvmOverloads constructor( return diff } - override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { + override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { if (type == MachineType.GENERATOR) - return Fraction.ZERO + return ImpreciseFraction.ZERO 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 diff = new.minus(batteryLevel) @@ -89,15 +88,15 @@ open class MatteryMachineEnergyStorage @JvmOverloads constructor( } 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("max_input") { maxInput = deserializeNBT(it) } // nbt.ifHas("max_output") { maxOutput = deserializeNBT(it) } } companion object { - val DEFAULT_MAX_RECEIVE = Fraction(200) + val DEFAULT_MAX_RECEIVE = ImpreciseFraction(200) val DEFAULT_MAX_EXTRACT = DEFAULT_MAX_RECEIVE - val DEFAULT_MAX_CAPACITY = Fraction(60000) + val DEFAULT_MAX_CAPACITY = ImpreciseFraction(60000) } } \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.kt index 2355736bd..73cbcebf3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.kt @@ -36,6 +36,7 @@ import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.capability.extractEnergy import ru.dbotthepony.mc.otm.capability.receiveEnergy 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.set import java.util.* @@ -43,13 +44,13 @@ import java.util.* @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapabilityProvider, IAndroidCapability, INBTSerializable { - @JvmField protected var battery = Fraction.ZERO - @JvmField protected var maxBattery = Fraction(60000) + @JvmField protected var battery = ImpreciseFraction.ZERO + @JvmField protected var maxBattery = ImpreciseFraction(60000) override var batteryItemStack = ItemStack.EMPTY - private var remoteBattery = Fraction(-1) - private var remoteMaxBattery = Fraction(-1) + private var remoteBattery = ImpreciseFraction(-1) + private var remoteMaxBattery = ImpreciseFraction(-1) private var remoteBatteryStack = ItemStack.EMPTY @JvmField protected val features: MutableMap, AndroidFeature> = HashMap() @@ -119,8 +120,8 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab } override fun invalidateNetworkState() { - remoteBattery = Fraction.MINUS_ONE - remoteMaxBattery = Fraction.MINUS_ONE + remoteBattery = ImpreciseFraction.MINUS_ONE + remoteMaxBattery = ImpreciseFraction.MINUS_ONE remoteBatteryStack = ItemStack.EMPTY 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 } - override fun setMaxEnergy(value: Fraction) { + override fun setMaxEnergy(value: ImpreciseFraction) { maxBattery = value } @@ -170,11 +171,11 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab compound!! compound.ifHas("energy_stored") { - battery = Fraction.deserializeNBT(it) + battery = ImpreciseFraction.deserializeNBT(it) } compound.ifHas("energy_stored_max") { - maxBattery = Fraction.deserializeNBT(it) + maxBattery = ImpreciseFraction.deserializeNBT(it) } 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 { - return Fraction.ZERO + override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { + return ImpreciseFraction.ZERO } - override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { var howMuch = howMuch - var drained = Fraction.ZERO + var drained = ImpreciseFraction.ZERO if (!batteryItemStack.isEmpty) { 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) { ent.awardStat(Registry.Names.POWER_CONSUMED, drained.toInt() * 10) } @@ -344,9 +345,9 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab return drained } - override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { + override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { var howMuch = howMuch - var received = Fraction.ZERO + var received = ImpreciseFraction.ZERO if (!batteryItemStack.isEmpty) { 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 } } @@ -376,7 +377,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab return received } - override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { return receiveEnergyOuter(howMuch, simulate) } @@ -384,7 +385,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab return ent } - override val batteryLevel: Fraction get() { + override val batteryLevel: ImpreciseFraction get() { if (!batteryItemStack.isEmpty) { val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve() @@ -402,7 +403,7 @@ open class AndroidCapability(@JvmField protected val ent: LivingEntity) : ICapab return battery } - override val maxBatteryLevel: Fraction get() { + override val maxBatteryLevel: ImpreciseFraction get() { if (batteryItemStack != ItemStack.EMPTY) { val resolver = batteryItemStack.getCapability(CapabilityEnergy.ENERGY).resolve() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.kt index 51a56c87b..e6617807c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.kt @@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.android.AndroidResearch import ru.dbotthepony.mc.otm.android.AndroidResearchType import ru.dbotthepony.mc.otm.capability.MatteryCapability 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.AndroidStatusPacket import ru.dbotthepony.mc.otm.set @@ -58,8 +59,8 @@ class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply isAndroid = true willBecomeAndroid = false - battery = Fraction(60000) - maxBattery = Fraction(60000) + battery = ImpreciseFraction(60000) + maxBattery = ImpreciseFraction(60000) } fun becomeAndroidAndKill() { @@ -74,8 +75,8 @@ class AndroidCapabilityPlayer(@JvmField val ply: Player) : AndroidCapability(ply if (!isAndroid) return isAndroid = false - battery = Fraction(0) - maxBattery = Fraction(60000) + battery = ImpreciseFraction(0) + maxBattery = ImpreciseFraction(60000) 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 } } \ No newline at end of file diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.kt index 03c697fbb..12164f46b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.kt @@ -8,7 +8,7 @@ import net.minecraftforge.event.entity.living.LivingHurtEvent import ru.dbotthepony.mc.otm.android.AndroidFeature import ru.dbotthepony.mc.otm.android.AndroidFeatureType import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage -import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import java.util.* interface IAndroidCapability : IMatteryEnergyStorage, INBTSerializable { @@ -40,6 +40,6 @@ interface IAndroidCapability : IMatteryEnergyStorage, INBTSerializable : IStorageComponent { var isDirty: Boolean - val storedCount: Fraction - val driveCapacity: Fraction + val storedCount: ImpreciseFraction + val driveCapacity: ImpreciseFraction // not extending INBTSerializable to avoid serializing it as forgecaps fun serializeNBT(): CompoundTag diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt index ec9a0eb55..9c99501f8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt @@ -13,6 +13,7 @@ import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag import net.minecraft.nbt.Tag 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.set import java.util.ArrayList @@ -20,7 +21,7 @@ import java.util.HashSet abstract class AbstractMatteryDrive @JvmOverloads constructor( - override var driveCapacity: Fraction, + override var driveCapacity: ImpreciseFraction, override val uuid: UUID = UUID.randomUUID(), var maxDifferentStacks: Int = 0xFFFF ) : IMatteryDrive { @@ -42,12 +43,12 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor var storedDifferentStacks = 0 - override var storedCount = Fraction.ZERO + override var storedCount = ImpreciseFraction.ZERO protected set override fun insertStack(stack: T, simulate: Boolean): T { 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() } @@ -97,16 +98,16 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor 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 val get = storedByID[id] ?: return identity().empty() - if (amount <= Fraction.ZERO) + if (amount <= ImpreciseFraction.ZERO) amount = get.stack.getMaxStackSize().orElse(get.stack.count) amount = amount.min(get.stack.count) - if (amount <= Fraction.ZERO) + if (amount <= ImpreciseFraction.ZERO) return identity().empty() val copy = get.stack.copy() as T @@ -130,7 +131,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor storedCount = storedCount.minus(amount) get.stack.shrink(amount) - if (get.stack.count.compareTo(Fraction.ZERO) != 0) { + if (!get.stack.count.isZero) { for (listener in listeners) { listener.changeObject(get.id(), get.stack.count) } @@ -170,11 +171,11 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor override fun deserializeNBT(nbt: CompoundTag) { storedStacks.clear() storedByID.clear() - storedCount = Fraction.ZERO + storedCount = ImpreciseFraction.ZERO storedDifferentStacks = 0 nbt.ifHas("capacity") { - driveCapacity = deserializeNBT(it) + driveCapacity = ImpreciseFraction.deserializeNBT(it) } maxDifferentStacks = nbt.getInt("max_different_stacks") diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.kt index 3c3d1e489..d46db09de 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.kt @@ -7,6 +7,7 @@ import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items import net.minecraftforge.registries.RegistryManager 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.storage.IStorageTuple import ru.dbotthepony.mc.otm.storage.ItemStackWrapper @@ -14,10 +15,10 @@ import ru.dbotthepony.mc.otm.storage.StorageObjectRegistry import java.util.* class ItemMatteryDrive : AbstractMatteryDrive, IItemMatteryDrive { - constructor(capacity: Fraction, 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: Fraction, uuid: UUID) : super(capacity, uuid) - constructor(capacity: Fraction) : super(capacity) + constructor(capacity: ImpreciseFraction, max_different_stacks: Int) : super(capacity, maxDifferentStacks = max_different_stacks) + constructor(capacity: ImpreciseFraction, uuid: UUID, max_different_stacks: Int) : super(capacity, uuid, max_different_stacks) + constructor(capacity: ImpreciseFraction, uuid: UUID) : super(capacity, uuid) + constructor(capacity: ImpreciseFraction) : super(capacity) private val identity = StorageObjectRegistry.getOrError(ItemStackWrapper::class.java) override fun identity() = identity @@ -86,6 +87,6 @@ class ItemMatteryDrive : AbstractMatteryDrive, IItemMatteryDri companion object { @JvmField - val DUMMY = ItemMatteryDrive(Fraction(0), UUID(0L, 0L), 0) + val DUMMY = ItemMatteryDrive(ImpreciseFraction(0), UUID(0L, 0L), 0) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/EnergyCounterRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/EnergyCounterRenderer.kt index cf123334d..d9dfaef96 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/EnergyCounterRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/EnergyCounterRenderer.kt @@ -51,8 +51,8 @@ class EnergyCounterRenderer(private val context: BlockEntityRendererProvider.Con poseStack.pushPose() 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.sumHistory(20).decimalString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y + font.lineHeight, 0xFFFFFF) + font.drawAligned(poseStack, tile.lastTick.toString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y, 0xFFFFFF) + font.drawAligned(poseStack, tile.sumHistory(20).toString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y + font.lineHeight, 0xFFFFFF) poseStack.popPose() y += font.lineHeight * 3 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/Gauges.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/Gauges.kt index c8f8df595..21bb0a8f8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/Gauges.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/Gauges.kt @@ -105,7 +105,7 @@ open class PatternGaugePanel @JvmOverloads constructor( protected open fun makeTooltip(): MutableList { return mutableListOf( 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)) ) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Fraction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Fraction.kt index 33431f108..a93b1ae6a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Fraction.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Fraction.kt @@ -10,6 +10,8 @@ import java.math.BigInteger import java.math.MathContext import java.math.RoundingMode +private val IMPRECISE_CONTEXT = MathContext(17) + private fun powScale(int: Int): BigInteger { if (int <= 0) 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()) } + 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 { if (isNaN()) { return byteArrayOf(1, 0, 0, 0, 0, 1, 0, 0, 0, 0) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/ImpreciseFraction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/ImpreciseFraction.kt index 264ea73fa..f0bad9ce9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/ImpreciseFraction.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/ImpreciseFraction.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.core import net.minecraft.nbt.ByteArrayTag import net.minecraft.nbt.StringTag import net.minecraft.nbt.Tag +import net.minecraft.network.FriendlyByteBuf import java.math.BigDecimal import java.math.BigInteger import java.math.MathContext @@ -13,6 +14,14 @@ private fun isZero(value: BigInteger) = value == BigInteger.ZERO 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 { LONG_BUFF.position(0) LONG_BUFF.putLong(value) @@ -33,6 +42,29 @@ private fun bytesToLong(value: ByteArray, from: Int = 0): 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 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 } +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") class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Double = 0.0) : Comparable { @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: Long, decimal: Double = 0.0) : this(BigInteger.valueOf(whole), decimal) constructor(value: BigDecimal) : this(value.toBigInteger(), value.remainder(BigDecimal.ONE).toDouble()) // TODO - constructor(value: Float) : this(BigDecimal(value.toString())) - constructor(value: Double) : this(BigDecimal(value.toString())) + constructor(value: Float) : this(BigInteger.valueOf((value - value % 1.0).toLong()), value % 1.0) + constructor(value: Double) : this(BigInteger.valueOf((value - value % 1.0).toLong()), value % 1.0) constructor(value: String) : this(BigDecimal(value)) 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 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) } + 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 { return ImpreciseFraction(-whole, decimal) } override fun equals(other: Any?): Boolean { - if (isNaN()) + if (isNaN) return false if (other is ImpreciseFraction) { @@ -149,7 +213,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do } fun equalsStrict(other: Any?): Boolean { - if (isNaN()) + if (isNaN) return false if (other is ImpreciseFraction) { @@ -160,16 +224,36 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do } override fun hashCode(): Int { - if (isNaN()) + if (isNaN) return Double.NaN.hashCode() return 31 * decimal.hashCode() + whole.hashCode() } - override fun toString(): String { - if (isNaN()) + fun toString(decimals: Int): String { + if (isNaN) 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()) { 1 -> "$whole.${decimal.toString().substring(2)}" 0 -> "0.0" @@ -178,9 +262,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do } } - fun toDouble(): Double { - return java.lang.Double.parseDouble(toString()) - } + override fun toString() = toString(-1) fun toBigDecmial(): BigDecimal { return BigDecimal(whole) + BigDecimal(decimal) @@ -197,9 +279,9 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do } override fun compareTo(other: ImpreciseFraction): Int { - if (isNaN()) + if (isNaN) return 1 - else if (other.isNaN()) + else if (other.isNaN) return -1 val a = signum() @@ -222,9 +304,9 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do } fun compareToStrict(other: ImpreciseFraction): Int { - if (isNaN()) + if (isNaN) return 1 - else if (other.isNaN()) + else if (other.isNaN) return -1 val a = signum() @@ -246,16 +328,16 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do return whole.compareTo(other.whole) } - fun toBytesArray(): ByteArray { + fun toByteArray(): ByteArray { val whole = whole.toByteArray() return byteArrayOf(whole.size.toByte(), *whole, *longToBytes(decimal.toBits())) } 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 { if (signum() >= 0) @@ -295,28 +377,105 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do 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 { @JvmField val MINUS_ZERO = ImpreciseFraction(0, -0.0) @JvmField val ZERO = ImpreciseFraction(BigInteger.ZERO) @JvmField val ONE = ImpreciseFraction(BigInteger.ONE) + @JvmField val MINUS_ONE = ImpreciseFraction(-BigInteger.ONE) @JvmField val TWO = ImpreciseFraction(BigInteger.TWO) @JvmField val TEN = ImpreciseFraction(BigInteger.TEN) - fun fromBytesArray(input: ByteArray): ImpreciseFraction { - val size = if (input[0] < 0) input[0].toInt() + 256 else input[0].toInt() + @JvmField val INT_MAX_VALUE = ImpreciseFraction(BI_INT_MAX) + @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 bits = bytesToLong(input, 1 + size) return ImpreciseFraction(BigInteger(slice), Double.fromBits(bits)) } + @JvmStatic fun deserializeNBT(input: Tag?): ImpreciseFraction { if (input is ByteArrayTag) { - return fromBytesArray(input.asByteArray) + return fromByteArray(input.asByteArray) } else if (input is StringTag) { return ImpreciseFraction(input.asString) } 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) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterNetworkGraph.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterNetworkGraph.kt index d756d8511..b5fe1b517 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterNetworkGraph.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/graph/matter/MatterNetworkGraph.kt @@ -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.matter.* import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.graph.Abstract6Graph import ru.dbotthepony.mc.otm.graph.Graph6Node import java.util.* @@ -71,8 +72,8 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe } } - fun getMatterStorageLevel(): Fraction { - var level = Fraction.ZERO + fun getMatterStorageLevel(): ImpreciseFraction { + var level = ImpreciseFraction.ZERO for (node in _nodes) { val matter = node.value.getMatterHandler() @@ -85,8 +86,8 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe return level } - fun getMatterStorageMaxLevel(): Fraction { - var level = Fraction.ZERO + fun getMatterStorageMaxLevel(): ImpreciseFraction { + var level = ImpreciseFraction.ZERO for (node in _nodes) { val matter = node.value.getMatterHandler() @@ -99,12 +100,12 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe return level } - fun extractMatter(howMuch: Fraction, simulate: Boolean): Fraction { - if (howMuch <= Fraction.ZERO) - return Fraction.ZERO + fun extractMatter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { + if (howMuch <= ImpreciseFraction.ZERO) + return ImpreciseFraction.ZERO var howMuch = howMuch - var extracted = Fraction.ZERO + var extracted = ImpreciseFraction.ZERO for (node in _nodes) { val matter = node.value.getMatterHandler() @@ -114,7 +115,7 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe howMuch -= value extracted += value - if (howMuch <= Fraction.ZERO) + if (howMuch <= ImpreciseFraction.ZERO) return extracted } } @@ -122,12 +123,12 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe return extracted } - fun receiveMatter(howMuch: Fraction, simulate: Boolean): Fraction { - if (howMuch <= Fraction.ZERO) - return Fraction.ZERO + fun receiveMatter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { + if (howMuch <= ImpreciseFraction.ZERO) + return ImpreciseFraction.ZERO var howMuch = howMuch - var received = Fraction.ZERO + var received = ImpreciseFraction.ZERO for (node in _nodes) { val matter = node.value.getMatterHandler() @@ -137,7 +138,7 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe howMuch -= value received += value - if (howMuch <= Fraction.ZERO) + if (howMuch <= ImpreciseFraction.ZERO) return received } } @@ -145,12 +146,12 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe return received } - fun receiveMatterForce(howMuch: Fraction, simulate: Boolean): Fraction { - if (howMuch <= Fraction.ZERO) - return Fraction.ZERO + fun receiveMatterForce(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { + if (howMuch <= ImpreciseFraction.ZERO) + return ImpreciseFraction.ZERO var howMuch = howMuch - var received = Fraction.ZERO + var received = ImpreciseFraction.ZERO for (node in _nodes) { val matter = node.value.getMatterHandler() @@ -160,7 +161,7 @@ class MatterNetworkGraph : Abstract6Graph(), IMatterGraphListe howMuch -= value received += value - if (howMuch <= Fraction.ZERO) + if (howMuch <= ImpreciseFraction.ZERO) return received } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemBattery.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemBattery.kt index 4185619d4..c4c918a6e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemBattery.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemBattery.kt @@ -20,25 +20,26 @@ import net.minecraft.world.item.TooltipFlag import net.minecraft.world.level.Level import net.minecraftforge.common.capabilities.Capability import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction class ItemBattery : Item { private inner class BatteryMatteryCapability(private val stack: ItemStack) : IMatteryEnergyStorage, ICapabilityProvider { - private fun energy(): Fraction { + private fun energy(): ImpreciseFraction { val tag = stack.orCreateTag return if (tag.contains("otm_energy")) { - deserializeNBT(tag["otm_energy"]) - } else Fraction.ZERO + ImpreciseFraction.deserializeNBT(tag["otm_energy"]) + } else ImpreciseFraction.ZERO } - private fun energy(value: Fraction) { + private fun energy(value: ImpreciseFraction) { 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) } - override fun extractEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { if (isCreative) return howMuch val new = energy().minus(howMuch.min(extract)).moreThanZero() val diff = energy().minus(new) @@ -50,11 +51,11 @@ class ItemBattery : Item { return diff } - override fun receiveEnergyOuter(howMuch: Fraction, simulate: Boolean): Fraction { + override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { return receiveEnergyInner(howMuch, simulate) } - override fun receiveEnergyInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { if (isCreative) return howMuch val new = energy().plus(howMuch.min(receive)).min(storage) val diff = new.minus(energy()) @@ -66,15 +67,15 @@ class ItemBattery : Item { return diff } - override val missingPower: Fraction get() { - return if (isCreative) MatteryCapability.LONG_MAX_VALUE else super.missingPower + override val missingPower: ImpreciseFraction get() { + return if (isCreative) ImpreciseFraction.LONG_MAX_VALUE else super.missingPower } - override val batteryLevel: Fraction get() { - return if (isCreative) MatteryCapability.LONG_MAX_VALUE else energy() + override val batteryLevel: ImpreciseFraction get() { + return if (isCreative) ImpreciseFraction.LONG_MAX_VALUE else energy() } - override val maxBatteryLevel: Fraction get() { + override val maxBatteryLevel: ImpreciseFraction get() { return storage } @@ -94,12 +95,12 @@ class ItemBattery : Item { } private val isCreative: Boolean - val storage: Fraction - val receive: Fraction - val extract: Fraction + val storage: ImpreciseFraction + val receive: ImpreciseFraction + val extract: ImpreciseFraction 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) ) { isCreative = false @@ -115,9 +116,9 @@ class ItemBattery : Item { constructor() : super(Properties().stacksTo(1).rarity(Rarity.EPIC).tab(OverdriveThatMatters.CREATIVE_TAB)) { isCreative = true - storage = MatteryCapability.LONG_MAX_VALUE - receive = MatteryCapability.LONG_MAX_VALUE - extract = MatteryCapability.LONG_MAX_VALUE + storage = ImpreciseFraction.LONG_MAX_VALUE + receive = ImpreciseFraction.LONG_MAX_VALUE + extract = ImpreciseFraction.LONG_MAX_VALUE throughputText = TranslatableComponent("otm.item.power.infinite.throughput").withStyle(ChatFormatting.GRAY) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemMatterCapacitor.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemMatterCapacitor.kt index 957a32745..3ab20d83d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemMatterCapacitor.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemMatterCapacitor.kt @@ -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.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction.Companion.deserializeNBT +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.menu.FormattingHelper import javax.annotation.ParametersAreNonnullByDefault @@ -33,34 +34,34 @@ class ItemMatterCapacitor : Item { return if (cap === MatteryCapability.MATTER) resolver.cast() else LazyOptional.empty() } - private fun matter(): Fraction { + private fun matter(): ImpreciseFraction { val tag = stack.orCreateTag - return if (tag.contains("otm_matter")) { - deserializeNBT(tag["otm_matter"]) - } else Fraction.ZERO + return if (tag.contains("matter")) { + ImpreciseFraction.deserializeNBT(tag["matter"]) + } else ImpreciseFraction.ZERO } - private fun matter(value: Fraction) { - stack.getOrCreateTag().put("otm_matter", value.serializeNBT()) + private fun matter(value: ImpreciseFraction) { + stack.getOrCreateTag().put("matter", value.serializeNBT()) } - override fun getStoredMatter(): Fraction { - return if (isCreative) Fraction.LONG_MAX_VALUE else matter() + override fun getStoredMatter(): ImpreciseFraction { + return if (isCreative) ImpreciseFraction.LONG_MAX_VALUE else matter() } - override fun getMaxStoredMatter(): Fraction { + override fun getMaxStoredMatter(): ImpreciseFraction { return storage } - override fun getMissingMatter(): Fraction { - return if (isCreative) Fraction.LONG_MAX_VALUE else super.getMissingMatter() + override fun getMissingMatter(): ImpreciseFraction { + 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) } - override fun receiveMatterInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { if (isCreative) return howMuch val new = matter().plus(howMuch.min(maxInput)).min(storage) val diff = new.minus(matter()) @@ -72,11 +73,11 @@ class ItemMatterCapacitor : Item { return diff } - override fun extractMatterOuter(howMuch: Fraction, simulate: Boolean): Fraction { + override fun extractMatterOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { return extractMatterInner(howMuch, simulate) } - override fun extractMatterInner(howMuch: Fraction, simulate: Boolean): Fraction { + override fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { if (isCreative) return howMuch val new = matter().minus(howMuch.min(maxOutput)).moreThanZero() val diff = matter().minus(new) @@ -93,17 +94,17 @@ class ItemMatterCapacitor : Item { } } - val storage: Fraction + val storage: ImpreciseFraction 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 this.storage = storage } constructor() : super(Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB).rarity(Rarity.EPIC)) { isCreative = true - storage = MatteryCapability.LONG_MAX_VALUE + storage = ImpreciseFraction.LONG_MAX_VALUE } override fun appendHoverText( @@ -133,8 +134,8 @@ class ItemMatterCapacitor : Item { } companion object { - private val maxInput = MatteryCapability.LONG_MAX_VALUE - private val maxOutput = MatteryCapability.LONG_MAX_VALUE + private val maxInput = ImpreciseFraction.LONG_MAX_VALUE + private val maxOutput = ImpreciseFraction.LONG_MAX_VALUE private val INFINITE_STORAGE: Component = TranslatableComponent("otm.item.matter.infinite").withStyle(ChatFormatting.GRAY) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.kt index 7abb58fbe..0c9fd180c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.kt @@ -25,15 +25,16 @@ import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraftforge.event.entity.player.EntityItemPickupEvent import ru.dbotthepony.mc.otm.capability.drive.DrivePool import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.set import java.util.* class ItemPortableCondensationDrive(capacity: Int) : Item(Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)) { - val capacity: Fraction + val capacity: ImpreciseFraction init { - this.capacity = Fraction(capacity) + this.capacity = ImpreciseFraction(capacity) } private inner class DriveCapability(private val stack: ItemStack) : ICapabilityProvider { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuEnergyCounter.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuEnergyCounter.kt index 880a377a0..c85fac927 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuEnergyCounter.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuEnergyCounter.kt @@ -5,16 +5,17 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.Registry import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer +import ru.dbotthepony.mc.otm.menu.data.ImpreciseFractionDataContainer class MenuEnergyCounter @JvmOverloads constructor( p_38852_: Int, inventory: Inventory, tile: BlockEntityEnergyCounter? = null ) : MatteryMenu(Registry.Menus.ENERGY_COUNTER, p_38852_, inventory, tile) { - @JvmField val passed = FractionDataContainer() - @JvmField val average = FractionDataContainer() - @JvmField val last20Ticks = FractionDataContainer() - @JvmField val lastTick = FractionDataContainer() + @JvmField val passed = ImpreciseFractionDataContainer() + @JvmField val average = ImpreciseFractionDataContainer() + @JvmField val last20Ticks = ImpreciseFractionDataContainer() + @JvmField val lastTick = ImpreciseFractionDataContainer() // TODO: Graph and proper networking for it private var ticksPassed = 0 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterCapacitor.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterCapacitor.kt index 45c96958d..a292a9f8e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterCapacitor.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterCapacitor.kt @@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.Registry import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCapacitorBank import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget @@ -26,9 +27,9 @@ class MenuMatterCapacitor @JvmOverloads constructor( } else { matterGauge = LevelGaugeWidget(this, tile) 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 }) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterScanner.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterScanner.kt index d5f544d1e..abc086544 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterScanner.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterScanner.kt @@ -9,6 +9,7 @@ import net.minecraft.world.SimpleContainer import net.minecraft.world.item.ItemStack import ru.dbotthepony.mc.otm.Registry import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.matter.MatterRegistry import java.math.BigInteger @@ -37,8 +38,8 @@ class MenuMatterScanner @JvmOverloads constructor( if (tile != null) { progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }, tile::isUnableToProcess) patterns = LevelGaugeWidget(this, - { Fraction(tile.getAsMatterGraph()?.getPatternCount()?.toBigInteger() ?: BigInteger.ZERO) }, - { Fraction(tile.getAsMatterGraph()?.getPatternCapacity()?.toBigInteger() ?: BigInteger.ZERO) }) + { ImpreciseFraction(tile.getAsMatterGraph()?.getPatternCount()?.toBigInteger() ?: BigInteger.ZERO) }, + { ImpreciseFraction(tile.getAsMatterGraph()?.getPatternCapacity()?.toBigInteger() ?: BigInteger.ZERO) }) } else { progress = ProgressGaugeWidget(this) patterns = LevelGaugeWidget(this) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuPatternStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuPatternStorage.kt index 3d8d00573..e7b7f73d6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuPatternStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuPatternStorage.kt @@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory import ru.dbotthepony.mc.otm.Registry import ru.dbotthepony.mc.otm.block.entity.BlockEntityPatternStorage import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget @@ -26,9 +27,9 @@ class MenuPatternStorage @JvmOverloads constructor( } else { stored_this = LevelGaugeWidget(this, tile) 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) }) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/FractionDataContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/FractionDataContainer.kt index 801a20954..6157cf150 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/FractionDataContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/FractionDataContainer.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.menu.data import net.minecraft.world.inventory.ContainerData import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.network.NetworkHelper import java.util.zip.CRC32 @@ -47,6 +48,7 @@ class FractionDataContainer : ContainerData { set(value) { _value = value + val _value = _value if (_value == null) { buffer.fill(0) return @@ -54,7 +56,95 @@ class FractionDataContainer : ContainerData { try { 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() crc.update(bytes) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.kt index fcdefbbf0..f0b696950 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.kt @@ -8,7 +8,7 @@ import net.minecraft.world.inventory.ClickAction import net.minecraft.world.inventory.ClickType import net.minecraft.world.item.ItemStack 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.network.MatteryNetworking 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) = 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) { if (!remote) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/LevelGaugeWidget.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/LevelGaugeWidget.kt index 469057044..d4cf734a7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/LevelGaugeWidget.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/widget/LevelGaugeWidget.kt @@ -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.IPatternStorage 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.data.FractionDataContainer +import ru.dbotthepony.mc.otm.menu.data.ImpreciseFractionDataContainer @Suppress("unused") class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) { - @JvmField var level = {Fraction.ONE} - @JvmField var maxLevel = {Fraction.ONE} + @JvmField var level = { ImpreciseFraction.ONE} + @JvmField var maxLevel = {ImpreciseFraction.ONE} - @JvmField val levelContainer = FractionDataContainer() - @JvmField val maxLevelContainer = FractionDataContainer() + @JvmField val levelContainer = ImpreciseFractionDataContainer() + @JvmField val maxLevelContainer = ImpreciseFractionDataContainer() constructor( menu: MatteryMenu, @@ -41,14 +43,14 @@ class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) { ) : this(menu) { if (patterns == null) return - this.level = {Fraction(patterns.stored)} - this.maxLevel = {Fraction(patterns.capacity)} + this.level = {ImpreciseFraction(patterns.stored)} + this.maxLevel = {ImpreciseFraction(patterns.capacity)} } constructor( menu: MatteryMenu, - level: () -> Fraction, - maxLevel: () -> Fraction, + level: () -> ImpreciseFraction, + maxLevel: () -> ImpreciseFraction, ) : this(menu) { this.level = level this.maxLevel = maxLevel @@ -64,7 +66,7 @@ class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) { maxLevelContainer.value = maxLevel.invoke() } - fun level(): Fraction = levelContainer.value - fun maxLevel(): Fraction = maxLevelContainer.value + fun level(): ImpreciseFraction = levelContainer.value + fun maxLevel(): ImpreciseFraction = maxLevelContainer.value fun percentage(): Float = levelContainer.value.percentage(maxLevelContainer.value) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/API.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/API.kt index ab2eef382..3456c4b5c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/API.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/API.kt @@ -1,19 +1,19 @@ package ru.dbotthepony.mc.otm.storage -import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import java.util.* interface IStorageStack { fun copy(): IStorageStack - var count: Fraction + var count: ImpreciseFraction fun isEmpty(): Boolean /** * @return max stack size for this stack object * [Optional.empty()] if unlimited (default) */ - fun getMaxStackSize(): Optional = Optional.empty() + fun getMaxStackSize(): Optional = Optional.empty() /** * Returns Identity utilized to partition view table (if it has any). @@ -38,11 +38,11 @@ interface IStorageStack { */ fun sameItem(other: IStorageStack): Boolean - fun grow(amount: Fraction) { + fun grow(amount: ImpreciseFraction) { count += amount } - fun shrink(amount: Fraction) { + fun shrink(amount: ImpreciseFraction) { count -= amount } } @@ -83,9 +83,9 @@ interface IStorageView : IStorageTrigger { * @param simulate whenever to simulate the action or not * @return copy of object, with amount of units actually extracted */ - fun extractStack(id: UUID, amount: Fraction, simulate: Boolean): T - fun extractStack(id: UUID, amount: Int, simulate: Boolean): T = extractStack(id, Fraction(amount), simulate) - fun extractStack(id: UUID, amount: Long, simulate: Boolean): T = extractStack(id, Fraction(amount), simulate) + fun extractStack(id: UUID, amount: ImpreciseFraction, simulate: Boolean): T + 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, ImpreciseFraction(amount), simulate) /** * Designed for views, for extraction with less computation overhead caused by @@ -96,12 +96,12 @@ interface IStorageView : IStorageTrigger { * @param simulate whenever to simulate the action or not * @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 } - fun extractStackCount(id: UUID, amount: Int, simulate: Boolean): Fraction = extractStackCount(id, Fraction(amount), simulate) - fun extractStackCount(id: UUID, amount: Long, 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): ImpreciseFraction = extractStackCount(id, ImpreciseFraction(amount), simulate) fun getStacks(): Collection> @@ -139,7 +139,7 @@ interface IStorageListener { /** * 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 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/ItemStackWrapper.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/ItemStackWrapper.kt index 894149f28..2a813dd09 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/ItemStackWrapper.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/ItemStackWrapper.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.storage import net.minecraft.world.item.ItemStack import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import java.util.* @JvmRecord @@ -14,14 +15,14 @@ data class ItemStackWrapper(val stack: ItemStack) : IStorageStack { stack.count = Math.max(value, 0) } - override var count: Fraction - get() = Fraction(stack.count) + override var count: ImpreciseFraction + get() = ImpreciseFraction(stack.count) set(value) = setCount(value.toInt()) fun getCountInt() = stack.count - override fun getMaxStackSize(): Optional { - return Optional.of(Fraction(stack.maxStackSize)) + override fun getMaxStackSize(): Optional { + return Optional.of(ImpreciseFraction(stack.maxStackSize)) } override fun isEmpty(): Boolean = stack.isEmpty diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/VirtualComponent.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/VirtualComponent.kt index 302a525ad..a3e5ac8ab 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/VirtualComponent.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/VirtualComponent.kt @@ -2,14 +2,15 @@ package ru.dbotthepony.mc.otm.storage import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.core.ImpreciseFraction import java.util.* class RemoteTuple(val obj: T, val remote_id: UUID, val provider: IStorageView, val local: LocalTuple) { - fun extract(amount: Fraction, simulate: Boolean): T { + fun extract(amount: ImpreciseFraction, simulate: Boolean): T { 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) } @@ -145,8 +146,8 @@ open class VirtualComponent(identity: Class) : IStorageCom } } - override fun changeObject(id: UUID, newCount: Fraction) { - assert(newCount > Fraction.ZERO) + override fun changeObject(id: UUID, newCount: ImpreciseFraction) { + assert(newCount > ImpreciseFraction.ZERO) val tuple = remoteByUUID[id] ?: throw IllegalStateException("No such tuple with id $id") val diff = newCount - tuple.obj.count @@ -167,7 +168,7 @@ open class VirtualComponent(identity: Class) : IStorageCom 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 if (a || b) { @@ -195,21 +196,21 @@ open class VirtualComponent(identity: Class) : IStorageCom return leftover } - override fun extractStack(id: UUID, amount: Fraction, simulate: Boolean): T { - if (amount.isZero()) + override fun extractStack(id: UUID, amount: ImpreciseFraction, simulate: Boolean): T { + if (amount.isZero) return identity.empty var amount = amount val tuple: LocalTuple? = localByUUID[id] - if (tuple == null || amount.isZero()) + if (tuple == null || amount.isZero) return identity.empty - if (amount <= Fraction.MINUS_ONE) + if (amount <= ImpreciseFraction.MINUS_ONE) amount = tuple.stack.getMaxStackSize().orElse(tuple.stack.count) val toExtract = tuple.stack.count.min(amount) - var extracted = Fraction.ZERO + var extracted = ImpreciseFraction.ZERO val copy = tuple.stack.copy() as T for (remote_tuple in tuple.tuples) { @@ -219,7 +220,7 @@ open class VirtualComponent(identity: Class) : IStorageCom break } - if (extracted > Fraction.ZERO) { + if (extracted > ImpreciseFraction.ZERO) { copy.count = extracted return copy } @@ -235,11 +236,11 @@ open class PoweredVirtualComponent(identity: Class, @JvmFi } override fun insertStack(stack: T, simulate: Boolean): T { - val required = stack.count * identity.energyPerOperation + val required = identity.energyPerOperation * stack.count val energy = energyProvider() val extracted = energy.extractEnergyInner(required, true) - if (extracted.isZero()) { + if (extracted.isZero) { return stack.copy() as T } @@ -255,7 +256,7 @@ open class PoweredVirtualComponent(identity: Class, @JvmFi } if (!simulate) { - val requiredNew = (stack.count - leftover.count) * identity.energyPerOperation + val requiredNew = identity.energyPerOperation * stack.count - leftover.count energy.extractEnergyInner(requiredNew, false) } @@ -266,7 +267,7 @@ open class PoweredVirtualComponent(identity: Class, @JvmFi val oldCount = stack.count stack.count = extracted / identity.energyPerOperation val diff = oldCount - stack.count - val newRequired = stack.count * identity.energyPerOperation + val newRequired = identity.energyPerOperation * stack.count val newExtracted = energy.extractEnergyInner(newRequired, true) if (newExtracted == newRequired) { @@ -293,12 +294,12 @@ open class PoweredVirtualComponent(identity: Class, @JvmFi return stack } - override fun extractStack(id: UUID, amount: Fraction, simulate: Boolean): T { - val required = amount * identity.energyPerOperation + override fun extractStack(id: UUID, amount: ImpreciseFraction, simulate: Boolean): T { + val required = identity.energyPerOperation * amount val energy = energyProvider() val extracted = energy.extractEnergyInner(required, true) - if (extracted.isZero()) { + if (extracted.isZero) { return identity.empty } diff --git a/src/test/kotlin/ru/dbotthepony/mc/otm/tests/ImpreciseFractionTests.kt b/src/test/kotlin/ru/dbotthepony/mc/otm/tests/ImpreciseFractionTests.kt index 278da8ec6..d011f9a9a 100644 --- a/src/test/kotlin/ru/dbotthepony/mc/otm/tests/ImpreciseFractionTests.kt +++ b/src/test/kotlin/ru/dbotthepony/mc/otm/tests/ImpreciseFractionTests.kt @@ -37,7 +37,7 @@ object ImpreciseFractionTests { @DisplayName("ImpreciseFraction store/load") fun storeLoad() { val f = ImpreciseFraction(4, 0.28) - val loaded = ImpreciseFraction.fromBytesArray(f.toBytesArray()) + val loaded = ImpreciseFraction.fromByteArray(f.toByteArray()) check(f == loaded) { "$f != $loaded" } } }