Fix loss of precision in energy values for robot/computer UI.
This commit is contained in:
@@ -11,7 +11,6 @@ import li.cil.oc2.common.network.message.OpenComputerTerminalMessage;
|
||||
import li.cil.oc2.common.vm.Terminal;
|
||||
import li.cil.oc2.common.vm.VirtualMachine;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.inventory.ContainerLevelAccess;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraftforge.energy.IEnergyStorage;
|
||||
@@ -23,7 +22,7 @@ public abstract class AbstractComputerContainer extends AbstractMachineTerminalC
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected AbstractComputerContainer(final MenuType<?> type, final int id, final Player player, final ComputerBlockEntity computer, final ContainerData energyInfo) {
|
||||
protected AbstractComputerContainer(final MenuType<?> type, final int id, final Player player, final ComputerBlockEntity computer, final IntPrecisionContainerData energyInfo) {
|
||||
super(type, id, energyInfo);
|
||||
this.computer = computer;
|
||||
|
||||
@@ -76,28 +75,20 @@ public abstract class AbstractComputerContainer extends AbstractMachineTerminalC
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected static ContainerData createEnergyInfo(final IEnergyStorage energy, final CommonDeviceBusController busController) {
|
||||
return new ContainerData() {
|
||||
protected static IntPrecisionContainerData createEnergyInfo(final IEnergyStorage energy, final CommonDeviceBusController busController) {
|
||||
return new IntPrecisionContainerData() {
|
||||
@Override
|
||||
public int get(final int index) {
|
||||
switch (index) {
|
||||
case AbstractMachineContainer.ENERGY_STORED_INDEX:
|
||||
return energy.getEnergyStored();
|
||||
case AbstractMachineContainer.ENERGY_CAPACITY_INDEX:
|
||||
return energy.getMaxEnergyStored();
|
||||
case AbstractMachineContainer.ENERGY_CONSUMPTION_INDEX:
|
||||
return busController.getEnergyConsumption();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
public int getInt(final int index) {
|
||||
return switch (index) {
|
||||
case AbstractMachineContainer.ENERGY_STORED_INDEX -> energy.getEnergyStored();
|
||||
case AbstractMachineContainer.ENERGY_CAPACITY_INDEX -> energy.getMaxEnergyStored();
|
||||
case AbstractMachineContainer.ENERGY_CONSUMPTION_INDEX -> busController.getEnergyConsumption();
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(final int index, final int value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
public int getIntCount() {
|
||||
return ENERGY_INFO_SIZE;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package li.cil.oc2.common.container;
|
||||
|
||||
import li.cil.oc2.common.vm.VirtualMachine;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.inventory.SimpleContainerData;
|
||||
|
||||
public abstract class AbstractMachineContainer extends AbstractContainer {
|
||||
protected static final int ENERGY_INFO_SIZE = 3;
|
||||
@@ -14,11 +12,11 @@ public abstract class AbstractMachineContainer extends AbstractContainer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final ContainerData energyInfo;
|
||||
private final IntPrecisionContainerData energyInfo;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected AbstractMachineContainer(final MenuType<?> type, final int id, final ContainerData energyInfo) {
|
||||
protected AbstractMachineContainer(final MenuType<?> type, final int id, final IntPrecisionContainerData energyInfo) {
|
||||
super(type, id);
|
||||
this.energyInfo = energyInfo;
|
||||
|
||||
@@ -35,20 +33,20 @@ public abstract class AbstractMachineContainer extends AbstractContainer {
|
||||
public abstract void sendPowerStateToServer(final boolean value);
|
||||
|
||||
public int getEnergy() {
|
||||
return energyInfo.get(ENERGY_STORED_INDEX);
|
||||
return energyInfo.getInt(ENERGY_STORED_INDEX);
|
||||
}
|
||||
|
||||
public int getEnergyCapacity() {
|
||||
return energyInfo.get(ENERGY_CAPACITY_INDEX);
|
||||
return energyInfo.getInt(ENERGY_CAPACITY_INDEX);
|
||||
}
|
||||
|
||||
public int getEnergyConsumption() {
|
||||
return energyInfo.get(ENERGY_CONSUMPTION_INDEX);
|
||||
return energyInfo.getInt(ENERGY_CONSUMPTION_INDEX);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected static ContainerData createEnergyInfo() {
|
||||
return new SimpleContainerData(ENERGY_INFO_SIZE);
|
||||
protected static IntPrecisionContainerData createEnergyInfo() {
|
||||
return new SimpleIntPrecisionContainerData(ENERGY_INFO_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import net.minecraft.world.inventory.MenuType;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public abstract class AbstractMachineTerminalContainer extends AbstractMachineContainer {
|
||||
protected AbstractMachineTerminalContainer(final MenuType<?> type, final int id, final ContainerData energyInfo) {
|
||||
protected AbstractMachineTerminalContainer(final MenuType<?> type, final int id, final IntPrecisionContainerData energyInfo) {
|
||||
super(type, id, energyInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import li.cil.oc2.common.network.message.RobotTerminalInputMessage;
|
||||
import li.cil.oc2.common.vm.Terminal;
|
||||
import li.cil.oc2.common.vm.VirtualMachine;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@@ -21,7 +20,7 @@ public abstract class AbstractRobotContainer extends AbstractMachineTerminalCont
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public AbstractRobotContainer(final MenuType<?> type, final int id, final RobotEntity robot, final ContainerData energyInfo) {
|
||||
public AbstractRobotContainer(final MenuType<?> type, final int id, final RobotEntity robot, final IntPrecisionContainerData energyInfo) {
|
||||
super(type, id, energyInfo);
|
||||
this.robot = robot;
|
||||
}
|
||||
@@ -69,10 +68,10 @@ public abstract class AbstractRobotContainer extends AbstractMachineTerminalCont
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected static ContainerData createEnergyInfo(final FixedEnergyStorage energy, final CommonDeviceBusController busController) {
|
||||
return new ContainerData() {
|
||||
protected static IntPrecisionContainerData createEnergyInfo(final FixedEnergyStorage energy, final CommonDeviceBusController busController) {
|
||||
return new IntPrecisionContainerData() {
|
||||
@Override
|
||||
public int get(final int index) {
|
||||
public int getInt(final int index) {
|
||||
return switch (index) {
|
||||
case AbstractMachineContainer.ENERGY_STORED_INDEX -> energy.getEnergyStored();
|
||||
case AbstractMachineContainer.ENERGY_CAPACITY_INDEX -> energy.getMaxEnergyStored();
|
||||
@@ -82,11 +81,7 @@ public abstract class AbstractRobotContainer extends AbstractMachineTerminalCont
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(final int index, final int value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
public int getIntCount() {
|
||||
return ENERGY_INFO_SIZE;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,7 +13,6 @@ import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraftforge.energy.IEnergyStorage;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
@@ -45,7 +44,7 @@ public final class ComputerInventoryContainer extends AbstractComputerContainer
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private ComputerInventoryContainer(final int id, final ComputerBlockEntity computer, final Player player, final ContainerData energyInfo) {
|
||||
private ComputerInventoryContainer(final int id, final ComputerBlockEntity computer, final Player player, final IntPrecisionContainerData energyInfo) {
|
||||
super(Containers.COMPUTER.get(), id, player, computer, energyInfo);
|
||||
|
||||
final VMItemStackHandlers handlers = computer.getItemStackHandlers();
|
||||
|
||||
@@ -11,7 +11,6 @@ import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraftforge.energy.IEnergyStorage;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
@@ -43,7 +42,7 @@ public final class ComputerTerminalContainer extends AbstractComputerContainer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private ComputerTerminalContainer(final int id, final Player player, final ComputerBlockEntity computer, final ContainerData energyInfo) {
|
||||
private ComputerTerminalContainer(final int id, final Player player, final ComputerBlockEntity computer, final IntPrecisionContainerData energyInfo) {
|
||||
super(Containers.COMPUTER_TERMINAL.get(), id, player, computer, energyInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package li.cil.oc2.common.container;
|
||||
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
|
||||
/**
|
||||
* Utility class for synchronizing full-precision ints using {@link ContainerData}.
|
||||
* <p>
|
||||
* Expects either {@link #getInt(int)} and {@link #getIntCount()} or {@link #get(int)} and {@link #getCount()} to be
|
||||
* overridden.
|
||||
*/
|
||||
public abstract class IntPrecisionContainerData implements ContainerData {
|
||||
public int getInt(final int index) {
|
||||
return (get(index * 2 + 1) << 16) | get(index * 2);
|
||||
}
|
||||
|
||||
public void setInt(final int index, final int value) {
|
||||
}
|
||||
|
||||
public int getIntCount() {
|
||||
return getCount() / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get(final int index) {
|
||||
final int intValue = getInt(index / 2);
|
||||
if ((index & 1) == 0) {
|
||||
return intValue & 0xFFFF; // Low half.
|
||||
} else {
|
||||
return (intValue >>> 16) & 0xFFFF; // High half.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(final int index, final int value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return getIntCount() * 2;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
@@ -45,7 +44,7 @@ public final class RobotInventoryContainer extends AbstractRobotContainer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private RobotInventoryContainer(final int id, final RobotEntity robot, final Player player, final ContainerData energyInfo) {
|
||||
private RobotInventoryContainer(final int id, final RobotEntity robot, final Player player, final IntPrecisionContainerData energyInfo) {
|
||||
super(Containers.ROBOT.get(), id, robot, energyInfo);
|
||||
|
||||
final VMItemStackHandlers handlers = robot.getItemStackHandlers();
|
||||
|
||||
@@ -12,7 +12,6 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
@@ -44,7 +43,7 @@ public final class RobotTerminalContainer extends AbstractRobotContainer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private RobotTerminalContainer(final int id, final RobotEntity robot, final ContainerData energyInfo) {
|
||||
private RobotTerminalContainer(final int id, final RobotEntity robot, final IntPrecisionContainerData energyInfo) {
|
||||
super(Containers.ROBOT_TERMINAL.get(), id, robot, energyInfo);
|
||||
|
||||
// It's kinda dumb we need to access technically-client-side stuff here, but that's the nature of containers
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package li.cil.oc2.common.container;
|
||||
|
||||
import net.minecraft.world.inventory.SimpleContainerData;
|
||||
|
||||
public final class SimpleIntPrecisionContainerData extends IntPrecisionContainerData {
|
||||
private final SimpleContainerData data;
|
||||
|
||||
public SimpleIntPrecisionContainerData(final int size) {
|
||||
data = new SimpleContainerData(size * 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get(final int index) {
|
||||
return data.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(final int index, final int value) {
|
||||
data.set(index, value & 0xFFFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return data.getCount();
|
||||
}
|
||||
}
|
||||
@@ -13,25 +13,25 @@ public final class NBTToJsonConverter {
|
||||
}
|
||||
|
||||
switch (tag.getId()) {
|
||||
case NBTTagIds.TAG_BYTE: {
|
||||
case NBTTagIds.TAG_BYTE -> {
|
||||
return new JsonPrimitive(((ByteTag) tag).getAsByte());
|
||||
}
|
||||
case NBTTagIds.TAG_SHORT: {
|
||||
case NBTTagIds.TAG_SHORT -> {
|
||||
return new JsonPrimitive(((ShortTag) tag).getAsShort());
|
||||
}
|
||||
case NBTTagIds.TAG_INT: {
|
||||
case NBTTagIds.TAG_INT -> {
|
||||
return new JsonPrimitive(((IntTag) tag).getAsInt());
|
||||
}
|
||||
case NBTTagIds.TAG_LONG: {
|
||||
case NBTTagIds.TAG_LONG -> {
|
||||
return new JsonPrimitive(((LongTag) tag).getAsLong());
|
||||
}
|
||||
case NBTTagIds.TAG_FLOAT: {
|
||||
case NBTTagIds.TAG_FLOAT -> {
|
||||
return new JsonPrimitive(((FloatTag) tag).getAsFloat());
|
||||
}
|
||||
case NBTTagIds.TAG_DOUBLE: {
|
||||
case NBTTagIds.TAG_DOUBLE -> {
|
||||
return new JsonPrimitive(((DoubleTag) tag).getAsDouble());
|
||||
}
|
||||
case NBTTagIds.TAG_BYTE_ARRAY: {
|
||||
case NBTTagIds.TAG_BYTE_ARRAY -> {
|
||||
final JsonArray json = new JsonArray();
|
||||
final byte[] array = ((ByteArrayTag) tag).getAsByteArray();
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
@@ -39,10 +39,10 @@ public final class NBTToJsonConverter {
|
||||
}
|
||||
return json;
|
||||
}
|
||||
case NBTTagIds.TAG_STRING: {
|
||||
case NBTTagIds.TAG_STRING -> {
|
||||
return new JsonPrimitive(tag.getAsString());
|
||||
}
|
||||
case NBTTagIds.TAG_LIST: {
|
||||
case NBTTagIds.TAG_LIST -> {
|
||||
final JsonArray json = new JsonArray();
|
||||
final ListTag listTag = (ListTag) tag;
|
||||
for (final Tag item : listTag) {
|
||||
@@ -50,7 +50,7 @@ public final class NBTToJsonConverter {
|
||||
}
|
||||
return json;
|
||||
}
|
||||
case NBTTagIds.TAG_COMPOUND: {
|
||||
case NBTTagIds.TAG_COMPOUND -> {
|
||||
final JsonObject json = new JsonObject();
|
||||
final CompoundTag compoundTag = (CompoundTag) tag;
|
||||
for (final String key : compoundTag.getAllKeys()) {
|
||||
@@ -58,7 +58,7 @@ public final class NBTToJsonConverter {
|
||||
}
|
||||
return json;
|
||||
}
|
||||
case NBTTagIds.TAG_INT_ARRAY: {
|
||||
case NBTTagIds.TAG_INT_ARRAY -> {
|
||||
final JsonArray json = new JsonArray();
|
||||
final int[] array = ((IntArrayTag) tag).getAsIntArray();
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
@@ -66,7 +66,7 @@ public final class NBTToJsonConverter {
|
||||
}
|
||||
return json;
|
||||
}
|
||||
case NBTTagIds.TAG_LONG_ARRAY: {
|
||||
case NBTTagIds.TAG_LONG_ARRAY -> {
|
||||
final JsonArray json = new JsonArray();
|
||||
final long[] array = ((LongArrayTag) tag).getAsLongArray();
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
@@ -74,7 +74,7 @@ public final class NBTToJsonConverter {
|
||||
}
|
||||
return json;
|
||||
}
|
||||
default: {
|
||||
default -> {
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,24 +11,12 @@ public final class MessageJsonDeserializer implements JsonDeserializer<RPCDevice
|
||||
public RPCDeviceBusAdapter.Message deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
|
||||
final JsonObject jsonObject = json.getAsJsonObject();
|
||||
final String messageType = jsonObject.get("type").getAsString();
|
||||
final Object messageData;
|
||||
switch (messageType) {
|
||||
case RPCDeviceBusAdapter.Message.MESSAGE_TYPE_LIST: {
|
||||
messageData = null;
|
||||
break;
|
||||
}
|
||||
case RPCDeviceBusAdapter.Message.MESSAGE_TYPE_METHODS: {
|
||||
messageData = UUID.fromString(jsonObject.getAsJsonPrimitive("data").getAsString());
|
||||
break;
|
||||
}
|
||||
case RPCDeviceBusAdapter.Message.MESSAGE_TYPE_INVOKE_METHOD: {
|
||||
messageData = context.deserialize(jsonObject.getAsJsonObject("data"), RPCDeviceBusAdapter.MethodInvocation.class);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new JsonParseException(RPCDeviceBusAdapter.ERROR_UNKNOWN_MESSAGE_TYPE);
|
||||
}
|
||||
}
|
||||
final Object messageData = switch (messageType) {
|
||||
case RPCDeviceBusAdapter.Message.MESSAGE_TYPE_LIST -> null;
|
||||
case RPCDeviceBusAdapter.Message.MESSAGE_TYPE_METHODS -> UUID.fromString(jsonObject.getAsJsonPrimitive("data").getAsString());
|
||||
case RPCDeviceBusAdapter.Message.MESSAGE_TYPE_INVOKE_METHOD -> context.deserialize(jsonObject.getAsJsonObject("data"), RPCDeviceBusAdapter.MethodInvocation.class);
|
||||
default -> throw new JsonParseException(RPCDeviceBusAdapter.ERROR_UNKNOWN_MESSAGE_TYPE);
|
||||
};
|
||||
|
||||
return new RPCDeviceBusAdapter.Message(messageType, messageData);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user