From 6d78029af2bde038be3d4f4108ab08150c51f37c Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 23 Dec 2021 22:46:25 +0700 Subject: [PATCH] Kotlin, Unit tests, Fraction instead of BigDecimal --- build.gradle | 12 + .../mc/otm/OverdriveThatMatters.java | 6 +- .../java/ru/dbotthepony/mc/otm/Registry.java | 17 +- .../android/feature/AndroidNanobotsArmor.java | 9 +- .../feature/AndroidNanobotsRegeneration.java | 9 +- .../entity/BlockEntityAndroidStation.java | 9 +- .../block/entity/BlockEntityBatteryBank.java | 73 +-- .../block/entity/BlockEntityBlackHole.java | 23 +- .../block/entity/BlockEntityDriveRack.java | 3 +- .../block/entity/BlockEntityDriveViewer.java | 15 +- .../entity/BlockEntityEnergyCounter.java | 91 +-- .../block/entity/BlockEntityItemMonitor.java | 3 +- .../entity/BlockEntityMatterBottler.java | 55 +- .../BlockEntityMatterCapacitorBank.java | 41 +- .../entity/BlockEntityMatterDecomposer.java | 21 +- .../entity/BlockEntityMatterReplicator.java | 31 +- .../entity/BlockEntityMatterScanner.java | 9 +- .../entity/BlockEntityMatteryPowered.java | 15 +- .../worker/BlockEntityMatteryWorker.java | 22 +- .../otm/block/entity/worker/MachineJob.java | 11 +- .../block/entity/worker/WorkTickContext.java | 5 +- .../otm/capability/IMatteryEnergyStorage.java | 82 ++- .../mc/otm/capability/MatteryCapability.java | 25 +- .../MatteryMachineEnergyStorage.java | 63 +- .../capability/android/AndroidCapability.java | 117 ++-- .../android/AndroidCapabilityPlayer.java | 19 +- .../android/IAndroidCapability.java | 5 +- .../drive/AbstractMatteryDrive.java | 39 +- .../otm/capability/drive/IMatteryDrive.java | 5 +- .../capability/drive/ItemMatteryDrive.java | 5 +- .../otm/capability/matter/IMatterHandler.java | 17 +- .../matter/MatterHandlerCapability.java | 61 +- .../dbotthepony/mc/otm/client/AndroidGui.java | 5 +- .../client/screen/EnergyCounterScreen.java | 6 +- .../dbotthepony/mc/otm/item/ItemBattery.java | 66 +-- .../mc/otm/item/ItemMatterCapacitor.java | 64 +- .../item/ItemPortableCondensationDrive.java | 5 +- .../dbotthepony/mc/otm/matter/MatterGrid.java | 79 +-- .../mc/otm/matter/MatterRegistry.java | 356 +++++------ .../mc/otm/menu/DriveViewerMenu.java | 12 +- .../mc/otm/menu/EnergyCounterMenu.java | 13 +- .../mc/otm/menu/FormattingHelper.java | 93 +++ .../mc/otm/menu/MatterCapacitorBankMenu.java | 5 +- .../mc/otm/menu/data/NetworkedItemView.java | 11 +- .../otm/menu/widget/BatteryLevelWidget.java | 5 +- .../mc/otm/menu/widget/MatterLevelWidget.java | 5 +- .../otm/menu/widget/StorageGaugeWidget.java | 20 +- .../mc/otm/network/MatterRegistryPacket.java | 9 +- .../mc/otm/network/NetworkHelper.java | 30 + .../network/android/AndroidEnergyPacket.java | 7 +- .../mc/otm/storage/IStorageListener.java | 3 +- .../mc/otm/storage/IStorageStack.java | 15 +- .../mc/otm/storage/IStorageView.java | 5 +- .../mc/otm/storage/ItemStackWrapper.java | 13 +- .../mc/otm/storage/VirtualComponent.java | 29 +- .../ru/dbotthepony/mc/otm/core/Fraction.kt | 555 ++++++++++++++++++ .../mc/otm/menu/data/FractionDataContainer.kt | 51 ++ .../dbotthepony/mc/otm/tests/FractionTests.kt | 121 ++++ .../mc/otm/tests/NetworkingTests.kt | 52 ++ 59 files changed, 1752 insertions(+), 801 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/core/Fraction.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/FractionDataContainer.kt create mode 100644 src/test/kotlin/ru/dbotthepony/mc/otm/tests/FractionTests.kt create mode 100644 src/test/kotlin/ru/dbotthepony/mc/otm/tests/NetworkingTests.kt diff --git a/build.gradle b/build.gradle index 93eae300d..8f61425f1 100644 --- a/build.gradle +++ b/build.gradle @@ -5,8 +5,11 @@ buildscript { maven { url = 'https://maven.minecraftforge.net' } mavenCentral() } + dependencies { classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true + + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0" } } @@ -14,6 +17,9 @@ apply plugin: 'net.minecraftforge.gradle' // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. apply plugin: 'eclipse' apply plugin: 'maven-publish' +apply plugin: 'kotlin' + +apply from: 'https://raw.githubusercontent.com/thedarkcolour/KotlinForForge/site/thedarkcolour/kotlinforforge/gradle/kff-3.0.0.gradle' version = '1.0' group = 'ru.dbotthepony.mc' // http://maven.apache.org/guides/mini/guide-naming-conventions.html @@ -29,6 +35,10 @@ exec { args 'shapenator.js' } +test { + useJUnitPlatform() +} + minecraft { // The mappings can be changed at any time and must be in the following format. // Channel: Version: @@ -140,6 +150,8 @@ dependencies { // The userdev artifact is a special name and will get all sorts of transformations applied to it. minecraft 'net.minecraftforge:forge:1.18.1-39.0.7' + testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2' + // Real mod deobf dependency examples - these get remapped to your current mappings // compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index 326669693..5319aabec 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -6,6 +6,8 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.TickEvent; +import net.minecraftforge.event.server.ServerAboutToStartEvent; +import net.minecraftforge.event.server.ServerStoppingEvent; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.InterModComms; @@ -16,14 +18,12 @@ import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.event.server.ServerAboutToStartEvent; -import net.minecraftforge.event.server.ServerStoppingEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import ru.dbotthepony.mc.otm.block.entity.BlockEntityBlackHole; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.android.AndroidCapability; import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer; -import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.drive.DrivePool; import ru.dbotthepony.mc.otm.client.AndroidGui; import ru.dbotthepony.mc.otm.client.EventHandler; diff --git a/src/main/java/ru/dbotthepony/mc/otm/Registry.java b/src/main/java/ru/dbotthepony/mc/otm/Registry.java index f3cda2660..ed890c481 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/Registry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/Registry.java @@ -37,6 +37,7 @@ import ru.dbotthepony.mc.otm.block.entity.*; import ru.dbotthepony.mc.otm.android.AndroidFeatureType; import ru.dbotthepony.mc.otm.client.render.BlackHoleRenderer; import ru.dbotthepony.mc.otm.client.render.SkinElement; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.item.*; import ru.dbotthepony.mc.otm.menu.*; import ru.dbotthepony.mc.otm.client.screen.*; @@ -410,17 +411,17 @@ public class Registry { public static final ItemPill PILL_ANDROID = new ItemPill(ItemPill.PillType.BECOME_ANDROID); public static final ItemPill PILL_HUMANE = new ItemPill(ItemPill.PillType.BECOME_HUMANE); - public static final ItemBattery BATTERY_CRUDE = new ItemBattery(new BigDecimal(30_000), new BigDecimal(150), new BigDecimal(150)); - public static final ItemBattery BATTERY_BASIC = new ItemBattery(new BigDecimal(60_000), new BigDecimal(300), new BigDecimal(300)); - public static final ItemBattery BATTERY_NORMAL = new ItemBattery(new BigDecimal(250_000), new BigDecimal(1000), new BigDecimal(1000)); - public static final ItemBattery BATTERY_DENSE = new ItemBattery(new BigDecimal(1_000_000), new BigDecimal(2000), new BigDecimal(2000)); - public static final ItemBattery BATTERY_CAPACITOR = new ItemBattery(new BigDecimal(150_000), new BigDecimal(15000), new BigDecimal(15000)); + 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_CREATIVE = new ItemBattery(); public static final Item MATTER_CAPACITOR_PARTS = new Item(new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); - public static final ItemMatterCapacitor MATTER_CAPACITOR_BASIC = new ItemMatterCapacitor(new BigDecimal("4")); - public static final ItemMatterCapacitor MATTER_CAPACITOR_NORMAL = new ItemMatterCapacitor(new BigDecimal("10")); - public static final ItemMatterCapacitor MATTER_CAPACITOR_DENSE = new ItemMatterCapacitor(new BigDecimal("40")); + 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_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 52ccce1ef..c4fcbd88a 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 @@ -8,6 +8,7 @@ import ru.dbotthepony.mc.otm.android.AndroidFeature; 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 java.math.BigDecimal; @@ -38,8 +39,8 @@ public class AndroidNanobotsArmor extends AndroidFeature { protected int ticks_passed = 0; protected int layers = 0; - protected static final BigDecimal ENERGY_PER_BUILT = new BigDecimal(200); - protected static final BigDecimal ENERGY_PER_HITPOINT = new BigDecimal(500); + protected static final Fraction ENERGY_PER_BUILT = new Fraction(200); + protected static final Fraction ENERGY_PER_HITPOINT = new Fraction(500); public static final int[] TICKS = new int[] { 80, // 4 seconds to build a layer @@ -77,9 +78,9 @@ public class AndroidNanobotsArmor extends AndroidFeature { var absorbed = event.getAmount() * SHIELD_STRENGTH[layers]; if (absorbed > 0.1f) { - var required = ENERGY_PER_HITPOINT.multiply(new BigDecimal(Float.toString(absorbed))); + var required = ENERGY_PER_HITPOINT.times(absorbed); var extracted = capability.extractEnergyInner(required, false); - var real_absorbed = absorbed * extracted.divide(required, MatteryCapability.ROUND_RULES).floatValue(); + var real_absorbed = absorbed * extracted.div(required).toFloat(); event.setAmount(event.getAmount() - real_absorbed); if (capability.getEntity() instanceof ServerPlayer ply) { 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 f6ddbb02b..c7db98957 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 @@ -8,6 +8,7 @@ import ru.dbotthepony.mc.otm.android.AndroidFeature; 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 java.math.BigDecimal; @@ -19,7 +20,7 @@ public class AndroidNanobotsRegeneration extends AndroidFeature { protected int ticks_passed = 0; protected int heal_ticks = 0; - protected static final BigDecimal ENERGY_PER_HITPOINT = new BigDecimal(800); + protected static final Fraction ENERGY_PER_HITPOINT = new Fraction(800); protected static final int[] TICKS_BETWEEN_HEAL = new int[] { 100, // 5 seconds @@ -39,11 +40,11 @@ public class AndroidNanobotsRegeneration extends AndroidFeature { if (ticks_passed > wait_time) { var missing = Math.min(1, ent.getMaxHealth() - ent.getHealth()); - var extract = capability.extractEnergyInner(ENERGY_PER_HITPOINT.multiply(new BigDecimal(Float.toString(missing))), false); + var extract = capability.extractEnergyInner(ENERGY_PER_HITPOINT.times(missing), false); - if (extract.compareTo(BigDecimal.ZERO) > 0) { + if (extract.compareTo(Fraction.ZERO) > 0) { heal_ticks = Math.min(heal_ticks + 1, level); - var heal = missing * extract.divide(ENERGY_PER_HITPOINT, MatteryCapability.ROUND_RULES).floatValue(); + var heal = missing * extract.div(ENERGY_PER_HITPOINT).toFloat(); ent.heal(heal); if (capability.getEntity() instanceof ServerPlayer ply) { diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java index d620f74df..464ed7a0c 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java @@ -17,6 +17,7 @@ import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; 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.menu.AndroidStationMenu; import javax.annotation.Nullable; @@ -43,7 +44,7 @@ public class BlockEntityAndroidStation extends BlockEntityMatteryPowered impleme public BlockEntityAndroidStation(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.ANDROID_STATION, p_155229_, p_155230_); - energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(100_000), new BigDecimal(250), new BigDecimal(250)); + energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new Fraction(100_000), new Fraction(250), new Fraction(250)); } public static void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { @@ -69,13 +70,13 @@ public class BlockEntityAndroidStation extends BlockEntityMatteryPowered impleme final var missing = capability.getMissingPower(); - if (missing.compareTo(BigDecimal.ZERO) > 0) { + if (missing.compareTo(Fraction.ZERO) > 0) { final var extract = tile.energy.extractEnergyInner(missing, true); - if (extract.compareTo(BigDecimal.ZERO) > 0) { + if (extract.compareTo(Fraction.ZERO) > 0) { final var received = capability.receiveEnergyOuter(extract, true); - if (received.compareTo(BigDecimal.ZERO) > 0) { + if (received.compareTo(Fraction.ZERO) > 0) { tile.energy.extractEnergyInner(extract, false); capability.receiveEnergyOuter(extract, false); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java index ac4fae505..741950216 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java @@ -27,6 +27,7 @@ import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.container.MatteryContainer; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.menu.BatteryBankMenu; import javax.annotation.Nonnull; @@ -63,7 +64,7 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { (slot, amount, stack) -> true )); - public record BatteryBankDistribution(BigDecimal[] distribution, BigDecimal max_throughput) { + public record BatteryBankDistribution(Fraction[] distribution, Fraction max_throughput) { } @@ -86,16 +87,16 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { @Nonnull @Override - public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { + public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) { if (mode == BankMode.RECEIVE) - return BigDecimal.ZERO; + return Fraction.ZERO; return extractEnergyInner(howMuch, simulate); } BatteryBankDistribution getDistribution(boolean mode) { - BigDecimal[] distribution = new BigDecimal[tile.battery_container.getContainerSize()]; - BigDecimal summ = BigDecimal.ZERO; + Fraction[] distribution = new Fraction[tile.battery_container.getContainerSize()]; + Fraction summ = Fraction.ZERO; for (int i = 0; i < tile.battery_container.getContainerSize(); i++) { ItemStack stack = tile.battery_container.getItem(i); @@ -104,57 +105,57 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { Optional cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); if (cap.isPresent()) { - BigDecimal diff = mode ? cap.get().receiveEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true) : cap.get().extractEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true); + Fraction diff = mode ? cap.get().receiveEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true) : cap.get().extractEnergyOuter(MatteryCapability.LONG_MAX_VALUE, true); distribution[i] = diff; - summ = summ.add(diff); + summ = summ.plus(diff); } else { Optional cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); if (cap2.isPresent()) { - BigDecimal diff = new BigDecimal(mode ? cap2.get().receiveEnergy(Integer.MAX_VALUE, true) : cap2.get().extractEnergy(Integer.MAX_VALUE, true)); + Fraction diff = new Fraction(mode ? cap2.get().receiveEnergy(Integer.MAX_VALUE, true) : cap2.get().extractEnergy(Integer.MAX_VALUE, true)); distribution[i] = diff; - summ = summ.add(diff); + summ = summ.plus(diff); } } } else { - distribution[i] = BigDecimal.ZERO; + distribution[i] = Fraction.ZERO; } } - if (summ.compareTo(BigDecimal.ZERO) != 0) { + if (summ.compareTo(Fraction.ZERO) != 0) { for (int i = 0; i < tile.battery_container.getContainerSize(); i++) { - distribution[i] = distribution[i].divide(summ, MatteryCapability.ROUND_RULES); + distribution[i] = distribution[i].div(summ); } } return new BatteryBankDistribution(distribution, summ); } - private BigDecimal distributeEnergy(boolean mode, BigDecimal howMuch, boolean simulate) { + private Fraction distributeEnergy(boolean mode, Fraction howMuch, boolean simulate) { BatteryBankDistribution distribution = getDistribution(mode); - if (distribution.max_throughput.compareTo(BigDecimal.ZERO) == 0) - return BigDecimal.ZERO; + if (distribution.max_throughput.compareTo(Fraction.ZERO) == 0) + return Fraction.ZERO; - BigDecimal[] distList = distribution.distribution; - BigDecimal summ = BigDecimal.ZERO; + Fraction[] distList = distribution.distribution; + Fraction summ = Fraction.ZERO; for (int i = 0; i < tile.battery_container.getContainerSize(); i++) { - if (!distList[i].equals(BigDecimal.ZERO)) { + if (!distList[i].equals(Fraction.ZERO)) { ItemStack stack = tile.battery_container.getItem(i); if (!stack.isEmpty()) { Optional cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); if (cap.isPresent()) { - BigDecimal diff = mode ? cap.get().receiveEnergyOuter(howMuch.multiply(distList[i], MatteryCapability.ROUND_RULES), simulate) : cap.get().extractEnergyOuter(howMuch.multiply(distList[i], MatteryCapability.ROUND_RULES), simulate); - summ = summ.add(diff); + Fraction diff = mode ? cap.get().receiveEnergyOuter(howMuch.times(distList[i]), simulate) : cap.get().extractEnergyOuter(howMuch.times(distList[i]), simulate); + summ = summ.plus(diff); } else { Optional cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); if (cap2.isPresent()) { - BigDecimal diff = mode ? MatteryCapability.floodFE(cap2.get(), howMuch.multiply(distList[i], MatteryCapability.ROUND_RULES), simulate) : MatteryCapability.drainFE(cap2.get(), howMuch.multiply(distList[i], MatteryCapability.ROUND_RULES), simulate); - summ = summ.add(diff); + Fraction diff = mode ? MatteryCapability.floodFE(cap2.get(), howMuch.times(distList[i]), simulate) : MatteryCapability.drainFE(cap2.get(), howMuch.times(distList[i]), simulate); + summ = summ.plus(diff); } } } @@ -166,29 +167,29 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { @Nonnull @Override - public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { + public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) { return distributeEnergy(false, howMuch, simulate); } @Nonnull @Override - public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { + public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) { if (mode == BankMode.EXTRACT) - return BigDecimal.ZERO; + return Fraction.ZERO; return receiveEnergyInner(howMuch, simulate); } @Nonnull @Override - public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { + public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) { return distributeEnergy(true, howMuch, simulate); } @Nonnull @Override - public BigDecimal getBatteryLevel() { - BigDecimal result = BigDecimal.ZERO; + public Fraction getBatteryLevel() { + Fraction result = Fraction.ZERO; for (int i = 0; i < tile.battery_container.getContainerSize(); i++) { ItemStack stack = tile.battery_container.getItem(i); @@ -197,12 +198,12 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { Optional cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); if (cap.isPresent()) { - result = result.add(cap.get().getBatteryLevel(), MatteryCapability.ROUND_RULES); + result = result.plus(cap.get().getBatteryLevel()); } else { Optional cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); if (cap2.isPresent()) { - result = result.add(new BigDecimal(cap2.get().getEnergyStored()), MatteryCapability.ROUND_RULES); + result = result.plus(cap2.get().getEnergyStored()); } } } @@ -213,8 +214,8 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { @Nonnull @Override - public BigDecimal getMaxBatteryLevel() { - BigDecimal result = BigDecimal.ZERO; + public Fraction getMaxBatteryLevel() { + Fraction result = Fraction.ZERO; for (int i = 0; i < tile.battery_container.getContainerSize(); i++) { ItemStack stack = tile.battery_container.getItem(i); @@ -223,12 +224,12 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { Optional cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); if (cap.isPresent()) { - result = result.add(cap.get().getMaxBatteryLevel(), MatteryCapability.ROUND_RULES); + result = result.plus(cap.get().getMaxBatteryLevel()); } else { Optional cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); if (cap2.isPresent()) { - result = result.add(new BigDecimal(cap2.get().getMaxEnergyStored()), MatteryCapability.ROUND_RULES); + result = result.plus(cap2.get().getMaxEnergyStored()); } } } @@ -354,7 +355,7 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { if (cap.canReceive()) { BatteryBankDistribution distribution = tile.energy.getDistribution(false); - BigDecimal diff = cap.receiveEnergyOuter(distribution.max_throughput, true); + Fraction diff = cap.receiveEnergyOuter(distribution.max_throughput, true); diff = tile.energy.extractEnergyOuter(diff, false); cap.receiveEnergyOuter(diff, false); } @@ -363,7 +364,7 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { if (cap.canReceive()) { BatteryBankDistribution distribution = tile.energy.getDistribution(false); - BigDecimal diff = MatteryCapability.floodFE(cap, distribution.max_throughput, true); + Fraction diff = MatteryCapability.floodFE(cap, distribution.max_throughput, true); diff = tile.energy.extractEnergyOuter(diff, false); MatteryCapability.floodFE(cap, diff, false); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBlackHole.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBlackHole.java index 03995c352..a73cf9435 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBlackHole.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBlackHole.java @@ -33,6 +33,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.matter.MatterRegistry; import javax.annotation.Nullable; @@ -49,8 +50,8 @@ public class BlockEntityBlackHole extends BlockEntity { setMass(mass); } - public static final BigDecimal NORMAL_MASS = new BigDecimal(1_000); - private BigDecimal mass = NORMAL_MASS; + public static final Fraction NORMAL_MASS = new Fraction(1_000); + private Fraction mass = NORMAL_MASS; private double gravitation_strength = 1; private boolean suppress_updates = true; public boolean spin_direction = false; @@ -284,19 +285,19 @@ public class BlockEntityBlackHole extends BlockEntity { } } - public void addMass(BigDecimal mass) { - setMass(this.mass.add(mass)); + public void addMass(Fraction mass) { + setMass(this.mass.plus(mass)); } - public void setMass(BigDecimal mass) { - if (mass.compareTo(BigDecimal.ZERO) <= 0) { + public void setMass(Fraction mass) { + if (mass.compareTo(Fraction.ZERO) <= 0) { collapse(); return; } this.mass = mass; setChanged(); - gravitation_strength = mass.divide(NORMAL_MASS, MatteryCapability.ROUND_RULES).doubleValue(); + gravitation_strength = mass.div(NORMAL_MASS).toDouble(); if (gravitation_strength > 1) { gravitation_strength = Math.min(20, Math.sqrt(gravitation_strength)); @@ -327,8 +328,8 @@ public class BlockEntityBlackHole extends BlockEntity { } public void readBlackHoleData(CompoundTag tag) { - if (tag.get("mass") instanceof StringTag str) - setMass(new BigDecimal(str.getAsString())); + if (tag.contains("mass")) + setMass(Fraction.deserializeNBT(tag.get("mass"))); spin_direction = tag.getBoolean("spin_direction"); } @@ -426,7 +427,7 @@ public class BlockEntityBlackHole extends BlockEntity { } } - public static final BigDecimal HAWKING_MASS_LOSE_STEP = new BigDecimal("-0.1"); + public static final Fraction HAWKING_MASS_LOSE_STEP = new Fraction("-0.1"); public static void ticker(Level level, BlockPos blockPos, BlockState blockState, T t) { if (t instanceof BlockEntityBlackHole tile) { @@ -457,7 +458,7 @@ public class BlockEntityBlackHole extends BlockEntity { } else { var mass = MatterRegistry.getMatterValue(item.getItem()); - if (mass.compareTo(BigDecimal.ZERO) > 0) + if (mass.compareTo(Fraction.ZERO) > 0) tile.addMass(mass); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveRack.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveRack.java index 614330d54..7b46e7ba3 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveRack.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveRack.java @@ -20,6 +20,7 @@ import ru.dbotthepony.mc.otm.capability.AbstractStorageGridCell; 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.menu.DriveRackMenu; import ru.dbotthepony.mc.otm.storage.ItemStackWrapper; import ru.dbotthepony.mc.otm.storage.VirtualComponent; @@ -34,7 +35,7 @@ import java.math.BigDecimal; public class BlockEntityDriveRack extends BlockEntityMatteryPowered { public BlockEntityDriveRack(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.DRIVE_RACK, p_155229_, p_155230_); - energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(80_000)); + energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new Fraction(80_000)); } public final MatteryContainer drives = new MatteryContainer(this::setChanged, 4) { diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveViewer.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveViewer.java index b253d4562..2c788482e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveViewer.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityDriveViewer.java @@ -21,6 +21,7 @@ import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage; import ru.dbotthepony.mc.otm.container.MatteryContainer; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.menu.DriveViewerMenu; import javax.annotation.Nullable; @@ -30,7 +31,7 @@ import java.math.BigDecimal; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault public class BlockEntityDriveViewer extends BlockEntityMatteryPowered { - public static final BigDecimal MTE_PER_OPERATION = new BigDecimal("3.125"); + public static final Fraction MTE_PER_OPERATION = new Fraction("3.125"); public boolean canIOItems() { return energy.getBatteryLevel().compareTo(MTE_PER_OPERATION) >= 0; @@ -65,20 +66,20 @@ public class BlockEntityDriveViewer extends BlockEntityMatteryPowered { if (!canIOItems()) return 0; - var extracted = energy.extractEnergyInner(MTE_PER_OPERATION.multiply(new BigDecimal(desired)), true); - var modulo = extracted.divideToIntegralValue(MTE_PER_OPERATION); + var extracted = energy.extractEnergyInner(MTE_PER_OPERATION.times(desired), true); + var modulo = extracted.rem(MTE_PER_OPERATION); if (simulate) - return modulo.intValue(); + return modulo.toInt(); - energy.extractEnergyInner(modulo.multiply(MTE_PER_OPERATION), false); + energy.extractEnergyInner(modulo.times(MTE_PER_OPERATION), false); - return modulo.intValue(); + return modulo.toInt(); } public BlockEntityDriveViewer(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.DRIVE_VIEWER, p_155229_, p_155230_); - energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(30_000)); + energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new Fraction(30_000)); } private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.drive_viewer"); diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.java index d8ccdfc63..c2091fc95 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.java @@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.block.BlockEnergyCounter; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu; import javax.annotation.Nonnull; @@ -36,23 +37,23 @@ import java.util.Arrays; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault public class BlockEntityEnergyCounter extends BlockEntityMattery { - protected BigDecimal passed = BigDecimal.ZERO; - protected final BigDecimal[] history = new BigDecimal[10 * 20]; + protected Fraction passed = Fraction.ZERO; + protected final Fraction[] history = new Fraction[10 * 20]; protected int history_tick = 0; public static void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { if (t instanceof BlockEntityEnergyCounter tile) { tile.history_tick = (tile.history_tick + 1) % tile.history.length; - tile.history[tile.history_tick] = BigDecimal.ZERO; + tile.history[tile.history_tick] = Fraction.ZERO; } } - public BigDecimal[] getHistory(int ticks) { + public Fraction[] getHistory(int ticks) { if (ticks < 1 || ticks >= history.length) { throw new IllegalArgumentException("Invalid history length provided"); } - final var history = new BigDecimal[ticks]; + final var history = new Fraction[ticks]; for (int i = 0; i < ticks; i++) { int index = (history_tick - i) % this.history.length; @@ -66,16 +67,16 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery { return history; } - public BigDecimal calcAverage(int ticks) { - return sumHistory(ticks).divide(new BigDecimal(ticks), MatteryCapability.ROUND_RULES); + public Fraction calcAverage(int ticks) { + return sumHistory(ticks).div(ticks); } - public BigDecimal sumHistory(int ticks) { + public Fraction sumHistory(int ticks) { if (ticks < 1 || ticks >= history.length) { throw new IllegalArgumentException("Invalid history length provided"); } - var value = BigDecimal.ZERO; + var value = Fraction.ZERO; for (int i = 0; i < ticks; i++) { int index = (history_tick - i) % this.history.length; @@ -83,19 +84,19 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery { if (index < 0) index += this.history.length; - value = value.add(history[index]); + value = value.plus(history[index]); } return value; } - public BigDecimal getPassed() { + public Fraction getPassed() { return passed; } public BlockEntityEnergyCounter(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.ENERGY_COUNTER, p_155229_, p_155230_); - Arrays.fill(history, BigDecimal.ZERO); + Arrays.fill(history, Fraction.ZERO); } @Override @@ -117,17 +118,29 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery { public void load(CompoundTag nbt) { super.load(nbt); - if (nbt.get("passed") instanceof StringTag tag) - passed = new BigDecimal(tag.getAsString()); + if (nbt.contains("passed")) + passed = Fraction.deserializeNBT(nbt.get("passed")); if (nbt.get("history_tick") instanceof IntTag tag) history_tick = tag.getAsInt(); + // TODO: старый формат данных, удалить на релизе var list = nbt.getList("history", Tag.TAG_STRING); for (int i = 0; i < list.size(); i++) { try { - history[i] = new BigDecimal(list.getString(i)); + history[i] = Fraction.fromString(list.getString(i)); + } catch(Throwable err) { + LOGGER.error(err); + } + } + + // новый формат данных + list = nbt.getList("history", Tag.TAG_BYTE_ARRAY); + + for (int i = 0; i < list.size(); i++) { + try { + history[i] = Fraction.fromString(list.getString(i)); } catch(Throwable err) { LOGGER.error(err); } @@ -176,21 +189,21 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery { } @Override - public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { + public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) { return extractEnergyInner(howMuch, simulate); } @Override - public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { + public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) { if (is_input) - return BigDecimal.ZERO; + return Fraction.ZERO; if (input_cap_mte.isPresent()) { final var value = input_cap_mte.resolve().get().extractEnergyOuter(howMuch, simulate); if (!simulate) { - passed = passed.add(value); - history[history_tick] = history[history_tick].add(value); + passed = passed.plus(value); + history[history_tick] = history[history_tick].plus(value); setChangedLight(); } @@ -201,33 +214,33 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery { final var value = MatteryCapability.drainFE(input_cap_fe.resolve().get(), howMuch, simulate); if (!simulate) { - passed = passed.add(value); - history[history_tick] = history[history_tick].add(value); + passed = passed.plus(value); + history[history_tick] = history[history_tick].plus(value); setChangedLight(); } return value; } - return BigDecimal.ZERO; + return Fraction.ZERO; } @Override - public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { + public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) { return receiveEnergyInner(howMuch, simulate); } @Override - public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { + public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) { if (!is_input) - return BigDecimal.ZERO; + return Fraction.ZERO; if (output_cap_mte.isPresent()) { final var value = output_cap_mte.resolve().get().receiveEnergyOuter(howMuch, simulate); if (!simulate) { - passed = passed.add(value); - history[history_tick] = history[history_tick].add(value); + passed = passed.plus(value); + history[history_tick] = history[history_tick].plus(value); setChangedLight(); } @@ -238,26 +251,26 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery { final var value = MatteryCapability.floodFE(output_cap_fe.resolve().get(), howMuch, simulate); if (!simulate) { - passed = passed.add(value); - history[history_tick] = history[history_tick].add(value); + passed = passed.plus(value); + history[history_tick] = history[history_tick].plus(value); setChangedLight(); } return value; } - return BigDecimal.ZERO; + return Fraction.ZERO; } @Override - public BigDecimal getBatteryLevel() { + public Fraction getBatteryLevel() { if (is_input) { if (output_cap_mte.isPresent()) { return output_cap_mte.resolve().get().getBatteryLevel(); } if (output_cap_fe.isPresent()) { - return new BigDecimal(output_cap_fe.resolve().get().getEnergyStored()); + return new Fraction(output_cap_fe.resolve().get().getEnergyStored()); } } else { if (input_cap_mte.isPresent()) { @@ -265,22 +278,22 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery { } if (input_cap_fe.isPresent()) { - return new BigDecimal(input_cap_fe.resolve().get().getEnergyStored()); + return new Fraction(input_cap_fe.resolve().get().getEnergyStored()); } } - return BigDecimal.ZERO; + return Fraction.ZERO; } @Override - public BigDecimal getMaxBatteryLevel() { + public Fraction getMaxBatteryLevel() { if (is_input) { if (output_cap_mte.isPresent()) { return output_cap_mte.resolve().get().getMaxBatteryLevel(); } if (output_cap_fe.isPresent()) { - return new BigDecimal(output_cap_fe.resolve().get().getMaxEnergyStored()); + return new Fraction(output_cap_fe.resolve().get().getMaxEnergyStored()); } } else { if (input_cap_mte.isPresent()) { @@ -288,11 +301,11 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery { } if (input_cap_fe.isPresent()) { - return new BigDecimal(input_cap_fe.resolve().get().getMaxEnergyStored()); + return new Fraction(input_cap_fe.resolve().get().getMaxEnergyStored()); } } - return BigDecimal.ZERO; + return Fraction.ZERO; } @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityItemMonitor.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityItemMonitor.java index 9d2bde572..af91647bf 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityItemMonitor.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityItemMonitor.java @@ -17,6 +17,7 @@ import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.capability.AbstractStorageGridCell; 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.menu.ItemMonitorMenu; import javax.annotation.Nonnull; @@ -29,7 +30,7 @@ import java.math.BigDecimal; public class BlockEntityItemMonitor extends BlockEntityMatteryPowered { public BlockEntityItemMonitor(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.ITEM_MONITOR, p_155229_, p_155230_); - energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(80_000)); + energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new Fraction(80_000)); } public final AbstractStorageGridCell cell = new AbstractStorageGridCell(); diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.java index 1e08ceeff..2ee7ee8b4 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.java @@ -25,6 +25,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.container.MatteryContainerHandler; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu; @@ -85,7 +86,7 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen return slot < 3; }); - public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.BIDIRECTIONAL, new BigDecimal(4)) { + public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.BIDIRECTIONAL, new Fraction(4)) { @Nonnull @Override public MatterDirection getDirection() { @@ -93,12 +94,12 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen } }; - private static final BigDecimal MATTER_EXCHANGE_RATE = new BigDecimal("0.04"); - private static final BigDecimal ENERGY_CONSUMPTION = new BigDecimal(20); + private static final Fraction MATTER_EXCHANGE_RATE = new Fraction("0.04"); + private static final Fraction ENERGY_CONSUMPTION = new Fraction(20); private LazyOptional cell_resolver = LazyOptional.of(() -> this); - protected BigDecimal initial_capacity; + protected Fraction initial_capacity; protected ItemStack last_work_stack; private MatterGrid grid; @@ -202,7 +203,7 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen matter.deserializeNBT(_matter); } - private static final BigDecimal EXTRACTION_TICKS = new BigDecimal(200); + private static final Fraction EXTRACTION_TICKS = new Fraction(200); public float getWorkProgress() { if (last_work_stack == null) { @@ -216,18 +217,18 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen } if (work_flow) { - if (cap.get().getMaxStoredMatter().subtract(initial_capacity).compareTo(BigDecimal.ZERO) <= 0) { + if (cap.get().getMaxStoredMatter().minus(initial_capacity).compareTo(Fraction.ZERO) <= 0) { return 0; } - return cap.get().getStoredMatter().subtract(initial_capacity).divide(cap.get().getMaxStoredMatter().subtract(initial_capacity), MatteryCapability.ROUND_RULES).floatValue(); + return cap.get().getStoredMatter().minus(initial_capacity).div(cap.get().getMaxStoredMatter().minus(initial_capacity)).toFloat(); } - if (initial_capacity.compareTo(BigDecimal.ZERO) <= 0) { + if (initial_capacity.compareTo(Fraction.ZERO) <= 0) { return 0; } - return BigDecimal.ONE.subtract(cap.get().getStoredMatter().divide(initial_capacity, MatteryCapability.ROUND_RULES)).floatValue(); + return Fraction.ONE.minus(cap.get().getStoredMatter().div(initial_capacity)).toFloat(); } public static void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { @@ -253,7 +254,7 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen if (!get.isEmpty()) { var cap = get.getCapability(MatteryCapability.MATTER).resolve(); - if (cap.isPresent() && cap.get().getDirection() != (tile.work_flow ? IMatterHandler.MatterDirection.EXTRACT : IMatterHandler.MatterDirection.RECEIVE) && (tile.work_flow ? cap.get().getMissingMatter().compareTo(BigDecimal.ZERO) > 0 : cap.get().getStoredMatter().compareTo(BigDecimal.ZERO) > 0)) { + if (cap.isPresent() && cap.get().getDirection() != (tile.work_flow ? IMatterHandler.MatterDirection.EXTRACT : IMatterHandler.MatterDirection.RECEIVE) && (tile.work_flow ? cap.get().getMissingMatter().compareTo(Fraction.ZERO) > 0 : cap.get().getStoredMatter().compareTo(Fraction.ZERO) > 0)) { work_stack = get; capability = cap.get(); work_slot = i; @@ -280,29 +281,29 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen if (tile.grid != null) { var extracted = tile.grid.extractMatter( tile.matter.getMissingMatter() - .min(MATTER_EXCHANGE_RATE.multiply(EXTRACTION_TICKS)) - .min(capability.getMissingMatter().subtract(tile.matter.getStoredMatter())) + .min(MATTER_EXCHANGE_RATE.times(EXTRACTION_TICKS)) + .min(capability.getMissingMatter().minus(tile.matter.getStoredMatter())) , true); - if (extracted.compareTo(BigDecimal.ZERO) > 0) { + if (extracted.compareTo(Fraction.ZERO) > 0) { var received = tile.matter.receiveMatterOuter(extracted, false); tile.grid.extractMatter(received, false); } } } - if (tile.matter.getStoredMatter().compareTo(BigDecimal.ZERO) > 0) { + if (tile.matter.getStoredMatter().compareTo(Fraction.ZERO) > 0) { var energy = tile.energy.extractEnergyInner(ENERGY_CONSUMPTION, true); - if (energy.compareTo(BigDecimal.ZERO) > 0) { - var matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getStoredMatter()).multiply(energy.divide(ENERGY_CONSUMPTION, MatteryCapability.ROUND_RULES)), true); + if (energy.compareTo(Fraction.ZERO) > 0) { + var matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getStoredMatter()).times(energy.div(ENERGY_CONSUMPTION)), true); - if (matter.compareTo(BigDecimal.ZERO) > 0) { - tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.multiply(matter.divide(MATTER_EXCHANGE_RATE, MatteryCapability.ROUND_RULES)), false); + if (matter.compareTo(Fraction.ZERO) > 0) { + tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.times(matter.div(MATTER_EXCHANGE_RATE)), false); capability.receiveMatterOuter(matter, false); tile.matter.extractMatterInner(matter, false); - if (capability.getMissingMatter().compareTo(BigDecimal.ZERO) == 0) { + if (capability.getMissingMatter().compareTo(Fraction.ZERO) == 0) { for (int i = 3; i < 6; i++) { if (tile.work_slots.getItem(i).isEmpty()) { tile.work_slots.setItem(work_slot, ItemStack.EMPTY); @@ -327,15 +328,15 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen var energy = tile.energy.extractEnergyInner(ENERGY_CONSUMPTION, true); - if (energy.compareTo(BigDecimal.ZERO) > 0) { - var matter = capability.extractMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getMissingMatter()).multiply(energy.divide(ENERGY_CONSUMPTION, MatteryCapability.ROUND_RULES)), true); + if (energy.compareTo(Fraction.ZERO) > 0) { + var matter = capability.extractMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getMissingMatter()).times(energy.div(ENERGY_CONSUMPTION)), true); - if (matter.compareTo(BigDecimal.ZERO) > 0) { - tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.multiply(matter.divide(MATTER_EXCHANGE_RATE, MatteryCapability.ROUND_RULES)), false); + if (matter.compareTo(Fraction.ZERO) > 0) { + tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.times(matter.div(MATTER_EXCHANGE_RATE)), false); capability.extractMatterOuter(matter, false); tile.matter.receiveMatterInner(matter, false); - if (capability.getStoredMatter().compareTo(BigDecimal.ZERO) == 0) { + if (capability.getStoredMatter().compareTo(Fraction.ZERO) == 0) { for (int i = 2; i >= 0; i--) { if (tile.work_slots.getItem(i).isEmpty()) { tile.work_slots.setItem(work_slot, ItemStack.EMPTY); @@ -352,9 +353,9 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen } } - if (tile.matter.getStoredMatter().compareTo(BigDecimal.ZERO) > 0 && tile.grid != null) { - BigDecimal diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true); - BigDecimal diff2 = tile.grid.softPushMatter(diff, true); + if (tile.matter.getStoredMatter().compareTo(Fraction.ZERO) > 0 && tile.grid != null) { + var diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true); + var diff2 = tile.grid.softPushMatter(diff, true); tile.matter.extractMatterInner(diff2, false); tile.grid.softPushMatter(diff2, false); diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.java index 294c379c3..cb3ecab7e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.java @@ -17,6 +17,7 @@ import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; import ru.dbotthepony.mc.otm.block.BlockBatteryBank; import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; @@ -37,8 +38,8 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement public final IMatterHandler matter = new IMatterHandler() { @Nonnull @Override - public BigDecimal getStoredMatter() { - BigDecimal summ = BigDecimal.ZERO; + public Fraction getStoredMatter() { + Fraction summ = Fraction.ZERO; for (int i = 0; i < matter_container.getContainerSize(); i++) { ItemStack stack = matter_container.getItem(i); @@ -47,7 +48,7 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement Optional handler = stack.getCapability(MatteryCapability.MATTER).resolve(); if (handler.isPresent()) { - summ = summ.add(handler.get().getStoredMatter()); + summ = summ.plus(handler.get().getStoredMatter()); } } } @@ -57,8 +58,8 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement @Nonnull @Override - public BigDecimal getMaxStoredMatter() { - BigDecimal summ = BigDecimal.ZERO; + public Fraction getMaxStoredMatter() { + Fraction summ = Fraction.ZERO; for (int i = 0; i < matter_container.getContainerSize(); i++) { ItemStack stack = matter_container.getItem(i); @@ -67,7 +68,7 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement Optional handler = stack.getCapability(MatteryCapability.MATTER).resolve(); if (handler.isPresent()) { - summ = summ.add(handler.get().getMaxStoredMatter()); + summ = summ.plus(handler.get().getMaxStoredMatter()); } } } @@ -77,14 +78,14 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement @Nonnull @Override - public BigDecimal receiveMatterOuter(BigDecimal howMuch, boolean simulate) { + public Fraction receiveMatterOuter(Fraction howMuch, boolean simulate) { return receiveMatterInner(howMuch, simulate); } @Nonnull @Override - public BigDecimal receiveMatterInner(BigDecimal howMuch, boolean simulate) { - BigDecimal summ = BigDecimal.ZERO; + public Fraction receiveMatterInner(Fraction howMuch, boolean simulate) { + Fraction summ = Fraction.ZERO; for (int i = 0; i < matter_container.getContainerSize(); i++) { ItemStack stack = matter_container.getItem(i); @@ -93,11 +94,11 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement Optional handler = stack.getCapability(MatteryCapability.MATTER).resolve(); if (handler.isPresent()) { - BigDecimal diff = handler.get().receiveMatterOuter(howMuch, simulate); - summ = summ.add(diff); - howMuch = howMuch.subtract(diff); + var diff = handler.get().receiveMatterOuter(howMuch, simulate); + summ = summ.plus(diff); + howMuch = howMuch.minus(diff); - if (howMuch.compareTo(BigDecimal.ZERO) == 0) { + if (howMuch.compareTo(Fraction.ZERO) == 0) { break; } } @@ -109,14 +110,14 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement @Nonnull @Override - public BigDecimal extractMatterOuter(BigDecimal howMuch, boolean simulate) { + public Fraction extractMatterOuter(Fraction howMuch, boolean simulate) { return extractMatterInner(howMuch, simulate); } @Nonnull @Override - public BigDecimal extractMatterInner(BigDecimal howMuch, boolean simulate) { - BigDecimal summ = BigDecimal.ZERO; + public Fraction extractMatterInner(Fraction howMuch, boolean simulate) { + Fraction summ = Fraction.ZERO; for (int i = 0; i < matter_container.getContainerSize(); i++) { ItemStack stack = matter_container.getItem(i); @@ -125,11 +126,11 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement Optional handler = stack.getCapability(MatteryCapability.MATTER).resolve(); if (handler.isPresent()) { - BigDecimal diff = handler.get().extractMatterOuter(howMuch, simulate); - summ = summ.add(diff); - howMuch = howMuch.subtract(diff); + var diff = handler.get().extractMatterOuter(howMuch, simulate); + summ = summ.plus(diff); + howMuch = howMuch.minus(diff); - if (howMuch.compareTo(BigDecimal.ZERO) == 0) { + if (howMuch.compareTo(Fraction.ZERO) == 0) { break; } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java index 00df095d7..3e3a6442b 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java @@ -27,6 +27,7 @@ import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage; import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability; import ru.dbotthepony.mc.otm.container.MatteryContainer; import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu; @@ -41,7 +42,7 @@ import java.math.BigDecimal; public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implements IMatterGridCell { private static final TranslatableComponent MACHINE_NAME = new TranslatableComponent("block.overdrive_that_matters.matter_decomposer"); private boolean valid = true; - public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.EXTRACT, new BigDecimal("20")); + public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.EXTRACT, new Fraction("20")); private LazyOptional matter_resolver = LazyOptional.of(() -> matter); // вход, выход @@ -54,7 +55,7 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem public BlockEntityMatterDecomposer(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.MATTER_DECOMPOSER, p_155229_, p_155230_); - energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(400_000), new BigDecimal(2000), new BigDecimal(2000)); + energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new Fraction(400_000), new Fraction(2000), new Fraction(2000)); } @Override @@ -130,7 +131,7 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem @Nonnull @Override protected MachineJobStatus onJobFinish(MachineJob job) { - BigDecimal matter_value = MatterRegistry.getMatterValue(job.stack()); + var matter_value = MatterRegistry.getMatterValue(job.stack()); matter.receiveMatterInner(matter_value, false); return new MachineJobStatus(); } @@ -145,11 +146,11 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem copy.setCount(1); if (MatterRegistry.canDecompose(copy)) { - BigDecimal matter_value = MatterRegistry.getMatterValue(copy); + var matter_value = MatterRegistry.getMatterValue(copy); if (!matter_value.equals(BigDecimal.ZERO) && matter.canReceiveAll(matter_value)) { stack.shrink(1); - return new MachineJob(copy, matter_value.doubleValue() * 12_500d); + return new MachineJob(copy, matter_value.toDouble() * 12_500d); } } } @@ -162,9 +163,9 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem tile.batteryChargeLoop(); tile.workerLoop(); - if (tile.matter.getStoredMatter().compareTo(BigDecimal.ZERO) > 0 && tile.grid != null) { - BigDecimal diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true); - BigDecimal diff2 = tile.grid.softPushMatter(diff, true); + if (tile.matter.getStoredMatter().compareTo(Fraction.ZERO) > 0 && tile.grid != null) { + var diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true); + var diff2 = tile.grid.softPushMatter(diff, true); tile.matter.extractMatterInner(diff2, false); tile.grid.softPushMatter(diff2, false); @@ -212,10 +213,10 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem this.grid = grid; } - private static final BigDecimal BASE_CONSUMPTION = new BigDecimal(240); + private static final Fraction BASE_CONSUMPTION = new Fraction(240); @Override - protected BigDecimal getBaseConsumption() { + protected Fraction getBaseConsumption() { return BASE_CONSUMPTION; } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.java index 6e915135c..76c65c207 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.java @@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.capability.*; import ru.dbotthepony.mc.otm.capability.matter.*; import ru.dbotthepony.mc.otm.container.MatteryContainer; import ru.dbotthepony.mc.otm.container.MatteryContainerHandler; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu; @@ -38,10 +39,10 @@ import java.math.BigDecimal; public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implements IMatterGridCell { public BlockEntityMatterReplicator(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_); - energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(200_000), new BigDecimal(4000), new BigDecimal(4000)); + energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new Fraction(200_000), new Fraction(4000), new Fraction(4000)); } - public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.RECEIVE, new BigDecimal(2)); + public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.RECEIVE, new Fraction(2)); // обычные запросы public final MatteryContainer regular_slots = new MatteryContainer(this::setChanged, 3); @@ -53,7 +54,7 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.matter_replicator"); - private static final BigDecimal BASE_CONSUMPTION = new BigDecimal(400); + private static final Fraction BASE_CONSUMPTION = new Fraction(400); @Override protected Component getDefaultDisplayName() { @@ -68,7 +69,7 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem @Nonnull @Override - protected BigDecimal getBaseConsumption() { + protected Fraction getBaseConsumption() { return BASE_CONSUMPTION; } @@ -110,9 +111,9 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem } private static final double TICKS_PER_MTU = 20_000d; - private static final BigDecimal TICKS_PER_MTU_BD = new BigDecimal(20_000); + private static final Fraction TICKS_PER_MTU_BD = new Fraction(20_000); private static final double MTU_PER_TICK = 1d / 20_000d; - private static final BigDecimal MTU_PER_TICK_BD = BigDecimal.ONE.divide(TICKS_PER_MTU_BD, MatteryCapability.ROUND_RULES); + private static final Fraction MTU_PER_TICK_BD = Fraction.ONE.div(TICKS_PER_MTU_BD); @Override public void setLevel(Level p_155231_) { @@ -139,7 +140,7 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem if (!MatterRegistry.hasMatterValue(stack)) return null; - MachineJob job = new MachineJob(stack, MatterRegistry.getMatterValue(stack).doubleValue() * TICKS_PER_MTU); + MachineJob job = new MachineJob(stack, MatterRegistry.getMatterValue(stack).toDouble() * TICKS_PER_MTU); job.data().put("task", allocation.task().serializeNBT()); @@ -149,11 +150,11 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem return job; } - private static final BigDecimal DRAIN_MULT = new BigDecimal(200); + private static final Fraction DRAIN_MULT = new Fraction(200); @Override protected MachineJobStatus onWorkTick(WorkTickContext context) { - BigDecimal drain_per_tick = MTU_PER_TICK_BD.multiply(context.work_speed(), MatteryCapability.ROUND_RULES); + var drain_per_tick = MTU_PER_TICK_BD.times(context.work_speed()); if (matter.extractMatterInner(drain_per_tick, true).compareTo(drain_per_tick) < 0) { // в машине недостаточно материи @@ -162,8 +163,8 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem if (drain_per_tick.compareTo(matter.getMaxStoredMatter()) > 0) { // в тик требуется больше материи, чем её может хранить репликатор - BigDecimal to_extract = drain_per_tick.subtract(matter.extractMatterInner(drain_per_tick, true)); - BigDecimal drain = grid.extractMatter(to_extract, true); + var to_extract = drain_per_tick.minus(matter.extractMatterInner(drain_per_tick, true)); + var drain = grid.extractMatter(to_extract, true); if (drain.compareTo(to_extract) < 0) { // недостаточно материи в сети @@ -178,15 +179,15 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem } else { // в тик требуется меньше материи, чем её может хранить репликатор // примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше - BigDecimal to_extract = matter.getMissingMatter().min(drain_per_tick.multiply(DRAIN_MULT)); - BigDecimal drain = grid.extractMatter(to_extract, true); + var to_extract = matter.getMissingMatter().min(drain_per_tick.times(DRAIN_MULT)); + var drain = grid.extractMatter(to_extract, true); - if (drain.compareTo(BigDecimal.ZERO) == 0) { + if (drain.compareTo(Fraction.ZERO) == 0) { // в сети нет материи return new MachineJobStatus(false, 200); } - BigDecimal received = matter.receiveMatterOuter(drain, false); + var received = matter.receiveMatterOuter(drain, false); grid.extractMatter(received, false); // получили материю, проверяем возможность работы diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.java index 83ff7604c..2422ed118 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.java @@ -22,6 +22,7 @@ import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus; import ru.dbotthepony.mc.otm.capability.*; import ru.dbotthepony.mc.otm.capability.matter.*; import ru.dbotthepony.mc.otm.container.MatteryContainerHandler; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.Registry; @@ -49,7 +50,7 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implement public BlockEntityMatterScanner(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.MATTER_SCANNER, p_155229_, p_155230_); - energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(40000), new BigDecimal(400), new BigDecimal(400)); + energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new Fraction(40000), new Fraction(400), new Fraction(400)); } private boolean valid = true; @@ -137,11 +138,11 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implement super.load(nbt); } - private static final BigDecimal BASE_CONSUMPTION = new BigDecimal("40"); + private static final Fraction BASE_CONSUMPTION = new Fraction("40"); @Override @Nonnull - protected BigDecimal getBaseConsumption() { + protected Fraction getBaseConsumption() { return BASE_CONSUMPTION; } @@ -220,7 +221,7 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implement copy.setCount(1); stack.shrink(1); input_slot.setChanged(); - return new MachineJob(copy, MatterRegistry.getMatterValue(copy).doubleValue() * 35_000d); + return new MachineJob(copy, MatterRegistry.getMatterValue(copy).toDouble() * 35_000d); } return null; diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.java index bfbf93dca..8da4d90ac 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.java @@ -15,6 +15,7 @@ import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage; import ru.dbotthepony.mc.otm.container.MatteryContainer; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -35,17 +36,17 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery { if (energy == null) return; - if (energy.getMissingPower().compareTo(BigDecimal.ZERO) <= 0) + if (energy.getMissingPower().compareTo(Fraction.ZERO) <= 0) return; var demand = energy.getMissingPower(); - if (demand.compareTo(BigDecimal.ZERO) == 0) + if (demand.compareTo(Fraction.ZERO) == 0) return; demand = demand.min(energy.receiveEnergyOuter(demand, true)); - for (int i = 0; i < battery_container.getContainerSize() && demand.compareTo(BigDecimal.ZERO) > 0; i++) { + for (int i = 0; i < battery_container.getContainerSize() && demand.compareTo(Fraction.ZERO) > 0; i++) { final var stack = battery_container.getItem(i); if (!stack.isEmpty()) { @@ -54,13 +55,13 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery { if (mattery_storage.isPresent()) { final var drain = mattery_storage.get().extractEnergyOuter(demand, true); - if (drain.compareTo(BigDecimal.ZERO) != 0) { + if (drain.compareTo(Fraction.ZERO) != 0) { final var receive = energy.receiveEnergyOuter(drain, true); mattery_storage.get().extractEnergyOuter(receive, false); energy.receiveEnergyOuter(receive, false); - demand = demand.subtract(receive, MatteryCapability.ROUND_RULES); + demand = demand.minus(receive); } } else { final var storage = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); @@ -68,13 +69,13 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery { if (storage.isPresent()) { final var drain = MatteryCapability.drainFE(storage.get(), demand, true); - if (drain.compareTo(BigDecimal.ZERO) != 0) { + if (drain.compareTo(Fraction.ZERO) != 0) { final var receive = energy.receiveEnergyOuter(drain, true); MatteryCapability.drainFE(storage.get(), receive, false); energy.receiveEnergyOuter(receive, false); - demand = demand.subtract(receive, MatteryCapability.ROUND_RULES); + demand = demand.minus(receive); } } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.java index bc12c2d4b..5faf5f76f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.java @@ -11,6 +11,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatteryPowered; import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -24,9 +25,9 @@ abstract public class BlockEntityMatteryWorker extends BlockEntityMatteryPowered super(p_155228_, p_155229_, p_155230_); } - protected abstract BigDecimal getBaseConsumption(); + protected abstract Fraction getBaseConsumption(); - protected BigDecimal consumptionPerWork() { + protected Fraction consumptionPerWork() { return getBaseConsumption(); } @@ -150,7 +151,7 @@ abstract public class BlockEntityMatteryWorker extends BlockEntityMatteryPowered return; } - if (current_job.power_consumption_multiplier().compareTo(BigDecimal.ZERO) != 0 && energy.getBatteryLevel().compareTo(BigDecimal.ZERO) == 0) { + if (current_job.power_consumption_multiplier().compareTo(Fraction.ZERO) != 0 && energy.getBatteryLevel().compareTo(Fraction.ZERO) == 0) { idle_ticks_anim++; if (level != null && idle_ticks_anim > 20 && getBlockState().hasProperty(WorkerState.WORKER_STATE) && getBlockState().getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) { @@ -163,11 +164,10 @@ abstract public class BlockEntityMatteryWorker extends BlockEntityMatteryPowered idle_ticks_anim = 0; if (work_ticks < current_job.ticks_processing_time()) { - if (current_job.power_consumption_multiplier().compareTo(BigDecimal.ZERO) != 0) { - BigDecimal required_power = consumptionPerWork().multiply(current_job.power_consumption_multiplier()); - BigDecimal extracted_power = energy.extractEnergyInner(required_power, true); - - BigDecimal work_speed = extracted_power.divide(required_power, MatteryCapability.ROUND_RULES); + if (current_job.power_consumption_multiplier().compareTo(Fraction.ZERO) != 0) { + var required_power = consumptionPerWork().times(current_job.power_consumption_multiplier()); + var extracted_power = energy.extractEnergyInner(required_power, true); + var work_speed = extracted_power.div(required_power); MachineJobStatus status = onWorkTick(new WorkTickContext(current_job, required_power, extracted_power, work_speed)); @@ -179,11 +179,11 @@ abstract public class BlockEntityMatteryWorker extends BlockEntityMatteryPowered working_ticks_anim++; error_ticks_anim = 0; - double new_work_ticks = work_speed.doubleValue() + work_ticks; + double new_work_ticks = work_speed.toDouble() + work_ticks; if (new_work_ticks > current_job.ticks_processing_time()) { work_ticks = current_job.ticks_processing_time(); - energy.extractEnergyInner(extracted_power.multiply(new BigDecimal(1d - (new_work_ticks - current_job.ticks_processing_time()), MatteryCapability.ROUND_RULES)), false); + energy.extractEnergyInner(extracted_power.times(1d - (new_work_ticks - current_job.ticks_processing_time())), false); } else { work_ticks = new_work_ticks; energy.extractEnergyInner(extracted_power, false); @@ -200,7 +200,7 @@ abstract public class BlockEntityMatteryWorker extends BlockEntityMatteryPowered } } } else { - MachineJobStatus status = onWorkTick(new WorkTickContext(current_job, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ONE)); + MachineJobStatus status = onWorkTick(new WorkTickContext(current_job, Fraction.ZERO, Fraction.ZERO, Fraction.ONE)); if (!status.valid()) { throttle_ticks += status.throttle(); 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 b6505b7af..3d8278387 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,6 +6,7 @@ import net.minecraft.nbt.DoubleTag; import net.minecraft.nbt.StringTag; import net.minecraft.nbt.Tag; import net.minecraft.world.item.ItemStack; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; @@ -13,14 +14,14 @@ import java.math.BigDecimal; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -public record MachineJob(ItemStack stack, double ticks_processing_time, BigDecimal power_consumption_multiplier, +public record MachineJob(ItemStack stack, double ticks_processing_time, Fraction power_consumption_multiplier, CompoundTag data) { - public MachineJob(ItemStack stack, double ticks_processing_time, BigDecimal power_consumption_multiplier) { + public MachineJob(ItemStack stack, double ticks_processing_time, Fraction power_consumption_multiplier) { this(stack, ticks_processing_time, power_consumption_multiplier, new CompoundTag()); } public MachineJob(ItemStack stack, double ticks_processing_time) { - this(stack, ticks_processing_time, BigDecimal.ONE); + this(stack, ticks_processing_time, Fraction.ONE); } public CompoundTag serializeNBT() { @@ -40,11 +41,11 @@ public record MachineJob(ItemStack stack, double ticks_processing_time, BigDecim return null; if (nbt instanceof CompoundTag tag) { - if (tag.get("stack") instanceof CompoundTag stack_tag && tag.get("ticks_processing_time") instanceof DoubleTag ticks_processing_time && tag.get("power_consumption_multiplier") instanceof StringTag power_consumption_multiplier) { + if (tag.get("stack") instanceof CompoundTag stack_tag && tag.get("ticks_processing_time") instanceof DoubleTag ticks_processing_time && tag.contains("power_consumption_multiplier")) { ItemStack stack = ItemStack.of(stack_tag); if (!stack.isEmpty()) { - return new MachineJob(stack, ticks_processing_time.getAsDouble(), new BigDecimal(power_consumption_multiplier.getAsString()), tag.getCompound("data")); + return new MachineJob(stack, ticks_processing_time.getAsDouble(), Fraction.deserializeNBT(tag.get("power_consumption_multiplier")), 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 d6bcc36ad..ad02c1099 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 @@ -1,13 +1,14 @@ package ru.dbotthepony.mc.otm.block.entity.worker; import net.minecraft.MethodsReturnNonnullByDefault; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.ParametersAreNonnullByDefault; import java.math.BigDecimal; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -public record WorkTickContext(MachineJob job, BigDecimal required_power, BigDecimal extracted_power, - BigDecimal work_speed) { +public record WorkTickContext(MachineJob job, Fraction required_power, Fraction extracted_power, + Fraction work_speed) { } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java index 8dabffad2..f77f4736c 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java @@ -2,8 +2,8 @@ package ru.dbotthepony.mc.otm.capability; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraftforge.energy.IEnergyStorage; +import ru.dbotthepony.mc.otm.core.Fraction; -import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; import java.math.BigDecimal; @@ -12,114 +12,112 @@ import java.math.BigDecimal; @ParametersAreNonnullByDefault public interface IMatteryEnergyStorage extends IEnergyStorage { // such as cables. This is something that would work only with energy storage - BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate); + Fraction extractEnergyOuter(Fraction howMuch, boolean simulate); // 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 - BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate); + Fraction extractEnergyInner(Fraction howMuch, boolean simulate); // energy is received from outside, e.g. cables - BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate); + Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate); // energy is received from inside, e.g. generator generates power - BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate); + Fraction receiveEnergyInner(Fraction howMuch, boolean simulate); - default BigDecimal extractEnergyOuter(long howMuch, boolean simulate) { - return extractEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); + default Fraction extractEnergyOuter(long howMuch, boolean simulate) { + return extractEnergyOuter(new Fraction(howMuch), simulate); } - default BigDecimal extractEnergyOuter(int howMuch, boolean simulate) { - return extractEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); + default Fraction extractEnergyOuter(int howMuch, boolean simulate) { + return extractEnergyOuter(new Fraction(howMuch), simulate); } - default BigDecimal receiveEnergyOuter(long howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); + default Fraction receiveEnergyOuter(long howMuch, boolean simulate) { + return receiveEnergyOuter(new Fraction(howMuch), simulate); } - default BigDecimal receiveEnergyOuter(int howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); + default Fraction receiveEnergyOuter(int howMuch, boolean simulate) { + return receiveEnergyOuter(new Fraction(howMuch), simulate); } - default BigDecimal extractEnergyInner(long howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); + default Fraction extractEnergyInner(long howMuch, boolean simulate) { + return receiveEnergyOuter(new Fraction(howMuch), simulate); } - default BigDecimal extractEnergyInner(int howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); + default Fraction extractEnergyInner(int howMuch, boolean simulate) { + return receiveEnergyOuter(new Fraction(howMuch), simulate); } - default BigDecimal receiveEnergyInner(long howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); + default Fraction receiveEnergyInner(long howMuch, boolean simulate) { + return receiveEnergyOuter(new Fraction(howMuch), simulate); } - default BigDecimal receiveEnergyInner(int howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); + default Fraction receiveEnergyInner(int howMuch, boolean simulate) { + return receiveEnergyOuter(new Fraction(howMuch), simulate); } - BigDecimal getBatteryLevel(); + Fraction getBatteryLevel(); - BigDecimal getMaxBatteryLevel(); + Fraction getMaxBatteryLevel(); - default BigDecimal getMissingPower() { - return getMaxBatteryLevel().subtract(getBatteryLevel(), MatteryCapability.ROUND_RULES); + default Fraction getMissingPower() { + return getMaxBatteryLevel().minus(getBatteryLevel()); } @Override default int receiveEnergy(int maxReceive, boolean simulate) { - BigDecimal toReceive = new BigDecimal(maxReceive, MatteryCapability.ROUND_RULES); - int received = receiveEnergyOuter(toReceive, true).intValue(); + int received = receiveEnergyOuter(maxReceive, true).toInt(); if (received == 0) { // Receiving only a fraction return 0; } - return receiveEnergyOuter(new BigDecimal(received, MatteryCapability.ROUND_RULES), simulate).intValue(); + return receiveEnergyOuter(new Fraction(received), simulate).toInt(); } @Override default int extractEnergy(int maxReceive, boolean simulate) { - BigDecimal toReceive = new BigDecimal(maxReceive, MatteryCapability.ROUND_RULES); - int extracted = extractEnergyOuter(toReceive, true).intValue(); + int extracted = extractEnergyOuter(maxReceive, true).toInt(); if (extracted == 0) { // Extracting only a fraction return 0; } - return extractEnergyOuter(new BigDecimal(extracted, MatteryCapability.ROUND_RULES), simulate).intValue(); + return extractEnergyOuter(new Fraction(extracted), simulate).toInt(); } @Override default int getEnergyStored() { - BigDecimal level = getBatteryLevel(); + Fraction level = getBatteryLevel(); - if (level.compareTo(MatteryCapability.INT_MAX_VALUE) == -1) { - return level.intValue(); + if (level.compareTo(MatteryCapability.INT_MAX_VALUE) < 0) { + return level.toInt(); } return Integer.MAX_VALUE; - }; + } @Override default int getMaxEnergyStored() { - BigDecimal level = getMaxBatteryLevel(); + Fraction level = getMaxBatteryLevel(); - if (level.compareTo(MatteryCapability.INT_MAX_VALUE) == -1) { - return level.intValue(); + if (level.compareTo(MatteryCapability.INT_MAX_VALUE) < 0) { + return level.toInt(); } return Integer.MAX_VALUE; - }; + } @Override default boolean canExtract() { - return extractEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0; - }; + return extractEnergyOuter(Fraction.ONE, true).compareTo(Fraction.ZERO) > 0; + } @Override default boolean canReceive() { - return receiveEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0; + return receiveEnergyOuter(Fraction.ONE, true).compareTo(Fraction.ZERO) > 0; }; } 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 95ea20320..8a98c78d3 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java @@ -8,6 +8,7 @@ import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider; import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage; +import ru.dbotthepony.mc.otm.core.Fraction; import java.math.BigDecimal; import java.math.MathContext; @@ -37,23 +38,23 @@ public class MatteryCapability { public static final MathContext ROUND_RULES = new MathContext(32, RoundingMode.HALF_DOWN); - public static final BigDecimal INT_MAX_VALUE = new BigDecimal(Integer.MAX_VALUE); - public static final BigDecimal INT_MIN_VALUE = new BigDecimal(Integer.MIN_VALUE); + 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 BigDecimal LONG_MAX_VALUE = new BigDecimal(Long.MAX_VALUE); - public static final BigDecimal LONG_MIN_VALUE = new BigDecimal(Long.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 BigDecimal drainFE(IEnergyStorage capability, BigDecimal howMuch, boolean simulate) { - if (howMuch.compareTo(BigDecimal.ONE) < 0) - return BigDecimal.ZERO; + public static Fraction drainFE(IEnergyStorage capability, Fraction howMuch, boolean simulate) { + if (howMuch.compareTo(Fraction.ONE) < 0) + return Fraction.ZERO; - return new BigDecimal(capability.extractEnergy(howMuch.compareTo(INT_MAX_VALUE) > 0 ? Integer.MAX_VALUE : howMuch.intValue(), simulate)); + return new Fraction(capability.extractEnergy(howMuch.compareTo(INT_MAX_VALUE) > 0 ? Integer.MAX_VALUE : howMuch.toInt(), simulate)); } - public static BigDecimal floodFE(IEnergyStorage capability, BigDecimal howMuch, boolean simulate) { - if (howMuch.compareTo(BigDecimal.ONE) < 0) - return BigDecimal.ZERO; + public static Fraction floodFE(IEnergyStorage capability, Fraction howMuch, boolean simulate) { + if (howMuch.compareTo(Fraction.ONE) < 0) + return Fraction.ZERO; - return new BigDecimal(capability.receiveEnergy(howMuch.compareTo(INT_MAX_VALUE) > 0 ? Integer.MAX_VALUE : howMuch.intValue(), simulate)); + 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/MatteryMachineEnergyStorage.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.java index 6fcd0a8e9..1819379aa 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.java @@ -4,6 +4,7 @@ import net.minecraft.MethodsReturnNonnullByDefault; 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 javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; @@ -18,18 +19,18 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS CAPACITOR, } - public static final BigDecimal DEFAULT_MAX_RECEIVE = new BigDecimal(200); - public static final BigDecimal DEFAULT_MAX_EXTRACT = new BigDecimal(200); - public static final BigDecimal DEFAULT_MAX_CAPACITY = new BigDecimal(60000); + public static final Fraction DEFAULT_MAX_RECEIVE = new Fraction(200); + public static final Fraction DEFAULT_MAX_EXTRACT = new Fraction(200); + public static final Fraction DEFAULT_MAX_CAPACITY = new Fraction(60000); - protected BigDecimal energy_stored = BigDecimal.ZERO; - protected BigDecimal energy_stored_max; - protected BigDecimal max_input; - protected BigDecimal max_output; + protected Fraction energy_stored = Fraction.ZERO; + protected Fraction energy_stored_max; + protected Fraction max_input; + protected Fraction max_output; protected final MachineType machine_type; protected final BlockEntity listener; - public MatteryMachineEnergyStorage(BlockEntity listener, MachineType type, BigDecimal capacity) { + public MatteryMachineEnergyStorage(BlockEntity listener, MachineType type, Fraction capacity) { this(listener, type, capacity, DEFAULT_MAX_RECEIVE, DEFAULT_MAX_EXTRACT); } @@ -37,7 +38,7 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS this(listener, type, DEFAULT_MAX_CAPACITY); } - public MatteryMachineEnergyStorage(BlockEntity listener, MachineType type, BigDecimal capacity, BigDecimal maxReceive, BigDecimal maxExtract) { + public MatteryMachineEnergyStorage(BlockEntity listener, MachineType type, Fraction capacity, Fraction maxReceive, Fraction maxExtract) { this.listener = listener; energy_stored_max = capacity; max_input = maxReceive; @@ -47,9 +48,9 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS @Nonnull @Override - public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { + public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) { if (machine_type == MachineType.WORKER) { - return BigDecimal.ZERO; + return Fraction.ZERO; } return extractEnergyInner(howMuch, simulate); @@ -57,11 +58,11 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS @Nonnull @Override - public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { - BigDecimal new_energy = energy_stored.subtract(howMuch.min(max_output), MatteryCapability.ROUND_RULES).max(BigDecimal.ZERO); - BigDecimal diff = energy_stored.subtract(new_energy); + public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) { + Fraction new_energy = energy_stored.minus(howMuch.min(max_output)).moreThanZero(); + Fraction diff = energy_stored.minus(new_energy); - if (!simulate && !energy_stored.equals(new_energy)) { + if (!simulate && !energy_stored.equalsCompact(new_energy)) { energy_stored = new_energy; listener.setChanged(); } @@ -71,9 +72,9 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS @Nonnull @Override - public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { + public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) { if (machine_type == MachineType.GENERATOR) { - return BigDecimal.ZERO; + return Fraction.ZERO; } return receiveEnergyInner(howMuch, simulate); @@ -81,11 +82,11 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS @Nonnull @Override - public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { - BigDecimal new_energy = energy_stored.add(howMuch.min(max_input), MatteryCapability.ROUND_RULES).min(energy_stored_max); - BigDecimal diff = new_energy.subtract(energy_stored); + public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) { + Fraction new_energy = energy_stored.plus(howMuch.min(max_input)).min(energy_stored_max); + Fraction diff = new_energy.minus(energy_stored); - if (!simulate && !energy_stored.equals(new_energy)) { + if (!simulate && !energy_stored.equalsCompact(new_energy)) { energy_stored = new_energy; listener.setChanged(); } @@ -95,13 +96,13 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS @Nonnull @Override - public BigDecimal getBatteryLevel() { + public Fraction getBatteryLevel() { return energy_stored; } @Nonnull @Override - public BigDecimal getMaxBatteryLevel() { + public Fraction getMaxBatteryLevel() { return energy_stored_max; } @@ -119,25 +120,25 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS @Nonnull public CompoundTag serializeNBT() { CompoundTag tag = new CompoundTag(); - tag.putString("energy_stored", energy_stored.toString()); - tag.putString("energy_stored_max", energy_stored_max.toString()); - tag.putString("max_input", max_input.toString()); - tag.putString("max_output", max_output.toString()); + tag.put("energy_stored", energy_stored.serializeNBT()); + tag.put("energy_stored_max", energy_stored_max.serializeNBT()); + tag.put("max_input", max_input.serializeNBT()); + tag.put("max_output", max_output.serializeNBT()); return tag; } @Override public void deserializeNBT(CompoundTag nbt) { if (nbt.contains("energy_stored")) - energy_stored = new BigDecimal(nbt.getString("energy_stored")); + energy_stored = Fraction.deserializeNBT(nbt.get("energy_stored")); if (nbt.contains("energy_stored_max")) - energy_stored_max = new BigDecimal(nbt.getString("energy_stored_max")); + energy_stored_max = Fraction.deserializeNBT(nbt.get("energy_stored_max")); if (nbt.contains("max_input")) - max_input = new BigDecimal(nbt.getString("max_input")); + max_input = Fraction.deserializeNBT(nbt.get("max_input")); if (nbt.contains("max_output")) - max_output = new BigDecimal(nbt.getString("max_output")); + max_output = Fraction.deserializeNBT(nbt.get("max_output")); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.java index e7b1fb83b..34fae34fe 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapability.java @@ -28,6 +28,7 @@ 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.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.network.android.AndroidBatteryPacket; import ru.dbotthepony.mc.otm.network.android.AndroidEnergyPacket; @@ -43,12 +44,12 @@ import java.util.*; @ParametersAreNonnullByDefault public class AndroidCapability implements ICapabilityProvider, IAndroidCapability, INBTSerializable { protected final LivingEntity ent; - protected BigDecimal energy_stored = new BigDecimal(0); - protected BigDecimal energy_stored_max = new BigDecimal(60_000); + protected Fraction energy_stored = Fraction.ZERO; + protected Fraction energy_stored_max = new Fraction(60_000); protected ItemStack battery = ItemStack.EMPTY; - private BigDecimal network_energy = new BigDecimal(-1); - private BigDecimal network_energy_max = new BigDecimal(-1); + private Fraction network_energy = new Fraction(-1); + private Fraction network_energy_max = new Fraction(-1); private ItemStack network_battery = ItemStack.EMPTY; protected final Map, AndroidFeature> features = new HashMap<>(); @@ -158,8 +159,8 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit @Override public void invalidateNetworkState() { - network_energy = new BigDecimal(-1); - network_energy_max = new BigDecimal(-1); + network_energy = Fraction.MINUS_ONE; + network_energy_max = Fraction.MINUS_ONE; network_battery = ItemStack.EMPTY; if (ent instanceof ServerPlayer ply) { @@ -171,12 +172,12 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit } @Override - public void setEnergy(BigDecimal value) { + public void setEnergy(Fraction value) { energy_stored = value; } @Override - public void setMaxEnergy(BigDecimal value) { + public void setMaxEnergy(Fraction value) { energy_stored_max = value; } @@ -232,10 +233,10 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit @Override public void deserializeNBT(CompoundTag compound) { if (compound.contains("energy_stored")) - energy_stored = new BigDecimal(compound.getString("energy_stored")); + energy_stored = Fraction.deserializeNBT(compound.get("energy_stored")); if (compound.contains("energy_stored_max")) - energy_stored_max = new BigDecimal(compound.getString("energy_stored_max")); + energy_stored_max = Fraction.deserializeNBT(compound.get("energy_stored_max")); if (compound.contains("battery")) battery = ItemStack.of(compound.getCompound("battery")); @@ -371,52 +372,52 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit ent.removeEffect(effect); if (!battery.isEmpty()) { - BigDecimal demand = energy_stored_max.subtract(energy_stored, MatteryCapability.ROUND_RULES); + Fraction demand = energy_stored_max.minus(energy_stored); - if (demand.compareTo(BigDecimal.ZERO) > 0) { + if (demand.compareTo(Fraction.ZERO) > 0) { Optional get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve(); if (get_mattery.isPresent()) { - demand = demand.subtract(get_mattery.get().extractEnergyInner(demand, false), MatteryCapability.ROUND_RULES); + demand = demand.minus(get_mattery.get().extractEnergyInner(demand, false)); } - if (demand.compareTo(BigDecimal.ONE) >= 0) { + if (demand.compareTo(Fraction.ONE) >= 0) { Optional get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve(); if (get_energy.isPresent()) { - demand = demand.subtract(MatteryCapability.drainFE(get_energy.get(), demand, false), MatteryCapability.ROUND_RULES); + demand = demand.minus(MatteryCapability.drainFE(get_energy.get(), demand, false)); } } - energy_stored = energy_stored_max.subtract(demand); + energy_stored = energy_stored_max.minus(demand); } } } @Nonnull @Override - public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { - return BigDecimal.ZERO; + public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) { + return Fraction.ZERO; } @Nonnull @Override - public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { - BigDecimal drained = BigDecimal.ZERO; + public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) { + Fraction drained = Fraction.ZERO; if (battery != ItemStack.EMPTY) { Optional get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve(); if (get_mattery.isPresent()) { - BigDecimal changed = get_mattery.get().extractEnergyOuter(howMuch, simulate); + Fraction changed = get_mattery.get().extractEnergyOuter(howMuch, simulate); - if (changed.compareTo(BigDecimal.ZERO) > 0) { - drained = drained.add(changed, MatteryCapability.ROUND_RULES); - howMuch = howMuch.subtract(changed, MatteryCapability.ROUND_RULES); + if (changed.compareTo(Fraction.ZERO) > 0) { + drained = drained.plus(changed); + howMuch = howMuch.minus(changed); - if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { + if (howMuch.compareTo(Fraction.ZERO) <= 0) { if (!simulate && ent instanceof ServerPlayer ply) { - ply.awardStat(Registry.Names.POWER_CONSUMED, drained.intValue() * 10); + ply.awardStat(Registry.Names.POWER_CONSUMED, drained.toInt() * 10); } return drained; @@ -424,19 +425,19 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit } } - if (howMuch.compareTo(BigDecimal.ONE) >= 0) { + if (howMuch.compareTo(Fraction.ONE) >= 0) { Optional get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve(); if (get_energy.isPresent()) { - BigDecimal changed = MatteryCapability.drainFE(get_energy.get(), howMuch, simulate); + Fraction changed = MatteryCapability.drainFE(get_energy.get(), howMuch, simulate); - if (changed.compareTo(BigDecimal.ZERO) > 0) { - drained = drained.add(changed, MatteryCapability.ROUND_RULES); - howMuch = howMuch.subtract(changed, MatteryCapability.ROUND_RULES); + if (changed.compareTo(Fraction.ZERO) > 0) { + drained = drained.plus(changed); + howMuch = howMuch.minus(changed); - if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { + if (howMuch.compareTo(Fraction.ZERO) <= 0) { if (!simulate && ent instanceof ServerPlayer ply) { - ply.awardStat(Registry.Names.POWER_CONSUMED, drained.intValue() * 10); + ply.awardStat(Registry.Names.POWER_CONSUMED, drained.toInt() * 10); } return drained; @@ -446,14 +447,14 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit } } - BigDecimal new_energy = energy_stored.subtract(howMuch, MatteryCapability.ROUND_RULES).max(BigDecimal.ZERO); - drained = drained.add(energy_stored.subtract(new_energy, MatteryCapability.ROUND_RULES)); + Fraction new_energy = energy_stored.minus(howMuch).max(Fraction.ZERO); + drained = drained.plus(energy_stored.minus(new_energy)); if (!simulate) { energy_stored = new_energy; if (ent instanceof ServerPlayer ply) { - ply.awardStat(Registry.Names.POWER_CONSUMED, drained.intValue() * 10); + ply.awardStat(Registry.Names.POWER_CONSUMED, drained.toInt() * 10); } } @@ -462,36 +463,36 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit @Nonnull @Override - public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { - BigDecimal received = BigDecimal.ZERO; + public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) { + Fraction received = Fraction.ZERO; if (battery != ItemStack.EMPTY) { Optional get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve(); if (get_mattery.isPresent()) { - BigDecimal changed = get_mattery.get().receiveEnergyOuter(howMuch, simulate); + Fraction changed = get_mattery.get().receiveEnergyOuter(howMuch, simulate); - if (changed.compareTo(BigDecimal.ZERO) > 0) { - received = received.add(changed, MatteryCapability.ROUND_RULES); - howMuch = howMuch.subtract(changed, MatteryCapability.ROUND_RULES); + if (changed.compareTo(Fraction.ZERO) > 0) { + received = received.plus(changed); + howMuch = howMuch.minus(changed); - if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { + if (howMuch.compareTo(Fraction.ZERO) <= 0) { return received; } } } - if (howMuch.compareTo(BigDecimal.ONE) >= 0) { + if (howMuch.compareTo(Fraction.ONE) >= 0) { Optional get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve(); if (get_energy.isPresent()) { - BigDecimal changed = MatteryCapability.floodFE(get_energy.get(), howMuch, simulate); + Fraction changed = MatteryCapability.floodFE(get_energy.get(), howMuch, simulate); - if (changed.compareTo(BigDecimal.ZERO) > 0) { - received = received.add(changed, MatteryCapability.ROUND_RULES); - howMuch = howMuch.subtract(changed, MatteryCapability.ROUND_RULES); + if (changed.compareTo(Fraction.ZERO) > 0) { + received = received.plus(changed); + howMuch = howMuch.minus(changed); - if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { + if (howMuch.compareTo(Fraction.ZERO) <= 0) { return received; } } @@ -499,8 +500,8 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit } } - BigDecimal new_energy = energy_stored.add(howMuch, MatteryCapability.ROUND_RULES).min(energy_stored_max); - received = received.add(new_energy.subtract(energy_stored, MatteryCapability.ROUND_RULES), MatteryCapability.ROUND_RULES); + Fraction new_energy = energy_stored.plus(howMuch).min(energy_stored_max); + received = received.plus(new_energy.minus(energy_stored)); if (!simulate) { energy_stored = new_energy; @@ -511,7 +512,7 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit @Nonnull @Override - public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { + public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) { return receiveEnergyOuter(howMuch, simulate); } @@ -533,18 +534,18 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit @Override @Nonnull - public BigDecimal getBatteryLevel() { + public Fraction getBatteryLevel() { if (battery != ItemStack.EMPTY) { Optional get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve(); if (get_mattery.isPresent()) { - return get_mattery.get().getBatteryLevel().add(energy_stored, MatteryCapability.ROUND_RULES); + return get_mattery.get().getBatteryLevel().plus(energy_stored); } Optional get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve(); if (get_energy.isPresent()) { - return new BigDecimal(get_energy.get().getEnergyStored()).add(energy_stored, MatteryCapability.ROUND_RULES); + return energy_stored.plus(get_energy.get().getEnergyStored()); } } @@ -553,18 +554,18 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit @Override @Nonnull - public BigDecimal getMaxBatteryLevel() { + public Fraction getMaxBatteryLevel() { if (battery != ItemStack.EMPTY) { Optional get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve(); if (get_mattery.isPresent()) { - return get_mattery.get().getMaxBatteryLevel().add(energy_stored_max, MatteryCapability.ROUND_RULES); + return get_mattery.get().getMaxBatteryLevel().plus(energy_stored_max); } Optional get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve(); if (get_energy.isPresent()) { - return new BigDecimal(get_energy.get().getMaxEnergyStored()).add(energy_stored_max, MatteryCapability.ROUND_RULES); + return energy_stored_max.plus(get_energy.get().getMaxEnergyStored()); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java index 099165fdd..38b3c4890 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/android/AndroidCapabilityPlayer.java @@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.Registry; 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.network.android.AndroidResearchPacket; import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket; @@ -75,8 +76,8 @@ public class AndroidCapabilityPlayer extends AndroidCapability { is_android = true; will_become_android = false; - energy_stored = new BigDecimal(60_000); - energy_stored_max = new BigDecimal(60_000); + energy_stored = new Fraction(60_000); + energy_stored_max = new Fraction(60_000); } public void becomeAndroidAndKill() { @@ -96,8 +97,8 @@ public class AndroidCapabilityPlayer extends AndroidCapability { is_android = false; - energy_stored = new BigDecimal(0); - energy_stored_max = new BigDecimal(60_000); + energy_stored = new Fraction(0); + energy_stored_max = new Fraction(60_000); dropBattery(); } @@ -247,7 +248,7 @@ public class AndroidCapabilityPlayer extends AndroidCapability { } } - public static final BigDecimal ENERGY_FOR_HUNGER_POINT = new BigDecimal(1000); + public static final Fraction ENERGY_FOR_HUNGER_POINT = new Fraction(1000); public int sleep_ticks = 0; public static final int SLEEP_TICKS_LIMIT = 80; @@ -315,13 +316,13 @@ public class AndroidCapabilityPlayer extends AndroidCapability { var food_level = (float) stats.getFoodLevel(); if (stats.getSaturationLevel() < food_level) { - BigDecimal extracted = this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT.multiply(new BigDecimal(Float.toString(food_level - stats.getSaturationLevel()))), false); - stats.setSaturation(stats.getSaturationLevel() + extracted.divide(ENERGY_FOR_HUNGER_POINT, MatteryCapability.ROUND_RULES).floatValue()); + Fraction extracted = this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT.times(food_level - stats.getSaturationLevel()), false); + stats.setSaturation(stats.getSaturationLevel() + extracted.div(ENERGY_FOR_HUNGER_POINT).toFloat()); } if (stats.getExhaustionLevel() > 0f) { - BigDecimal extracted = this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT.multiply(new BigDecimal(Float.toString(stats.getExhaustionLevel() / 4f))), false); - stats.setExhaustion(stats.getExhaustionLevel() - extracted.divide(ENERGY_FOR_HUNGER_POINT, MatteryCapability.ROUND_RULES).floatValue() * 4f); + Fraction extracted = this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT.times(stats.getExhaustionLevel() / 4f), false); + stats.setExhaustion(stats.getExhaustionLevel() - extracted.div(ENERGY_FOR_HUNGER_POINT).toFloat() * 4f); } } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java index a74b8a991..cb7606868 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/android/IAndroidCapability.java @@ -9,6 +9,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 javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -45,6 +46,6 @@ public interface IAndroidCapability extends IMatteryEnergyStorage, INBTSerializa void invalidateNetworkState(); // tell capability that player forgot everything, and everything needs to be re-networked - void setEnergy(BigDecimal value); - void setMaxEnergy(BigDecimal value); + void setEnergy(Fraction value); + void setMaxEnergy(Fraction value); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.java b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.java index a67d767c8..10017db73 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.java @@ -4,6 +4,7 @@ import net.minecraft.MethodsReturnNonnullByDefault; 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.storage.*; import javax.annotation.Nonnull; @@ -22,16 +23,16 @@ abstract public class AbstractMatteryDrive implements I protected boolean dirty = false; protected int different_stacks = 0; - protected BigDecimal stored = BigDecimal.ZERO; + protected Fraction stored = Fraction.ZERO; protected int max_different_stacks; - protected BigDecimal capacity; + protected Fraction capacity; - public AbstractMatteryDrive(BigDecimal capacity, int max_different_stacks) { + public AbstractMatteryDrive(Fraction capacity, int max_different_stacks) { this.capacity = capacity; this.max_different_stacks = max_different_stacks; } - public AbstractMatteryDrive(BigDecimal capacity) { + public AbstractMatteryDrive(Fraction capacity) { this(capacity, 0xFFFF); } @@ -51,12 +52,12 @@ abstract public class AbstractMatteryDrive implements I } @Override - public BigDecimal getStoredCount() { + public Fraction getStoredCount() { return stored; } @Override - public BigDecimal getCapacity() { + public Fraction getCapacity() { return capacity; } @@ -64,9 +65,9 @@ abstract public class AbstractMatteryDrive implements I @Override @SuppressWarnings("unchecked") public T insertStack(T stack, boolean simulate) { - BigDecimal max_insert = getCapacity().subtract(getStoredCount()).min(stack.getCount()); + var max_insert = getCapacity().minus(getStoredCount()).min(stack.getCount()); - if (max_insert.compareTo(BigDecimal.ZERO) <= 0) + if (max_insert.compareTo(Fraction.ZERO) <= 0) return stack; final var listing = items.computeIfAbsent(stack.partitionKey(), (key) -> new ArrayList<>()); @@ -75,7 +76,7 @@ abstract public class AbstractMatteryDrive implements I if (state.stack().sameItem(stack)) { if (!simulate) { state.stack().grow(max_insert); - stored = stored.add(max_insert); + stored = stored.plus(max_insert); for (var listener : listeners2) { listener.changeObject(state.id(), state.stack().getCount()); @@ -96,7 +97,7 @@ abstract public class AbstractMatteryDrive implements I if (!simulate) { different_stacks++; - stored = stored.add(max_insert); + stored = stored.plus(max_insert); final var copy = (T) stack.copy(); copy.setCount(max_insert); @@ -119,18 +120,18 @@ abstract public class AbstractMatteryDrive implements I @Nonnull @Override @SuppressWarnings("unchecked") - public T extractStack(UUID id, BigDecimal amount, boolean simulate) { + public T extractStack(UUID id, Fraction amount, boolean simulate) { var get = items_by_id.get(id); if (get == null) return identity().empty(); - if (amount.compareTo(BigDecimal.ZERO) <= 0) + if (amount.compareTo(Fraction.ZERO) <= 0) amount = get.stack().getMaxStackSize().orElse(get.stack().getCount()); amount = amount.min(get.stack().getCount()); - if (amount.compareTo(BigDecimal.ZERO) <= 0) + if (amount.compareTo(Fraction.ZERO) <= 0) return identity().empty(); final var copy = (T) get.stack().copy(); @@ -151,10 +152,10 @@ abstract public class AbstractMatteryDrive implements I } } - stored = stored.subtract(amount); + stored = stored.minus(amount); get.stack().shrink(amount); - if (get.stack().getCount().compareTo(BigDecimal.ZERO) != 0) { + if (get.stack().getCount().compareTo(Fraction.ZERO) != 0) { for (var listener : listeners2) { listener.changeObject(get.id(), get.stack().getCount()); } @@ -200,10 +201,12 @@ abstract public class AbstractMatteryDrive implements I public void deserializeNBT(CompoundTag nbt) { items.clear(); items_by_id.clear(); - stored = BigDecimal.ZERO; + stored = Fraction.ZERO; different_stacks = 0; - capacity = new BigDecimal(nbt.getString("capacity")); + if (nbt.contains("capacity")) + capacity = Fraction.deserializeNBT(nbt.get("capacity")); + max_different_stacks = nbt.getInt("max_different_stacks"); for (var _entry : nbt.getList("items", Tag.TAG_COMPOUND)) { @@ -211,7 +214,7 @@ abstract public class AbstractMatteryDrive implements I final var stack = deserializeStack(entry); if (stack != null) { - stored = stored.add(stack.getCount()); + stored = stored.plus(stack.getCount()); different_stacks++; final var id = entry.getLongArray("id"); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/IMatteryDrive.java b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/IMatteryDrive.java index 2ff22fa6b..21812366d 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/IMatteryDrive.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/IMatteryDrive.java @@ -4,6 +4,7 @@ import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.storage.*; import javax.annotation.ParametersAreNonnullByDefault; @@ -18,8 +19,8 @@ public interface IMatteryDrive extends IStorageComponen void markDirty(); void markClean(); - BigDecimal getStoredCount(); - BigDecimal getCapacity(); + Fraction getStoredCount(); + Fraction getCapacity(); // not extending INBTSerializable to avoid serializing it as forgecaps CompoundTag serializeNBT(); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.java b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.java index 431294f16..0f7abe61c 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/drive/ItemMatteryDrive.java @@ -7,6 +7,7 @@ import net.minecraft.world.item.Item; 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.storage.IStorageTuple; import ru.dbotthepony.mc.otm.storage.ItemStackWrapper; import ru.dbotthepony.mc.otm.storage.StorageObjectRegistry; @@ -24,11 +25,11 @@ import java.util.Objects; public class ItemMatteryDrive extends AbstractMatteryDrive implements IItemMatteryDrive { private static StorageObjectTuple identity; - public ItemMatteryDrive(BigDecimal capacity, int max_different_stacks) { + public ItemMatteryDrive(Fraction capacity, int max_different_stacks) { super(capacity, max_different_stacks); } - public ItemMatteryDrive(BigDecimal capacity) { + public ItemMatteryDrive(Fraction capacity) { super(capacity); } 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 d71e81948..e4a2cd68a 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,6 +1,7 @@ package ru.dbotthepony.mc.otm.capability.matter; import net.minecraft.MethodsReturnNonnullByDefault; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; @@ -15,18 +16,18 @@ public interface IMatterHandler { BIDIRECTIONAL // storage } - BigDecimal getStoredMatter(); - BigDecimal getMaxStoredMatter(); + Fraction getStoredMatter(); + Fraction getMaxStoredMatter(); - BigDecimal receiveMatterOuter(BigDecimal howMuch, boolean simulate); - BigDecimal receiveMatterInner(BigDecimal howMuch, boolean simulate); + Fraction receiveMatterOuter(Fraction howMuch, boolean simulate); + Fraction receiveMatterInner(Fraction howMuch, boolean simulate); - BigDecimal extractMatterOuter(BigDecimal howMuch, boolean simulate); - BigDecimal extractMatterInner(BigDecimal howMuch, boolean simulate); + Fraction extractMatterOuter(Fraction howMuch, boolean simulate); + Fraction extractMatterInner(Fraction howMuch, boolean simulate); MatterDirection getDirection(); - default BigDecimal getMissingMatter() { - return getMaxStoredMatter().subtract(getStoredMatter()); + default Fraction 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 5164abcd0..e66c71cc7 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 @@ -5,6 +5,7 @@ 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 javax.annotation.Nonnull; @@ -16,17 +17,17 @@ import java.math.BigDecimal; @ParametersAreNonnullByDefault public class MatterHandlerCapability implements IMatterHandler, INBTSerializable { protected final Runnable listener; - protected BigDecimal stored = BigDecimal.ZERO; + protected Fraction stored = Fraction.ZERO; protected MatterDirection direction; - protected BigDecimal max_storage; + protected Fraction max_storage; - protected BigDecimal max_receive; - protected BigDecimal max_extract; + protected Fraction max_receive; + protected Fraction max_extract; public MatterHandlerCapability( @Nullable Runnable listener, MatterDirection direction, - BigDecimal max_storage + Fraction max_storage ) { this.listener = listener; this.direction = direction; @@ -36,9 +37,9 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable public MatterHandlerCapability( @Nullable Runnable listener, MatterDirection direction, - BigDecimal max_storage, - BigDecimal max_receive, - BigDecimal max_extract + Fraction max_storage, + Fraction max_receive, + Fraction max_extract ) { this(listener, direction, max_storage); @@ -62,41 +63,41 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable @Nonnull @Override - public BigDecimal getStoredMatter() { + public Fraction getStoredMatter() { return stored; } @Nonnull @Override - public BigDecimal getMaxStoredMatter() { + public Fraction getMaxStoredMatter() { return max_storage; } - public boolean canReceiveAll(BigDecimal value) { - return max_storage.compareTo(value) >= 0 && stored.add(value).compareTo(max_storage) <= 0; + public boolean canReceiveAll(Fraction value) { + return max_storage.compareTo(value) >= 0 && stored.plus(value).compareTo(max_storage) <= 0; } @Nonnull @Override - public BigDecimal receiveMatterOuter(BigDecimal howMuch, boolean simulate) { + public Fraction receiveMatterOuter(Fraction howMuch, boolean simulate) { if (getDirection() == MatterDirection.EXTRACT) - return BigDecimal.ZERO; + return Fraction.ZERO; return receiveMatterInner(howMuch, simulate); } @Nonnull @Override - public BigDecimal receiveMatterInner(BigDecimal howMuch, boolean simulate) { - BigDecimal new_matter; + public Fraction receiveMatterInner(Fraction howMuch, boolean simulate) { + Fraction new_matter; if (max_receive == null) { - new_matter = stored.add(howMuch, MatterRegistry.ROUND_RULES).min(max_storage); + new_matter = stored.plus(howMuch).min(max_storage); } else { - new_matter = stored.add(howMuch.min(max_receive), MatterRegistry.ROUND_RULES).min(max_storage); + new_matter = stored.plus(howMuch.min(max_receive)).min(max_storage); } - BigDecimal diff = new_matter.subtract(stored); + Fraction diff = new_matter.minus(stored); if (!simulate && new_matter.compareTo(stored) != 0) { stored = new_matter; @@ -111,25 +112,25 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable @Nonnull @Override - public BigDecimal extractMatterOuter(BigDecimal howMuch, boolean simulate) { + public Fraction extractMatterOuter(Fraction howMuch, boolean simulate) { if (getDirection() == MatterDirection.RECEIVE) - return BigDecimal.ZERO; + return Fraction.ZERO; return extractMatterInner(howMuch, simulate); } @Nonnull @Override - public BigDecimal extractMatterInner(BigDecimal howMuch, boolean simulate) { - BigDecimal new_matter; + public Fraction extractMatterInner(Fraction howMuch, boolean simulate) { + Fraction new_matter; if (max_receive == null) { - new_matter = stored.subtract(howMuch, MatterRegistry.ROUND_RULES).max(BigDecimal.ZERO); + new_matter = stored.minus(howMuch).moreThanZero(); } else { - new_matter = stored.subtract(howMuch.min(max_receive), MatterRegistry.ROUND_RULES).max(BigDecimal.ZERO); + new_matter = stored.minus(howMuch.min(max_receive)).moreThanZero(); } - BigDecimal diff = stored.subtract(new_matter); + Fraction diff = stored.minus(new_matter); if (!simulate && new_matter.compareTo(stored) != 0) { stored = new_matter; @@ -166,18 +167,18 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable @Override public void deserializeNBT(CompoundTag tag) { if (tag.contains("stored")) - stored = new BigDecimal(tag.getString("stored")); + stored = Fraction.deserializeNBT(tag.get("stored")); if (tag.contains("max_storage")) - max_storage = new BigDecimal(tag.getString("max_storage")); + max_storage = Fraction.deserializeNBT(tag.get("max_storage")); if (tag.contains("max_receive")) - max_receive = new BigDecimal(tag.getString("max_receive")); + max_receive = Fraction.deserializeNBT(tag.get("max_receive")); else max_receive = null; if (tag.contains("max_extract")) - max_extract = new BigDecimal(tag.getString("max_extract")); + max_extract = Fraction.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 12df2352b..319465991 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java +++ b/src/main/java/ru/dbotthepony/mc/otm/client/AndroidGui.java @@ -25,6 +25,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters; 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 java.math.BigDecimal; import java.util.Optional; @@ -162,10 +163,10 @@ public class AndroidGui { float level; - if (android.getMaxBatteryLevel().compareTo(BigDecimal.ZERO) == 0) { + if (android.getMaxBatteryLevel().compareTo(Fraction.ZERO) == 0) { level = 0f; } else { - level = android.getBatteryLevel().divide(android.getMaxBatteryLevel(), MatteryCapability.ROUND_RULES).floatValue(); + level = android.getBatteryLevel().div(android.getMaxBatteryLevel()).toFloat(); if (level >= 0.98f) level = 1f; diff --git a/src/main/java/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.java b/src/main/java/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.java index 50c2871d1..79cd63f47 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.java +++ b/src/main/java/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.java @@ -27,7 +27,7 @@ public class EnergyCounterScreen extends MatteryScreen { public void tick() { super.tick(); - setText(new TranslatableComponent("otm.item.power.passed", FormattingHelper.formatPower(menu.passed.getDecimal()))); + setText(new TranslatableComponent("otm.item.power.passed", FormattingHelper.formatPower(menu.passed.getValue()))); } }; @@ -39,7 +39,7 @@ public class EnergyCounterScreen extends MatteryScreen { public void tick() { super.tick(); - setText(new TranslatableComponent("otm.item.power.average", FormattingHelper.formatPower(menu.average.getDecimal()))); + setText(new TranslatableComponent("otm.item.power.average", FormattingHelper.formatPower(menu.average.getValue()))); } }; @@ -51,7 +51,7 @@ public class EnergyCounterScreen extends MatteryScreen { public void tick() { super.tick(); - setText(new TranslatableComponent("otm.item.power.last_20_ticks", FormattingHelper.formatPower(menu.last_20_ticks.getDecimal()))); + setText(new TranslatableComponent("otm.item.power.last_20_ticks", FormattingHelper.formatPower(menu.last_20_ticks.getValue()))); } }; diff --git a/src/main/java/ru/dbotthepony/mc/otm/item/ItemBattery.java b/src/main/java/ru/dbotthepony/mc/otm/item/ItemBattery.java index c9003ce2f..8a1258506 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/item/ItemBattery.java +++ b/src/main/java/ru/dbotthepony/mc/otm/item/ItemBattery.java @@ -7,59 +7,44 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.world.item.*; import net.minecraft.world.level.Level; -import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.energy.CapabilityEnergy; -import net.minecraftforge.fml.loading.FMLEnvironment; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.menu.FormattingHelper; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.math.BigDecimal; import java.util.List; -import java.util.Objects; public class ItemBattery extends Item { public class BatteryMatteryCapability implements IMatteryEnergyStorage, ICapabilityProvider { - private final BigDecimal storage; - private final BigDecimal max_input; - private final BigDecimal max_output; + private final Fraction storage; + private final Fraction max_input; + private final Fraction max_output; private final boolean is_creative; - private BigDecimal energy; - private String _energy; private final ItemStack stack; - private BigDecimal energy() { + private Fraction energy() { CompoundTag tag = stack.getOrCreateTag(); if (tag.contains("otm_energy")) { - String get_energy = tag.getString("otm_energy"); - - if (Objects.equals(_energy, get_energy)) { - return energy; - } - - energy = new BigDecimal(tag.getString("otm_energy")); - _energy = get_energy; - - return energy; + return Fraction.deserializeNBT(tag.get("otm_energy")); } - return BigDecimal.ZERO; + return Fraction.ZERO; } - private void energy(BigDecimal value) { - energy = value; - stack.getOrCreateTag().putString("otm_energy", value.toString()); + private void energy(Fraction value) { + stack.getOrCreateTag().put("otm_energy", value.serializeNBT()); } - public BatteryMatteryCapability(ItemStack stack, BigDecimal storage, BigDecimal max_input, BigDecimal max_output) { + public BatteryMatteryCapability(ItemStack stack, Fraction storage, Fraction max_input, Fraction max_output) { this.stack = stack; is_creative = false; this.storage = storage; @@ -77,18 +62,18 @@ public class ItemBattery extends Item { @Nonnull @Override - public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { + public Fraction extractEnergyOuter(@Nonnull Fraction howMuch, boolean simulate) { return extractEnergyInner(howMuch, simulate); } @Nonnull @Override - public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { + public Fraction extractEnergyInner(@Nonnull Fraction howMuch, boolean simulate) { if (is_creative) return howMuch; - BigDecimal new_energy = energy().subtract(howMuch.min(max_output), MatteryCapability.ROUND_RULES).max(BigDecimal.ZERO); - BigDecimal diff = energy().subtract(new_energy); + Fraction new_energy = energy().minus(howMuch.min(max_output)).moreThanZero(); + Fraction diff = energy().minus(new_energy); if (!simulate) { energy(new_energy); @@ -99,18 +84,18 @@ public class ItemBattery extends Item { @Nonnull @Override - public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { + public Fraction receiveEnergyOuter(@Nonnull Fraction howMuch, boolean simulate) { return receiveEnergyInner(howMuch, simulate); } @Nonnull @Override - public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { + public Fraction receiveEnergyInner(@Nonnull Fraction howMuch, boolean simulate) { if (is_creative) return howMuch; - BigDecimal new_energy = energy().add(howMuch.min(max_input), MatteryCapability.ROUND_RULES).min(storage); - BigDecimal diff = new_energy.subtract(energy()); + Fraction new_energy = energy().plus(howMuch.min(max_input)).min(storage); + Fraction diff = new_energy.minus(energy()); if (!simulate) { energy(new_energy); @@ -119,8 +104,9 @@ public class ItemBattery extends Item { return diff; } + @Nonnull @Override - public BigDecimal getMissingPower() { + public Fraction getMissingPower() { if (is_creative) return MatteryCapability.LONG_MAX_VALUE; @@ -129,7 +115,7 @@ public class ItemBattery extends Item { @Nonnull @Override - public BigDecimal getBatteryLevel() { + public Fraction getBatteryLevel() { if (is_creative) return MatteryCapability.LONG_MAX_VALUE; @@ -138,7 +124,7 @@ public class ItemBattery extends Item { @Nonnull @Override - public BigDecimal getMaxBatteryLevel() { + public Fraction getMaxBatteryLevel() { if (is_creative) return MatteryCapability.LONG_MAX_VALUE; @@ -169,14 +155,14 @@ public class ItemBattery extends Item { private final boolean is_creative; - public final BigDecimal storage; - public final BigDecimal receive; - public final BigDecimal extract; + public final Fraction storage; + public final Fraction receive; + public final Fraction extract; private final Component THROUGHPUT; private static final Component INFINITE_STORAGE = new TranslatableComponent("otm.item.power.infinite.storage").withStyle(ChatFormatting.GRAY); - public ItemBattery(BigDecimal storage, BigDecimal receive, BigDecimal extract) { + public ItemBattery(Fraction storage, Fraction receive, Fraction extract) { super(new Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)); is_creative = false; this.storage = storage; diff --git a/src/main/java/ru/dbotthepony/mc/otm/item/ItemMatterCapacitor.java b/src/main/java/ru/dbotthepony/mc/otm/item/ItemMatterCapacitor.java index 7b0b7d8c9..7a3fc99e9 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/item/ItemMatterCapacitor.java +++ b/src/main/java/ru/dbotthepony/mc/otm/item/ItemMatterCapacitor.java @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.item; import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; @@ -13,14 +14,18 @@ import net.minecraftforge.common.util.LazyOptional; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.menu.FormattingHelper; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; import java.math.BigDecimal; import java.util.List; import java.util.Objects; +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault public class ItemMatterCapacitor extends Item { public static class ItemMatterCapacitorCapability implements ICapabilityProvider, IMatterHandler { private final LazyOptional resolver = LazyOptional.of(() -> this); @@ -33,40 +38,31 @@ public class ItemMatterCapacitor extends Item { return LazyOptional.empty(); } - private final BigDecimal storage; - private final BigDecimal max_input; - private final BigDecimal max_output; + + private final Fraction storage; + private final Fraction max_input; + private final Fraction max_output; private final boolean is_creative; - private BigDecimal energy; + private Fraction energy; private String _energy; private final ItemStack stack; - private BigDecimal matter() { + private Fraction matter() { CompoundTag tag = stack.getOrCreateTag(); if (tag.contains("otm_matter")) { - String get_energy = tag.getString("otm_matter"); - - if (Objects.equals(_energy, get_energy)) { - return energy; - } - - energy = new BigDecimal(tag.getString("otm_matter")); - _energy = get_energy; - - return energy; + return Fraction.deserializeNBT(tag.get("otm_matter")); } - return BigDecimal.ZERO; + return Fraction.ZERO; } - private void matter(BigDecimal value) { - energy = value; - stack.getOrCreateTag().putString("otm_matter", value.toString()); + private void matter(Fraction value) { + stack.getOrCreateTag().put("otm_matter", value.serializeNBT()); } - public ItemMatterCapacitorCapability(ItemStack stack, BigDecimal storage, BigDecimal max_input, BigDecimal max_output) { + public ItemMatterCapacitorCapability(ItemStack stack, Fraction storage, Fraction max_input, Fraction max_output) { this.stack = stack; is_creative = false; this.storage = storage; @@ -82,7 +78,7 @@ public class ItemMatterCapacitor extends Item { max_output = MatteryCapability.LONG_MAX_VALUE; } - public ItemMatterCapacitorCapability(ItemStack stack, BigDecimal storage) { + public ItemMatterCapacitorCapability(ItemStack stack, Fraction storage) { this.stack = stack; is_creative = false; this.storage = storage; @@ -92,7 +88,7 @@ public class ItemMatterCapacitor extends Item { @Nonnull @Override - public BigDecimal getStoredMatter() { + public Fraction getStoredMatter() { if (is_creative) return MatteryCapability.LONG_MAX_VALUE; @@ -101,7 +97,7 @@ public class ItemMatterCapacitor extends Item { @Nonnull @Override - public BigDecimal getMaxStoredMatter() { + public Fraction getMaxStoredMatter() { if (is_creative) return MatteryCapability.LONG_MAX_VALUE; @@ -110,7 +106,7 @@ public class ItemMatterCapacitor extends Item { @Nonnull @Override - public BigDecimal getMissingMatter() { + public Fraction getMissingMatter() { if (is_creative) return MatteryCapability.LONG_MAX_VALUE; @@ -119,18 +115,18 @@ public class ItemMatterCapacitor extends Item { @Nonnull @Override - public BigDecimal receiveMatterOuter(BigDecimal howMuch, boolean simulate) { + public Fraction receiveMatterOuter(Fraction howMuch, boolean simulate) { return receiveMatterInner(howMuch, simulate); } @Nonnull @Override - public BigDecimal receiveMatterInner(BigDecimal howMuch, boolean simulate) { + public Fraction receiveMatterInner(Fraction howMuch, boolean simulate) { if (is_creative) return howMuch; - BigDecimal new_matter = matter().add(howMuch.min(max_input), MatteryCapability.ROUND_RULES).min(storage); - BigDecimal diff = new_matter.subtract(matter()); + Fraction new_matter = matter().plus(howMuch.min(max_input)).min(storage); + Fraction diff = new_matter.minus(matter()); if (!simulate) { matter(new_matter); @@ -141,19 +137,19 @@ public class ItemMatterCapacitor extends Item { @Nonnull @Override - public BigDecimal extractMatterOuter(BigDecimal howMuch, boolean simulate) { + public Fraction extractMatterOuter(Fraction howMuch, boolean simulate) { return extractMatterInner(howMuch, simulate); } @Nonnull @Override - public BigDecimal extractMatterInner(BigDecimal howMuch, boolean simulate) { + public Fraction extractMatterInner(Fraction howMuch, boolean simulate) { if (is_creative) return howMuch; - BigDecimal new_matter = matter().subtract(howMuch.min(max_output), MatteryCapability.ROUND_RULES).max(BigDecimal.ZERO); - BigDecimal diff = matter().subtract(new_matter); + Fraction new_matter = matter().minus(howMuch.min(max_output)).moreThanZero(); + Fraction diff = matter().minus(new_matter); if (!simulate) { matter(new_matter); @@ -169,13 +165,13 @@ public class ItemMatterCapacitor extends Item { } } - public final BigDecimal storage; + public final Fraction storage; private static final Component INFINITE_STORAGE = new TranslatableComponent("otm.item.matter.infinite").withStyle(ChatFormatting.GRAY); private final boolean is_creative; - public ItemMatterCapacitor(BigDecimal storage) { + public ItemMatterCapacitor(Fraction storage) { super(new Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)); is_creative = false; this.storage = storage; diff --git a/src/main/java/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.java b/src/main/java/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.java index 06492df4f..7abaa082f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.java +++ b/src/main/java/ru/dbotthepony/mc/otm/item/ItemPortableCondensationDrive.java @@ -23,6 +23,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.drive.DrivePool; import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive; import ru.dbotthepony.mc.otm.capability.drive.ItemMatteryDrive; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -32,11 +33,11 @@ import java.util.List; import java.util.UUID; public class ItemPortableCondensationDrive extends Item { - public final BigDecimal capacity; + public final Fraction capacity; public ItemPortableCondensationDrive(int capacity) { super(new Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)); - this.capacity = new BigDecimal(capacity); + this.capacity = new Fraction(capacity); } @SubscribeEvent diff --git a/src/main/java/ru/dbotthepony/mc/otm/matter/MatterGrid.java b/src/main/java/ru/dbotthepony/mc/otm/matter/MatterGrid.java index d047d8e59..59978248b 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/matter/MatterGrid.java +++ b/src/main/java/ru/dbotthepony/mc/otm/matter/MatterGrid.java @@ -10,6 +10,7 @@ import ru.dbotthepony.mc.otm.AbstractGrid; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.matter.*; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; @@ -31,81 +32,81 @@ public class MatterGrid extends AbstractGrid implements IMatter super(MatteryCapability.MATTER_CELL); } - public BigDecimal getCapacity() { - BigDecimal summ = BigDecimal.ZERO; + public Fraction getCapacity() { + Fraction summ = Fraction.ZERO; for (IMatterGridCell cell : cells) { IMatterHandler handler = cell.getMatterHandler(); if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) { - summ = summ.add(handler.getMaxStoredMatter()); + summ = summ.plus(handler.getMaxStoredMatter()); } } return summ; } - public BigDecimal getPotentialCapacity() { - BigDecimal summ = BigDecimal.ZERO; + public Fraction getPotentialCapacity() { + Fraction summ = Fraction.ZERO; for (IMatterGridCell cell : cells) { IMatterHandler handler = cell.getMatterHandler(); if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) { - summ = summ.add(handler.getMaxStoredMatter()); + summ = summ.plus(handler.getMaxStoredMatter()); } } return summ; } - public BigDecimal getStored() { - BigDecimal summ = BigDecimal.ZERO; + public Fraction getStored() { + Fraction summ = Fraction.ZERO; for (IMatterGridCell cell : cells) { IMatterHandler handler = cell.getMatterHandler(); if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) { - summ = summ.add(handler.getStoredMatter()); + summ = summ.plus(handler.getStoredMatter()); } } return summ; } - public BigDecimal getPotentialStored() { - BigDecimal summ = BigDecimal.ZERO; + public Fraction getPotentialStored() { + Fraction summ = Fraction.ZERO; for (IMatterGridCell cell : cells) { IMatterHandler handler = cell.getMatterHandler(); if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) { - summ = summ.add(handler.getStoredMatter()); + summ = summ.plus(handler.getStoredMatter()); } } return summ; } - public BigDecimal extractMatter(BigDecimal howMuch, boolean simulate) { - if (howMuch.compareTo(BigDecimal.ZERO) <= 0) - return BigDecimal.ZERO; + public Fraction extractMatter(Fraction howMuch, boolean simulate) { + if (howMuch.compareTo(Fraction.ZERO) <= 0) + return Fraction.ZERO; validate(); - BigDecimal extracted = BigDecimal.ZERO; + Fraction extracted = Fraction.ZERO; for (IMatterGridCell cell : cells) { IMatterHandler handler = cell.getMatterHandler(); if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) { - BigDecimal drain = handler.extractMatterOuter(howMuch, simulate); + var drain = handler.extractMatterOuter(howMuch, simulate); - if (!drain.equals(BigDecimal.ZERO)) { - extracted = extracted.add(drain); - howMuch = howMuch.subtract(drain); + if (!drain.equalsCompact(Fraction.ZERO)) { + extracted = extracted.plus(drain); + howMuch = howMuch.minus(drain); - if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { + if (howMuch.compareTo(Fraction.ZERO) <= 0) { break; } } @@ -115,25 +116,25 @@ public class MatterGrid extends AbstractGrid implements IMatter return extracted; } - public BigDecimal softPushMatter(BigDecimal howMuch, boolean simulate) { - if (howMuch.compareTo(BigDecimal.ZERO) <= 0) - return BigDecimal.ZERO; + public Fraction softPushMatter(Fraction howMuch, boolean simulate) { + if (howMuch.compareTo(Fraction.ZERO) <= 0) + return Fraction.ZERO; validate(); - BigDecimal received = BigDecimal.ZERO; + Fraction received = Fraction.ZERO; for (IMatterGridCell cell : cells) { IMatterHandler handler = cell.getMatterHandler(); if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) { - BigDecimal receive = handler.receiveMatterOuter(howMuch, simulate); + var receive = handler.receiveMatterOuter(howMuch, simulate); - if (!receive.equals(BigDecimal.ZERO)) { - received = received.add(receive); - howMuch = howMuch.subtract(receive); + if (!receive.equalsCompact(Fraction.ZERO)) { + received = received.plus(receive); + howMuch = howMuch.minus(receive); - if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { + if (howMuch.compareTo(Fraction.ZERO) <= 0) { break; } } @@ -143,25 +144,25 @@ public class MatterGrid extends AbstractGrid implements IMatter return received; } - public BigDecimal pushMatter(BigDecimal howMuch, boolean simulate) { - if (howMuch.compareTo(BigDecimal.ZERO) <= 0) - return BigDecimal.ZERO; + public Fraction pushMatter(Fraction howMuch, boolean simulate) { + if (howMuch.compareTo(Fraction.ZERO) <= 0) + return Fraction.ZERO; validate(); - BigDecimal received = BigDecimal.ZERO; + Fraction received = Fraction.ZERO; for (IMatterGridCell cell : cells) { IMatterHandler handler = cell.getMatterHandler(); if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.EXTRACT) { - BigDecimal receive = handler.receiveMatterOuter(howMuch, simulate); + var receive = handler.receiveMatterOuter(howMuch, simulate); - if (!receive.equals(BigDecimal.ZERO)) { - received = received.add(receive); - howMuch = howMuch.subtract(receive); + if (!receive.equalsCompact(Fraction.ZERO)) { + received = received.plus(receive); + howMuch = howMuch.minus(receive); - if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { + if (howMuch.compareTo(Fraction.ZERO) <= 0) { break; } } 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 07d087a06..58bf2b752 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/matter/MatterRegistry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/matter/MatterRegistry.java @@ -19,22 +19,22 @@ import net.minecraftforge.network.PacketDistributor; 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.menu.FormattingHelper; import ru.dbotthepony.mc.otm.network.MatterRegistryPacket; import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.storage.ItemStackWrapper; import javax.annotation.Nullable; -import java.math.BigDecimal; 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 BigDecimal getMatterValue(Item item) { - return ITEMS.getOrDefault(item, INITIAL_ITEMS.getOrDefault(item, BigDecimal.ZERO)); + public static Fraction getMatterValue(Item item) { + return ITEMS.getOrDefault(item, INITIAL_ITEMS.getOrDefault(item, Fraction.ZERO)); } public static boolean hasMatterValue(Item item) { @@ -49,25 +49,25 @@ public class MatterRegistry { } public static boolean canDecompose(ItemStack stack) { - if (stack.getCapability(MatteryCapability.DRIVE).isPresent() && stack.getCapability(MatteryCapability.DRIVE).resolve().get().getStoredCount().compareTo(BigDecimal.ZERO) > 0) + if (stack.getCapability(MatteryCapability.DRIVE).isPresent() && stack.getCapability(MatteryCapability.DRIVE).resolve().get().getStoredCount().compareTo(Fraction.ZERO) > 0) return false; - if (stack.getCapability(MatteryCapability.MATTER).isPresent() && stack.getCapability(MatteryCapability.MATTER).resolve().get().getStoredMatter().compareTo(BigDecimal.ZERO) > 0) + if (stack.getCapability(MatteryCapability.MATTER).isPresent() && stack.getCapability(MatteryCapability.MATTER).resolve().get().getStoredMatter().compareTo(Fraction.ZERO) > 0) return false; return hasMatterValue(stack.getItem()); } - private static BigDecimal getMatterValue(ItemStack stack, int level) { + private static Fraction getMatterValue(ItemStack stack, int level) { if (level >= 100) { - return BigDecimal.ZERO; + return Fraction.ZERO; } Item item = stack.getItem(); var matter = getMatterValue(item); if (item.isDamageable(stack)) { - matter = matter.multiply(BigDecimal.ONE.subtract(new BigDecimal(item.getDamage(stack)).divide(new BigDecimal(item.getMaxDamage(stack)), ROUND_RULES))); + matter = matter.times(Fraction.ONE.minus(new Fraction(item.getDamage(stack)).div(new Fraction(item.getMaxDamage(stack))))); } var cap1 = stack.getCapability(MatteryCapability.DRIVE).resolve(); @@ -75,115 +75,115 @@ public class MatterRegistry { if (cap1.isPresent() && cap1.get().storageIdentity() == ItemStackWrapper.class) { for (var stored : ((IMatteryDrive) cap1.get()).getStacks()) { - matter = matter.add(getMatterValue(stored.stack().stack(), level + 1)); + matter = matter.plus(getMatterValue(stored.stack().stack(), level + 1)); } } if (cap2.isPresent()) { - matter = matter.add(cap2.get().getStoredMatter()); + matter = matter.plus(cap2.get().getStoredMatter()); } return matter; } - public static BigDecimal getMatterValue(ItemStack stack) { + public static Fraction getMatterValue(ItemStack stack) { return getMatterValue(stack, 0); } public static void registerInitialItems() { // basic things - INITIAL_ITEMS.put(Items.DIRT, new BigDecimal("0.0013")); - INITIAL_ITEMS.put(Items.DIRT_PATH, new BigDecimal("0.0013")); - INITIAL_ITEMS.put(Items.GRASS_BLOCK, new BigDecimal("0.0016")); + 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.POINTED_DRIPSTONE, new BigDecimal("0.0007")); + INITIAL_ITEMS.put(Items.POINTED_DRIPSTONE, new Fraction("0.0007")); - INITIAL_ITEMS.put(Items.STONE, new BigDecimal("0.001")); - INITIAL_ITEMS.put(Items.COBBLESTONE, new BigDecimal("0.001")); - INITIAL_ITEMS.put(Items.MOSSY_COBBLESTONE, new BigDecimal("0.001")); - INITIAL_ITEMS.put(Items.NETHERRACK, new BigDecimal("0.00027")); - INITIAL_ITEMS.put(Items.GRANITE, new BigDecimal("0.0011")); - INITIAL_ITEMS.put(Items.DIORITE, new BigDecimal("0.0013")); - INITIAL_ITEMS.put(Items.ANDESITE, new BigDecimal("0.0012")); - INITIAL_ITEMS.put(Items.BASALT, new BigDecimal("0.0013")); + 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.SOUL_SAND, new BigDecimal("0.00087")); - INITIAL_ITEMS.put(Items.SOUL_SOIL, new BigDecimal("0.00087")); + INITIAL_ITEMS.put(Items.SOUL_SAND, new Fraction("0.00087")); + INITIAL_ITEMS.put(Items.SOUL_SOIL, new Fraction("0.00087")); - INITIAL_ITEMS.put(Items.ICE, new BigDecimal("0.0002")); + INITIAL_ITEMS.put(Items.ICE, new Fraction("0.0002")); - INITIAL_ITEMS.put(Items.GRAVEL, new BigDecimal("0.001")); - INITIAL_ITEMS.put(Items.FLINT, new BigDecimal("0.001")); + INITIAL_ITEMS.put(Items.GRAVEL, new Fraction("0.001")); + INITIAL_ITEMS.put(Items.FLINT, new Fraction("0.001")); - INITIAL_ITEMS.put(Items.SAND, new BigDecimal("0.0005")); - INITIAL_ITEMS.put(Items.RED_SAND, new BigDecimal("0.0005")); + INITIAL_ITEMS.put(Items.SAND, new Fraction("0.0005")); + INITIAL_ITEMS.put(Items.RED_SAND, new Fraction("0.0005")); - INITIAL_ITEMS.put(Items.TUFF, new BigDecimal("0.0007")); - INITIAL_ITEMS.put(Items.DEEPSLATE, new BigDecimal("0.0014")); - INITIAL_ITEMS.put(Items.COBBLED_DEEPSLATE, new BigDecimal("0.0014")); + 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.BLACKSTONE, new BigDecimal("0.0015")); + INITIAL_ITEMS.put(Items.BLACKSTONE, new Fraction("0.0015")); - INITIAL_ITEMS.put(Items.INFESTED_STONE, new BigDecimal("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_COBBLESTONE, new BigDecimal("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_STONE_BRICKS, new BigDecimal("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_MOSSY_STONE_BRICKS, new BigDecimal("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_CRACKED_STONE_BRICKS, new BigDecimal("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_CHISELED_STONE_BRICKS, new BigDecimal("0.063")); - INITIAL_ITEMS.put(Items.INFESTED_DEEPSLATE, new BigDecimal("0.067")); + 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")); // affected by luck enchantment, thus can be duped - // INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new BigDecimal("0.037")); - INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new BigDecimal("0.34")); + // INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new Fraction("0.037")); + INITIAL_ITEMS.put(Items.GILDED_BLACKSTONE, new Fraction("0.34")); // assuming it is very light since it is floating - INITIAL_ITEMS.put(Items.END_STONE, new BigDecimal("0.0004")); + INITIAL_ITEMS.put(Items.END_STONE, new Fraction("0.0004")); - INITIAL_ITEMS.put(Items.OBSIDIAN, new BigDecimal("0.038")); + INITIAL_ITEMS.put(Items.OBSIDIAN, new Fraction("0.038")); // metallic / chemical things - INITIAL_ITEMS.put(Items.COAL, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.LAPIS_LAZULI, new BigDecimal("0.0042")); - INITIAL_ITEMS.put(Items.REDSTONE, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.CHARCOAL, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.DIAMOND, new BigDecimal("0.5")); - INITIAL_ITEMS.put(Items.EMERALD, new BigDecimal("0.46")); - INITIAL_ITEMS.put(Items.IRON_INGOT, new BigDecimal("0.03")); - INITIAL_ITEMS.put(Items.COPPER_INGOT, new BigDecimal("0.014")); - INITIAL_ITEMS.put(Items.GOLD_INGOT, new BigDecimal("0.32")); - INITIAL_ITEMS.put(Items.NETHERITE_SCRAP, new BigDecimal("1.2")); - INITIAL_ITEMS.put(Items.QUARTZ, new BigDecimal("0.008")); - INITIAL_ITEMS.put(Items.GLOWSTONE_DUST, new BigDecimal("0.007")); - INITIAL_ITEMS.put(Items.AMETHYST_SHARD, new BigDecimal("0.034")); + 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")); // living things - INITIAL_ITEMS.put(Items.MOSS_BLOCK, new BigDecimal("0.0012")); + INITIAL_ITEMS.put(Items.MOSS_BLOCK, new Fraction("0.0012")); - INITIAL_ITEMS.put(Items.OAK_LOG, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.SPRUCE_LOG, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.BIRCH_LOG, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.JUNGLE_LOG, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.ACACIA_LOG, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.DARK_OAK_LOG, new BigDecimal("0.005")); + 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.BAMBOO, new BigDecimal("0.00085")); + INITIAL_ITEMS.put(Items.BAMBOO, new Fraction("0.00085")); - INITIAL_ITEMS.put(Items.CRIMSON_PLANKS, new BigDecimal("0.003")); - INITIAL_ITEMS.put(Items.WARPED_PLANKS, new BigDecimal("0.003")); + INITIAL_ITEMS.put(Items.CRIMSON_PLANKS, new Fraction("0.003")); + INITIAL_ITEMS.put(Items.WARPED_PLANKS, new Fraction("0.003")); - INITIAL_ITEMS.put(Items.STRIPPED_OAK_LOG, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.STRIPPED_SPRUCE_LOG, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.STRIPPED_BIRCH_LOG, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.STRIPPED_JUNGLE_LOG, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.STRIPPED_ACACIA_LOG, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.STRIPPED_DARK_OAK_LOG, new BigDecimal("0.005")); + 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.CACTUS, new BigDecimal("0.0039")); - INITIAL_ITEMS.put(Items.PUMPKIN, new BigDecimal("0.005")); - INITIAL_ITEMS.put(Items.MELON, new BigDecimal("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")); // flowers! - final BigDecimal flower_value = new BigDecimal("0.0031"); + final Fraction flower_value = new Fraction("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 +197,28 @@ public class MatterRegistry { INITIAL_ITEMS.put(Items.CORNFLOWER, flower_value); INITIAL_ITEMS.put(Items.LILY_OF_THE_VALLEY, flower_value); - final BigDecimal big_flower_value = new BigDecimal("0.0042"); + final Fraction big_flower_value = new Fraction("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 BigDecimal("0.0067")); - INITIAL_ITEMS.put(Items.BROWN_MUSHROOM, new BigDecimal("0.0034")); - INITIAL_ITEMS.put(Items.RED_MUSHROOM, new BigDecimal("0.0034")); - INITIAL_ITEMS.put(Items.CRIMSON_FUNGUS, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.WARPED_FUNGUS, new BigDecimal("0.004")); + 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")); // grass - final BigDecimal grass_value = new BigDecimal("0.0024"); + final Fraction grass_value = new Fraction("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 BigDecimal("0.002")); + INITIAL_ITEMS.put(Items.NETHER_SPROUTS, new Fraction("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 BigDecimal("0.0035")); - INITIAL_ITEMS.put(Items.LARGE_FERN, new BigDecimal("0.0035")); + INITIAL_ITEMS.put(Items.TALL_GRASS, new Fraction("0.0035")); + INITIAL_ITEMS.put(Items.LARGE_FERN, new Fraction("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,104 +227,104 @@ 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 BigDecimal("0.0017")); - INITIAL_ITEMS.put(Items.GLOW_LICHEN, new BigDecimal("0.0026")); - INITIAL_ITEMS.put(Items.AZALEA, new BigDecimal("0.0018")); + 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.FLOWERING_AZALEA, grass_value); // living plant (not very blocky) things // saplings - INITIAL_ITEMS.put(Items.OAK_SAPLING, new BigDecimal("0.0035")); - INITIAL_ITEMS.put(Items.SPRUCE_SAPLING, new BigDecimal("0.0045")); - INITIAL_ITEMS.put(Items.BIRCH_SAPLING, new BigDecimal("0.0035")); - INITIAL_ITEMS.put(Items.JUNGLE_SAPLING, new BigDecimal("0.0048")); - INITIAL_ITEMS.put(Items.ACACIA_SAPLING, new BigDecimal("0.0033")); - INITIAL_ITEMS.put(Items.DARK_OAK_SAPLING, new BigDecimal("0.005")); + 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.WHEAT_SEEDS, new BigDecimal("0.0007")); - INITIAL_ITEMS.put(Items.BEETROOT_SEEDS, new BigDecimal("0.0007")); - // INITIAL_ITEMS.put(Items.MELON_SEEDS, new BigDecimal("0.0013")); - INITIAL_ITEMS.put(Items.WHEAT, new BigDecimal("0.0016")); - INITIAL_ITEMS.put(Items.NETHER_WART, new BigDecimal("0.0017")); - INITIAL_ITEMS.put(Items.CARROT, new BigDecimal("0.0019")); - INITIAL_ITEMS.put(Items.POTATO, new BigDecimal("0.0021")); - INITIAL_ITEMS.put(Items.BEETROOT, new BigDecimal("0.0021")); - INITIAL_ITEMS.put(Items.MELON_SLICE, new BigDecimal("0.0008")); + 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.COCOA_BEANS, new BigDecimal("0.00035")); - INITIAL_ITEMS.put(Items.HONEYCOMB, new BigDecimal("0.0014")); - INITIAL_ITEMS.put(Items.SUGAR_CANE, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.APPLE, new BigDecimal("0.0061")); - INITIAL_ITEMS.put(Items.SWEET_BERRIES, new BigDecimal("0.0035")); - INITIAL_ITEMS.put(Items.GLOW_BERRIES, new BigDecimal("0.0041")); - INITIAL_ITEMS.put(Items.KELP, new BigDecimal("0.0009")); + 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")); // living animal things - INITIAL_ITEMS.put(Items.STRING, new BigDecimal("0.0006")); - INITIAL_ITEMS.put(Items.COBWEB, new BigDecimal("0.0006")); - INITIAL_ITEMS.put(Items.INK_SAC, new BigDecimal("0.0009")); - INITIAL_ITEMS.put(Items.SPIDER_EYE, new BigDecimal("0.001")); - INITIAL_ITEMS.put(Items.FEATHER, new BigDecimal("0.0007")); - INITIAL_ITEMS.put(Items.GUNPOWDER, new BigDecimal("0.003")); - INITIAL_ITEMS.put(Items.LEATHER, new BigDecimal("0.0065")); - INITIAL_ITEMS.put(Items.BONE, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.ENDER_PEARL, new BigDecimal("0.041")); - INITIAL_ITEMS.put(Items.GHAST_TEAR, new BigDecimal("0.023")); - INITIAL_ITEMS.put(Items.BLAZE_ROD, new BigDecimal("0.02")); - INITIAL_ITEMS.put(Items.SLIME_BALL, new BigDecimal("0.0015")); - INITIAL_ITEMS.put(Items.EGG, new BigDecimal("0.0011")); + 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.PORKCHOP, new BigDecimal("0.0047")); - INITIAL_ITEMS.put(Items.BEEF, new BigDecimal("0.0047")); - INITIAL_ITEMS.put(Items.MUTTON, new BigDecimal("0.004")); + 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.PUFFERFISH, new BigDecimal("0.013")); - INITIAL_ITEMS.put(Items.COD, new BigDecimal("0.013")); - INITIAL_ITEMS.put(Items.SALMON, new BigDecimal("0.013")); - INITIAL_ITEMS.put(Items.TROPICAL_FISH, new BigDecimal("0.013")); + 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")); // building items - INITIAL_ITEMS.put(Items.CLAY_BALL, new BigDecimal("0.0006")); - INITIAL_ITEMS.put(Items.SNOWBALL, new BigDecimal("0.00041")); + INITIAL_ITEMS.put(Items.CLAY_BALL, new Fraction("0.0006")); + INITIAL_ITEMS.put(Items.SNOWBALL, new Fraction("0.00041")); // loot - INITIAL_ITEMS.put(Items.TOTEM_OF_UNDYING, new BigDecimal("1.47")); - INITIAL_ITEMS.put(Items.TRIDENT, new BigDecimal("1.35")); + INITIAL_ITEMS.put(Items.TOTEM_OF_UNDYING, new Fraction("1.47")); + INITIAL_ITEMS.put(Items.TRIDENT, new Fraction("1.35")); /* - INITIAL_ITEMS.put(Items.WHITE_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.ORANGE_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.MAGENTA_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.LIGHT_BLUE_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.YELLOW_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.LIME_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.PINK_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.GRAY_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.LIGHT_GRAY_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.CYAN_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.PURPLE_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.BLUE_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.BROWN_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.GREEN_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.RED_WOOL, new BigDecimal("0.004")); - INITIAL_ITEMS.put(Items.BLACK_WOOL, new BigDecimal("0.004")); + 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.CRIMSON_LOG, new BigDecimal("0.005")); - // INITIAL_ITEMS.put(Items.WARPED_LOG, new BigDecimal("0.005")); + // INITIAL_ITEMS.put(Items.CRIMSON_LOG, new Fraction("0.005")); + // INITIAL_ITEMS.put(Items.WARPED_LOG, new Fraction("0.005")); } - private static void registerPostItem(Item item, Item base, BigDecimal multiplier) { - BigDecimal value = getMatterValue(base); + private static void registerPostItem(Item item, Item base, Fraction multiplier) { + Fraction value = getMatterValue(base); - if (!value.equals(BigDecimal.ZERO)) { - ITEMS.put(item, value.multiply(multiplier)); + if (!value.equals(Fraction.ZERO)) { + ITEMS.put(item, value.times(multiplier)); } } public static void registerPostItems() { - registerPostItem(Items.CHIPPED_ANVIL, Items.ANVIL, new BigDecimal("0.8")); - registerPostItem(Items.DAMAGED_ANVIL, Items.ANVIL, new BigDecimal("0.5")); + registerPostItem(Items.CHIPPED_ANVIL, Items.ANVIL, new Fraction("0.8")); + registerPostItem(Items.DAMAGED_ANVIL, Items.ANVIL, new Fraction("0.5")); } public static final MathContext ROUND_RULES = MatteryCapability.ROUND_RULES; @@ -341,8 +341,8 @@ public class MatterRegistry { private static final Item[] scan_stack = new Item[1000]; @Nullable - private static BigDecimal determineValue(Item item) { - BigDecimal _get = ITEMS.get(item); + private static Fraction determineValue(Item item) { + Fraction _get = ITEMS.get(item); if (_get != null) { return _get; @@ -379,13 +379,13 @@ public class MatterRegistry { } } - return BigDecimal.ZERO; + return Fraction.ZERO; } seen_items.put(item, 0); if (!results.containsKey(item)) { - return BigDecimal.ZERO; + return Fraction.ZERO; } scan_stack[stack_index] = item; @@ -393,32 +393,32 @@ public class MatterRegistry { boolean defer_occured = false; - BigDecimal smallest_possible_total = null; + Fraction smallest_possible_total = null; for (Recipe recipe : results.get(item)) { ItemStack self = recipe.getResultItem(); - BigDecimal recipe_summ = BigDecimal.ZERO; + Fraction recipe_summ = Fraction.ZERO; boolean this_defered = false; for (Ingredient ingredient : recipe.getIngredients()) { ItemStack[] items = ingredient.getItems(); - BigDecimal smallest_possible = null; + Fraction smallest_possible = null; for (ItemStack stack : items) { if (!stack.isEmpty()) { - BigDecimal determine = determineValue(stack.getItem()); + Fraction determine = determineValue(stack.getItem()); // if we hit an recursive recipe, defer it if (determine != null) { - if (determine.compareTo(BigDecimal.ZERO) == 0) { + if (determine.compareTo(Fraction.ZERO) == 0) { // 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 BigDecimal.ZERO; + return Fraction.ZERO; } if (smallest_possible == null || smallest_possible.compareTo(determine) > 0) @@ -437,14 +437,14 @@ public class MatterRegistry { break; if (smallest_possible != null) { - recipe_summ = recipe_summ.add(smallest_possible, ROUND_RULES); + recipe_summ = recipe_summ.plus(smallest_possible); } } if (this_defered) continue; - recipe_summ = recipe_summ.divide(new BigDecimal(self.getCount()), ROUND_RULES); + recipe_summ = recipe_summ.div(new Fraction(self.getCount())); if (smallest_possible_total == null || smallest_possible_total.compareTo(recipe_summ) > 0) smallest_possible_total = recipe_summ; @@ -469,7 +469,7 @@ public class MatterRegistry { scan_stack[stack_index] = null; stack_index--; - return BigDecimal.ZERO; + return Fraction.ZERO; } private static void flood(List> recipe_type) { @@ -564,9 +564,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)) { - BigDecimal matter_value = getMatterValue(event.getItemStack()); + Fraction matter_value = getMatterValue(event.getItemStack()); - if (!matter_value.equals(BigDecimal.ZERO)) { + if (!matter_value.equals(Fraction.ZERO)) { event.getToolTip().add(FormattingHelper.formatMatterValue(matter_value).withStyle(ChatFormatting.AQUA)); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/DriveViewerMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/DriveViewerMenu.java index e72e2a33b..3ecce0ab2 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/DriveViewerMenu.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/DriveViewerMenu.java @@ -136,7 +136,7 @@ public class DriveViewerMenu extends PoweredMatteryMenu implements INetworkedIte if (amount == item.getCount()) { var remaining = last_drive.insertStack(new ItemStackWrapper(item), false); - if (remaining.getCount().intValue() == item.getCount()) + if (remaining.getCount().toInt() == item.getCount()) return ItemStack.EMPTY; if (remaining.isEmpty()) { @@ -147,8 +147,8 @@ public class DriveViewerMenu extends PoweredMatteryMenu implements INetworkedIte } var copy = item.copy(); - tile.getIOItemCount(item.getCount() - remaining.getCount().intValue(), false); - item.shrink(remaining.getCount().intValue()); + tile.getIOItemCount(item.getCount() - remaining.getCount().toInt(), false); + item.shrink(remaining.getCount().toInt()); slot.setChanged(); return copy; @@ -159,12 +159,12 @@ public class DriveViewerMenu extends PoweredMatteryMenu implements INetworkedIte var remaining = last_drive.insertStack(new ItemStackWrapper(copy_insert), false); - if (remaining.getCount().intValue() == copy_insert.getCount()) + if (remaining.getCount().toInt() == copy_insert.getCount()) return ItemStack.EMPTY; var copy = item.copy(); - tile.getIOItemCount(amount - remaining.getCount().intValue(), false); - item.shrink(amount - remaining.getCount().intValue()); + tile.getIOItemCount(amount - remaining.getCount().toInt(), false); + item.shrink(amount - remaining.getCount().toInt()); slot.setChanged(); return copy; diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.java index c564edf21..ed35413a5 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.java @@ -6,13 +6,14 @@ import net.minecraft.world.level.block.entity.BlockEntity; import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter; import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer; +import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer; import javax.annotation.Nullable; public class EnergyCounterMenu extends MatteryMenu { - public final BigDecimalDataContainer passed = new BigDecimalDataContainer(); - public final BigDecimalDataContainer average = new BigDecimalDataContainer(); - public final BigDecimalDataContainer last_20_ticks = new BigDecimalDataContainer(); + public final FractionDataContainer passed = new FractionDataContainer(); + public final FractionDataContainer average = new FractionDataContainer(); + public final FractionDataContainer last_20_ticks = new FractionDataContainer(); // TODO: Graph and proper networking for it private int ticks_passed = 0; @@ -33,11 +34,11 @@ public class EnergyCounterMenu extends MatteryMenu { if (tile != null) { BlockEntityEnergyCounter tile = (BlockEntityEnergyCounter) this.tile; - passed.setDecimal(tile.getPassed()); - average.setDecimal(tile.calcAverage(20)); + passed.setValue(tile.getPassed()); + average.setValue(tile.calcAverage(20)); if (ticks_passed == 0) { - last_20_ticks.setDecimal(tile.sumHistory(20)); + last_20_ticks.setValue(tile.sumHistory(20)); } ticks_passed = (ticks_passed + 1) % 20; 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 3ffd56aeb..b5d44b8b8 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java @@ -5,6 +5,7 @@ import net.minecraft.network.chat.FormattedText; 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 java.math.BigDecimal; import java.math.BigInteger; @@ -33,6 +34,17 @@ public class FormattingHelper { new BigDecimal("1000000000000000000000000"), // "otm.suffix.yotta": "Y%s", }; + public static final Fraction[] SUFFIX_ABOVE_ONE_FRAC = new Fraction[] { + Fraction.fromString("1000"), // "otm.suffix.kilo": "k%s", + Fraction.fromString("1000000"), // "otm.suffix.mega": "M%s", + Fraction.fromString("1000000000"), // "otm.suffix.giga": "G%s", + Fraction.fromString("1000000000000"), // "otm.suffix.tera": "T%s", + Fraction.fromString("1000000000000000"), // "otm.suffix.peta": "P%s", + Fraction.fromString("1000000000000000000"), // "otm.suffix.exa": "E%s", + Fraction.fromString("1000000000000000000000"), // "otm.suffix.zetta": "Z%s", + Fraction.fromString("1000000000000000000000000"), // "otm.suffix.yotta": "Y%s", + }; + public static final String[] SUFFIX_COMPONENTS_BELOW_ONE = new String[] { "otm.suffix.deci", "otm.suffix.centi", @@ -59,6 +71,19 @@ public class FormattingHelper { new BigDecimal("0.000000000000000000000001"), // "otm.suffix.yocto": "y%s", }; + public static final Fraction[] SUFFIX_BELOW_ONE_FRAC = new Fraction[] { + Fraction.fromString("0.1"), // "otm.suffix.milli": "d%s", + Fraction.fromString("0.01"), // "otm.suffix.milli": "c%s", + Fraction.fromString("0.001"), // "otm.suffix.milli": "m%s", + Fraction.fromString("0.000001"), // "otm.suffix.micro": "μ%s", + Fraction.fromString("0.000000001"), // "otm.suffix.nano": "n%s", + Fraction.fromString("0.000000000001"), // "otm.suffix.pico": "p%s", + Fraction.fromString("0.000000000000001"), // "otm.suffix.femto": "f%s", + Fraction.fromString("0.000000000000000001"), // "otm.suffix.atto": "a%s", + Fraction.fromString("0.000000000000000000001"), // "otm.suffix.zepto": "z%s", + Fraction.fromString("0.000000000000000000000001"), // "otm.suffix.yocto": "y%s", + }; + public static String formatDecimal(BigDecimal value, int decimals) { return value.setScale(decimals, RoundingMode.HALF_UP).toString(); } @@ -70,26 +95,50 @@ public class FormattingHelper { return new TranslatableComponent("otm.gui.level", formatSI(power, POWER_NAME), formatSI(max_power, POWER_NAME)); } + public static Component formatPowerLevel(Fraction power, Fraction 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)); } + public static Component formatMatterLevel(Fraction power, Fraction 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)); } + public static TranslatableComponent formatMatterValue(Fraction matter) { + return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME)); + } + public static Component formatMatterValuePlain(BigDecimal matter) { return formatSI(matter, MATTER_NAME); } + public static Component formatMatterValuePlain(Fraction matter) { + return formatSI(matter, MATTER_NAME); + } + public static Component formatPower(BigDecimal power) { return formatSI(power, POWER_NAME); } + public static Component formatPower(Fraction power) { + return formatSI(power, POWER_NAME); + } + public static Component formatSI(BigDecimal value) { return formatSI(value, ""); } + public static Component formatSI(Fraction value) { + return formatSI(value, ""); + } + public static Component formatSI(BigDecimal value, Object end_suffix) { if (value.compareTo(BigDecimal.ZERO) == 0) { if ("".equals(end_suffix)) { @@ -133,4 +182,48 @@ public class FormattingHelper { return new TranslatableComponent("otm.suffix.merge", formatDecimal(value, 2), end_suffix); } } + + public static Component formatSI(Fraction value, Object end_suffix) { + if (value.compareTo(Fraction.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(Fraction.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_FRAC.length - 1; i >= 0; i--) { + if (value.compareTo(SUFFIX_ABOVE_ONE_FRAC[i]) >= 0) { + return new TranslatableComponent(SUFFIX_COMPONENTS_ABOVE_ONE[i], value.div(SUFFIX_ABOVE_ONE_FRAC[i]).decimalString(2, true), end_suffix); + } + } + + if ("".equals(end_suffix)) { + return new TextComponent(value.decimalString(2, true)); + } else { + return new TranslatableComponent("otm.suffix.merge", value.decimalString(2, true), end_suffix); + } + } + + for (int i = SUFFIX_BELOW_ONE.length - 1; i >= 0; i--) { + if (value.compareTo(SUFFIX_BELOW_ONE_FRAC[i]) < 0) { + return new TranslatableComponent(SUFFIX_COMPONENTS_BELOW_ONE[i], value.div(SUFFIX_BELOW_ONE_FRAC[i]).decimalString(2, true), end_suffix); + } + } + + if ("".equals(end_suffix)) { + return new TextComponent(value.decimalString(2, true)); + } else { + return new TranslatableComponent("otm.suffix.merge", value.decimalString(2, true), end_suffix); + } + } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/MatterCapacitorBankMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/MatterCapacitorBankMenu.java index e640dbc38..6d2b328be 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/MatterCapacitorBankMenu.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/MatterCapacitorBankMenu.java @@ -6,6 +6,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.capability.matter.IMatterHandler; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.menu.slot.MatterContainerInputSlot; import ru.dbotthepony.mc.otm.menu.widget.MatterLevelWidget; @@ -34,13 +35,13 @@ public class MatterCapacitorBankMenu extends MatteryMenu { return tile.getMatterGrid().getStored(); } - return BigDecimal.ZERO; + return Fraction.ZERO; }, () -> { if (tile.getMatterGrid() != null) { return tile.getMatterGrid().getCapacity(); } - return BigDecimal.ZERO; + return Fraction.ZERO; }); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.java b/src/main/java/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.java index 928d5162e..181f9984f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/data/NetworkedItemView.java @@ -8,6 +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.menu.MatteryMenu; import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.network.SetCarriedPacket; @@ -99,8 +100,8 @@ public class NetworkedItemView implements IStorageListener { } @Override - public void changeObject(UUID id, BigDecimal new_count) { - changeObject(id, new_count.intValue()); + public void changeObject(UUID id, Fraction new_count) { + changeObject(id, new_count.toInt()); } @Override @@ -217,13 +218,13 @@ public class NetworkedItemView implements IStorageListener { } int amount = calculateIOAmount(action == ClickAction.PRIMARY ? get_state.stack().getMaxStackSize() : Math.max(1, get_state.stack().getMaxStackSize() / 2)); - var extracted = provider.extractStack(get_state.id_upstream(), new BigDecimal(amount), true); + var extracted = provider.extractStack(get_state.id_upstream(), new Fraction(amount), true); if (!extracted.isEmpty()) { var move = menu.quickMoveToInventory(extracted.stack(), false); if (move.remaining().getCount() != extracted.stack().getCount()) { - provider.extractStack(get_state.id_upstream(), new BigDecimal(extracted.stack().getCount() - move.remaining().getCount()), false); + provider.extractStack(get_state.id_upstream(), new Fraction(extracted.stack().getCount() - move.remaining().getCount()), false); doneIOAmount(extracted.stack().getCount() - move.remaining().getCount()); } } @@ -277,7 +278,7 @@ public class NetworkedItemView implements IStorageListener { int amount = calculateIOAmount(action == ClickAction.PRIMARY ? get_state.stack().getMaxStackSize() : Math.max(1, get_state.stack().getMaxStackSize() / 2)); - var extracted = provider.extractStack(get_state.id_upstream(), new BigDecimal(amount), false); + var extracted = provider.extractStack(get_state.id_upstream(), new Fraction(amount), false); doneIOAmount(extracted.getCountInt()); menu.setCarried(extracted.stack()); diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/widget/BatteryLevelWidget.java b/src/main/java/ru/dbotthepony/mc/otm/menu/widget/BatteryLevelWidget.java index d8fdde0a9..2e3b646a9 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/widget/BatteryLevelWidget.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/widget/BatteryLevelWidget.java @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.menu.widget; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.menu.FormattingHelper; import ru.dbotthepony.mc.otm.menu.MatteryMenu; @@ -20,7 +21,7 @@ public class BatteryLevelWidget extends StorageGaugeWidget { super(menu, x, y); } - public BatteryLevelWidget(MatteryMenu menu, int x, int y, Supplier value_supplier, Supplier max_value_supplier) { + public BatteryLevelWidget(MatteryMenu menu, int x, int y, Supplier value_supplier, Supplier max_value_supplier) { super(menu, x, y, value_supplier, max_value_supplier); } @@ -49,7 +50,7 @@ public class BatteryLevelWidget extends StorageGaugeWidget { public List getTooltip() { return List.of( new TranslatableComponent("otm.gui.power.percentage_level", String.format("%.2f", getLevel() * 100d)), - FormattingHelper.formatPowerLevel(value_container.getDecimal(), max_value_container.getDecimal()) + FormattingHelper.formatPowerLevel(value_container.getValue(), max_value_container.getValue()) ); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/widget/MatterLevelWidget.java b/src/main/java/ru/dbotthepony/mc/otm/menu/widget/MatterLevelWidget.java index 06728efb5..04e465c3a 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/widget/MatterLevelWidget.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/widget/MatterLevelWidget.java @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.menu.widget; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.menu.FormattingHelper; import ru.dbotthepony.mc.otm.menu.MatteryMenu; @@ -28,7 +29,7 @@ public class MatterLevelWidget extends StorageGaugeWidget { this(menu, 0, 0, capability); } - public MatterLevelWidget(MatteryMenu menu, int x, int y, Supplier value_supplier, Supplier max_value_supplier) { + public MatterLevelWidget(MatteryMenu menu, int x, int y, Supplier value_supplier, Supplier max_value_supplier) { super(menu, x, y, value_supplier, max_value_supplier); } @@ -57,7 +58,7 @@ public class MatterLevelWidget extends StorageGaugeWidget { public List getTooltip() { return List.of( new TranslatableComponent("otm.gui.matter.percentage_level", String.format("%.2f", getLevel() * 100d)), - FormattingHelper.formatMatterLevel(value_container.getDecimal(), max_value_container.getDecimal()) + FormattingHelper.formatMatterLevel(value_container.getValue(), max_value_container.getValue()) ); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/widget/StorageGaugeWidget.java b/src/main/java/ru/dbotthepony/mc/otm/menu/widget/StorageGaugeWidget.java index b3d9da5fd..03d1a9d8f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/widget/StorageGaugeWidget.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/widget/StorageGaugeWidget.java @@ -1,18 +1,20 @@ package ru.dbotthepony.mc.otm.menu.widget; import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.menu.MatteryMenu; import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer; +import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer; import java.math.BigDecimal; import java.util.function.Supplier; abstract public class StorageGaugeWidget extends GaugeWidget { - protected Supplier value_supplier; - protected Supplier max_value_supplier; + protected Supplier value_supplier; + protected Supplier max_value_supplier; - protected final BigDecimalDataContainer value_container = new BigDecimalDataContainer(); - protected final BigDecimalDataContainer max_value_container = new BigDecimalDataContainer(); + protected final FractionDataContainer value_container = new FractionDataContainer(); + protected final FractionDataContainer max_value_container = new FractionDataContainer(); public StorageGaugeWidget(MatteryMenu menu, int x, int y) { this(menu, x, y, null, null); @@ -22,7 +24,7 @@ abstract public class StorageGaugeWidget extends GaugeWidget { this(menu, 0, 0, null, null); } - public StorageGaugeWidget(MatteryMenu menu, int x, int y, Supplier value_supplier, Supplier max_value_supplier) { + public StorageGaugeWidget(MatteryMenu menu, int x, int y, Supplier value_supplier, Supplier max_value_supplier) { super(menu, x, y); this.value_supplier = value_supplier; this.max_value_supplier = max_value_supplier; @@ -31,7 +33,7 @@ abstract public class StorageGaugeWidget extends GaugeWidget { addDataSlots(max_value_container); } - public StorageGaugeWidget(MatteryMenu menu, Supplier value_supplier, Supplier max_value_supplier) { + public StorageGaugeWidget(MatteryMenu menu, Supplier value_supplier, Supplier max_value_supplier) { this(menu, 0, 0, value_supplier, max_value_supplier); } @@ -40,12 +42,12 @@ abstract public class StorageGaugeWidget extends GaugeWidget { if (value_supplier == null || max_value_supplier == null) return; - value_container.setDecimal(value_supplier.get()); - max_value_container.setDecimal(max_value_supplier.get()); + value_container.setValue(value_supplier.get()); + max_value_container.setValue(max_value_supplier.get()); } @Override public float getLevel() { - return max_value_container.getDecimal().compareTo(BigDecimal.ZERO) == 0 ? 0f : value_container.getDecimal().divide(max_value_container.getDecimal(), MatteryCapability.ROUND_RULES).floatValue(); + return max_value_container.getValue().compareTo(Fraction.ZERO) == 0 ? 0f : value_container.getValue().div(max_value_container.getValue()).toFloat(); } } 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 c8e2235b9..a074963bd 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/network/MatterRegistryPacket.java +++ b/src/main/java/ru/dbotthepony/mc/otm/network/MatterRegistryPacket.java @@ -7,6 +7,7 @@ import net.minecraftforge.fml.DistExecutor; 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.matter.MatterRegistry; import java.math.BigDecimal; @@ -14,14 +15,14 @@ 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); for (var entry : list.entrySet()) { buffer.writeInt(registry.getID(entry.getKey())); - NetworkHelper.writeDecimal(buffer, entry.getValue()); + entry.getValue().write(buffer); } } @@ -29,10 +30,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()), NetworkHelper.readDecimal(buffer)); + map.put(registry.getValue(buffer.readInt()), Fraction.read(buffer)); } return new MatterRegistryPacket(map); diff --git a/src/main/java/ru/dbotthepony/mc/otm/network/NetworkHelper.java b/src/main/java/ru/dbotthepony/mc/otm/network/NetworkHelper.java index fc6de894e..83a41f18c 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/network/NetworkHelper.java +++ b/src/main/java/ru/dbotthepony/mc/otm/network/NetworkHelper.java @@ -23,4 +23,34 @@ public class NetworkHelper { buffer.writeByte(build.length); for (byte b : build) buffer.writeByte(b); } + + public static short[] bytesToShorts(byte[] input) { + if (input.length % 2 != 0) { + short[] values = new short[input.length / 2 + 1]; + + for (int i = 0; i < values.length - 1; i++) + values[i] = (short) ((input[i * 2] & 0xFF) | (input[i * 2 + 1] & 0xFF) << 8); + + values[values.length - 1] = input[input.length - 1]; + return values; + } + + short[] values = new short[input.length / 2]; + + for (int i = 0; i < values.length; i++) + values[i] = (short) ((input[i * 2] & 0xFF) | (input[i * 2 + 1] & 0xFF) << 8); + + return values; + } + + public static byte[] shortsToBytes(short[] input) { + byte[] values = new byte[input.length * 2]; + + for (int i = 0; i < input.length; i++) { + values[i * 2] = (byte) (input[i] & 0xFF); + values[i * 2 + 1] = (byte) ((input[i] & 0xFF00) >> 8); + } + + return values; + } } 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 85123b55f..5206da01f 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 @@ -6,15 +6,16 @@ import net.minecraftforge.api.distmarker.Dist; 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.network.NetworkHelper; import java.math.BigDecimal; import java.util.function.Supplier; -public record AndroidEnergyPacket(boolean is_maximal, BigDecimal energy) { +public record AndroidEnergyPacket(boolean is_maximal, Fraction energy) { public void write(FriendlyByteBuf buffer) { buffer.writeBoolean(is_maximal); - NetworkHelper.writeDecimal(buffer, energy); + energy.write(buffer); } public void play(Supplier context) { @@ -39,6 +40,6 @@ public record AndroidEnergyPacket(boolean is_maximal, BigDecimal energy) { } public static AndroidEnergyPacket read(FriendlyByteBuf buffer) { - return new AndroidEnergyPacket(buffer.readBoolean(), NetworkHelper.readDecimal(buffer)); + return new AndroidEnergyPacket(buffer.readBoolean(), Fraction.read(buffer)); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageListener.java b/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageListener.java index d821280d6..10953bc02 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageListener.java +++ b/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageListener.java @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.storage; import net.minecraft.MethodsReturnNonnullByDefault; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.ParametersAreNonnullByDefault; import java.math.BigDecimal; @@ -10,6 +11,6 @@ import java.util.UUID; @ParametersAreNonnullByDefault public interface IStorageListener { void addObject(T stack, UUID id, IStorageView provider); - void changeObject(UUID id, BigDecimal new_count); + void changeObject(UUID id, Fraction new_count); void removeObject(UUID id); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageStack.java b/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageStack.java index 4beee7e0c..784fef1c3 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageStack.java +++ b/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageStack.java @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.storage; import net.minecraft.MethodsReturnNonnullByDefault; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.ParametersAreNonnullByDefault; import java.math.BigDecimal; @@ -18,8 +19,8 @@ import java.util.Optional; public interface IStorageStack { IStorageStack copy(); - void setCount(BigDecimal value); - BigDecimal getCount(); + void setCount(Fraction value); + Fraction getCount(); boolean isEmpty(); @@ -27,7 +28,7 @@ public interface IStorageStack { * @return max stack size for this stack object * Optional.empty() if unlimited (default) */ - default Optional getMaxStackSize() { + default Optional getMaxStackSize() { return Optional.empty(); } @@ -54,11 +55,11 @@ public interface IStorageStack { */ boolean sameItem(IStorageStack other); - default void grow(BigDecimal amount) { - setCount(getCount().add(amount)); + default void grow(Fraction amount) { + setCount(getCount().plus(amount)); } - default void shrink(BigDecimal amount) { - setCount(getCount().subtract(amount)); + default void shrink(Fraction amount) { + setCount(getCount().minus(amount)); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageView.java b/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageView.java index 522e61400..88c055f01 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageView.java +++ b/src/main/java/ru/dbotthepony/mc/otm/storage/IStorageView.java @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.storage; import net.minecraft.MethodsReturnNonnullByDefault; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.ParametersAreNonnullByDefault; import java.math.BigDecimal; @@ -23,7 +24,7 @@ public interface IStorageView extends IStorageTrigger extends IStorageTrigger getMaxStackSize() { - return Optional.of(new BigDecimal(stack.getMaxStackSize())); + public Optional getMaxStackSize() { + return Optional.of(new Fraction(stack.getMaxStackSize())); } @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/storage/VirtualComponent.java b/src/main/java/ru/dbotthepony/mc/otm/storage/VirtualComponent.java index 3b56ab6a1..38d292848 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/storage/VirtualComponent.java +++ b/src/main/java/ru/dbotthepony/mc/otm/storage/VirtualComponent.java @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.storage; import net.minecraft.MethodsReturnNonnullByDefault; +import ru.dbotthepony.mc.otm.core.Fraction; import javax.annotation.ParametersAreNonnullByDefault; import java.math.BigDecimal; @@ -26,11 +27,11 @@ public class VirtualComponent implements IStorageCompon } public record RemoteTuple(T object, UUID remote_id, IStorageView provider, LocalTuple local) { - public T extract(BigDecimal amount, boolean simulate) { + public T extract(Fraction amount, boolean simulate) { return provider.extractStack(remote_id, amount, simulate); } - public BigDecimal extractCount(BigDecimal amount, boolean simulate) { + public Fraction extractCount(Fraction amount, boolean simulate) { return provider.extractStackCount(remote_id, amount, simulate); } @@ -133,32 +134,30 @@ public class VirtualComponent implements IStorageCompon return tuple != null ? tuple.stack : identity.empty(); } - public static final BigDecimal MINUS_ONE = new BigDecimal(-1); - @Override @SuppressWarnings("unchecked") - public T extractStack(UUID id, BigDecimal amount, boolean simulate) { + public T extractStack(UUID id, Fraction amount, boolean simulate) { var tuple = indexed_by_local_uuid.get(id); - if (tuple == null || amount.compareTo(BigDecimal.ZERO) == 0) + if (tuple == null || amount.compareTo(Fraction.ZERO) == 0) return identity.empty(); - if (amount.compareTo(MINUS_ONE) <= 0) + if (amount.compareTo(Fraction.MINUS_ONE) <= 0) amount = tuple.stack.getMaxStackSize().orElse(tuple.stack.getCount()); - BigDecimal extract = tuple.stack.getCount().min(amount); - BigDecimal extracted = BigDecimal.ZERO; + var extract = tuple.stack.getCount().min(amount); + var extracted = Fraction.ZERO; final var copy = (T) tuple.stack.copy(); for (var remote_tuple : tuple.tuples) { - extracted = extracted.add(remote_tuple.extractCount(extract.subtract(extracted), simulate)); + extracted = extracted.plus(remote_tuple.extractCount(extract.minus(extracted), simulate)); if (extracted.compareTo(extract) >= 0) break; } - if (extracted.compareTo(BigDecimal.ZERO) > 0) { + if (extracted.compareTo(Fraction.ZERO) > 0) { copy.setCount(extracted); return copy; } @@ -224,14 +223,14 @@ public class VirtualComponent implements IStorageCompon @Override - public void changeObject(UUID id, BigDecimal new_count) { - assert new_count.compareTo(BigDecimal.ZERO) > 0; + public void changeObject(UUID id, Fraction new_count) { + assert new_count.compareTo(Fraction.ZERO) > 0; var tuple = indexed_by_remote_uuid.get(id); if (tuple == null) throw new IllegalStateException("No such tuple with id " + id); - final var diff = new_count.subtract(tuple.object.getCount()); + final var diff = new_count.minus(tuple.object.getCount()); tuple.object.setCount(new_count); tuple.local.stack.grow(diff); @@ -253,7 +252,7 @@ public class VirtualComponent implements IStorageCompon indexed_by_remote_uuid.remove(id); - final boolean a = tuple.local.stack.getCount().compareTo(BigDecimal.ZERO) <= 0; + final boolean a = tuple.local.stack.getCount().compareTo(Fraction.ZERO) <= 0; final boolean b = tuple.local.tuples.size() == 0; if (a || b) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Fraction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Fraction.kt new file mode 100644 index 000000000..8240ef093 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Fraction.kt @@ -0,0 +1,555 @@ +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 +import java.math.RoundingMode + +fun powScale(int: Int): BigInteger { + if (int <= 0) + return BigInteger.ONE + + var result = BigInteger.TEN + + for (i in 2 .. int) + result *= BigInteger.TEN + + return result +} + +fun powUnscaled(unscaled: BigInteger, scale: Int): BigInteger { + if (scale >= 0) + return unscaled + + var result = unscaled + + for (i in 2 .. -scale) + result *= BigInteger.TEN + + return result +} + +val DEFAULT_MATH_CONTEXT = MathContext(64, RoundingMode.HALF_UP) + +@Suppress("NOTHING_TO_INLINE") +inline fun invertCompare(int: Int): Int { + if (int == 0) + return 0 + + return if (int < 0) 1 else -1 +} + +@JvmRecord +data class Fraction @JvmOverloads constructor(@JvmField val value: BigInteger, @JvmField val divisor: BigInteger = BigInteger.ONE, @JvmField val compact: Boolean = true) { + @JvmOverloads constructor(value: Long, compact: Boolean = true) : this(BigInteger.valueOf(value), compact = compact) + @JvmOverloads constructor(value: Int, compact: Boolean = true) : this(BigInteger.valueOf(value.toLong()), compact = compact) + @JvmOverloads constructor(value: Float, compact: Boolean = true) : this(BigDecimal(value.toString()), compact = compact) + @JvmOverloads constructor(value: Double, compact: Boolean = true) : this(BigDecimal(value.toString()), compact = compact) + @JvmOverloads constructor(value: String, compact: Boolean = true) : this(BigDecimal(value), compact = compact) + + @JvmOverloads constructor(value: Long, div: Long, compact: Boolean = true) : this(BigInteger.valueOf(value), BigInteger.valueOf(div), compact = compact) + @JvmOverloads constructor(value: Int, div: Int, compact: Boolean = true) : this(BigInteger.valueOf(value.toLong()), BigInteger.valueOf(div.toLong()), compact = compact) + @JvmOverloads constructor(value: Float, div: Float, compact: Boolean = true) : this(BigDecimal(value.toString()), BigDecimal(div.toString()), compact = compact) + @JvmOverloads constructor(value: Double, div: Double, compact: Boolean = true) : this(BigDecimal(value.toString()), BigDecimal(div.toString()), compact = compact) + @JvmOverloads constructor(value: String, div: String, compact: Boolean = true) : this(BigDecimal(value), BigDecimal(div), compact = compact) + + @JvmOverloads constructor(value: BigDecimal, compact: Boolean = true) : this(powUnscaled(value.unscaledValue(), value.scale()), powScale(value.scale()), compact = compact) + @JvmOverloads constructor(value: BigDecimal, div: BigDecimal, compact: Boolean = true) : this(powUnscaled(value.unscaledValue(), value.scale()).multiply(powScale(div.scale())), powScale(value.scale()).multiply(powUnscaled(div.unscaledValue(), div.scale())), compact = compact) + + fun compactAndCanonize(): Fraction { + if (value == BigInteger.ZERO || value == BigInteger.ONE || divisor == BigInteger.ONE) + return this + + val a = signnum() + val b = value.signum() + val c = divisor.signum() + + if (a != b && a != c) { + val mod = value % divisor + + if (mod == BigInteger.ZERO) + return Fraction(-value / -divisor, compact = compact) + + return Fraction(-value, -divisor) + } + + val mod = value % divisor + + if (mod == BigInteger.ZERO) + return Fraction(value / divisor, compact = compact) + + return this + } + + fun compact(): Fraction { + if (value == BigInteger.ZERO || value == BigInteger.ONE || divisor == BigInteger.ONE) + return this + + val mod = value % divisor + + if (mod == BigInteger.ZERO) + return Fraction(value / divisor, compact = compact) + + return this + } + + fun canonize(): Fraction { + if (value == BigInteger.ZERO || value == BigInteger.ONE || divisor == BigInteger.ONE || divisor == BigInteger.ZERO) + return this + + val a = signnum() + val b = value.signum() + val c = divisor.signum() + + if (a != b && a != c) + return Fraction(-value, -divisor) + + return this + } + + // Операторы + fun equalsCompact(other: Fraction?): Boolean { + if (other == null) + return false + + val a = compact() + val b = other.compact() + + return a.value == b.value && a.divisor == b.divisor + } + + operator fun compareTo(other: Fraction): Int { + if (divisor == other.divisor) + return value.compareTo(other.value) + + val a = signnum() + val b = other.signnum() + + if (a == b && a == 0) + return 0 + + if (a < b) + return -1 + else if (a > b) + return 1 + + val cmp = (value * other.divisor).compareTo(other.value * divisor) + + if (a != value.signum() && a != divisor.signum()) { + if (b != other.value.signum() && b != other.divisor.signum()) { + return cmp + } + + return invertCompare(cmp) + } else if (b != other.value.signum() && b != other.divisor.signum()) { + return invertCompare(cmp) + } + + return cmp + } + + fun plusCompact(other: Fraction): Fraction { + if (divisor == other.divisor) { + if (divisor == BigInteger.ONE) + return Fraction(value + other.value) + + val new = value + other.value + val mod = new % divisor + + if (mod == BigInteger.ZERO) + return Fraction(new / divisor) + + return Fraction(value + other.value, divisor) + } + + val new = value * other.divisor + other.value * divisor + val div = divisor * other.divisor + val mod = new % div + + if (mod == BigInteger.ZERO) + return Fraction(new / div) + + return Fraction(new, div) + } + + operator fun plus(other: Fraction): Fraction { + if (compact) + return plusCompact(other) + + if (divisor == other.divisor) { + return Fraction(value + other.value, divisor, compact = false) + } + + return Fraction(value * other.divisor + other.value * divisor, divisor * other.divisor, compact = false) + } + + fun minusCompact(other: Fraction): Fraction { + if (divisor == other.divisor) { + if (divisor == BigInteger.ONE) + return Fraction(value + other.value) + + val new = value - other.value + val mod = new % divisor + + if (mod == BigInteger.ZERO) + return Fraction(new / divisor) + + return Fraction(value + other.value, divisor) + } + + val new = value * other.divisor - other.value * divisor + val div = divisor * other.divisor + val mod = new % div + + if (mod == BigInteger.ZERO) + return Fraction(new / div) + + return Fraction(new, div) + } + + operator fun minus(other: Fraction): Fraction { + if (compact) + return minusCompact(other) + + if (divisor == other.divisor) { + return Fraction(value - other.value, divisor, compact = false) + } + + return Fraction(value * other.divisor - other.value * divisor, divisor * other.divisor, compact = false) + } + + fun timesCompact(other: Fraction): Fraction { + val new = value * other.value + val div = divisor * other.divisor + val mod = new % div + + if (mod == BigInteger.ZERO) + return Fraction(new / div) + + return Fraction(new, div) + } + + operator fun times(other: Fraction): Fraction { + if (compact) + return timesCompact(other) + + return Fraction(value * other.value, divisor * other.divisor, compact = false) + } + + fun divCompact(other: Fraction): Fraction { + val new = value * other.divisor + val div = divisor * other.value + val mod = new % div + + if (mod == BigInteger.ZERO) + return Fraction(new / div) + + return Fraction(new, div) + } + + operator fun div(other: Fraction): Fraction { + if (compact) + return divCompact(other) + + return Fraction(value * other.divisor, divisor * other.value, compact = false) + } + + operator fun unaryMinus(): Fraction { + return Fraction(-value, divisor) + } + + operator fun unaryPlus(): Fraction { + return this + } + + operator fun plus(other: Float): Fraction = plus(Fraction(other)) + operator fun minus(other: Float): Fraction = minus(Fraction(other)) + operator fun times(other: Float): Fraction = times(Fraction(other)) + operator fun div(other: Float): Fraction = div(Fraction(other)) + + operator fun plus(other: Double): Fraction = plus(Fraction(other)) + operator fun minus(other: Double): Fraction = minus(Fraction(other)) + operator fun times(other: Double): Fraction = times(Fraction(other)) + operator fun div(other: Double): Fraction = div(Fraction(other)) + + // может вызвать путаницу + /* + operator fun plus(other: BigDecimal): Fraction = plus(Fraction(other)) + operator fun minus(other: BigDecimal): Fraction = minus(Fraction(other)) + operator fun times(other: BigDecimal): Fraction = times(Fraction(other)) + operator fun div(other: BigDecimal): Fraction = div(Fraction(other)) + + operator fun plus(other: BigInteger): Fraction = plus(Fraction(other)) + operator fun minus(other: BigInteger): Fraction = minus(Fraction(other)) + operator fun times(other: BigInteger): Fraction = times(Fraction(other)) + operator fun div(other: BigInteger): Fraction = div(Fraction(other)) + */ + + operator fun plus(other: Int): Fraction = plus(Fraction(other)) + operator fun minus(other: Int): Fraction = minus(Fraction(other)) + operator fun times(other: Int): Fraction = times(Fraction(other)) + operator fun div(other: Int): Fraction = div(Fraction(other)) + + operator fun plus(other: Long): Fraction = plus(Fraction(other)) + operator fun minus(other: Long): Fraction = minus(Fraction(other)) + operator fun times(other: Long): Fraction = times(Fraction(other)) + operator fun div(other: Long): Fraction = div(Fraction(other)) + + /* + fun add(other: Float): Fraction = plus(Fraction(other)) + fun subtract(other: Float): Fraction = minus(Fraction(other)) + fun multiply(other: Float): Fraction = times(Fraction(other)) + fun divide(other: Float): Fraction = div(Fraction(other)) + + fun add(other: Double): Fraction = plus(Fraction(other)) + fun subtract(other: Double): Fraction = minus(Fraction(other)) + fun multiply(other: Double): Fraction = times(Fraction(other)) + fun divide(other: Double): Fraction = div(Fraction(other)) + + fun add(other: Int): Fraction = plus(Fraction(other)) + fun subtract(other: Int): Fraction = minus(Fraction(other)) + fun multiply(other: Int): Fraction = times(Fraction(other)) + fun divide(other: Int): Fraction = div(Fraction(other)) + + fun add(other: Long): Fraction = plus(Fraction(other)) + fun subtract(other: Long): Fraction = minus(Fraction(other)) + fun multiply(other: Long): Fraction = times(Fraction(other)) + fun divide(other: Long): Fraction = div(Fraction(other)) + + fun add(other: Fraction): Fraction = plus(other) + fun subtract(other: Fraction): Fraction = minus(other) + fun multiply(other: Fraction): Fraction = times(other) + fun divide(other: Fraction): Fraction = div(other) + */ + + operator fun rem(other: Fraction): Fraction { + return Fraction((this / other).wholePart()) + } + + // Преобразования + fun toFloat(): Float { + return (value / divisor).toFloat() + ((value % divisor).toFloat() / divisor.toFloat()) + } + + fun toDouble(): Double { + return (value / divisor).toDouble() + ((value % divisor).toDouble() / divisor.toDouble()) + } + + fun toByteArray(): ByteArray { + val bytesA = value.toByteArray() + val bytesB = divisor.toByteArray() + + return byteArrayOf(bytesA.size.toByte(), *bytesA, bytesB.size.toByte(), *bytesB) + } + + fun toInt(): Int { + return (value / divisor).toInt() + } + + fun toLong(): Long { + return (value / divisor).toLong() + } + + @JvmOverloads + fun toBigDecimal(context: MathContext = DEFAULT_MATH_CONTEXT): BigDecimal { + return BigDecimal(value).divide(BigDecimal(divisor), context) + } + + // Утилиты + fun wholePart(): BigInteger { + return value / divisor + } + + fun fractionPart(): Fraction { + return Fraction(value % divisor, divisor) + } + + fun modPart(): BigInteger { + return value % divisor + } + + override fun toString(): String { + return "$value/$divisor" + } + + fun formattedString(): String { + return "${wholePart()} ${modPart()}/$divisor" + } + + @JvmOverloads + fun decimalString(nums: Int = 2, strict: Boolean = false): String { + val whole = wholePart() + val fraction = modPart() + + if (fraction == BigInteger.ZERO) { + if (!strict) + return whole.toString() + + return "${whole}.${"0".repeat(nums)}" + } + + var strdec = (fraction.toDouble() / divisor.toDouble()).toString() + + if (strdec.length == 1) { + strdec = "" + + if (strict) { + strdec = "0".repeat(nums) + } + } else { + strdec = strdec.substring(2) + + if (strict && strdec.length < nums) { + strdec += "0".repeat(nums - strdec.length) + } else if (strdec.length > nums) { + strdec = strdec.substring(0, nums) + } + } + + if (strdec == "") { + return whole.toString() + } + + return "${whole}.$strdec" + } + + fun signnum(): Int { + val a = value.signum() + val b = divisor.signum() + + if (a == b) { + if (a == 0) + return 0 + + return 1 + } + + return -1 + } + + fun serializeNBT(): ByteArrayTag { + return ByteArrayTag(toByteArray()) + } + + fun isNaN(): Boolean { + return divisor == BigInteger.ZERO + } + + fun write(buff: FriendlyByteBuf) { + buff.writeByteArray(toByteArray()) + } + + fun max(vararg others: Fraction): Fraction { + var max = this + + for (other in others) { + if (max < other) { + max = other + } + } + + return max + } + + fun min(vararg others: Fraction): Fraction { + var min = this + + for (other in others) { + if (min > other) { + min = other + } + } + + return min + } + + fun moreThanZero(): Fraction { + if (signnum() >= 0) + return this + + return ZERO + } + + fun lessOrZero(): Fraction { + if (signnum() <= 0) + return this + + return ZERO + } + + companion object { + @JvmField + val ZERO = Fraction(BigInteger.ZERO) + + @JvmField + val HALF = Fraction(BigInteger.ONE, BigInteger.TWO) + + @JvmField + val THIRD = Fraction(BigInteger.ONE, BigInteger.valueOf(3)) + + @JvmField + val ONE = Fraction(BigInteger.ONE) + + @JvmField + val TWO = Fraction(BigInteger.TWO) + + @JvmField + val MINUS_ONE = Fraction(-1) + + @JvmField + val TEN = Fraction(BigInteger.TEN) + + @JvmStatic + fun read(buff: FriendlyByteBuf): Fraction { + return fromByteArray(buff.readByteArray()) + } + + @JvmStatic + fun fromByteArray(bytes: ByteArray): Fraction { + val bytesA = bytes.copyOfRange(1, 1 + bytes[0].toInt()) + val offsetB = 1 + bytes[0].toInt() + val bytesB = bytes.copyOfRange(offsetB + 1, offsetB + 1 + bytes[offsetB].toInt()) + + return Fraction(BigInteger(bytesA), BigInteger(bytesB)) + } + + @JvmStatic + fun deserializeNBT(bytesTag: ByteArrayTag): Fraction { + val bytes = bytesTag.asByteArray + return fromByteArray(bytes) + } + + // Преобразование строки в дробь с подавлением ошибок форматирования + @JvmStatic + fun fromString(str: String): Fraction { + try { + return Fraction(BigDecimal(str)) + } catch(err: Throwable) { + return ZERO + } + } + + @JvmStatic + fun deserializeNBT(tag: Tag?): Fraction { + if (tag == null) + return ZERO + + if (tag is ByteArrayTag) + return deserializeNBT(tag) + + if (tag is StringTag) + return try { + fromString(tag.asString) + } catch (anything: Throwable) { + ZERO + } + + return ZERO + } + } +} + 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 new file mode 100644 index 000000000..50f8fd8d9 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/data/FractionDataContainer.kt @@ -0,0 +1,51 @@ +package ru.dbotthepony.mc.otm.menu.data + +import net.minecraft.world.inventory.ContainerData +import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.network.NetworkHelper + +class FractionDataContainer : ContainerData { + companion object { + const val NETWORK_PAYLOAD_SIZE = 32 + } + + private var _value: Fraction? = Fraction.ZERO + + fun hasComputedValue(): Boolean { + return _value != null + } + + var value: Fraction + get() { + if (_value != null) + return _value!! + + _value = Fraction.fromByteArray(NetworkHelper.shortsToBytes(buffer)) + return _value!! + } + set(value) { + _value = value + + if (_value == null) { + buffer.fill(0) + return + } + + NetworkHelper.bytesToShorts(_value!!.toByteArray()).copyInto(buffer) + } + + 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() + _value = null + } + + override fun getCount(): Int { + return buffer.size + } +} diff --git a/src/test/kotlin/ru/dbotthepony/mc/otm/tests/FractionTests.kt b/src/test/kotlin/ru/dbotthepony/mc/otm/tests/FractionTests.kt new file mode 100644 index 000000000..5d9715c69 --- /dev/null +++ b/src/test/kotlin/ru/dbotthepony/mc/otm/tests/FractionTests.kt @@ -0,0 +1,121 @@ +package ru.dbotthepony.mc.otm.tests + +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import ru.dbotthepony.mc.otm.core.Fraction +import java.math.BigDecimal +import java.math.BigInteger + +object FractionTests { + @Test + @DisplayName("Fraction declaration") + fun declaration() { + println("BigInteger 1/1 == ${Fraction(BigInteger.valueOf(1), BigInteger.valueOf(1))}") + println("BigDecimal 1 == ${Fraction(BigDecimal("1"))}") + + var one = BigDecimal("1.00") + + println("Unscaled ${one.unscaledValue()} with scale ${one.scale()} of $one") + println("BigDecimal $one == ${Fraction(one)}") + assert(Fraction(one).compareTo(Fraction.ONE) == 0) + + one = BigDecimal("1.0000") + + println("Unscaled ${one.unscaledValue()} with scale ${one.scale()} of $one") + println("BigDecimal $one == ${Fraction(one)}") + assert(Fraction(one).compareTo(Fraction.ONE) == 0) + + println("1/2 == ${Fraction(1, 2)}") + println("-1/2 == ${Fraction(-1, 2)}") + println("1/-2 == ${Fraction(1, -2)}") + println("-1/-2 == ${Fraction(-1, -2)}") + + println("canonical 1/2 == ${Fraction(1, 2).canonize()}") + println("canonical -1/2 == ${Fraction(-1, 2).canonize()}") + println("canonical 1/-2 == ${Fraction(1, -2).canonize()}") + println("canonical -1/-2 == ${Fraction(-1, -2).canonize()}") + } + + @Test + @DisplayName("Fraction comparison") + fun equality() { + assert(Fraction(1).compareTo(Fraction.ONE) == 0) + assert(Fraction(1.0).compareTo(Fraction.ONE) == 0) + assert(Fraction(1.0F).compareTo(Fraction.ONE) == 0) + assert(Fraction(1, 1).compareTo(Fraction.ONE) == 0) + assert(Fraction(1.0, 1.0).compareTo(Fraction.ONE) == 0) + assert(Fraction(1.0F, 1.0F).compareTo(Fraction.ONE) == 0) + + assert(Fraction(1, 2).compareTo(Fraction.HALF) == 0) + assert(Fraction(1.0, 2.0).compareTo(Fraction.HALF) == 0) + assert(Fraction(1.0F, 2.0F).compareTo(Fraction.HALF) == 0) + + assert(Fraction(-1, -2).compareTo(Fraction.HALF) == 0) + assert(Fraction(-1.0, -2.0).compareTo(Fraction.HALF) == 0) + assert(Fraction(-1.0F, -2.0F).compareTo(Fraction.HALF) == 0) + + assert(Fraction(-1, 2).compareTo(Fraction.HALF) != 0) + assert(Fraction(-1.0, 2.0).compareTo(Fraction.HALF) != 0) + assert(Fraction(-1.0F, 2.0F).compareTo(Fraction.HALF) != 0) + + assert(Fraction(1, 2).compareTo(Fraction.ONE) != 0) + assert(Fraction(1.0, 2.0).compareTo(Fraction.ONE) != 0) + assert(Fraction(1.0F, 2.0F).compareTo(Fraction.ONE) != 0) + + assert(Fraction(2).compareTo(Fraction.TWO) == 0) + assert(Fraction(2.0).compareTo(Fraction.TWO) == 0) + assert(Fraction(2.0F).compareTo(Fraction.TWO) == 0) + assert(Fraction(2, 1).compareTo(Fraction.TWO) == 0) + assert(Fraction(2.0, 1.0).compareTo(Fraction.TWO) == 0) + assert(Fraction(2.0F, 1.0F).compareTo(Fraction.TWO) == 0) + + assert(Fraction(4, 3) > Fraction(5, 4)) + assert(Fraction(4, 4) < Fraction(5, 4)) + + assert(Fraction(-15, 2) < Fraction(2, 4)) + assert(Fraction(-1, 2) < Fraction(2, 4)) + assert(Fraction(-15, -2) > Fraction(2, 4)) + assert(Fraction(-15, -2) > Fraction(-2, -4)) + assert(Fraction(-15, 2) < Fraction(-2, -4)) + } + + @Test + @DisplayName("Fraction math") + fun math() { + assert((Fraction(1) / Fraction(1)) == Fraction(1)) + assert((Fraction(2) / Fraction(1)) == Fraction(2, 1)) + assert((Fraction(2) / Fraction(2)) == Fraction(1)) + + assert((Fraction(4, 3) / Fraction(5, 4)) == (Fraction(4, 3) * Fraction(4, 5))) + assert((Fraction(4, 3) + Fraction(5, 4)) == Fraction(31, 12)) + } + + @Test + @DisplayName("Fraction serialization test") + fun serialization() { + var value = Fraction(1) + var serialized = value.serializeNBT() + + assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0) + + value = Fraction(4, 2) + serialized = value.serializeNBT() + + assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0) + + value = Fraction(-4, 2) + serialized = value.serializeNBT() + + assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0) + + value = Fraction(-4, -18) + serialized = value.serializeNBT() + + assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0) + + value = Fraction("3407203485237459085739045724837543569234750927348902374590872345", "-57777772398450982374590230984532984") + serialized = value.serializeNBT() + + assert(value.compareTo(Fraction.deserializeNBT(serialized)) == 0) + } +} diff --git a/src/test/kotlin/ru/dbotthepony/mc/otm/tests/NetworkingTests.kt b/src/test/kotlin/ru/dbotthepony/mc/otm/tests/NetworkingTests.kt new file mode 100644 index 000000000..67fd5c569 --- /dev/null +++ b/src/test/kotlin/ru/dbotthepony/mc/otm/tests/NetworkingTests.kt @@ -0,0 +1,52 @@ +package ru.dbotthepony.mc.otm.tests + +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import ru.dbotthepony.mc.otm.core.Fraction +import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer +import ru.dbotthepony.mc.otm.network.NetworkHelper +import kotlin.experimental.and + +object NetworkingTests { + @Test + @DisplayName("Test FractionDataContainer store/load") + fun fraction() { + val container = FractionDataContainer() + var frac = Fraction(18, 4) + + container.value = frac + container[1] = container[1] + assert(!container.hasComputedValue()) + + assert(container.value.compareTo(frac) == 0) { "${container.value} != $frac" } + + frac = Fraction(2_000_000, 1) + + container.value = frac + container[1] = container[1] + assert(!container.hasComputedValue()) + + assert(container.value.compareTo(frac) == 0) { "${container.value} != $frac" } + } + + @Test + @DisplayName("Test NetworkHelper byte/short transition") + fun networkHelper() { + var bytes = byteArrayOf(7, 8, -10) + var shorts = NetworkHelper.bytesToShorts(bytes) + + assert(shorts.size == 2) { "Shorts array is not size of 2, but size of ${shorts.size}" } + assert((shorts[0].toInt() and 0xFF).toByte() == bytes[0]) { "${shorts[0] and 0xFF} != ${bytes[0]} ${shorts.joinToString()}" } + assert(((shorts[0].toInt() and 0xFF00) shr 8).toByte() == bytes[1]) { "${(shorts[0].toInt() and 0xFF00) shr 8} != ${bytes[1]} ${shorts.joinToString()}" } + assert((shorts[1].toInt() and 0xFF).toByte() == bytes[2]) { "${shorts[1] and 0xFF} != ${bytes[2]} ${shorts.joinToString()}" } + + bytes = byteArrayOf(7, 8, -10, 4) + shorts = NetworkHelper.bytesToShorts(bytes) + + assert(shorts.size == 2) { "Shorts array is not size of 2, but size of ${shorts.size}" } + assert((shorts[0].toInt() and 0xFF).toByte() == bytes[0]) { "${shorts[0] and 0xFF} != ${bytes[0]} ${shorts.joinToString()}" } + assert(((shorts[0].toInt() and 0xFF00) shr 8).toByte() == bytes[1]) { "${(shorts[0].toInt() and 0xFF00) shr 8} != ${bytes[1]} ${shorts.joinToString()}" } + assert((shorts[1].toInt() and 0xFF).toByte() == bytes[2]) { "${shorts[1] and 0xFF} != ${bytes[2]} ${shorts.joinToString()}" } + assert(((shorts[1].toInt() and 0xFF00) shr 8).toByte() == bytes[3]) { "${(shorts[1].toInt() and 0xFF00) shr 8} != ${bytes[3]} ${shorts.joinToString()}" } + } +}