Kotlin, Unit tests, Fraction instead of BigDecimal

This commit is contained in:
DBotThePony 2021-12-23 22:46:25 +07:00
parent 69defb2e62
commit 6d78029af2
Signed by: DBot
GPG Key ID: DCC23B5715498507
59 changed files with 1752 additions and 801 deletions

View File

@ -5,8 +5,11 @@ buildscript {
maven { url = 'https://maven.minecraftforge.net' } maven { url = 'https://maven.minecraftforge.net' }
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true 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. // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'maven-publish' 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' version = '1.0'
group = 'ru.dbotthepony.mc' // http://maven.apache.org/guides/mini/guide-naming-conventions.html group = 'ru.dbotthepony.mc' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
@ -29,6 +35,10 @@ exec {
args 'shapenator.js' args 'shapenator.js'
} }
test {
useJUnitPlatform()
}
minecraft { minecraft {
// The mappings can be changed at any time and must be in the following format. // The mappings can be changed at any time and must be in the following format.
// Channel: Version: // Channel: Version:
@ -140,6 +150,8 @@ dependencies {
// The userdev artifact is a special name and will get all sorts of transformations applied to it. // 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' 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 // 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 // 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 // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency

View File

@ -6,6 +6,8 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.TickEvent; 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.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.InterModComms; 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.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 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.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityBlackHole; 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.AndroidCapability;
import ru.dbotthepony.mc.otm.capability.android.AndroidCapabilityPlayer; 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.capability.drive.DrivePool;
import ru.dbotthepony.mc.otm.client.AndroidGui; import ru.dbotthepony.mc.otm.client.AndroidGui;
import ru.dbotthepony.mc.otm.client.EventHandler; import ru.dbotthepony.mc.otm.client.EventHandler;

View File

@ -37,6 +37,7 @@ import ru.dbotthepony.mc.otm.block.entity.*;
import ru.dbotthepony.mc.otm.android.AndroidFeatureType; import ru.dbotthepony.mc.otm.android.AndroidFeatureType;
import ru.dbotthepony.mc.otm.client.render.BlackHoleRenderer; import ru.dbotthepony.mc.otm.client.render.BlackHoleRenderer;
import ru.dbotthepony.mc.otm.client.render.SkinElement; import ru.dbotthepony.mc.otm.client.render.SkinElement;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.item.*; import ru.dbotthepony.mc.otm.item.*;
import ru.dbotthepony.mc.otm.menu.*; import ru.dbotthepony.mc.otm.menu.*;
import ru.dbotthepony.mc.otm.client.screen.*; import ru.dbotthepony.mc.otm.client.screen.*;
@ -410,17 +411,17 @@ public class Registry {
public static final ItemPill PILL_ANDROID = new ItemPill(ItemPill.PillType.BECOME_ANDROID); 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 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_CRUDE = new ItemBattery(new Fraction(30_000), new Fraction(150), new Fraction(150));
public static final ItemBattery BATTERY_BASIC = new ItemBattery(new BigDecimal(60_000), new BigDecimal(300), new BigDecimal(300)); 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 BigDecimal(250_000), new BigDecimal(1000), new BigDecimal(1000)); 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 BigDecimal(1_000_000), new BigDecimal(2000), new BigDecimal(2000)); 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 BigDecimal(150_000), new BigDecimal(15000), new BigDecimal(15000)); 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 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 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_BASIC = new ItemMatterCapacitor(new Fraction("4"));
public static final ItemMatterCapacitor MATTER_CAPACITOR_NORMAL = new ItemMatterCapacitor(new BigDecimal("10")); public static final ItemMatterCapacitor MATTER_CAPACITOR_NORMAL = new ItemMatterCapacitor(new Fraction("10"));
public static final ItemMatterCapacitor MATTER_CAPACITOR_DENSE = new ItemMatterCapacitor(new BigDecimal("40")); public static final ItemMatterCapacitor MATTER_CAPACITOR_DENSE = new ItemMatterCapacitor(new Fraction("40"));
public static final ItemMatterCapacitor MATTER_CAPACITOR_CREATIVE = new ItemMatterCapacitor(); public static final ItemMatterCapacitor MATTER_CAPACITOR_CREATIVE = new ItemMatterCapacitor();
public static final ItemPatternStorage PATTERN_DRIVE_NORMAL = new ItemPatternStorage(4); public static final ItemPatternStorage PATTERN_DRIVE_NORMAL = new ItemPatternStorage(4);

View File

@ -8,6 +8,7 @@ import ru.dbotthepony.mc.otm.android.AndroidFeature;
import ru.dbotthepony.mc.otm.android.AndroidFeatureType; import ru.dbotthepony.mc.otm.android.AndroidFeatureType;
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -38,8 +39,8 @@ public class AndroidNanobotsArmor extends AndroidFeature {
protected int ticks_passed = 0; protected int ticks_passed = 0;
protected int layers = 0; protected int layers = 0;
protected static final BigDecimal ENERGY_PER_BUILT = new BigDecimal(200); protected static final Fraction ENERGY_PER_BUILT = new Fraction(200);
protected static final BigDecimal ENERGY_PER_HITPOINT = new BigDecimal(500); protected static final Fraction ENERGY_PER_HITPOINT = new Fraction(500);
public static final int[] TICKS = new int[] { public static final int[] TICKS = new int[] {
80, // 4 seconds to build a layer 80, // 4 seconds to build a layer
@ -77,9 +78,9 @@ public class AndroidNanobotsArmor extends AndroidFeature {
var absorbed = event.getAmount() * SHIELD_STRENGTH[layers]; var absorbed = event.getAmount() * SHIELD_STRENGTH[layers];
if (absorbed > 0.1f) { 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 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); event.setAmount(event.getAmount() - real_absorbed);
if (capability.getEntity() instanceof ServerPlayer ply) { if (capability.getEntity() instanceof ServerPlayer ply) {

View File

@ -8,6 +8,7 @@ import ru.dbotthepony.mc.otm.android.AndroidFeature;
import ru.dbotthepony.mc.otm.android.AndroidFeatureType; import ru.dbotthepony.mc.otm.android.AndroidFeatureType;
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -19,7 +20,7 @@ public class AndroidNanobotsRegeneration extends AndroidFeature {
protected int ticks_passed = 0; protected int ticks_passed = 0;
protected int heal_ticks = 0; protected int heal_ticks = 0;
protected static final 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[] { protected static final int[] TICKS_BETWEEN_HEAL = new int[] {
100, // 5 seconds 100, // 5 seconds
@ -39,11 +40,11 @@ public class AndroidNanobotsRegeneration extends AndroidFeature {
if (ticks_passed > wait_time) { if (ticks_passed > wait_time) {
var missing = Math.min(1, ent.getMaxHealth() - ent.getHealth()); var missing = Math.min(1, ent.getMaxHealth() - ent.getHealth());
var extract = capability.extractEnergyInner(ENERGY_PER_HITPOINT.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); 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); ent.heal(heal);
if (capability.getEntity() instanceof ServerPlayer ply) { if (capability.getEntity() instanceof ServerPlayer ply) {

View File

@ -17,6 +17,7 @@ import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu; import ru.dbotthepony.mc.otm.menu.AndroidStationMenu;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -43,7 +44,7 @@ public class BlockEntityAndroidStation extends BlockEntityMatteryPowered impleme
public BlockEntityAndroidStation(BlockPos p_155229_, BlockState p_155230_) { public BlockEntityAndroidStation(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.ANDROID_STATION, p_155229_, 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 <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { public static <T extends BlockEntity> 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(); 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); 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); final var received = capability.receiveEnergyOuter(extract, true);
if (received.compareTo(BigDecimal.ZERO) > 0) { if (received.compareTo(Fraction.ZERO) > 0) {
tile.energy.extractEnergyInner(extract, false); tile.energy.extractEnergyInner(extract, false);
capability.receiveEnergyOuter(extract, false); capability.receiveEnergyOuter(extract, false);
} }

View File

@ -27,6 +27,7 @@ import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable;
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.container.MatteryContainer; import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.menu.BatteryBankMenu; import ru.dbotthepony.mc.otm.menu.BatteryBankMenu;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -63,7 +64,7 @@ public class BlockEntityBatteryBank extends BlockEntityMattery {
(slot, amount, stack) -> true (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 @Nonnull
@Override @Override
public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) {
if (mode == BankMode.RECEIVE) if (mode == BankMode.RECEIVE)
return BigDecimal.ZERO; return Fraction.ZERO;
return extractEnergyInner(howMuch, simulate); return extractEnergyInner(howMuch, simulate);
} }
BatteryBankDistribution getDistribution(boolean mode) { BatteryBankDistribution getDistribution(boolean mode) {
BigDecimal[] distribution = new BigDecimal[tile.battery_container.getContainerSize()]; Fraction[] distribution = new Fraction[tile.battery_container.getContainerSize()];
BigDecimal summ = BigDecimal.ZERO; Fraction summ = Fraction.ZERO;
for (int i = 0; i < tile.battery_container.getContainerSize(); i++) { for (int i = 0; i < tile.battery_container.getContainerSize(); i++) {
ItemStack stack = tile.battery_container.getItem(i); ItemStack stack = tile.battery_container.getItem(i);
@ -104,57 +105,57 @@ public class BlockEntityBatteryBank extends BlockEntityMattery {
Optional<IMatteryEnergyStorage> cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); Optional<IMatteryEnergyStorage> cap = stack.getCapability(MatteryCapability.ENERGY).resolve();
if (cap.isPresent()) { 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; distribution[i] = diff;
summ = summ.add(diff); summ = summ.plus(diff);
} else { } else {
Optional<IEnergyStorage> cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); Optional<IEnergyStorage> cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve();
if (cap2.isPresent()) { 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; distribution[i] = diff;
summ = summ.add(diff); summ = summ.plus(diff);
} }
} }
} else { } 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++) { 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); 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); BatteryBankDistribution distribution = getDistribution(mode);
if (distribution.max_throughput.compareTo(BigDecimal.ZERO) == 0) if (distribution.max_throughput.compareTo(Fraction.ZERO) == 0)
return BigDecimal.ZERO; return Fraction.ZERO;
BigDecimal[] distList = distribution.distribution; Fraction[] distList = distribution.distribution;
BigDecimal summ = BigDecimal.ZERO; Fraction summ = Fraction.ZERO;
for (int i = 0; i < tile.battery_container.getContainerSize(); i++) { 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); ItemStack stack = tile.battery_container.getItem(i);
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
Optional<IMatteryEnergyStorage> cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); Optional<IMatteryEnergyStorage> cap = stack.getCapability(MatteryCapability.ENERGY).resolve();
if (cap.isPresent()) { 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); Fraction diff = mode ? cap.get().receiveEnergyOuter(howMuch.times(distList[i]), simulate) : cap.get().extractEnergyOuter(howMuch.times(distList[i]), simulate);
summ = summ.add(diff); summ = summ.plus(diff);
} else { } else {
Optional<IEnergyStorage> cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); Optional<IEnergyStorage> cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve();
if (cap2.isPresent()) { 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); Fraction diff = mode ? MatteryCapability.floodFE(cap2.get(), howMuch.times(distList[i]), simulate) : MatteryCapability.drainFE(cap2.get(), howMuch.times(distList[i]), simulate);
summ = summ.add(diff); summ = summ.plus(diff);
} }
} }
} }
@ -166,29 +167,29 @@ public class BlockEntityBatteryBank extends BlockEntityMattery {
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) {
return distributeEnergy(false, howMuch, simulate); return distributeEnergy(false, howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) {
if (mode == BankMode.EXTRACT) if (mode == BankMode.EXTRACT)
return BigDecimal.ZERO; return Fraction.ZERO;
return receiveEnergyInner(howMuch, simulate); return receiveEnergyInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) {
return distributeEnergy(true, howMuch, simulate); return distributeEnergy(true, howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal getBatteryLevel() { public Fraction getBatteryLevel() {
BigDecimal result = BigDecimal.ZERO; Fraction result = Fraction.ZERO;
for (int i = 0; i < tile.battery_container.getContainerSize(); i++) { for (int i = 0; i < tile.battery_container.getContainerSize(); i++) {
ItemStack stack = tile.battery_container.getItem(i); ItemStack stack = tile.battery_container.getItem(i);
@ -197,12 +198,12 @@ public class BlockEntityBatteryBank extends BlockEntityMattery {
Optional<IMatteryEnergyStorage> cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); Optional<IMatteryEnergyStorage> cap = stack.getCapability(MatteryCapability.ENERGY).resolve();
if (cap.isPresent()) { if (cap.isPresent()) {
result = result.add(cap.get().getBatteryLevel(), MatteryCapability.ROUND_RULES); result = result.plus(cap.get().getBatteryLevel());
} else { } else {
Optional<IEnergyStorage> cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); Optional<IEnergyStorage> cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve();
if (cap2.isPresent()) { 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 @Nonnull
@Override @Override
public BigDecimal getMaxBatteryLevel() { public Fraction getMaxBatteryLevel() {
BigDecimal result = BigDecimal.ZERO; Fraction result = Fraction.ZERO;
for (int i = 0; i < tile.battery_container.getContainerSize(); i++) { for (int i = 0; i < tile.battery_container.getContainerSize(); i++) {
ItemStack stack = tile.battery_container.getItem(i); ItemStack stack = tile.battery_container.getItem(i);
@ -223,12 +224,12 @@ public class BlockEntityBatteryBank extends BlockEntityMattery {
Optional<IMatteryEnergyStorage> cap = stack.getCapability(MatteryCapability.ENERGY).resolve(); Optional<IMatteryEnergyStorage> cap = stack.getCapability(MatteryCapability.ENERGY).resolve();
if (cap.isPresent()) { if (cap.isPresent()) {
result = result.add(cap.get().getMaxBatteryLevel(), MatteryCapability.ROUND_RULES); result = result.plus(cap.get().getMaxBatteryLevel());
} else { } else {
Optional<IEnergyStorage> cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); Optional<IEnergyStorage> cap2 = stack.getCapability(CapabilityEnergy.ENERGY).resolve();
if (cap2.isPresent()) { 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()) { if (cap.canReceive()) {
BatteryBankDistribution distribution = tile.energy.getDistribution(false); 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); diff = tile.energy.extractEnergyOuter(diff, false);
cap.receiveEnergyOuter(diff, false); cap.receiveEnergyOuter(diff, false);
} }
@ -363,7 +364,7 @@ public class BlockEntityBatteryBank extends BlockEntityMattery {
if (cap.canReceive()) { if (cap.canReceive()) {
BatteryBankDistribution distribution = tile.energy.getDistribution(false); 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); diff = tile.energy.extractEnergyOuter(diff, false);
MatteryCapability.floodFE(cap, diff, false); MatteryCapability.floodFE(cap, diff, false);
} }

View File

@ -33,6 +33,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.matter.MatterRegistry;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -49,8 +50,8 @@ public class BlockEntityBlackHole extends BlockEntity {
setMass(mass); setMass(mass);
} }
public static final BigDecimal NORMAL_MASS = new BigDecimal(1_000); public static final Fraction NORMAL_MASS = new Fraction(1_000);
private BigDecimal mass = NORMAL_MASS; private Fraction mass = NORMAL_MASS;
private double gravitation_strength = 1; private double gravitation_strength = 1;
private boolean suppress_updates = true; private boolean suppress_updates = true;
public boolean spin_direction = false; public boolean spin_direction = false;
@ -284,19 +285,19 @@ public class BlockEntityBlackHole extends BlockEntity {
} }
} }
public void addMass(BigDecimal mass) { public void addMass(Fraction mass) {
setMass(this.mass.add(mass)); setMass(this.mass.plus(mass));
} }
public void setMass(BigDecimal mass) { public void setMass(Fraction mass) {
if (mass.compareTo(BigDecimal.ZERO) <= 0) { if (mass.compareTo(Fraction.ZERO) <= 0) {
collapse(); collapse();
return; return;
} }
this.mass = mass; this.mass = mass;
setChanged(); setChanged();
gravitation_strength = mass.divide(NORMAL_MASS, MatteryCapability.ROUND_RULES).doubleValue(); gravitation_strength = mass.div(NORMAL_MASS).toDouble();
if (gravitation_strength > 1) { if (gravitation_strength > 1) {
gravitation_strength = Math.min(20, Math.sqrt(gravitation_strength)); gravitation_strength = Math.min(20, Math.sqrt(gravitation_strength));
@ -327,8 +328,8 @@ public class BlockEntityBlackHole extends BlockEntity {
} }
public void readBlackHoleData(CompoundTag tag) { public void readBlackHoleData(CompoundTag tag) {
if (tag.get("mass") instanceof StringTag str) if (tag.contains("mass"))
setMass(new BigDecimal(str.getAsString())); setMass(Fraction.deserializeNBT(tag.get("mass")));
spin_direction = tag.getBoolean("spin_direction"); 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 <T extends BlockEntity> void ticker(Level level, BlockPos blockPos, BlockState blockState, T t) { public static <T extends BlockEntity> void ticker(Level level, BlockPos blockPos, BlockState blockState, T t) {
if (t instanceof BlockEntityBlackHole tile) { if (t instanceof BlockEntityBlackHole tile) {
@ -457,7 +458,7 @@ public class BlockEntityBlackHole extends BlockEntity {
} else { } else {
var mass = MatterRegistry.getMatterValue(item.getItem()); var mass = MatterRegistry.getMatterValue(item.getItem());
if (mass.compareTo(BigDecimal.ZERO) > 0) if (mass.compareTo(Fraction.ZERO) > 0)
tile.addMass(mass); tile.addMass(mass);
} }
} }

View File

@ -20,6 +20,7 @@ import ru.dbotthepony.mc.otm.capability.AbstractStorageGridCell;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
import ru.dbotthepony.mc.otm.container.MatteryContainer; 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.menu.DriveRackMenu;
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper; import ru.dbotthepony.mc.otm.storage.ItemStackWrapper;
import ru.dbotthepony.mc.otm.storage.VirtualComponent; import ru.dbotthepony.mc.otm.storage.VirtualComponent;
@ -34,7 +35,7 @@ import java.math.BigDecimal;
public class BlockEntityDriveRack extends BlockEntityMatteryPowered { public class BlockEntityDriveRack extends BlockEntityMatteryPowered {
public BlockEntityDriveRack(BlockPos p_155229_, BlockState p_155230_) { public BlockEntityDriveRack(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.DRIVE_RACK, p_155229_, 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) { public final MatteryContainer drives = new MatteryContainer(this::setChanged, 4) {

View File

@ -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.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
import ru.dbotthepony.mc.otm.container.MatteryContainer; import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu; import ru.dbotthepony.mc.otm.menu.DriveViewerMenu;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -30,7 +31,7 @@ import java.math.BigDecimal;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class BlockEntityDriveViewer extends BlockEntityMatteryPowered { 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() { public boolean canIOItems() {
return energy.getBatteryLevel().compareTo(MTE_PER_OPERATION) >= 0; return energy.getBatteryLevel().compareTo(MTE_PER_OPERATION) >= 0;
@ -65,20 +66,20 @@ public class BlockEntityDriveViewer extends BlockEntityMatteryPowered {
if (!canIOItems()) if (!canIOItems())
return 0; return 0;
var extracted = energy.extractEnergyInner(MTE_PER_OPERATION.multiply(new BigDecimal(desired)), true); var extracted = energy.extractEnergyInner(MTE_PER_OPERATION.times(desired), true);
var modulo = extracted.divideToIntegralValue(MTE_PER_OPERATION); var modulo = extracted.rem(MTE_PER_OPERATION);
if (simulate) 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_) { public BlockEntityDriveViewer(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.DRIVE_VIEWER, p_155229_, 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"); private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.drive_viewer");

View File

@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.BlockEnergyCounter; import ru.dbotthepony.mc.otm.block.BlockEnergyCounter;
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu; import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -36,23 +37,23 @@ import java.util.Arrays;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class BlockEntityEnergyCounter extends BlockEntityMattery { public class BlockEntityEnergyCounter extends BlockEntityMattery {
protected BigDecimal passed = BigDecimal.ZERO; protected Fraction passed = Fraction.ZERO;
protected final BigDecimal[] history = new BigDecimal[10 * 20]; protected final Fraction[] history = new Fraction[10 * 20];
protected int history_tick = 0; protected int history_tick = 0;
public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) {
if (t instanceof BlockEntityEnergyCounter tile) { if (t instanceof BlockEntityEnergyCounter tile) {
tile.history_tick = (tile.history_tick + 1) % tile.history.length; 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) { if (ticks < 1 || ticks >= history.length) {
throw new IllegalArgumentException("Invalid history length provided"); 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++) { for (int i = 0; i < ticks; i++) {
int index = (history_tick - i) % this.history.length; int index = (history_tick - i) % this.history.length;
@ -66,16 +67,16 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery {
return history; return history;
} }
public BigDecimal calcAverage(int ticks) { public Fraction calcAverage(int ticks) {
return sumHistory(ticks).divide(new BigDecimal(ticks), MatteryCapability.ROUND_RULES); return sumHistory(ticks).div(ticks);
} }
public BigDecimal sumHistory(int ticks) { public Fraction sumHistory(int ticks) {
if (ticks < 1 || ticks >= history.length) { if (ticks < 1 || ticks >= history.length) {
throw new IllegalArgumentException("Invalid history length provided"); throw new IllegalArgumentException("Invalid history length provided");
} }
var value = BigDecimal.ZERO; var value = Fraction.ZERO;
for (int i = 0; i < ticks; i++) { for (int i = 0; i < ticks; i++) {
int index = (history_tick - i) % this.history.length; int index = (history_tick - i) % this.history.length;
@ -83,19 +84,19 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery {
if (index < 0) if (index < 0)
index += this.history.length; index += this.history.length;
value = value.add(history[index]); value = value.plus(history[index]);
} }
return value; return value;
} }
public BigDecimal getPassed() { public Fraction getPassed() {
return passed; return passed;
} }
public BlockEntityEnergyCounter(BlockPos p_155229_, BlockState p_155230_) { public BlockEntityEnergyCounter(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.ENERGY_COUNTER, p_155229_, p_155230_); super(Registry.BlockEntities.ENERGY_COUNTER, p_155229_, p_155230_);
Arrays.fill(history, BigDecimal.ZERO); Arrays.fill(history, Fraction.ZERO);
} }
@Override @Override
@ -117,17 +118,29 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery {
public void load(CompoundTag nbt) { public void load(CompoundTag nbt) {
super.load(nbt); super.load(nbt);
if (nbt.get("passed") instanceof StringTag tag) if (nbt.contains("passed"))
passed = new BigDecimal(tag.getAsString()); passed = Fraction.deserializeNBT(nbt.get("passed"));
if (nbt.get("history_tick") instanceof IntTag tag) if (nbt.get("history_tick") instanceof IntTag tag)
history_tick = tag.getAsInt(); history_tick = tag.getAsInt();
// TODO: старый формат данных, удалить на релизе
var list = nbt.getList("history", Tag.TAG_STRING); var list = nbt.getList("history", Tag.TAG_STRING);
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
try { 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) { } catch(Throwable err) {
LOGGER.error(err); LOGGER.error(err);
} }
@ -176,21 +189,21 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery {
} }
@Override @Override
public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) {
return extractEnergyInner(howMuch, simulate); return extractEnergyInner(howMuch, simulate);
} }
@Override @Override
public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) {
if (is_input) if (is_input)
return BigDecimal.ZERO; return Fraction.ZERO;
if (input_cap_mte.isPresent()) { if (input_cap_mte.isPresent()) {
final var value = input_cap_mte.resolve().get().extractEnergyOuter(howMuch, simulate); final var value = input_cap_mte.resolve().get().extractEnergyOuter(howMuch, simulate);
if (!simulate) { if (!simulate) {
passed = passed.add(value); passed = passed.plus(value);
history[history_tick] = history[history_tick].add(value); history[history_tick] = history[history_tick].plus(value);
setChangedLight(); setChangedLight();
} }
@ -201,33 +214,33 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery {
final var value = MatteryCapability.drainFE(input_cap_fe.resolve().get(), howMuch, simulate); final var value = MatteryCapability.drainFE(input_cap_fe.resolve().get(), howMuch, simulate);
if (!simulate) { if (!simulate) {
passed = passed.add(value); passed = passed.plus(value);
history[history_tick] = history[history_tick].add(value); history[history_tick] = history[history_tick].plus(value);
setChangedLight(); setChangedLight();
} }
return value; return value;
} }
return BigDecimal.ZERO; return Fraction.ZERO;
} }
@Override @Override
public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) {
return receiveEnergyInner(howMuch, simulate); return receiveEnergyInner(howMuch, simulate);
} }
@Override @Override
public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) {
if (!is_input) if (!is_input)
return BigDecimal.ZERO; return Fraction.ZERO;
if (output_cap_mte.isPresent()) { if (output_cap_mte.isPresent()) {
final var value = output_cap_mte.resolve().get().receiveEnergyOuter(howMuch, simulate); final var value = output_cap_mte.resolve().get().receiveEnergyOuter(howMuch, simulate);
if (!simulate) { if (!simulate) {
passed = passed.add(value); passed = passed.plus(value);
history[history_tick] = history[history_tick].add(value); history[history_tick] = history[history_tick].plus(value);
setChangedLight(); setChangedLight();
} }
@ -238,26 +251,26 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery {
final var value = MatteryCapability.floodFE(output_cap_fe.resolve().get(), howMuch, simulate); final var value = MatteryCapability.floodFE(output_cap_fe.resolve().get(), howMuch, simulate);
if (!simulate) { if (!simulate) {
passed = passed.add(value); passed = passed.plus(value);
history[history_tick] = history[history_tick].add(value); history[history_tick] = history[history_tick].plus(value);
setChangedLight(); setChangedLight();
} }
return value; return value;
} }
return BigDecimal.ZERO; return Fraction.ZERO;
} }
@Override @Override
public BigDecimal getBatteryLevel() { public Fraction getBatteryLevel() {
if (is_input) { if (is_input) {
if (output_cap_mte.isPresent()) { if (output_cap_mte.isPresent()) {
return output_cap_mte.resolve().get().getBatteryLevel(); return output_cap_mte.resolve().get().getBatteryLevel();
} }
if (output_cap_fe.isPresent()) { if (output_cap_fe.isPresent()) {
return new BigDecimal(output_cap_fe.resolve().get().getEnergyStored()); return new Fraction(output_cap_fe.resolve().get().getEnergyStored());
} }
} else { } else {
if (input_cap_mte.isPresent()) { if (input_cap_mte.isPresent()) {
@ -265,22 +278,22 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery {
} }
if (input_cap_fe.isPresent()) { 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 @Override
public BigDecimal getMaxBatteryLevel() { public Fraction getMaxBatteryLevel() {
if (is_input) { if (is_input) {
if (output_cap_mte.isPresent()) { if (output_cap_mte.isPresent()) {
return output_cap_mte.resolve().get().getMaxBatteryLevel(); return output_cap_mte.resolve().get().getMaxBatteryLevel();
} }
if (output_cap_fe.isPresent()) { if (output_cap_fe.isPresent()) {
return new BigDecimal(output_cap_fe.resolve().get().getMaxEnergyStored()); return new Fraction(output_cap_fe.resolve().get().getMaxEnergyStored());
} }
} else { } else {
if (input_cap_mte.isPresent()) { if (input_cap_mte.isPresent()) {
@ -288,11 +301,11 @@ public class BlockEntityEnergyCounter extends BlockEntityMattery {
} }
if (input_cap_fe.isPresent()) { 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 @Override

View File

@ -17,6 +17,7 @@ import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.capability.AbstractStorageGridCell; import ru.dbotthepony.mc.otm.capability.AbstractStorageGridCell;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu; import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -29,7 +30,7 @@ import java.math.BigDecimal;
public class BlockEntityItemMonitor extends BlockEntityMatteryPowered { public class BlockEntityItemMonitor extends BlockEntityMatteryPowered {
public BlockEntityItemMonitor(BlockPos p_155229_, BlockState p_155230_) { public BlockEntityItemMonitor(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.ITEM_MONITOR, p_155229_, 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(); public final AbstractStorageGridCell cell = new AbstractStorageGridCell();

View File

@ -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.capability.matter.MatterHandlerCapability;
import ru.dbotthepony.mc.otm.container.MatteryContainer; import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler; 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.MatterGrid;
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu; import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu;
@ -85,7 +86,7 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen
return slot < 3; 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 @Nonnull
@Override @Override
public MatterDirection getDirection() { 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 Fraction MATTER_EXCHANGE_RATE = new Fraction("0.04");
private static final BigDecimal ENERGY_CONSUMPTION = new BigDecimal(20); private static final Fraction ENERGY_CONSUMPTION = new Fraction(20);
private LazyOptional<IMatterGridCell> cell_resolver = LazyOptional.of(() -> this); private LazyOptional<IMatterGridCell> cell_resolver = LazyOptional.of(() -> this);
protected BigDecimal initial_capacity; protected Fraction initial_capacity;
protected ItemStack last_work_stack; protected ItemStack last_work_stack;
private MatterGrid grid; private MatterGrid grid;
@ -202,7 +203,7 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen
matter.deserializeNBT(_matter); matter.deserializeNBT(_matter);
} }
private static final BigDecimal EXTRACTION_TICKS = new BigDecimal(200); private static final Fraction EXTRACTION_TICKS = new Fraction(200);
public float getWorkProgress() { public float getWorkProgress() {
if (last_work_stack == null) { if (last_work_stack == null) {
@ -216,18 +217,18 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen
} }
if (work_flow) { 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 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 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 <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) {
@ -253,7 +254,7 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen
if (!get.isEmpty()) { if (!get.isEmpty()) {
var cap = get.getCapability(MatteryCapability.MATTER).resolve(); 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; work_stack = get;
capability = cap.get(); capability = cap.get();
work_slot = i; work_slot = i;
@ -280,29 +281,29 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen
if (tile.grid != null) { if (tile.grid != null) {
var extracted = tile.grid.extractMatter( var extracted = tile.grid.extractMatter(
tile.matter.getMissingMatter() tile.matter.getMissingMatter()
.min(MATTER_EXCHANGE_RATE.multiply(EXTRACTION_TICKS)) .min(MATTER_EXCHANGE_RATE.times(EXTRACTION_TICKS))
.min(capability.getMissingMatter().subtract(tile.matter.getStoredMatter())) .min(capability.getMissingMatter().minus(tile.matter.getStoredMatter()))
, true); , true);
if (extracted.compareTo(BigDecimal.ZERO) > 0) { if (extracted.compareTo(Fraction.ZERO) > 0) {
var received = tile.matter.receiveMatterOuter(extracted, false); var received = tile.matter.receiveMatterOuter(extracted, false);
tile.grid.extractMatter(received, 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); var energy = tile.energy.extractEnergyInner(ENERGY_CONSUMPTION, true);
if (energy.compareTo(BigDecimal.ZERO) > 0) { if (energy.compareTo(Fraction.ZERO) > 0) {
var matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getStoredMatter()).multiply(energy.divide(ENERGY_CONSUMPTION, MatteryCapability.ROUND_RULES)), true); var matter = capability.receiveMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getStoredMatter()).times(energy.div(ENERGY_CONSUMPTION)), true);
if (matter.compareTo(BigDecimal.ZERO) > 0) { if (matter.compareTo(Fraction.ZERO) > 0) {
tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.multiply(matter.divide(MATTER_EXCHANGE_RATE, MatteryCapability.ROUND_RULES)), false); tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.times(matter.div(MATTER_EXCHANGE_RATE)), false);
capability.receiveMatterOuter(matter, false); capability.receiveMatterOuter(matter, false);
tile.matter.extractMatterInner(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++) { for (int i = 3; i < 6; i++) {
if (tile.work_slots.getItem(i).isEmpty()) { if (tile.work_slots.getItem(i).isEmpty()) {
tile.work_slots.setItem(work_slot, ItemStack.EMPTY); 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); var energy = tile.energy.extractEnergyInner(ENERGY_CONSUMPTION, true);
if (energy.compareTo(BigDecimal.ZERO) > 0) { if (energy.compareTo(Fraction.ZERO) > 0) {
var matter = capability.extractMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getMissingMatter()).multiply(energy.divide(ENERGY_CONSUMPTION, MatteryCapability.ROUND_RULES)), true); var matter = capability.extractMatterOuter(MATTER_EXCHANGE_RATE.min(tile.matter.getMissingMatter()).times(energy.div(ENERGY_CONSUMPTION)), true);
if (matter.compareTo(BigDecimal.ZERO) > 0) { if (matter.compareTo(Fraction.ZERO) > 0) {
tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.multiply(matter.divide(MATTER_EXCHANGE_RATE, MatteryCapability.ROUND_RULES)), false); tile.energy.extractEnergyInner(ENERGY_CONSUMPTION.times(matter.div(MATTER_EXCHANGE_RATE)), false);
capability.extractMatterOuter(matter, false); capability.extractMatterOuter(matter, false);
tile.matter.receiveMatterInner(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--) { for (int i = 2; i >= 0; i--) {
if (tile.work_slots.getItem(i).isEmpty()) { if (tile.work_slots.getItem(i).isEmpty()) {
tile.work_slots.setItem(work_slot, ItemStack.EMPTY); 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) { if (tile.matter.getStoredMatter().compareTo(Fraction.ZERO) > 0 && tile.grid != null) {
BigDecimal diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true); var diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true);
BigDecimal diff2 = tile.grid.softPushMatter(diff, true); var diff2 = tile.grid.softPushMatter(diff, true);
tile.matter.extractMatterInner(diff2, false); tile.matter.extractMatterInner(diff2, false);
tile.grid.softPushMatter(diff2, false); tile.grid.softPushMatter(diff2, false);

View File

@ -17,6 +17,7 @@ import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import ru.dbotthepony.mc.otm.block.BlockBatteryBank; import ru.dbotthepony.mc.otm.block.BlockBatteryBank;
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell; 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.MatterGrid;
import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
@ -37,8 +38,8 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement
public final IMatterHandler matter = new IMatterHandler() { public final IMatterHandler matter = new IMatterHandler() {
@Nonnull @Nonnull
@Override @Override
public BigDecimal getStoredMatter() { public Fraction getStoredMatter() {
BigDecimal summ = BigDecimal.ZERO; Fraction summ = Fraction.ZERO;
for (int i = 0; i < matter_container.getContainerSize(); i++) { for (int i = 0; i < matter_container.getContainerSize(); i++) {
ItemStack stack = matter_container.getItem(i); ItemStack stack = matter_container.getItem(i);
@ -47,7 +48,7 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement
Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve(); Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve();
if (handler.isPresent()) { 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 @Nonnull
@Override @Override
public BigDecimal getMaxStoredMatter() { public Fraction getMaxStoredMatter() {
BigDecimal summ = BigDecimal.ZERO; Fraction summ = Fraction.ZERO;
for (int i = 0; i < matter_container.getContainerSize(); i++) { for (int i = 0; i < matter_container.getContainerSize(); i++) {
ItemStack stack = matter_container.getItem(i); ItemStack stack = matter_container.getItem(i);
@ -67,7 +68,7 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement
Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve(); Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve();
if (handler.isPresent()) { 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 @Nonnull
@Override @Override
public BigDecimal receiveMatterOuter(BigDecimal howMuch, boolean simulate) { public Fraction receiveMatterOuter(Fraction howMuch, boolean simulate) {
return receiveMatterInner(howMuch, simulate); return receiveMatterInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveMatterInner(BigDecimal howMuch, boolean simulate) { public Fraction receiveMatterInner(Fraction howMuch, boolean simulate) {
BigDecimal summ = BigDecimal.ZERO; Fraction summ = Fraction.ZERO;
for (int i = 0; i < matter_container.getContainerSize(); i++) { for (int i = 0; i < matter_container.getContainerSize(); i++) {
ItemStack stack = matter_container.getItem(i); ItemStack stack = matter_container.getItem(i);
@ -93,11 +94,11 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement
Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve(); Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve();
if (handler.isPresent()) { if (handler.isPresent()) {
BigDecimal diff = handler.get().receiveMatterOuter(howMuch, simulate); var diff = handler.get().receiveMatterOuter(howMuch, simulate);
summ = summ.add(diff); summ = summ.plus(diff);
howMuch = howMuch.subtract(diff); howMuch = howMuch.minus(diff);
if (howMuch.compareTo(BigDecimal.ZERO) == 0) { if (howMuch.compareTo(Fraction.ZERO) == 0) {
break; break;
} }
} }
@ -109,14 +110,14 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractMatterOuter(BigDecimal howMuch, boolean simulate) { public Fraction extractMatterOuter(Fraction howMuch, boolean simulate) {
return extractMatterInner(howMuch, simulate); return extractMatterInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractMatterInner(BigDecimal howMuch, boolean simulate) { public Fraction extractMatterInner(Fraction howMuch, boolean simulate) {
BigDecimal summ = BigDecimal.ZERO; Fraction summ = Fraction.ZERO;
for (int i = 0; i < matter_container.getContainerSize(); i++) { for (int i = 0; i < matter_container.getContainerSize(); i++) {
ItemStack stack = matter_container.getItem(i); ItemStack stack = matter_container.getItem(i);
@ -125,11 +126,11 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement
Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve(); Optional<IMatterHandler> handler = stack.getCapability(MatteryCapability.MATTER).resolve();
if (handler.isPresent()) { if (handler.isPresent()) {
BigDecimal diff = handler.get().extractMatterOuter(howMuch, simulate); var diff = handler.get().extractMatterOuter(howMuch, simulate);
summ = summ.add(diff); summ = summ.plus(diff);
howMuch = howMuch.subtract(diff); howMuch = howMuch.minus(diff);
if (howMuch.compareTo(BigDecimal.ZERO) == 0) { if (howMuch.compareTo(Fraction.ZERO) == 0) {
break; break;
} }
} }

View File

@ -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.capability.matter.MatterHandlerCapability;
import ru.dbotthepony.mc.otm.container.MatteryContainer; import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell; 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.MatterGrid;
import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.matter.MatterRegistry;
import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu; import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu;
@ -41,7 +42,7 @@ import java.math.BigDecimal;
public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implements IMatterGridCell { public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implements IMatterGridCell {
private static final TranslatableComponent MACHINE_NAME = new TranslatableComponent("block.overdrive_that_matters.matter_decomposer"); private static final TranslatableComponent MACHINE_NAME = new TranslatableComponent("block.overdrive_that_matters.matter_decomposer");
private boolean valid = true; 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<IMatterHandler> matter_resolver = LazyOptional.of(() -> matter); private LazyOptional<IMatterHandler> matter_resolver = LazyOptional.of(() -> matter);
// вход, выход // вход, выход
@ -54,7 +55,7 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem
public BlockEntityMatterDecomposer(BlockPos p_155229_, BlockState p_155230_) { public BlockEntityMatterDecomposer(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.MATTER_DECOMPOSER, p_155229_, 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 @Override
@ -130,7 +131,7 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem
@Nonnull @Nonnull
@Override @Override
protected MachineJobStatus onJobFinish(MachineJob job) { protected MachineJobStatus onJobFinish(MachineJob job) {
BigDecimal matter_value = MatterRegistry.getMatterValue(job.stack()); var matter_value = MatterRegistry.getMatterValue(job.stack());
matter.receiveMatterInner(matter_value, false); matter.receiveMatterInner(matter_value, false);
return new MachineJobStatus(); return new MachineJobStatus();
} }
@ -145,11 +146,11 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem
copy.setCount(1); copy.setCount(1);
if (MatterRegistry.canDecompose(copy)) { 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)) { if (!matter_value.equals(BigDecimal.ZERO) && matter.canReceiveAll(matter_value)) {
stack.shrink(1); 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.batteryChargeLoop();
tile.workerLoop(); tile.workerLoop();
if (tile.matter.getStoredMatter().compareTo(BigDecimal.ZERO) > 0 && tile.grid != null) { if (tile.matter.getStoredMatter().compareTo(Fraction.ZERO) > 0 && tile.grid != null) {
BigDecimal diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true); var diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true);
BigDecimal diff2 = tile.grid.softPushMatter(diff, true); var diff2 = tile.grid.softPushMatter(diff, true);
tile.matter.extractMatterInner(diff2, false); tile.matter.extractMatterInner(diff2, false);
tile.grid.softPushMatter(diff2, false); tile.grid.softPushMatter(diff2, false);
@ -212,10 +213,10 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem
this.grid = grid; this.grid = grid;
} }
private static final BigDecimal BASE_CONSUMPTION = new BigDecimal(240); private static final Fraction BASE_CONSUMPTION = new Fraction(240);
@Override @Override
protected BigDecimal getBaseConsumption() { protected Fraction getBaseConsumption() {
return BASE_CONSUMPTION; return BASE_CONSUMPTION;
} }
} }

View File

@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.capability.*;
import ru.dbotthepony.mc.otm.capability.matter.*; import ru.dbotthepony.mc.otm.capability.matter.*;
import ru.dbotthepony.mc.otm.container.MatteryContainer; import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler; 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.MatterGrid;
import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.matter.MatterRegistry;
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu; import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu;
@ -38,10 +39,10 @@ import java.math.BigDecimal;
public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implements IMatterGridCell { public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implements IMatterGridCell {
public BlockEntityMatterReplicator(BlockPos p_155229_, BlockState p_155230_) { public BlockEntityMatterReplicator(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.MATTER_REPLICATOR, p_155229_, 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); 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 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 @Override
protected Component getDefaultDisplayName() { protected Component getDefaultDisplayName() {
@ -68,7 +69,7 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem
@Nonnull @Nonnull
@Override @Override
protected BigDecimal getBaseConsumption() { protected Fraction getBaseConsumption() {
return BASE_CONSUMPTION; 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 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 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 @Override
public void setLevel(Level p_155231_) { public void setLevel(Level p_155231_) {
@ -139,7 +140,7 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem
if (!MatterRegistry.hasMatterValue(stack)) if (!MatterRegistry.hasMatterValue(stack))
return null; 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()); job.data().put("task", allocation.task().serializeNBT());
@ -149,11 +150,11 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem
return job; return job;
} }
private static final BigDecimal DRAIN_MULT = new BigDecimal(200); private static final Fraction DRAIN_MULT = new Fraction(200);
@Override @Override
protected MachineJobStatus onWorkTick(WorkTickContext context) { 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) { 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) { if (drain_per_tick.compareTo(matter.getMaxStoredMatter()) > 0) {
// в тик требуется больше материи, чем её может хранить репликатор // в тик требуется больше материи, чем её может хранить репликатор
BigDecimal to_extract = drain_per_tick.subtract(matter.extractMatterInner(drain_per_tick, true)); var to_extract = drain_per_tick.minus(matter.extractMatterInner(drain_per_tick, true));
BigDecimal drain = grid.extractMatter(to_extract, true); var drain = grid.extractMatter(to_extract, true);
if (drain.compareTo(to_extract) < 0) { if (drain.compareTo(to_extract) < 0) {
// недостаточно материи в сети // недостаточно материи в сети
@ -178,15 +179,15 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem
} else { } else {
// в тик требуется меньше материи, чем её может хранить репликатор // в тик требуется меньше материи, чем её может хранить репликатор
// примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше // примем из сети недостающее количество бака материи, или 200 тиков репликации, что меньше
BigDecimal to_extract = matter.getMissingMatter().min(drain_per_tick.multiply(DRAIN_MULT)); var to_extract = matter.getMissingMatter().min(drain_per_tick.times(DRAIN_MULT));
BigDecimal drain = grid.extractMatter(to_extract, true); var drain = grid.extractMatter(to_extract, true);
if (drain.compareTo(BigDecimal.ZERO) == 0) { if (drain.compareTo(Fraction.ZERO) == 0) {
// в сети нет материи // в сети нет материи
return new MachineJobStatus(false, 200); return new MachineJobStatus(false, 200);
} }
BigDecimal received = matter.receiveMatterOuter(drain, false); var received = matter.receiveMatterOuter(drain, false);
grid.extractMatter(received, false); grid.extractMatter(received, false);
// получили материю, проверяем возможность работы // получили материю, проверяем возможность работы

View File

@ -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.*;
import ru.dbotthepony.mc.otm.capability.matter.*; import ru.dbotthepony.mc.otm.capability.matter.*;
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler; 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.MatterGrid;
import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.matter.MatterRegistry;
import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.Registry;
@ -49,7 +50,7 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implement
public BlockEntityMatterScanner(BlockPos p_155229_, BlockState p_155230_) { public BlockEntityMatterScanner(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.MATTER_SCANNER, p_155229_, 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; private boolean valid = true;
@ -137,11 +138,11 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implement
super.load(nbt); super.load(nbt);
} }
private static final BigDecimal BASE_CONSUMPTION = new BigDecimal("40"); private static final Fraction BASE_CONSUMPTION = new Fraction("40");
@Override @Override
@Nonnull @Nonnull
protected BigDecimal getBaseConsumption() { protected Fraction getBaseConsumption() {
return BASE_CONSUMPTION; return BASE_CONSUMPTION;
} }
@ -220,7 +221,7 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implement
copy.setCount(1); copy.setCount(1);
stack.shrink(1); stack.shrink(1);
input_slot.setChanged(); 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; return null;

View File

@ -15,6 +15,7 @@ import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
import ru.dbotthepony.mc.otm.container.MatteryContainer; import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -35,17 +36,17 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery {
if (energy == null) if (energy == null)
return; return;
if (energy.getMissingPower().compareTo(BigDecimal.ZERO) <= 0) if (energy.getMissingPower().compareTo(Fraction.ZERO) <= 0)
return; return;
var demand = energy.getMissingPower(); var demand = energy.getMissingPower();
if (demand.compareTo(BigDecimal.ZERO) == 0) if (demand.compareTo(Fraction.ZERO) == 0)
return; return;
demand = demand.min(energy.receiveEnergyOuter(demand, true)); 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); final var stack = battery_container.getItem(i);
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
@ -54,13 +55,13 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery {
if (mattery_storage.isPresent()) { if (mattery_storage.isPresent()) {
final var drain = mattery_storage.get().extractEnergyOuter(demand, true); 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); final var receive = energy.receiveEnergyOuter(drain, true);
mattery_storage.get().extractEnergyOuter(receive, false); mattery_storage.get().extractEnergyOuter(receive, false);
energy.receiveEnergyOuter(receive, false); energy.receiveEnergyOuter(receive, false);
demand = demand.subtract(receive, MatteryCapability.ROUND_RULES); demand = demand.minus(receive);
} }
} else { } else {
final var storage = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); final var storage = stack.getCapability(CapabilityEnergy.ENERGY).resolve();
@ -68,13 +69,13 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery {
if (storage.isPresent()) { if (storage.isPresent()) {
final var drain = MatteryCapability.drainFE(storage.get(), demand, true); 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); final var receive = energy.receiveEnergyOuter(drain, true);
MatteryCapability.drainFE(storage.get(), receive, false); MatteryCapability.drainFE(storage.get(), receive, false);
energy.receiveEnergyOuter(receive, false); energy.receiveEnergyOuter(receive, false);
demand = demand.subtract(receive, MatteryCapability.ROUND_RULES); demand = demand.minus(receive);
} }
} }
} }

View File

@ -11,6 +11,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatteryPowered; import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatteryPowered;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -24,9 +25,9 @@ abstract public class BlockEntityMatteryWorker extends BlockEntityMatteryPowered
super(p_155228_, p_155229_, p_155230_); super(p_155228_, p_155229_, p_155230_);
} }
protected abstract BigDecimal getBaseConsumption(); protected abstract Fraction getBaseConsumption();
protected BigDecimal consumptionPerWork() { protected Fraction consumptionPerWork() {
return getBaseConsumption(); return getBaseConsumption();
} }
@ -150,7 +151,7 @@ abstract public class BlockEntityMatteryWorker extends BlockEntityMatteryPowered
return; 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++; idle_ticks_anim++;
if (level != null && idle_ticks_anim > 20 && getBlockState().hasProperty(WorkerState.WORKER_STATE) && getBlockState().getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) { 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; idle_ticks_anim = 0;
if (work_ticks < current_job.ticks_processing_time()) { if (work_ticks < current_job.ticks_processing_time()) {
if (current_job.power_consumption_multiplier().compareTo(BigDecimal.ZERO) != 0) { if (current_job.power_consumption_multiplier().compareTo(Fraction.ZERO) != 0) {
BigDecimal required_power = consumptionPerWork().multiply(current_job.power_consumption_multiplier()); var required_power = consumptionPerWork().times(current_job.power_consumption_multiplier());
BigDecimal extracted_power = energy.extractEnergyInner(required_power, true); var extracted_power = energy.extractEnergyInner(required_power, true);
var work_speed = extracted_power.div(required_power);
BigDecimal work_speed = extracted_power.divide(required_power, MatteryCapability.ROUND_RULES);
MachineJobStatus status = onWorkTick(new WorkTickContext(current_job, required_power, extracted_power, work_speed)); 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++; working_ticks_anim++;
error_ticks_anim = 0; 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()) { if (new_work_ticks > current_job.ticks_processing_time()) {
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 { } else {
work_ticks = new_work_ticks; work_ticks = new_work_ticks;
energy.extractEnergyInner(extracted_power, false); energy.extractEnergyInner(extracted_power, false);
@ -200,7 +200,7 @@ abstract public class BlockEntityMatteryWorker extends BlockEntityMatteryPowered
} }
} }
} else { } 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()) { if (!status.valid()) {
throttle_ticks += status.throttle(); throttle_ticks += status.throttle();

View File

@ -6,6 +6,7 @@ import net.minecraft.nbt.DoubleTag;
import net.minecraft.nbt.StringTag; import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
@ -13,14 +14,14 @@ import java.math.BigDecimal;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @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) { 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()); this(stack, ticks_processing_time, power_consumption_multiplier, new CompoundTag());
} }
public MachineJob(ItemStack stack, double ticks_processing_time) { 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() { public CompoundTag serializeNBT() {
@ -40,11 +41,11 @@ public record MachineJob(ItemStack stack, double ticks_processing_time, BigDecim
return null; return null;
if (nbt instanceof CompoundTag tag) { 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); ItemStack stack = ItemStack.of(stack_tag);
if (!stack.isEmpty()) { 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"));
} }
} }
} }

View File

@ -1,13 +1,14 @@
package ru.dbotthepony.mc.otm.block.entity.worker; package ru.dbotthepony.mc.otm.block.entity.worker;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal; import java.math.BigDecimal;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public record WorkTickContext(MachineJob job, BigDecimal required_power, BigDecimal extracted_power, public record WorkTickContext(MachineJob job, Fraction required_power, Fraction extracted_power,
BigDecimal work_speed) { Fraction work_speed) {
} }

View File

@ -2,8 +2,8 @@ package ru.dbotthepony.mc.otm.capability;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraftforge.energy.IEnergyStorage; import net.minecraftforge.energy.IEnergyStorage;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -12,114 +12,112 @@ import java.math.BigDecimal;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public interface IMatteryEnergyStorage extends IEnergyStorage { public interface IMatteryEnergyStorage extends IEnergyStorage {
// such as cables. This is something that would work only with energy storage // such as cables. This is something that would work only with energy storage
BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate); Fraction extractEnergyOuter(Fraction howMuch, boolean simulate);
// for internal needs, e.g. for work // for internal needs, e.g. for work
// CAN also be used by something that does evil // CAN also be used by something that does evil
// e.g. sucking out energy anomaly should use this // e.g. sucking out energy anomaly should use this
BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate); Fraction extractEnergyInner(Fraction howMuch, boolean simulate);
// energy is received from outside, e.g. cables // 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 // 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) { default Fraction extractEnergyOuter(long howMuch, boolean simulate) {
return extractEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); return extractEnergyOuter(new Fraction(howMuch), simulate);
} }
default BigDecimal extractEnergyOuter(int howMuch, boolean simulate) { default Fraction extractEnergyOuter(int howMuch, boolean simulate) {
return extractEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); return extractEnergyOuter(new Fraction(howMuch), simulate);
} }
default BigDecimal receiveEnergyOuter(long howMuch, boolean simulate) { default Fraction receiveEnergyOuter(long howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); return receiveEnergyOuter(new Fraction(howMuch), simulate);
} }
default BigDecimal receiveEnergyOuter(int howMuch, boolean simulate) { default Fraction receiveEnergyOuter(int howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); return receiveEnergyOuter(new Fraction(howMuch), simulate);
} }
default BigDecimal extractEnergyInner(long howMuch, boolean simulate) { default Fraction extractEnergyInner(long howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); return receiveEnergyOuter(new Fraction(howMuch), simulate);
} }
default BigDecimal extractEnergyInner(int howMuch, boolean simulate) { default Fraction extractEnergyInner(int howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); return receiveEnergyOuter(new Fraction(howMuch), simulate);
} }
default BigDecimal receiveEnergyInner(long howMuch, boolean simulate) { default Fraction receiveEnergyInner(long howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); return receiveEnergyOuter(new Fraction(howMuch), simulate);
} }
default BigDecimal receiveEnergyInner(int howMuch, boolean simulate) { default Fraction receiveEnergyInner(int howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); return receiveEnergyOuter(new Fraction(howMuch), simulate);
} }
BigDecimal getBatteryLevel(); Fraction getBatteryLevel();
BigDecimal getMaxBatteryLevel(); Fraction getMaxBatteryLevel();
default BigDecimal getMissingPower() { default Fraction getMissingPower() {
return getMaxBatteryLevel().subtract(getBatteryLevel(), MatteryCapability.ROUND_RULES); return getMaxBatteryLevel().minus(getBatteryLevel());
} }
@Override @Override
default int receiveEnergy(int maxReceive, boolean simulate) { default int receiveEnergy(int maxReceive, boolean simulate) {
BigDecimal toReceive = new BigDecimal(maxReceive, MatteryCapability.ROUND_RULES); int received = receiveEnergyOuter(maxReceive, true).toInt();
int received = receiveEnergyOuter(toReceive, true).intValue();
if (received == 0) { if (received == 0) {
// Receiving only a fraction // Receiving only a fraction
return 0; return 0;
} }
return receiveEnergyOuter(new BigDecimal(received, MatteryCapability.ROUND_RULES), simulate).intValue(); return receiveEnergyOuter(new Fraction(received), simulate).toInt();
} }
@Override @Override
default int extractEnergy(int maxReceive, boolean simulate) { default int extractEnergy(int maxReceive, boolean simulate) {
BigDecimal toReceive = new BigDecimal(maxReceive, MatteryCapability.ROUND_RULES); int extracted = extractEnergyOuter(maxReceive, true).toInt();
int extracted = extractEnergyOuter(toReceive, true).intValue();
if (extracted == 0) { if (extracted == 0) {
// Extracting only a fraction // Extracting only a fraction
return 0; return 0;
} }
return extractEnergyOuter(new BigDecimal(extracted, MatteryCapability.ROUND_RULES), simulate).intValue(); return extractEnergyOuter(new Fraction(extracted), simulate).toInt();
} }
@Override @Override
default int getEnergyStored() { default int getEnergyStored() {
BigDecimal level = getBatteryLevel(); Fraction level = getBatteryLevel();
if (level.compareTo(MatteryCapability.INT_MAX_VALUE) == -1) { if (level.compareTo(MatteryCapability.INT_MAX_VALUE) < 0) {
return level.intValue(); return level.toInt();
} }
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
}; }
@Override @Override
default int getMaxEnergyStored() { default int getMaxEnergyStored() {
BigDecimal level = getMaxBatteryLevel(); Fraction level = getMaxBatteryLevel();
if (level.compareTo(MatteryCapability.INT_MAX_VALUE) == -1) { if (level.compareTo(MatteryCapability.INT_MAX_VALUE) < 0) {
return level.intValue(); return level.toInt();
} }
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
}; }
@Override @Override
default boolean canExtract() { default boolean canExtract() {
return extractEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0; return extractEnergyOuter(Fraction.ONE, true).compareTo(Fraction.ZERO) > 0;
}; }
@Override @Override
default boolean canReceive() { default boolean canReceive() {
return receiveEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0; return receiveEnergyOuter(Fraction.ONE, true).compareTo(Fraction.ZERO) > 0;
}; };
} }

View File

@ -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.IMatterHandler;
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider; import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider;
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage; import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
import ru.dbotthepony.mc.otm.core.Fraction;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.MathContext; 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 MathContext ROUND_RULES = new MathContext(32, RoundingMode.HALF_DOWN);
public static final BigDecimal INT_MAX_VALUE = new BigDecimal(Integer.MAX_VALUE); public static final Fraction INT_MAX_VALUE = new Fraction(Integer.MAX_VALUE);
public static final BigDecimal INT_MIN_VALUE = new BigDecimal(Integer.MIN_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 Fraction LONG_MAX_VALUE = new Fraction(Long.MAX_VALUE);
public static final BigDecimal LONG_MIN_VALUE = new BigDecimal(Long.MIN_VALUE); public static final Fraction LONG_MIN_VALUE = new Fraction(Long.MIN_VALUE);
public static BigDecimal drainFE(IEnergyStorage capability, BigDecimal howMuch, boolean simulate) { public static Fraction drainFE(IEnergyStorage capability, Fraction howMuch, boolean simulate) {
if (howMuch.compareTo(BigDecimal.ONE) < 0) if (howMuch.compareTo(Fraction.ONE) < 0)
return BigDecimal.ZERO; 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) { public static Fraction floodFE(IEnergyStorage capability, Fraction howMuch, boolean simulate) {
if (howMuch.compareTo(BigDecimal.ONE) < 0) if (howMuch.compareTo(Fraction.ONE) < 0)
return BigDecimal.ZERO; 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));
} }
} }

View File

@ -4,6 +4,7 @@ import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.INBTSerializable;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
@ -18,18 +19,18 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS
CAPACITOR, CAPACITOR,
} }
public static final BigDecimal DEFAULT_MAX_RECEIVE = new BigDecimal(200); public static final Fraction DEFAULT_MAX_RECEIVE = new Fraction(200);
public static final BigDecimal DEFAULT_MAX_EXTRACT = new BigDecimal(200); public static final Fraction DEFAULT_MAX_EXTRACT = new Fraction(200);
public static final BigDecimal DEFAULT_MAX_CAPACITY = new BigDecimal(60000); public static final Fraction DEFAULT_MAX_CAPACITY = new Fraction(60000);
protected BigDecimal energy_stored = BigDecimal.ZERO; protected Fraction energy_stored = Fraction.ZERO;
protected BigDecimal energy_stored_max; protected Fraction energy_stored_max;
protected BigDecimal max_input; protected Fraction max_input;
protected BigDecimal max_output; protected Fraction max_output;
protected final MachineType machine_type; protected final MachineType machine_type;
protected final BlockEntity listener; 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); 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); 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; this.listener = listener;
energy_stored_max = capacity; energy_stored_max = capacity;
max_input = maxReceive; max_input = maxReceive;
@ -47,9 +48,9 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) {
if (machine_type == MachineType.WORKER) { if (machine_type == MachineType.WORKER) {
return BigDecimal.ZERO; return Fraction.ZERO;
} }
return extractEnergyInner(howMuch, simulate); return extractEnergyInner(howMuch, simulate);
@ -57,11 +58,11 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) {
BigDecimal new_energy = energy_stored.subtract(howMuch.min(max_output), MatteryCapability.ROUND_RULES).max(BigDecimal.ZERO); Fraction new_energy = energy_stored.minus(howMuch.min(max_output)).moreThanZero();
BigDecimal diff = energy_stored.subtract(new_energy); 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; energy_stored = new_energy;
listener.setChanged(); listener.setChanged();
} }
@ -71,9 +72,9 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) {
if (machine_type == MachineType.GENERATOR) { if (machine_type == MachineType.GENERATOR) {
return BigDecimal.ZERO; return Fraction.ZERO;
} }
return receiveEnergyInner(howMuch, simulate); return receiveEnergyInner(howMuch, simulate);
@ -81,11 +82,11 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) {
BigDecimal new_energy = energy_stored.add(howMuch.min(max_input), MatteryCapability.ROUND_RULES).min(energy_stored_max); Fraction new_energy = energy_stored.plus(howMuch.min(max_input)).min(energy_stored_max);
BigDecimal diff = new_energy.subtract(energy_stored); 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; energy_stored = new_energy;
listener.setChanged(); listener.setChanged();
} }
@ -95,13 +96,13 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS
@Nonnull @Nonnull
@Override @Override
public BigDecimal getBatteryLevel() { public Fraction getBatteryLevel() {
return energy_stored; return energy_stored;
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal getMaxBatteryLevel() { public Fraction getMaxBatteryLevel() {
return energy_stored_max; return energy_stored_max;
} }
@ -119,25 +120,25 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS
@Nonnull @Nonnull
public CompoundTag serializeNBT() { public CompoundTag serializeNBT() {
CompoundTag tag = new CompoundTag(); CompoundTag tag = new CompoundTag();
tag.putString("energy_stored", energy_stored.toString()); tag.put("energy_stored", energy_stored.serializeNBT());
tag.putString("energy_stored_max", energy_stored_max.toString()); tag.put("energy_stored_max", energy_stored_max.serializeNBT());
tag.putString("max_input", max_input.toString()); tag.put("max_input", max_input.serializeNBT());
tag.putString("max_output", max_output.toString()); tag.put("max_output", max_output.serializeNBT());
return tag; return tag;
} }
@Override @Override
public void deserializeNBT(CompoundTag nbt) { public void deserializeNBT(CompoundTag nbt) {
if (nbt.contains("energy_stored")) 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")) 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")) 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")) if (nbt.contains("max_output"))
max_output = new BigDecimal(nbt.getString("max_output")); max_output = Fraction.deserializeNBT(nbt.get("max_output"));
} }
} }

View File

@ -28,6 +28,7 @@ import ru.dbotthepony.mc.otm.android.AndroidFeature;
import ru.dbotthepony.mc.otm.android.AndroidFeatureType; import ru.dbotthepony.mc.otm.android.AndroidFeatureType;
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; 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.MatteryNetworking;
import ru.dbotthepony.mc.otm.network.android.AndroidBatteryPacket; import ru.dbotthepony.mc.otm.network.android.AndroidBatteryPacket;
import ru.dbotthepony.mc.otm.network.android.AndroidEnergyPacket; import ru.dbotthepony.mc.otm.network.android.AndroidEnergyPacket;
@ -43,12 +44,12 @@ import java.util.*;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class AndroidCapability implements ICapabilityProvider, IAndroidCapability, INBTSerializable<CompoundTag> { public class AndroidCapability implements ICapabilityProvider, IAndroidCapability, INBTSerializable<CompoundTag> {
protected final LivingEntity ent; protected final LivingEntity ent;
protected BigDecimal energy_stored = new BigDecimal(0); protected Fraction energy_stored = Fraction.ZERO;
protected BigDecimal energy_stored_max = new BigDecimal(60_000); protected Fraction energy_stored_max = new Fraction(60_000);
protected ItemStack battery = ItemStack.EMPTY; protected ItemStack battery = ItemStack.EMPTY;
private BigDecimal network_energy = new BigDecimal(-1); private Fraction network_energy = new Fraction(-1);
private BigDecimal network_energy_max = new BigDecimal(-1); private Fraction network_energy_max = new Fraction(-1);
private ItemStack network_battery = ItemStack.EMPTY; private ItemStack network_battery = ItemStack.EMPTY;
protected final Map<AndroidFeatureType<?>, AndroidFeature> features = new HashMap<>(); protected final Map<AndroidFeatureType<?>, AndroidFeature> features = new HashMap<>();
@ -158,8 +159,8 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit
@Override @Override
public void invalidateNetworkState() { public void invalidateNetworkState() {
network_energy = new BigDecimal(-1); network_energy = Fraction.MINUS_ONE;
network_energy_max = new BigDecimal(-1); network_energy_max = Fraction.MINUS_ONE;
network_battery = ItemStack.EMPTY; network_battery = ItemStack.EMPTY;
if (ent instanceof ServerPlayer ply) { if (ent instanceof ServerPlayer ply) {
@ -171,12 +172,12 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit
} }
@Override @Override
public void setEnergy(BigDecimal value) { public void setEnergy(Fraction value) {
energy_stored = value; energy_stored = value;
} }
@Override @Override
public void setMaxEnergy(BigDecimal value) { public void setMaxEnergy(Fraction value) {
energy_stored_max = value; energy_stored_max = value;
} }
@ -232,10 +233,10 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit
@Override @Override
public void deserializeNBT(CompoundTag compound) { public void deserializeNBT(CompoundTag compound) {
if (compound.contains("energy_stored")) 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")) 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")) if (compound.contains("battery"))
battery = ItemStack.of(compound.getCompound("battery")); battery = ItemStack.of(compound.getCompound("battery"));
@ -371,52 +372,52 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit
ent.removeEffect(effect); ent.removeEffect(effect);
if (!battery.isEmpty()) { 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<IMatteryEnergyStorage> get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve(); Optional<IMatteryEnergyStorage> get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve();
if (get_mattery.isPresent()) { 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<IEnergyStorage> get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve(); Optional<IEnergyStorage> get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve();
if (get_energy.isPresent()) { 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 @Nonnull
@Override @Override
public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { public Fraction extractEnergyOuter(Fraction howMuch, boolean simulate) {
return BigDecimal.ZERO; return Fraction.ZERO;
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { public Fraction extractEnergyInner(Fraction howMuch, boolean simulate) {
BigDecimal drained = BigDecimal.ZERO; Fraction drained = Fraction.ZERO;
if (battery != ItemStack.EMPTY) { if (battery != ItemStack.EMPTY) {
Optional<IMatteryEnergyStorage> get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve(); Optional<IMatteryEnergyStorage> get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve();
if (get_mattery.isPresent()) { 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) { if (changed.compareTo(Fraction.ZERO) > 0) {
drained = drained.add(changed, MatteryCapability.ROUND_RULES); drained = drained.plus(changed);
howMuch = howMuch.subtract(changed, MatteryCapability.ROUND_RULES); howMuch = howMuch.minus(changed);
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { if (howMuch.compareTo(Fraction.ZERO) <= 0) {
if (!simulate && ent instanceof ServerPlayer ply) { 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; 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<IEnergyStorage> get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve(); Optional<IEnergyStorage> get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve();
if (get_energy.isPresent()) { 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) { if (changed.compareTo(Fraction.ZERO) > 0) {
drained = drained.add(changed, MatteryCapability.ROUND_RULES); drained = drained.plus(changed);
howMuch = howMuch.subtract(changed, MatteryCapability.ROUND_RULES); howMuch = howMuch.minus(changed);
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { if (howMuch.compareTo(Fraction.ZERO) <= 0) {
if (!simulate && ent instanceof ServerPlayer ply) { 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; 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); Fraction new_energy = energy_stored.minus(howMuch).max(Fraction.ZERO);
drained = drained.add(energy_stored.subtract(new_energy, MatteryCapability.ROUND_RULES)); drained = drained.plus(energy_stored.minus(new_energy));
if (!simulate) { if (!simulate) {
energy_stored = new_energy; energy_stored = new_energy;
if (ent instanceof ServerPlayer ply) { 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 @Nonnull
@Override @Override
public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { public Fraction receiveEnergyOuter(Fraction howMuch, boolean simulate) {
BigDecimal received = BigDecimal.ZERO; Fraction received = Fraction.ZERO;
if (battery != ItemStack.EMPTY) { if (battery != ItemStack.EMPTY) {
Optional<IMatteryEnergyStorage> get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve(); Optional<IMatteryEnergyStorage> get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve();
if (get_mattery.isPresent()) { 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) { if (changed.compareTo(Fraction.ZERO) > 0) {
received = received.add(changed, MatteryCapability.ROUND_RULES); received = received.plus(changed);
howMuch = howMuch.subtract(changed, MatteryCapability.ROUND_RULES); howMuch = howMuch.minus(changed);
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { if (howMuch.compareTo(Fraction.ZERO) <= 0) {
return received; return received;
} }
} }
} }
if (howMuch.compareTo(BigDecimal.ONE) >= 0) { if (howMuch.compareTo(Fraction.ONE) >= 0) {
Optional<IEnergyStorage> get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve(); Optional<IEnergyStorage> get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve();
if (get_energy.isPresent()) { 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) { if (changed.compareTo(Fraction.ZERO) > 0) {
received = received.add(changed, MatteryCapability.ROUND_RULES); received = received.plus(changed);
howMuch = howMuch.subtract(changed, MatteryCapability.ROUND_RULES); howMuch = howMuch.minus(changed);
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { if (howMuch.compareTo(Fraction.ZERO) <= 0) {
return received; 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); Fraction new_energy = energy_stored.plus(howMuch).min(energy_stored_max);
received = received.add(new_energy.subtract(energy_stored, MatteryCapability.ROUND_RULES), MatteryCapability.ROUND_RULES); received = received.plus(new_energy.minus(energy_stored));
if (!simulate) { if (!simulate) {
energy_stored = new_energy; energy_stored = new_energy;
@ -511,7 +512,7 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { public Fraction receiveEnergyInner(Fraction howMuch, boolean simulate) {
return receiveEnergyOuter(howMuch, simulate); return receiveEnergyOuter(howMuch, simulate);
} }
@ -533,18 +534,18 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit
@Override @Override
@Nonnull @Nonnull
public BigDecimal getBatteryLevel() { public Fraction getBatteryLevel() {
if (battery != ItemStack.EMPTY) { if (battery != ItemStack.EMPTY) {
Optional<IMatteryEnergyStorage> get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve(); Optional<IMatteryEnergyStorage> get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve();
if (get_mattery.isPresent()) { if (get_mattery.isPresent()) {
return get_mattery.get().getBatteryLevel().add(energy_stored, MatteryCapability.ROUND_RULES); return get_mattery.get().getBatteryLevel().plus(energy_stored);
} }
Optional<IEnergyStorage> get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve(); Optional<IEnergyStorage> get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve();
if (get_energy.isPresent()) { 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 @Override
@Nonnull @Nonnull
public BigDecimal getMaxBatteryLevel() { public Fraction getMaxBatteryLevel() {
if (battery != ItemStack.EMPTY) { if (battery != ItemStack.EMPTY) {
Optional<IMatteryEnergyStorage> get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve(); Optional<IMatteryEnergyStorage> get_mattery = battery.getCapability(MatteryCapability.ENERGY).resolve();
if (get_mattery.isPresent()) { 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<IEnergyStorage> get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve(); Optional<IEnergyStorage> get_energy = battery.getCapability(CapabilityEnergy.ENERGY).resolve();
if (get_energy.isPresent()) { 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());
} }
} }

View File

@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.android.AndroidResearch; import ru.dbotthepony.mc.otm.android.AndroidResearch;
import ru.dbotthepony.mc.otm.android.AndroidResearchType; import ru.dbotthepony.mc.otm.android.AndroidResearchType;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.network.android.AndroidResearchPacket; import ru.dbotthepony.mc.otm.network.android.AndroidResearchPacket;
import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket; import ru.dbotthepony.mc.otm.network.android.AndroidStatusPacket;
@ -75,8 +76,8 @@ public class AndroidCapabilityPlayer extends AndroidCapability {
is_android = true; is_android = true;
will_become_android = false; will_become_android = false;
energy_stored = new BigDecimal(60_000); energy_stored = new Fraction(60_000);
energy_stored_max = new BigDecimal(60_000); energy_stored_max = new Fraction(60_000);
} }
public void becomeAndroidAndKill() { public void becomeAndroidAndKill() {
@ -96,8 +97,8 @@ public class AndroidCapabilityPlayer extends AndroidCapability {
is_android = false; is_android = false;
energy_stored = new BigDecimal(0); energy_stored = new Fraction(0);
energy_stored_max = new BigDecimal(60_000); energy_stored_max = new Fraction(60_000);
dropBattery(); 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 int sleep_ticks = 0;
public static final int SLEEP_TICKS_LIMIT = 80; public static final int SLEEP_TICKS_LIMIT = 80;
@ -315,13 +316,13 @@ public class AndroidCapabilityPlayer extends AndroidCapability {
var food_level = (float) stats.getFoodLevel(); var food_level = (float) stats.getFoodLevel();
if (stats.getSaturationLevel() < food_level) { if (stats.getSaturationLevel() < food_level) {
BigDecimal extracted = this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT.multiply(new BigDecimal(Float.toString(food_level - stats.getSaturationLevel()))), false); Fraction extracted = this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT.times(food_level - stats.getSaturationLevel()), false);
stats.setSaturation(stats.getSaturationLevel() + extracted.divide(ENERGY_FOR_HUNGER_POINT, MatteryCapability.ROUND_RULES).floatValue()); stats.setSaturation(stats.getSaturationLevel() + extracted.div(ENERGY_FOR_HUNGER_POINT).toFloat());
} }
if (stats.getExhaustionLevel() > 0f) { if (stats.getExhaustionLevel() > 0f) {
BigDecimal extracted = this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT.multiply(new BigDecimal(Float.toString(stats.getExhaustionLevel() / 4f))), false); Fraction extracted = this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT.times(stats.getExhaustionLevel() / 4f), false);
stats.setExhaustion(stats.getExhaustionLevel() - extracted.divide(ENERGY_FOR_HUNGER_POINT, MatteryCapability.ROUND_RULES).floatValue() * 4f); stats.setExhaustion(stats.getExhaustionLevel() - extracted.div(ENERGY_FOR_HUNGER_POINT).toFloat() * 4f);
} }
} }
} }

View File

@ -9,6 +9,7 @@ import net.minecraftforge.event.entity.living.LivingHurtEvent;
import ru.dbotthepony.mc.otm.android.AndroidFeature; import ru.dbotthepony.mc.otm.android.AndroidFeature;
import ru.dbotthepony.mc.otm.android.AndroidFeatureType; import ru.dbotthepony.mc.otm.android.AndroidFeatureType;
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; 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 invalidateNetworkState(); // tell capability that player forgot everything, and everything needs to be re-networked
void setEnergy(BigDecimal value); void setEnergy(Fraction value);
void setMaxEnergy(BigDecimal value); void setMaxEnergy(Fraction value);
} }

View File

@ -4,6 +4,7 @@ import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.storage.*; import ru.dbotthepony.mc.otm.storage.*;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -22,16 +23,16 @@ abstract public class AbstractMatteryDrive<T extends IStorageStack> implements I
protected boolean dirty = false; protected boolean dirty = false;
protected int different_stacks = 0; protected int different_stacks = 0;
protected BigDecimal stored = BigDecimal.ZERO; protected Fraction stored = Fraction.ZERO;
protected int max_different_stacks; 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.capacity = capacity;
this.max_different_stacks = max_different_stacks; this.max_different_stacks = max_different_stacks;
} }
public AbstractMatteryDrive(BigDecimal capacity) { public AbstractMatteryDrive(Fraction capacity) {
this(capacity, 0xFFFF); this(capacity, 0xFFFF);
} }
@ -51,12 +52,12 @@ abstract public class AbstractMatteryDrive<T extends IStorageStack> implements I
} }
@Override @Override
public BigDecimal getStoredCount() { public Fraction getStoredCount() {
return stored; return stored;
} }
@Override @Override
public BigDecimal getCapacity() { public Fraction getCapacity() {
return capacity; return capacity;
} }
@ -64,9 +65,9 @@ abstract public class AbstractMatteryDrive<T extends IStorageStack> implements I
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public T insertStack(T stack, boolean simulate) { 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; return stack;
final var listing = items.computeIfAbsent(stack.partitionKey(), (key) -> new ArrayList<>()); final var listing = items.computeIfAbsent(stack.partitionKey(), (key) -> new ArrayList<>());
@ -75,7 +76,7 @@ abstract public class AbstractMatteryDrive<T extends IStorageStack> implements I
if (state.stack().sameItem(stack)) { if (state.stack().sameItem(stack)) {
if (!simulate) { if (!simulate) {
state.stack().grow(max_insert); state.stack().grow(max_insert);
stored = stored.add(max_insert); stored = stored.plus(max_insert);
for (var listener : listeners2) { for (var listener : listeners2) {
listener.changeObject(state.id(), state.stack().getCount()); listener.changeObject(state.id(), state.stack().getCount());
@ -96,7 +97,7 @@ abstract public class AbstractMatteryDrive<T extends IStorageStack> implements I
if (!simulate) { if (!simulate) {
different_stacks++; different_stacks++;
stored = stored.add(max_insert); stored = stored.plus(max_insert);
final var copy = (T) stack.copy(); final var copy = (T) stack.copy();
copy.setCount(max_insert); copy.setCount(max_insert);
@ -119,18 +120,18 @@ abstract public class AbstractMatteryDrive<T extends IStorageStack> implements I
@Nonnull @Nonnull
@Override @Override
@SuppressWarnings("unchecked") @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); var get = items_by_id.get(id);
if (get == null) if (get == null)
return identity().empty(); return identity().empty();
if (amount.compareTo(BigDecimal.ZERO) <= 0) if (amount.compareTo(Fraction.ZERO) <= 0)
amount = get.stack().getMaxStackSize().orElse(get.stack().getCount()); amount = get.stack().getMaxStackSize().orElse(get.stack().getCount());
amount = amount.min(get.stack().getCount()); amount = amount.min(get.stack().getCount());
if (amount.compareTo(BigDecimal.ZERO) <= 0) if (amount.compareTo(Fraction.ZERO) <= 0)
return identity().empty(); return identity().empty();
final var copy = (T) get.stack().copy(); final var copy = (T) get.stack().copy();
@ -151,10 +152,10 @@ abstract public class AbstractMatteryDrive<T extends IStorageStack> implements I
} }
} }
stored = stored.subtract(amount); stored = stored.minus(amount);
get.stack().shrink(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) { for (var listener : listeners2) {
listener.changeObject(get.id(), get.stack().getCount()); listener.changeObject(get.id(), get.stack().getCount());
} }
@ -200,10 +201,12 @@ abstract public class AbstractMatteryDrive<T extends IStorageStack> implements I
public void deserializeNBT(CompoundTag nbt) { public void deserializeNBT(CompoundTag nbt) {
items.clear(); items.clear();
items_by_id.clear(); items_by_id.clear();
stored = BigDecimal.ZERO; stored = Fraction.ZERO;
different_stacks = 0; 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"); max_different_stacks = nbt.getInt("max_different_stacks");
for (var _entry : nbt.getList("items", Tag.TAG_COMPOUND)) { for (var _entry : nbt.getList("items", Tag.TAG_COMPOUND)) {
@ -211,7 +214,7 @@ abstract public class AbstractMatteryDrive<T extends IStorageStack> implements I
final var stack = deserializeStack(entry); final var stack = deserializeStack(entry);
if (stack != null) { if (stack != null) {
stored = stored.add(stack.getCount()); stored = stored.plus(stack.getCount());
different_stacks++; different_stacks++;
final var id = entry.getLongArray("id"); final var id = entry.getLongArray("id");

View File

@ -4,6 +4,7 @@ import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.storage.*; import ru.dbotthepony.mc.otm.storage.*;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
@ -18,8 +19,8 @@ public interface IMatteryDrive<T extends IStorageStack> extends IStorageComponen
void markDirty(); void markDirty();
void markClean(); void markClean();
BigDecimal getStoredCount(); Fraction getStoredCount();
BigDecimal getCapacity(); Fraction getCapacity();
// not extending INBTSerializable to avoid serializing it as forgecaps // not extending INBTSerializable to avoid serializing it as forgecaps
CompoundTag serializeNBT(); CompoundTag serializeNBT();

View File

@ -7,6 +7,7 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraftforge.registries.RegistryManager; import net.minecraftforge.registries.RegistryManager;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.storage.IStorageTuple; import ru.dbotthepony.mc.otm.storage.IStorageTuple;
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper; import ru.dbotthepony.mc.otm.storage.ItemStackWrapper;
import ru.dbotthepony.mc.otm.storage.StorageObjectRegistry; import ru.dbotthepony.mc.otm.storage.StorageObjectRegistry;
@ -24,11 +25,11 @@ import java.util.Objects;
public class ItemMatteryDrive extends AbstractMatteryDrive<ItemStackWrapper> implements IItemMatteryDrive { public class ItemMatteryDrive extends AbstractMatteryDrive<ItemStackWrapper> implements IItemMatteryDrive {
private static StorageObjectTuple<ItemStackWrapper> identity; private static StorageObjectTuple<ItemStackWrapper> identity;
public ItemMatteryDrive(BigDecimal capacity, int max_different_stacks) { public ItemMatteryDrive(Fraction capacity, int max_different_stacks) {
super(capacity, max_different_stacks); super(capacity, max_different_stacks);
} }
public ItemMatteryDrive(BigDecimal capacity) { public ItemMatteryDrive(Fraction capacity) {
super(capacity); super(capacity);
} }

View File

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

View File

@ -5,6 +5,7 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.matter.MatterRegistry;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -16,17 +17,17 @@ import java.math.BigDecimal;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class MatterHandlerCapability implements IMatterHandler, INBTSerializable<CompoundTag> { public class MatterHandlerCapability implements IMatterHandler, INBTSerializable<CompoundTag> {
protected final Runnable listener; protected final Runnable listener;
protected BigDecimal stored = BigDecimal.ZERO; protected Fraction stored = Fraction.ZERO;
protected MatterDirection direction; protected MatterDirection direction;
protected BigDecimal max_storage; protected Fraction max_storage;
protected BigDecimal max_receive; protected Fraction max_receive;
protected BigDecimal max_extract; protected Fraction max_extract;
public MatterHandlerCapability( public MatterHandlerCapability(
@Nullable Runnable listener, @Nullable Runnable listener,
MatterDirection direction, MatterDirection direction,
BigDecimal max_storage Fraction max_storage
) { ) {
this.listener = listener; this.listener = listener;
this.direction = direction; this.direction = direction;
@ -36,9 +37,9 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable
public MatterHandlerCapability( public MatterHandlerCapability(
@Nullable Runnable listener, @Nullable Runnable listener,
MatterDirection direction, MatterDirection direction,
BigDecimal max_storage, Fraction max_storage,
BigDecimal max_receive, Fraction max_receive,
BigDecimal max_extract Fraction max_extract
) { ) {
this(listener, direction, max_storage); this(listener, direction, max_storage);
@ -62,41 +63,41 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable
@Nonnull @Nonnull
@Override @Override
public BigDecimal getStoredMatter() { public Fraction getStoredMatter() {
return stored; return stored;
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal getMaxStoredMatter() { public Fraction getMaxStoredMatter() {
return max_storage; return max_storage;
} }
public boolean canReceiveAll(BigDecimal value) { public boolean canReceiveAll(Fraction value) {
return max_storage.compareTo(value) >= 0 && stored.add(value).compareTo(max_storage) <= 0; return max_storage.compareTo(value) >= 0 && stored.plus(value).compareTo(max_storage) <= 0;
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveMatterOuter(BigDecimal howMuch, boolean simulate) { public Fraction receiveMatterOuter(Fraction howMuch, boolean simulate) {
if (getDirection() == MatterDirection.EXTRACT) if (getDirection() == MatterDirection.EXTRACT)
return BigDecimal.ZERO; return Fraction.ZERO;
return receiveMatterInner(howMuch, simulate); return receiveMatterInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveMatterInner(BigDecimal howMuch, boolean simulate) { public Fraction receiveMatterInner(Fraction howMuch, boolean simulate) {
BigDecimal new_matter; Fraction new_matter;
if (max_receive == null) { if (max_receive == null) {
new_matter = stored.add(howMuch, MatterRegistry.ROUND_RULES).min(max_storage); new_matter = stored.plus(howMuch).min(max_storage);
} else { } 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) { if (!simulate && new_matter.compareTo(stored) != 0) {
stored = new_matter; stored = new_matter;
@ -111,25 +112,25 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractMatterOuter(BigDecimal howMuch, boolean simulate) { public Fraction extractMatterOuter(Fraction howMuch, boolean simulate) {
if (getDirection() == MatterDirection.RECEIVE) if (getDirection() == MatterDirection.RECEIVE)
return BigDecimal.ZERO; return Fraction.ZERO;
return extractMatterInner(howMuch, simulate); return extractMatterInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractMatterInner(BigDecimal howMuch, boolean simulate) { public Fraction extractMatterInner(Fraction howMuch, boolean simulate) {
BigDecimal new_matter; Fraction new_matter;
if (max_receive == null) { if (max_receive == null) {
new_matter = stored.subtract(howMuch, MatterRegistry.ROUND_RULES).max(BigDecimal.ZERO); new_matter = stored.minus(howMuch).moreThanZero();
} else { } 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) { if (!simulate && new_matter.compareTo(stored) != 0) {
stored = new_matter; stored = new_matter;
@ -166,18 +167,18 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable
@Override @Override
public void deserializeNBT(CompoundTag tag) { public void deserializeNBT(CompoundTag tag) {
if (tag.contains("stored")) if (tag.contains("stored"))
stored = new BigDecimal(tag.getString("stored")); stored = Fraction.deserializeNBT(tag.get("stored"));
if (tag.contains("max_storage")) 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")) if (tag.contains("max_receive"))
max_receive = new BigDecimal(tag.getString("max_receive")); max_receive = Fraction.deserializeNBT(tag.get("max_receive"));
else else
max_receive = null; max_receive = null;
if (tag.contains("max_extract")) if (tag.contains("max_extract"))
max_extract = new BigDecimal(tag.getString("max_extract")); max_extract = Fraction.deserializeNBT(tag.get("max_extract"));
else else
max_extract = null; max_extract = null;
} }

View File

@ -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.AndroidCapabilityPlayer;
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability; import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Optional; import java.util.Optional;
@ -162,10 +163,10 @@ public class AndroidGui {
float level; float level;
if (android.getMaxBatteryLevel().compareTo(BigDecimal.ZERO) == 0) { if (android.getMaxBatteryLevel().compareTo(Fraction.ZERO) == 0) {
level = 0f; level = 0f;
} else { } else {
level = android.getBatteryLevel().divide(android.getMaxBatteryLevel(), MatteryCapability.ROUND_RULES).floatValue(); level = android.getBatteryLevel().div(android.getMaxBatteryLevel()).toFloat();
if (level >= 0.98f) if (level >= 0.98f)
level = 1f; level = 1f;

View File

@ -27,7 +27,7 @@ public class EnergyCounterScreen extends MatteryScreen<EnergyCounterMenu> {
public void tick() { public void tick() {
super.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<EnergyCounterMenu> {
public void tick() { public void tick() {
super.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<EnergyCounterMenu> {
public void tick() { public void tick() {
super.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())));
} }
}; };

View File

@ -7,59 +7,44 @@ import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.item.*; import net.minecraft.world.item.*;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.fml.loading.FMLEnvironment;
import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.menu.FormattingHelper; import ru.dbotthepony.mc.otm.menu.FormattingHelper;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Objects;
public class ItemBattery extends Item { public class ItemBattery extends Item {
public class BatteryMatteryCapability implements IMatteryEnergyStorage, ICapabilityProvider { public class BatteryMatteryCapability implements IMatteryEnergyStorage, ICapabilityProvider {
private final BigDecimal storage; private final Fraction storage;
private final BigDecimal max_input; private final Fraction max_input;
private final BigDecimal max_output; private final Fraction max_output;
private final boolean is_creative; private final boolean is_creative;
private BigDecimal energy;
private String _energy;
private final ItemStack stack; private final ItemStack stack;
private BigDecimal energy() { private Fraction energy() {
CompoundTag tag = stack.getOrCreateTag(); CompoundTag tag = stack.getOrCreateTag();
if (tag.contains("otm_energy")) { if (tag.contains("otm_energy")) {
String get_energy = tag.getString("otm_energy"); return Fraction.deserializeNBT(tag.get("otm_energy"));
if (Objects.equals(_energy, get_energy)) {
return energy;
}
energy = new BigDecimal(tag.getString("otm_energy"));
_energy = get_energy;
return energy;
} }
return BigDecimal.ZERO; return Fraction.ZERO;
} }
private void energy(BigDecimal value) { private void energy(Fraction value) {
energy = value; stack.getOrCreateTag().put("otm_energy", value.serializeNBT());
stack.getOrCreateTag().putString("otm_energy", value.toString());
} }
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; this.stack = stack;
is_creative = false; is_creative = false;
this.storage = storage; this.storage = storage;
@ -77,18 +62,18 @@ public class ItemBattery extends Item {
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { public Fraction extractEnergyOuter(@Nonnull Fraction howMuch, boolean simulate) {
return extractEnergyInner(howMuch, simulate); return extractEnergyInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { public Fraction extractEnergyInner(@Nonnull Fraction howMuch, boolean simulate) {
if (is_creative) if (is_creative)
return howMuch; return howMuch;
BigDecimal new_energy = energy().subtract(howMuch.min(max_output), MatteryCapability.ROUND_RULES).max(BigDecimal.ZERO); Fraction new_energy = energy().minus(howMuch.min(max_output)).moreThanZero();
BigDecimal diff = energy().subtract(new_energy); Fraction diff = energy().minus(new_energy);
if (!simulate) { if (!simulate) {
energy(new_energy); energy(new_energy);
@ -99,18 +84,18 @@ public class ItemBattery extends Item {
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { public Fraction receiveEnergyOuter(@Nonnull Fraction howMuch, boolean simulate) {
return receiveEnergyInner(howMuch, simulate); return receiveEnergyInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { public Fraction receiveEnergyInner(@Nonnull Fraction howMuch, boolean simulate) {
if (is_creative) if (is_creative)
return howMuch; return howMuch;
BigDecimal new_energy = energy().add(howMuch.min(max_input), MatteryCapability.ROUND_RULES).min(storage); Fraction new_energy = energy().plus(howMuch.min(max_input)).min(storage);
BigDecimal diff = new_energy.subtract(energy()); Fraction diff = new_energy.minus(energy());
if (!simulate) { if (!simulate) {
energy(new_energy); energy(new_energy);
@ -119,8 +104,9 @@ public class ItemBattery extends Item {
return diff; return diff;
} }
@Nonnull
@Override @Override
public BigDecimal getMissingPower() { public Fraction getMissingPower() {
if (is_creative) if (is_creative)
return MatteryCapability.LONG_MAX_VALUE; return MatteryCapability.LONG_MAX_VALUE;
@ -129,7 +115,7 @@ public class ItemBattery extends Item {
@Nonnull @Nonnull
@Override @Override
public BigDecimal getBatteryLevel() { public Fraction getBatteryLevel() {
if (is_creative) if (is_creative)
return MatteryCapability.LONG_MAX_VALUE; return MatteryCapability.LONG_MAX_VALUE;
@ -138,7 +124,7 @@ public class ItemBattery extends Item {
@Nonnull @Nonnull
@Override @Override
public BigDecimal getMaxBatteryLevel() { public Fraction getMaxBatteryLevel() {
if (is_creative) if (is_creative)
return MatteryCapability.LONG_MAX_VALUE; return MatteryCapability.LONG_MAX_VALUE;
@ -169,14 +155,14 @@ public class ItemBattery extends Item {
private final boolean is_creative; private final boolean is_creative;
public final BigDecimal storage; public final Fraction storage;
public final BigDecimal receive; public final Fraction receive;
public final BigDecimal extract; public final Fraction extract;
private final Component THROUGHPUT; private final Component THROUGHPUT;
private static final Component INFINITE_STORAGE = new TranslatableComponent("otm.item.power.infinite.storage").withStyle(ChatFormatting.GRAY); 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)); super(new Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB));
is_creative = false; is_creative = false;
this.storage = storage; this.storage = storage;

View File

@ -1,6 +1,7 @@
package ru.dbotthepony.mc.otm.item; package ru.dbotthepony.mc.otm.item;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component; 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.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.menu.FormattingHelper; import ru.dbotthepony.mc.otm.menu.FormattingHelper;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class ItemMatterCapacitor extends Item { public class ItemMatterCapacitor extends Item {
public static class ItemMatterCapacitorCapability implements ICapabilityProvider, IMatterHandler { public static class ItemMatterCapacitorCapability implements ICapabilityProvider, IMatterHandler {
private final LazyOptional<IMatterHandler> resolver = LazyOptional.of(() -> this); private final LazyOptional<IMatterHandler> resolver = LazyOptional.of(() -> this);
@ -33,40 +38,31 @@ public class ItemMatterCapacitor extends Item {
return LazyOptional.empty(); return LazyOptional.empty();
} }
private final BigDecimal storage;
private final BigDecimal max_input; private final Fraction storage;
private final BigDecimal max_output; private final Fraction max_input;
private final Fraction max_output;
private final boolean is_creative; private final boolean is_creative;
private BigDecimal energy; private Fraction energy;
private String _energy; private String _energy;
private final ItemStack stack; private final ItemStack stack;
private BigDecimal matter() { private Fraction matter() {
CompoundTag tag = stack.getOrCreateTag(); CompoundTag tag = stack.getOrCreateTag();
if (tag.contains("otm_matter")) { if (tag.contains("otm_matter")) {
String get_energy = tag.getString("otm_matter"); return Fraction.deserializeNBT(tag.get("otm_matter"));
if (Objects.equals(_energy, get_energy)) {
return energy;
}
energy = new BigDecimal(tag.getString("otm_matter"));
_energy = get_energy;
return energy;
} }
return BigDecimal.ZERO; return Fraction.ZERO;
} }
private void matter(BigDecimal value) { private void matter(Fraction value) {
energy = value; stack.getOrCreateTag().put("otm_matter", value.serializeNBT());
stack.getOrCreateTag().putString("otm_matter", value.toString());
} }
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; this.stack = stack;
is_creative = false; is_creative = false;
this.storage = storage; this.storage = storage;
@ -82,7 +78,7 @@ public class ItemMatterCapacitor extends Item {
max_output = MatteryCapability.LONG_MAX_VALUE; max_output = MatteryCapability.LONG_MAX_VALUE;
} }
public ItemMatterCapacitorCapability(ItemStack stack, BigDecimal storage) { public ItemMatterCapacitorCapability(ItemStack stack, Fraction storage) {
this.stack = stack; this.stack = stack;
is_creative = false; is_creative = false;
this.storage = storage; this.storage = storage;
@ -92,7 +88,7 @@ public class ItemMatterCapacitor extends Item {
@Nonnull @Nonnull
@Override @Override
public BigDecimal getStoredMatter() { public Fraction getStoredMatter() {
if (is_creative) if (is_creative)
return MatteryCapability.LONG_MAX_VALUE; return MatteryCapability.LONG_MAX_VALUE;
@ -101,7 +97,7 @@ public class ItemMatterCapacitor extends Item {
@Nonnull @Nonnull
@Override @Override
public BigDecimal getMaxStoredMatter() { public Fraction getMaxStoredMatter() {
if (is_creative) if (is_creative)
return MatteryCapability.LONG_MAX_VALUE; return MatteryCapability.LONG_MAX_VALUE;
@ -110,7 +106,7 @@ public class ItemMatterCapacitor extends Item {
@Nonnull @Nonnull
@Override @Override
public BigDecimal getMissingMatter() { public Fraction getMissingMatter() {
if (is_creative) if (is_creative)
return MatteryCapability.LONG_MAX_VALUE; return MatteryCapability.LONG_MAX_VALUE;
@ -119,18 +115,18 @@ public class ItemMatterCapacitor extends Item {
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveMatterOuter(BigDecimal howMuch, boolean simulate) { public Fraction receiveMatterOuter(Fraction howMuch, boolean simulate) {
return receiveMatterInner(howMuch, simulate); return receiveMatterInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal receiveMatterInner(BigDecimal howMuch, boolean simulate) { public Fraction receiveMatterInner(Fraction howMuch, boolean simulate) {
if (is_creative) if (is_creative)
return howMuch; return howMuch;
BigDecimal new_matter = matter().add(howMuch.min(max_input), MatteryCapability.ROUND_RULES).min(storage); Fraction new_matter = matter().plus(howMuch.min(max_input)).min(storage);
BigDecimal diff = new_matter.subtract(matter()); Fraction diff = new_matter.minus(matter());
if (!simulate) { if (!simulate) {
matter(new_matter); matter(new_matter);
@ -141,19 +137,19 @@ public class ItemMatterCapacitor extends Item {
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractMatterOuter(BigDecimal howMuch, boolean simulate) { public Fraction extractMatterOuter(Fraction howMuch, boolean simulate) {
return extractMatterInner(howMuch, simulate); return extractMatterInner(howMuch, simulate);
} }
@Nonnull @Nonnull
@Override @Override
public BigDecimal extractMatterInner(BigDecimal howMuch, boolean simulate) { public Fraction extractMatterInner(Fraction howMuch, boolean simulate) {
if (is_creative) if (is_creative)
return howMuch; return howMuch;
BigDecimal new_matter = matter().subtract(howMuch.min(max_output), MatteryCapability.ROUND_RULES).max(BigDecimal.ZERO); Fraction new_matter = matter().minus(howMuch.min(max_output)).moreThanZero();
BigDecimal diff = matter().subtract(new_matter); Fraction diff = matter().minus(new_matter);
if (!simulate) { if (!simulate) {
matter(new_matter); 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 static final Component INFINITE_STORAGE = new TranslatableComponent("otm.item.matter.infinite").withStyle(ChatFormatting.GRAY);
private final boolean is_creative; private final boolean is_creative;
public ItemMatterCapacitor(BigDecimal storage) { public ItemMatterCapacitor(Fraction storage) {
super(new Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)); super(new Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB));
is_creative = false; is_creative = false;
this.storage = storage; this.storage = storage;

View File

@ -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.DrivePool;
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive; import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
import ru.dbotthepony.mc.otm.capability.drive.ItemMatteryDrive; import ru.dbotthepony.mc.otm.capability.drive.ItemMatteryDrive;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -32,11 +33,11 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
public class ItemPortableCondensationDrive extends Item { public class ItemPortableCondensationDrive extends Item {
public final BigDecimal capacity; public final Fraction capacity;
public ItemPortableCondensationDrive(int capacity) { public ItemPortableCondensationDrive(int capacity) {
super(new Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB)); super(new Properties().stacksTo(1).tab(OverdriveThatMatters.CREATIVE_TAB));
this.capacity = new BigDecimal(capacity); this.capacity = new Fraction(capacity);
} }
@SubscribeEvent @SubscribeEvent

View File

@ -10,6 +10,7 @@ import ru.dbotthepony.mc.otm.AbstractGrid;
import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.matter.*; import ru.dbotthepony.mc.otm.capability.matter.*;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
@ -31,81 +32,81 @@ public class MatterGrid extends AbstractGrid<IMatterGridCell> implements IMatter
super(MatteryCapability.MATTER_CELL); super(MatteryCapability.MATTER_CELL);
} }
public BigDecimal getCapacity() { public Fraction getCapacity() {
BigDecimal summ = BigDecimal.ZERO; Fraction summ = Fraction.ZERO;
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IMatterHandler handler = cell.getMatterHandler(); IMatterHandler handler = cell.getMatterHandler();
if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) { if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
summ = summ.add(handler.getMaxStoredMatter()); summ = summ.plus(handler.getMaxStoredMatter());
} }
} }
return summ; return summ;
} }
public BigDecimal getPotentialCapacity() { public Fraction getPotentialCapacity() {
BigDecimal summ = BigDecimal.ZERO; Fraction summ = Fraction.ZERO;
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IMatterHandler handler = cell.getMatterHandler(); IMatterHandler handler = cell.getMatterHandler();
if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) { if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) {
summ = summ.add(handler.getMaxStoredMatter()); summ = summ.plus(handler.getMaxStoredMatter());
} }
} }
return summ; return summ;
} }
public BigDecimal getStored() { public Fraction getStored() {
BigDecimal summ = BigDecimal.ZERO; Fraction summ = Fraction.ZERO;
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IMatterHandler handler = cell.getMatterHandler(); IMatterHandler handler = cell.getMatterHandler();
if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) { if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) {
summ = summ.add(handler.getStoredMatter()); summ = summ.plus(handler.getStoredMatter());
} }
} }
return summ; return summ;
} }
public BigDecimal getPotentialStored() { public Fraction getPotentialStored() {
BigDecimal summ = BigDecimal.ZERO; Fraction summ = Fraction.ZERO;
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IMatterHandler handler = cell.getMatterHandler(); IMatterHandler handler = cell.getMatterHandler();
if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) { if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) {
summ = summ.add(handler.getStoredMatter()); summ = summ.plus(handler.getStoredMatter());
} }
} }
return summ; return summ;
} }
public BigDecimal extractMatter(BigDecimal howMuch, boolean simulate) { public Fraction extractMatter(Fraction howMuch, boolean simulate) {
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) if (howMuch.compareTo(Fraction.ZERO) <= 0)
return BigDecimal.ZERO; return Fraction.ZERO;
validate(); validate();
BigDecimal extracted = BigDecimal.ZERO; Fraction extracted = Fraction.ZERO;
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IMatterHandler handler = cell.getMatterHandler(); IMatterHandler handler = cell.getMatterHandler();
if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.RECEIVE) { 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)) { if (!drain.equalsCompact(Fraction.ZERO)) {
extracted = extracted.add(drain); extracted = extracted.plus(drain);
howMuch = howMuch.subtract(drain); howMuch = howMuch.minus(drain);
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { if (howMuch.compareTo(Fraction.ZERO) <= 0) {
break; break;
} }
} }
@ -115,25 +116,25 @@ public class MatterGrid extends AbstractGrid<IMatterGridCell> implements IMatter
return extracted; return extracted;
} }
public BigDecimal softPushMatter(BigDecimal howMuch, boolean simulate) { public Fraction softPushMatter(Fraction howMuch, boolean simulate) {
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) if (howMuch.compareTo(Fraction.ZERO) <= 0)
return BigDecimal.ZERO; return Fraction.ZERO;
validate(); validate();
BigDecimal received = BigDecimal.ZERO; Fraction received = Fraction.ZERO;
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IMatterHandler handler = cell.getMatterHandler(); IMatterHandler handler = cell.getMatterHandler();
if (handler != null && handler.getDirection() == IMatterHandler.MatterDirection.BIDIRECTIONAL) { 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)) { if (!receive.equalsCompact(Fraction.ZERO)) {
received = received.add(receive); received = received.plus(receive);
howMuch = howMuch.subtract(receive); howMuch = howMuch.minus(receive);
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { if (howMuch.compareTo(Fraction.ZERO) <= 0) {
break; break;
} }
} }
@ -143,25 +144,25 @@ public class MatterGrid extends AbstractGrid<IMatterGridCell> implements IMatter
return received; return received;
} }
public BigDecimal pushMatter(BigDecimal howMuch, boolean simulate) { public Fraction pushMatter(Fraction howMuch, boolean simulate) {
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) if (howMuch.compareTo(Fraction.ZERO) <= 0)
return BigDecimal.ZERO; return Fraction.ZERO;
validate(); validate();
BigDecimal received = BigDecimal.ZERO; Fraction received = Fraction.ZERO;
for (IMatterGridCell cell : cells) { for (IMatterGridCell cell : cells) {
IMatterHandler handler = cell.getMatterHandler(); IMatterHandler handler = cell.getMatterHandler();
if (handler != null && handler.getDirection() != IMatterHandler.MatterDirection.EXTRACT) { 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)) { if (!receive.equalsCompact(Fraction.ZERO)) {
received = received.add(receive); received = received.plus(receive);
howMuch = howMuch.subtract(receive); howMuch = howMuch.minus(receive);
if (howMuch.compareTo(BigDecimal.ZERO) <= 0) { if (howMuch.compareTo(Fraction.ZERO) <= 0) {
break; break;
} }
} }

View File

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

View File

@ -136,7 +136,7 @@ public class DriveViewerMenu extends PoweredMatteryMenu implements INetworkedIte
if (amount == item.getCount()) { if (amount == item.getCount()) {
var remaining = last_drive.insertStack(new ItemStackWrapper(item), false); var remaining = last_drive.insertStack(new ItemStackWrapper(item), false);
if (remaining.getCount().intValue() == item.getCount()) if (remaining.getCount().toInt() == item.getCount())
return ItemStack.EMPTY; return ItemStack.EMPTY;
if (remaining.isEmpty()) { if (remaining.isEmpty()) {
@ -147,8 +147,8 @@ public class DriveViewerMenu extends PoweredMatteryMenu implements INetworkedIte
} }
var copy = item.copy(); var copy = item.copy();
tile.getIOItemCount(item.getCount() - remaining.getCount().intValue(), false); tile.getIOItemCount(item.getCount() - remaining.getCount().toInt(), false);
item.shrink(remaining.getCount().intValue()); item.shrink(remaining.getCount().toInt());
slot.setChanged(); slot.setChanged();
return copy; return copy;
@ -159,12 +159,12 @@ public class DriveViewerMenu extends PoweredMatteryMenu implements INetworkedIte
var remaining = last_drive.insertStack(new ItemStackWrapper(copy_insert), false); 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; return ItemStack.EMPTY;
var copy = item.copy(); var copy = item.copy();
tile.getIOItemCount(amount - remaining.getCount().intValue(), false); tile.getIOItemCount(amount - remaining.getCount().toInt(), false);
item.shrink(amount - remaining.getCount().intValue()); item.shrink(amount - remaining.getCount().toInt());
slot.setChanged(); slot.setChanged();
return copy; return copy;

View File

@ -6,13 +6,14 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter; import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter;
import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer; import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer;
import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class EnergyCounterMenu extends MatteryMenu { public class EnergyCounterMenu extends MatteryMenu {
public final BigDecimalDataContainer passed = new BigDecimalDataContainer(); public final FractionDataContainer passed = new FractionDataContainer();
public final BigDecimalDataContainer average = new BigDecimalDataContainer(); public final FractionDataContainer average = new FractionDataContainer();
public final BigDecimalDataContainer last_20_ticks = new BigDecimalDataContainer(); public final FractionDataContainer last_20_ticks = new FractionDataContainer();
// TODO: Graph and proper networking for it // TODO: Graph and proper networking for it
private int ticks_passed = 0; private int ticks_passed = 0;
@ -33,11 +34,11 @@ public class EnergyCounterMenu extends MatteryMenu {
if (tile != null) { if (tile != null) {
BlockEntityEnergyCounter tile = (BlockEntityEnergyCounter) this.tile; BlockEntityEnergyCounter tile = (BlockEntityEnergyCounter) this.tile;
passed.setDecimal(tile.getPassed()); passed.setValue(tile.getPassed());
average.setDecimal(tile.calcAverage(20)); average.setValue(tile.calcAverage(20));
if (ticks_passed == 0) { if (ticks_passed == 0) {
last_20_ticks.setDecimal(tile.sumHistory(20)); last_20_ticks.setValue(tile.sumHistory(20));
} }
ticks_passed = (ticks_passed + 1) % 20; ticks_passed = (ticks_passed + 1) % 20;

View File

@ -5,6 +5,7 @@ import net.minecraft.network.chat.FormattedText;
import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.chat.TranslatableComponent;
import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.core.Fraction;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
@ -33,6 +34,17 @@ public class FormattingHelper {
new BigDecimal("1000000000000000000000000"), // "otm.suffix.yotta": "Y%s", 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[] { public static final String[] SUFFIX_COMPONENTS_BELOW_ONE = new String[] {
"otm.suffix.deci", "otm.suffix.deci",
"otm.suffix.centi", "otm.suffix.centi",
@ -59,6 +71,19 @@ public class FormattingHelper {
new BigDecimal("0.000000000000000000000001"), // "otm.suffix.yocto": "y%s", 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) { public static String formatDecimal(BigDecimal value, int decimals) {
return value.setScale(decimals, RoundingMode.HALF_UP).toString(); 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)); 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) { public static Component formatMatterLevel(BigDecimal power, BigDecimal max_power) {
return new TranslatableComponent("otm.gui.level", formatMatterValuePlain(power), formatMatterValuePlain(max_power)); return new TranslatableComponent("otm.gui.level", formatMatterValuePlain(power), formatMatterValuePlain(max_power));
} }
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) { public static TranslatableComponent formatMatterValue(BigDecimal matter) {
return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME)); return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME));
} }
public static TranslatableComponent formatMatterValue(Fraction matter) {
return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME));
}
public static Component formatMatterValuePlain(BigDecimal matter) { public static Component formatMatterValuePlain(BigDecimal matter) {
return formatSI(matter, MATTER_NAME); return formatSI(matter, MATTER_NAME);
} }
public static Component formatMatterValuePlain(Fraction matter) {
return formatSI(matter, MATTER_NAME);
}
public static Component formatPower(BigDecimal power) { public static Component formatPower(BigDecimal power) {
return formatSI(power, POWER_NAME); return formatSI(power, POWER_NAME);
} }
public static Component formatPower(Fraction power) {
return formatSI(power, POWER_NAME);
}
public static Component formatSI(BigDecimal value) { public static Component formatSI(BigDecimal value) {
return formatSI(value, ""); return formatSI(value, "");
} }
public static Component formatSI(Fraction value) {
return formatSI(value, "");
}
public static Component formatSI(BigDecimal value, Object end_suffix) { public static Component formatSI(BigDecimal value, Object end_suffix) {
if (value.compareTo(BigDecimal.ZERO) == 0) { if (value.compareTo(BigDecimal.ZERO) == 0) {
if ("".equals(end_suffix)) { if ("".equals(end_suffix)) {
@ -133,4 +182,48 @@ public class FormattingHelper {
return new TranslatableComponent("otm.suffix.merge", formatDecimal(value, 2), end_suffix); 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);
}
}
} }

View File

@ -6,6 +6,7 @@ import net.minecraft.world.entity.player.Inventory;
import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCapacitorBank; import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCapacitorBank;
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; 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.slot.MatterContainerInputSlot;
import ru.dbotthepony.mc.otm.menu.widget.MatterLevelWidget; import ru.dbotthepony.mc.otm.menu.widget.MatterLevelWidget;
@ -34,13 +35,13 @@ public class MatterCapacitorBankMenu extends MatteryMenu {
return tile.getMatterGrid().getStored(); return tile.getMatterGrid().getStored();
} }
return BigDecimal.ZERO; return Fraction.ZERO;
}, () -> { }, () -> {
if (tile.getMatterGrid() != null) { if (tile.getMatterGrid() != null) {
return tile.getMatterGrid().getCapacity(); return tile.getMatterGrid().getCapacity();
} }
return BigDecimal.ZERO; return Fraction.ZERO;
}); });
} }

View File

@ -8,6 +8,7 @@ import net.minecraft.world.inventory.ClickAction;
import net.minecraft.world.inventory.ClickType; import net.minecraft.world.inventory.ClickType;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.menu.MatteryMenu; import ru.dbotthepony.mc.otm.menu.MatteryMenu;
import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.network.MatteryNetworking;
import ru.dbotthepony.mc.otm.network.SetCarriedPacket; import ru.dbotthepony.mc.otm.network.SetCarriedPacket;
@ -99,8 +100,8 @@ public class NetworkedItemView implements IStorageListener<ItemStackWrapper> {
} }
@Override @Override
public void changeObject(UUID id, BigDecimal new_count) { public void changeObject(UUID id, Fraction new_count) {
changeObject(id, new_count.intValue()); changeObject(id, new_count.toInt());
} }
@Override @Override
@ -217,13 +218,13 @@ public class NetworkedItemView implements IStorageListener<ItemStackWrapper> {
} }
int amount = calculateIOAmount(action == ClickAction.PRIMARY ? get_state.stack().getMaxStackSize() : Math.max(1, get_state.stack().getMaxStackSize() / 2)); 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()) { if (!extracted.isEmpty()) {
var move = menu.quickMoveToInventory(extracted.stack(), false); var move = menu.quickMoveToInventory(extracted.stack(), false);
if (move.remaining().getCount() != extracted.stack().getCount()) { 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()); doneIOAmount(extracted.stack().getCount() - move.remaining().getCount());
} }
} }
@ -277,7 +278,7 @@ public class NetworkedItemView implements IStorageListener<ItemStackWrapper> {
int amount = calculateIOAmount(action == ClickAction.PRIMARY ? get_state.stack().getMaxStackSize() : Math.max(1, get_state.stack().getMaxStackSize() / 2)); 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()); doneIOAmount(extracted.getCountInt());
menu.setCarried(extracted.stack()); menu.setCarried(extracted.stack());

View File

@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.menu.widget;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.chat.TranslatableComponent;
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.menu.FormattingHelper; import ru.dbotthepony.mc.otm.menu.FormattingHelper;
import ru.dbotthepony.mc.otm.menu.MatteryMenu; import ru.dbotthepony.mc.otm.menu.MatteryMenu;
@ -20,7 +21,7 @@ public class BatteryLevelWidget extends StorageGaugeWidget {
super(menu, x, y); super(menu, x, y);
} }
public BatteryLevelWidget(MatteryMenu menu, int x, int y, Supplier<BigDecimal> value_supplier, Supplier<BigDecimal> max_value_supplier) { public BatteryLevelWidget(MatteryMenu menu, int x, int y, Supplier<Fraction> value_supplier, Supplier<Fraction> max_value_supplier) {
super(menu, x, y, value_supplier, max_value_supplier); super(menu, x, y, value_supplier, max_value_supplier);
} }
@ -49,7 +50,7 @@ public class BatteryLevelWidget extends StorageGaugeWidget {
public List<Component> getTooltip() { public List<Component> getTooltip() {
return List.of( return List.of(
new TranslatableComponent("otm.gui.power.percentage_level", String.format("%.2f", getLevel() * 100d)), 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())
); );
} }
} }

View File

@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.menu.widget;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.chat.TranslatableComponent;
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; 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.FormattingHelper;
import ru.dbotthepony.mc.otm.menu.MatteryMenu; import ru.dbotthepony.mc.otm.menu.MatteryMenu;
@ -28,7 +29,7 @@ public class MatterLevelWidget extends StorageGaugeWidget {
this(menu, 0, 0, capability); this(menu, 0, 0, capability);
} }
public MatterLevelWidget(MatteryMenu menu, int x, int y, Supplier<BigDecimal> value_supplier, Supplier<BigDecimal> max_value_supplier) { public MatterLevelWidget(MatteryMenu menu, int x, int y, Supplier<Fraction> value_supplier, Supplier<Fraction> max_value_supplier) {
super(menu, x, y, value_supplier, max_value_supplier); super(menu, x, y, value_supplier, max_value_supplier);
} }
@ -57,7 +58,7 @@ public class MatterLevelWidget extends StorageGaugeWidget {
public List<Component> getTooltip() { public List<Component> getTooltip() {
return List.of( return List.of(
new TranslatableComponent("otm.gui.matter.percentage_level", String.format("%.2f", getLevel() * 100d)), 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())
); );
} }
} }

View File

@ -1,18 +1,20 @@
package ru.dbotthepony.mc.otm.menu.widget; package ru.dbotthepony.mc.otm.menu.widget;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.menu.MatteryMenu; import ru.dbotthepony.mc.otm.menu.MatteryMenu;
import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer; import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer;
import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.function.Supplier; import java.util.function.Supplier;
abstract public class StorageGaugeWidget extends GaugeWidget { abstract public class StorageGaugeWidget extends GaugeWidget {
protected Supplier<BigDecimal> value_supplier; protected Supplier<Fraction> value_supplier;
protected Supplier<BigDecimal> max_value_supplier; protected Supplier<Fraction> max_value_supplier;
protected final BigDecimalDataContainer value_container = new BigDecimalDataContainer(); protected final FractionDataContainer value_container = new FractionDataContainer();
protected final BigDecimalDataContainer max_value_container = new BigDecimalDataContainer(); protected final FractionDataContainer max_value_container = new FractionDataContainer();
public StorageGaugeWidget(MatteryMenu menu, int x, int y) { public StorageGaugeWidget(MatteryMenu menu, int x, int y) {
this(menu, x, y, null, null); this(menu, x, y, null, null);
@ -22,7 +24,7 @@ abstract public class StorageGaugeWidget extends GaugeWidget {
this(menu, 0, 0, null, null); this(menu, 0, 0, null, null);
} }
public StorageGaugeWidget(MatteryMenu menu, int x, int y, Supplier<BigDecimal> value_supplier, Supplier<BigDecimal> max_value_supplier) { public StorageGaugeWidget(MatteryMenu menu, int x, int y, Supplier<Fraction> value_supplier, Supplier<Fraction> max_value_supplier) {
super(menu, x, y); super(menu, x, y);
this.value_supplier = value_supplier; this.value_supplier = value_supplier;
this.max_value_supplier = max_value_supplier; this.max_value_supplier = max_value_supplier;
@ -31,7 +33,7 @@ abstract public class StorageGaugeWidget extends GaugeWidget {
addDataSlots(max_value_container); addDataSlots(max_value_container);
} }
public StorageGaugeWidget(MatteryMenu menu, Supplier<BigDecimal> value_supplier, Supplier<BigDecimal> max_value_supplier) { public StorageGaugeWidget(MatteryMenu menu, Supplier<Fraction> value_supplier, Supplier<Fraction> max_value_supplier) {
this(menu, 0, 0, value_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) if (value_supplier == null || max_value_supplier == null)
return; return;
value_container.setDecimal(value_supplier.get()); value_container.setValue(value_supplier.get());
max_value_container.setDecimal(max_value_supplier.get()); max_value_container.setValue(max_value_supplier.get());
} }
@Override @Override
public float getLevel() { 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();
} }
} }

View File

@ -7,6 +7,7 @@ import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.registries.ForgeRegistry; import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.RegistryManager; import net.minecraftforge.registries.RegistryManager;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.matter.MatterRegistry;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -14,14 +15,14 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Supplier; import java.util.function.Supplier;
public record MatterRegistryPacket(Map<Item, BigDecimal> list) { public record MatterRegistryPacket(Map<Item, Fraction> list) {
public void write(FriendlyByteBuf buffer) { public void write(FriendlyByteBuf buffer) {
buffer.writeInt(list.size()); buffer.writeInt(list.size());
var registry = (ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class); var registry = (ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class);
for (var entry : list.entrySet()) { for (var entry : list.entrySet()) {
buffer.writeInt(registry.getID(entry.getKey())); buffer.writeInt(registry.getID(entry.getKey()));
NetworkHelper.writeDecimal(buffer, entry.getValue()); entry.getValue().write(buffer);
} }
} }
@ -29,10 +30,10 @@ public record MatterRegistryPacket(Map<Item, BigDecimal> list) {
var size = buffer.readInt(); var size = buffer.readInt();
var registry = (ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class); var registry = (ForgeRegistry<Item>) RegistryManager.ACTIVE.getRegistry(Item.class);
var map = new HashMap<Item, BigDecimal>(); var map = new HashMap<Item, Fraction>();
for (int i = 0; i < size; i++) { 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); return new MatterRegistryPacket(map);

View File

@ -23,4 +23,34 @@ public class NetworkHelper {
buffer.writeByte(build.length); buffer.writeByte(build.length);
for (byte b : build) buffer.writeByte(b); 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;
}
} }

View File

@ -6,15 +6,16 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.NetworkEvent;
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.network.NetworkHelper; import ru.dbotthepony.mc.otm.network.NetworkHelper;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.function.Supplier; import java.util.function.Supplier;
public record AndroidEnergyPacket(boolean is_maximal, BigDecimal energy) { public record AndroidEnergyPacket(boolean is_maximal, Fraction energy) {
public void write(FriendlyByteBuf buffer) { public void write(FriendlyByteBuf buffer) {
buffer.writeBoolean(is_maximal); buffer.writeBoolean(is_maximal);
NetworkHelper.writeDecimal(buffer, energy); energy.write(buffer);
} }
public void play(Supplier<NetworkEvent.Context> context) { public void play(Supplier<NetworkEvent.Context> context) {
@ -39,6 +40,6 @@ public record AndroidEnergyPacket(boolean is_maximal, BigDecimal energy) {
} }
public static AndroidEnergyPacket read(FriendlyByteBuf buffer) { public static AndroidEnergyPacket read(FriendlyByteBuf buffer) {
return new AndroidEnergyPacket(buffer.readBoolean(), NetworkHelper.readDecimal(buffer)); return new AndroidEnergyPacket(buffer.readBoolean(), Fraction.read(buffer));
} }
} }

View File

@ -1,6 +1,7 @@
package ru.dbotthepony.mc.otm.storage; package ru.dbotthepony.mc.otm.storage;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -10,6 +11,6 @@ import java.util.UUID;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public interface IStorageListener<T extends IStorageStack> { public interface IStorageListener<T extends IStorageStack> {
void addObject(T stack, UUID id, IStorageView<T> provider); void addObject(T stack, UUID id, IStorageView<T> provider);
void changeObject(UUID id, BigDecimal new_count); void changeObject(UUID id, Fraction new_count);
void removeObject(UUID id); void removeObject(UUID id);
} }

View File

@ -1,6 +1,7 @@
package ru.dbotthepony.mc.otm.storage; package ru.dbotthepony.mc.otm.storage;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -18,8 +19,8 @@ import java.util.Optional;
public interface IStorageStack { public interface IStorageStack {
IStorageStack copy(); IStorageStack copy();
void setCount(BigDecimal value); void setCount(Fraction value);
BigDecimal getCount(); Fraction getCount();
boolean isEmpty(); boolean isEmpty();
@ -27,7 +28,7 @@ public interface IStorageStack {
* @return max stack size for this stack object * @return max stack size for this stack object
* Optional.empty() if unlimited (default) * Optional.empty() if unlimited (default)
*/ */
default Optional<BigDecimal> getMaxStackSize() { default Optional<Fraction> getMaxStackSize() {
return Optional.empty(); return Optional.empty();
} }
@ -54,11 +55,11 @@ public interface IStorageStack {
*/ */
boolean sameItem(IStorageStack other); boolean sameItem(IStorageStack other);
default void grow(BigDecimal amount) { default void grow(Fraction amount) {
setCount(getCount().add(amount)); setCount(getCount().plus(amount));
} }
default void shrink(BigDecimal amount) { default void shrink(Fraction amount) {
setCount(getCount().subtract(amount)); setCount(getCount().minus(amount));
} }
} }

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.storage;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -23,7 +24,7 @@ public interface IStorageView<T extends IStorageStack> extends IStorageTrigger<T
* @param simulate whenever to simulate the action or not * @param simulate whenever to simulate the action or not
* @return copy of object, with amount of units actually extracted * @return copy of object, with amount of units actually extracted
*/ */
T extractStack(UUID id, BigDecimal amount, boolean simulate); T extractStack(UUID id, Fraction amount, boolean simulate);
/** /**
* Designed for views, for extraction with less computation overhead caused by * Designed for views, for extraction with less computation overhead caused by
@ -34,7 +35,7 @@ public interface IStorageView<T extends IStorageStack> extends IStorageTrigger<T
* @param simulate whenever to simulate the action or not * @param simulate whenever to simulate the action or not
* @return amount extracted * @return amount extracted
*/ */
default BigDecimal extractStackCount(UUID id, BigDecimal amount, boolean simulate) { default Fraction extractStackCount(UUID id, Fraction amount, boolean simulate) {
return extractStack(id, amount, simulate).getCount(); return extractStack(id, amount, simulate).getCount();
} }

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.storage;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -18,8 +19,8 @@ public record ItemStackWrapper(ItemStack stack) implements IStorageStack {
} }
@Override @Override
public void setCount(BigDecimal value) { public void setCount(Fraction value) {
setCount(value.intValue()); setCount(value.toInt());
} }
public void setCount(int value) { public void setCount(int value) {
@ -27,8 +28,8 @@ public record ItemStackWrapper(ItemStack stack) implements IStorageStack {
} }
@Override @Override
public BigDecimal getCount() { public Fraction getCount() {
return new BigDecimal(stack.getCount()); return new Fraction(stack.getCount());
} }
public int getCountInt() { public int getCountInt() {
@ -36,8 +37,8 @@ public record ItemStackWrapper(ItemStack stack) implements IStorageStack {
} }
@Override @Override
public Optional<BigDecimal> getMaxStackSize() { public Optional<Fraction> getMaxStackSize() {
return Optional.of(new BigDecimal(stack.getMaxStackSize())); return Optional.of(new Fraction(stack.getMaxStackSize()));
} }
@Override @Override

View File

@ -1,6 +1,7 @@
package ru.dbotthepony.mc.otm.storage; package ru.dbotthepony.mc.otm.storage;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -26,11 +27,11 @@ public class VirtualComponent<T extends IStorageStack> implements IStorageCompon
} }
public record RemoteTuple<T extends IStorageStack>(T object, UUID remote_id, IStorageView<T> provider, LocalTuple<T> local) { public record RemoteTuple<T extends IStorageStack>(T object, UUID remote_id, IStorageView<T> provider, LocalTuple<T> local) {
public T extract(BigDecimal amount, boolean simulate) { public T extract(Fraction amount, boolean simulate) {
return provider.extractStack(remote_id, amount, 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); return provider.extractStackCount(remote_id, amount, simulate);
} }
@ -133,32 +134,30 @@ public class VirtualComponent<T extends IStorageStack> implements IStorageCompon
return tuple != null ? tuple.stack : identity.empty(); return tuple != null ? tuple.stack : identity.empty();
} }
public static final BigDecimal MINUS_ONE = new BigDecimal(-1);
@Override @Override
@SuppressWarnings("unchecked") @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); 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(); return identity.empty();
if (amount.compareTo(MINUS_ONE) <= 0) if (amount.compareTo(Fraction.MINUS_ONE) <= 0)
amount = tuple.stack.getMaxStackSize().orElse(tuple.stack.getCount()); amount = tuple.stack.getMaxStackSize().orElse(tuple.stack.getCount());
BigDecimal extract = tuple.stack.getCount().min(amount); var extract = tuple.stack.getCount().min(amount);
BigDecimal extracted = BigDecimal.ZERO; var extracted = Fraction.ZERO;
final var copy = (T) tuple.stack.copy(); final var copy = (T) tuple.stack.copy();
for (var remote_tuple : tuple.tuples) { 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) if (extracted.compareTo(extract) >= 0)
break; break;
} }
if (extracted.compareTo(BigDecimal.ZERO) > 0) { if (extracted.compareTo(Fraction.ZERO) > 0) {
copy.setCount(extracted); copy.setCount(extracted);
return copy; return copy;
} }
@ -224,14 +223,14 @@ public class VirtualComponent<T extends IStorageStack> implements IStorageCompon
@Override @Override
public void changeObject(UUID id, BigDecimal new_count) { public void changeObject(UUID id, Fraction new_count) {
assert new_count.compareTo(BigDecimal.ZERO) > 0; assert new_count.compareTo(Fraction.ZERO) > 0;
var tuple = indexed_by_remote_uuid.get(id); var tuple = indexed_by_remote_uuid.get(id);
if (tuple == null) if (tuple == null)
throw new IllegalStateException("No such tuple with id " + id); 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.object.setCount(new_count);
tuple.local.stack.grow(diff); tuple.local.stack.grow(diff);
@ -253,7 +252,7 @@ public class VirtualComponent<T extends IStorageStack> implements IStorageCompon
indexed_by_remote_uuid.remove(id); 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; final boolean b = tuple.local.tuples.size() == 0;
if (a || b) { if (a || b) {

View File

@ -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
}
}
}

View File

@ -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
}
}

View File

@ -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)
}
}

View File

@ -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()}" }
}
}