From e5f0e563a4bd7cf4735af8bb545588ccf943b21f Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 9 Aug 2021 19:31:36 +0700 Subject: [PATCH] Data container test, add graphics to android station --- .../entity/BlockEntityAndroidStation.java | 4 +- .../mc/otm/capability/AndroidCapability.java | 4 +- .../otm/capability/IMatteryEnergyStorage.java | 24 ++--- .../mc/otm/capability/MatteryCapability.java | 2 +- .../MatteryMachineEnergyStorage.java | 8 +- .../mc/otm/menu/AndroidStationMenu.java | 38 ++++++- .../menu/data/BigDecimalDataContainer.java | 101 ++++++++++++++++++ .../mc/otm/screen/AndroidStationScreen.java | 36 ++++++- .../textures/gui/android_station.png | Bin 0 -> 10466 bytes .../textures/gui/android_station.xcf | Bin 0 -> 24333 bytes 10 files changed, 192 insertions(+), 25 deletions(-) create mode 100644 src/main/java/ru/dbotthepony/mc/otm/menu/data/BigDecimalDataContainer.java create mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.png create mode 100644 src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.xcf diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java index 7c09d1522..1e62e7343 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java @@ -31,7 +31,7 @@ import java.util.List; public class BlockEntityAndroidStation extends BlockEntity implements MenuProvider { @Override public Component getDisplayName() { - return new TranslatableComponent("container.android_station"); + return new TranslatableComponent("container.otm.android_station"); } @Nullable @@ -40,7 +40,7 @@ public class BlockEntityAndroidStation extends BlockEntity implements MenuProvid return new AndroidStationMenu(containerID, inventory, new AndroidStationMenu.AndroidStationContainer(ply), this); } - private final MatteryMachineEnergyStorage energy = new MatteryMachineEnergyStorage(MatteryMachineEnergyStorage.MachineType.WORKER); + private final MatteryMachineEnergyStorage energy = new MatteryMachineEnergyStorage(MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(1_000_000_000_000L)); public BlockEntityAndroidStation(BlockPos p_155229_, BlockState p_155230_) { super(OverdriveThatMatters.ANDROID_STATION_FACTORY, p_155229_, p_155230_); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java index 969874517..6813c0ceb 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java @@ -123,7 +123,7 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit } BigDecimal new_energy = energy_stored.subtract(howMuch, MatteryCapability.ROUND_RULES).max(BigDecimal.ZERO); - BigDecimal diff = energy_stored.subtract(new_energy); + BigDecimal diff = energy_stored.subtract(new_energy, MatteryCapability.ROUND_RULES); if (!simulate) { energy_stored = new_energy; @@ -153,7 +153,7 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit } BigDecimal new_energy = energy_stored.add(howMuch, MatteryCapability.ROUND_RULES).min(energy_stored_max); - BigDecimal diff = new_energy.subtract(energy_stored); + BigDecimal diff = new_energy.subtract(energy_stored, MatteryCapability.ROUND_RULES); if (!simulate) { energy_stored = new_energy; diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java index e43fd80d8..d8a61bb61 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java @@ -27,42 +27,42 @@ public interface IMatteryEnergyStorage extends IEnergyStorage { @Nonnull default BigDecimal extractEnergyOuter(long howMuch, boolean simulate) { - return extractEnergyOuter(new BigDecimal(howMuch), simulate); + return extractEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); } @Nonnull default BigDecimal extractEnergyOuter(int howMuch, boolean simulate) { - return extractEnergyOuter(new BigDecimal(howMuch), simulate); + return extractEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); } @Nonnull default BigDecimal receiveEnergyOuter(long howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); } @Nonnull default BigDecimal receiveEnergyOuter(int howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); } @Nonnull default BigDecimal extractEnergyInner(long howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); } @Nonnull default BigDecimal extractEnergyInner(int howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); } @Nonnull default BigDecimal receiveEnergyInner(long howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); } @Nonnull default BigDecimal receiveEnergyInner(int howMuch, boolean simulate) { - return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + return receiveEnergyOuter(new BigDecimal(howMuch, MatteryCapability.ROUND_RULES), simulate); } @Nonnull @@ -77,7 +77,7 @@ public interface IMatteryEnergyStorage extends IEnergyStorage { @Override default int receiveEnergy(int maxReceive, boolean simulate) { - BigDecimal toReceive = new BigDecimal(maxReceive); + BigDecimal toReceive = new BigDecimal(maxReceive, MatteryCapability.ROUND_RULES); int received = receiveEnergyOuter(toReceive, true).intValue(); if (received == 0) { @@ -85,12 +85,12 @@ public interface IMatteryEnergyStorage extends IEnergyStorage { return 0; } - return receiveEnergyOuter(new BigDecimal(received), simulate).intValue(); + return receiveEnergyOuter(new BigDecimal(received, MatteryCapability.ROUND_RULES), simulate).intValue(); } @Override default int extractEnergy(int maxReceive, boolean simulate) { - BigDecimal toReceive = new BigDecimal(maxReceive); + BigDecimal toReceive = new BigDecimal(maxReceive, MatteryCapability.ROUND_RULES); int extracted = extractEnergyOuter(toReceive, true).intValue(); if (extracted == 0) { @@ -98,7 +98,7 @@ public interface IMatteryEnergyStorage extends IEnergyStorage { return 0; } - return extractEnergyOuter(new BigDecimal(extracted), simulate).intValue(); + return extractEnergyOuter(new BigDecimal(extracted, MatteryCapability.ROUND_RULES), simulate).intValue(); } @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java index e21fabfaf..4f114e817 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java @@ -14,7 +14,7 @@ public class MatteryCapability { @CapabilityInject(IAndroidCapability.class) public static Capability ANDROID = null; - public static final MathContext ROUND_RULES = new MathContext(0, RoundingMode.HALF_UP); + public static final MathContext ROUND_RULES = new MathContext(16, RoundingMode.HALF_UP); public static final BigDecimal INT_MAX_VALUE = new BigDecimal(Integer.MAX_VALUE); public static final BigDecimal INT_MIN_VALUE = new BigDecimal(Integer.MIN_VALUE); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.java index dc7db58a6..981744b24 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.java @@ -23,15 +23,15 @@ public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTS protected BigDecimal max_output; protected final MachineType machine_type; - public MatteryMachineEnergyStorage(BigDecimal capacity, MachineType type) { - this(capacity, type, DEFAULT_MAX_RECEIVE, DEFAULT_MAX_EXTRACT); + public MatteryMachineEnergyStorage(MachineType type, BigDecimal capacity) { + this(type, capacity, DEFAULT_MAX_RECEIVE, DEFAULT_MAX_EXTRACT); } public MatteryMachineEnergyStorage(MachineType type) { - this(DEFAULT_MAX_CAPACITY, type); + this(type, DEFAULT_MAX_CAPACITY); } - public MatteryMachineEnergyStorage(BigDecimal capacity, MachineType type, BigDecimal maxReceive, BigDecimal maxExtract) { + public MatteryMachineEnergyStorage(MachineType type, BigDecimal capacity, BigDecimal maxReceive, BigDecimal maxExtract) { energy_stored_max = capacity; max_input = maxReceive; max_output = maxExtract; diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java index 5cb2132e7..1caf462bf 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java @@ -14,7 +14,9 @@ import net.minecraftforge.energy.IEnergyStorage; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.block.entity.BlockEntityAndroidStation; import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer; import javax.annotation.Nullable; @@ -61,6 +63,8 @@ public class AndroidStationMenu extends AbstractContainerMenu { private Inventory inventory; private Player ply; private AndroidStationContainer container; + public BigDecimalDataContainer energy; + public BigDecimalDataContainer max_energy; // Clientside public AndroidStationMenu(int containerID, Inventory inventory) { @@ -75,17 +79,45 @@ public class AndroidStationMenu extends AbstractContainerMenu { this.tile = tile; this.ply = inventory.player; - this.addSlot(new AndroidBatterySlot(this.container, 0, 0, 0)); + if (tile == null) { + energy = new BigDecimalDataContainer(); + max_energy = new BigDecimalDataContainer(); + } else { + energy = new BigDecimalDataContainer() { + @Override + protected void updateValue() { + LazyOptional capability = tile.getCapability(MatteryCapability.ENERGY); + + if (capability.isPresent()) + setDecimal(capability.resolve().get().getBatteryLevel()); + } + }; + + max_energy = new BigDecimalDataContainer() { + @Override + protected void updateValue() { + LazyOptional capability = tile.getCapability(MatteryCapability.ENERGY); + + if (capability.isPresent()) + setDecimal(capability.resolve().get().getMaxBatteryLevel()); + } + }; + } + + this.addSlot(new AndroidBatterySlot(this.container, 0, 39, 15)); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 9; ++j) { - this.addSlot(new Slot(inventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + this.addSlot(new Slot(inventory, j + i * 9 + 9, 8 + j * 18, 97 + i * 18)); } } for (int k = 0; k < 9; ++k) { - this.addSlot(new Slot(inventory, k, 8 + k * 18, 142)); + this.addSlot(new Slot(inventory, k, 8 + k * 18, 155)); } + + this.addDataSlots(energy); + this.addDataSlots(max_energy); } @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/data/BigDecimalDataContainer.java b/src/main/java/ru/dbotthepony/mc/otm/menu/data/BigDecimalDataContainer.java new file mode 100644 index 000000000..fb239ba2d --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/data/BigDecimalDataContainer.java @@ -0,0 +1,101 @@ +package ru.dbotthepony.mc.otm.menu.data; + +import net.minecraft.world.inventory.ContainerData; + +import java.math.BigDecimal; +import java.math.BigInteger; + +public class BigDecimalDataContainer implements ContainerData { + public static final int NETWORK_PAYLOAD_SIZE = 8; + + private BigDecimal value; + private int[] buffer = new int[NETWORK_PAYLOAD_SIZE + 1]; + + public BigDecimal getDecimal() { + if (value != null) { + return value; + } + + byte[] _build = new byte[NETWORK_PAYLOAD_SIZE * 4]; + + int build_index = 0; + + // read payload + for (int i = 1; i <= NETWORK_PAYLOAD_SIZE; i++) { + _build[build_index] = (byte) ((buffer[i] & 0xFF000000) >> 24); + _build[build_index + 1] = (byte) ((buffer[i] & 0xFF0000) >> 16); + _build[build_index + 2] = (byte) ((buffer[i] & 0xFF00) >> 8); + _build[build_index + 3] = (byte) (buffer[i] & 0xFF); + + build_index += 4; + } + + byte[] build = new byte[_build[0] & 0xFF]; + + for (int i = 0; i < build.length; i++) { + build[i] = _build[i + 1]; + } + + value = new BigDecimal(new BigInteger(build), buffer[0]); + return value; + } + + public void setDecimal(BigDecimal decimal) { + if (decimal.equals(value)) { + return; + } + + value = decimal; + + int scale = decimal.scale(); + BigInteger integer = decimal.unscaledValue(); + + buffer[0] = scale; + byte[] _build = integer.toByteArray(); + byte[] build = new byte[NETWORK_PAYLOAD_SIZE * 4]; + + // insert, shift by one + for (int i = 0; i < Math.min(_build.length, NETWORK_PAYLOAD_SIZE * 4 - 1); i++) + build[i + 1] = _build[i]; + + // tell how many bytes are in there + build[0] = (byte) _build.length; + + int build_index = 0; + + // write + for (int i = 1; i <= NETWORK_PAYLOAD_SIZE; i++) { + buffer[i] = (build[build_index] & 0xFF) << 24 | + (build[build_index + 1] & 0xFF) << 16 | + (build[build_index + 2] & 0xFF) << 8 | + (build[build_index + 3] & 0xFF); + + build_index += 4; + } + } + + // override + protected void updateValue() { + + } + + @Override + public int get(int index) { + updateValue(); + return buffer[index]; + } + + @Override + public void set(int index, int _value) { + if (buffer[index] == _value) + return; + + value = null; + buffer[index] = _value; + } + + @Override + public int getCount() { + return NETWORK_PAYLOAD_SIZE + 1; + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java b/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java index 9c57f7e59..174b8037e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java +++ b/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java @@ -7,11 +7,25 @@ import net.minecraft.client.renderer.GameRenderer; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.menu.AndroidStationMenu; +import java.math.BigDecimal; + public class AndroidStationScreen extends AbstractContainerScreen { + private static final ResourceLocation CONTAINER_BACKGROUND = new ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/android_station.png"); + private final AndroidStationMenu station; + public AndroidStationScreen(AndroidStationMenu p_97741_, Inventory p_97742_, Component p_97743_) { super(p_97741_, p_97742_, p_97743_); + station = p_97741_; + + imageWidth = 176; + imageHeight = 178; + titleLabelY = 4; + + inventoryLabelY = imageHeight - 92; } @Override @@ -22,7 +36,27 @@ public class AndroidStationScreen extends AbstractContainerScreen 0.01) + this.blit(pose, i + 13, j + 15 + 46 - (int) (level * 45d), 176, 0, 7, (int) (level * 45d)); } } diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.png new file mode 100644 index 0000000000000000000000000000000000000000..242cc9cf905606f230a358c28c4fce3cd61fc4c2 GIT binary patch literal 10466 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 F*q5dM%7p*` literal 0 HcmV?d00001