Add logic for energy support, closes #3.

Computer and robot now consume energy; constant amount per tick while running.
Added charger block to allow charging robots.
Charger can charge anything with IEnergyStorage capability and items with it in an ItemHandler on top of it.
Also some renames, mostly nbt -> tag.
This commit is contained in:
Florian Nücke
2021-02-12 01:05:26 +01:00
parent 924294d394
commit c196659cc1
53 changed files with 988 additions and 436 deletions

View File

@@ -10,6 +10,7 @@ import li.cil.oc2.client.item.CustomItemModelProperties;
import li.cil.oc2.client.model.BusCableModelLoader;
import li.cil.oc2.client.renderer.NetworkCableRenderer;
import li.cil.oc2.client.renderer.entity.RobotEntityRenderer;
import li.cil.oc2.client.renderer.tileentity.ChargerTileEntityRenderer;
import li.cil.oc2.client.renderer.tileentity.ComputerTileEntityRenderer;
import li.cil.oc2.client.renderer.tileentity.DiskDriveTileEntityRenderer;
import li.cil.oc2.client.renderer.tileentity.NetworkConnectorTileEntityRenderer;
@@ -43,6 +44,7 @@ public final class ClientSetup {
ClientRegistry.bindTileEntityRenderer(TileEntities.COMPUTER_TILE_ENTITY.get(), ComputerTileEntityRenderer::new);
ClientRegistry.bindTileEntityRenderer(TileEntities.NETWORK_CONNECTOR_TILE_ENTITY.get(), NetworkConnectorTileEntityRenderer::new);
ClientRegistry.bindTileEntityRenderer(TileEntities.DISK_DRIVE_TILE_ENTITY.get(), DiskDriveTileEntityRenderer::new);
ClientRegistry.bindTileEntityRenderer(TileEntities.CHARGER_TILE_ENTITY.get(), ChargerTileEntityRenderer::new);
RenderingRegistry.registerEntityRenderingHandler(Entities.ROBOT.get(), RobotEntityRenderer::new);
}
@@ -65,5 +67,7 @@ public final class ClientSetup {
event.addSprite(ComputerTileEntityRenderer.OVERLAY_POWER_LOCATION);
event.addSprite(ComputerTileEntityRenderer.OVERLAY_STATUS_LOCATION);
event.addSprite(ComputerTileEntityRenderer.OVERLAY_TERMINAL_LOCATION);
event.addSprite(ChargerTileEntityRenderer.EFFECT_LOCATION);
}
}

View File

@@ -82,7 +82,7 @@ public final class CustomItemColors {
public static int getColor(final ItemStack stack) {
final CompoundNBT tag = ItemStackUtils.getModDataTag(stack);
if (tag != null && tag.contains(COLOR_TAG_NAME, NBTTagIds.TAG_INT)) {
if (tag.contains(COLOR_TAG_NAME, NBTTagIds.TAG_INT)) {
return tag.getInt(COLOR_TAG_NAME);
} else {
return GREY;

View File

@@ -1,7 +1,6 @@
package li.cil.oc2.client.renderer;
import li.cil.oc2.api.API;
import net.minecraft.client.renderer.RenderState;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
@@ -13,23 +12,26 @@ public abstract class CustomRenderType extends RenderType {
final TextureState texture = new TextureState(location, false, true);
final RenderType.State state = RenderType.State.getBuilder()
.texture(texture)
.writeMask(COLOR_WRITE)
.alpha(DEFAULT_ALPHA)
.transparency(ADDITIVE_TRANSPARENCY)
.cull(CULL_DISABLED)
.build(false);
return RenderType.makeType(
API.MOD_ID + ":unlit_block",
DefaultVertexFormats.POSITION_TEX,
GL11.GL_QUADS,
256,
false,
true,
state);
}
public static RenderType getNetworkCable() {
final State state = State.getBuilder()
.texture(RenderState.NO_TEXTURE)
.transparency(RenderState.NO_TRANSPARENCY)
.cull(RenderState.CULL_DISABLED)
.lightmap(RenderState.LIGHTMAP_ENABLED)
.texture(NO_TEXTURE)
.transparency(NO_TRANSPARENCY)
.cull(CULL_DISABLED)
.lightmap(LIGHTMAP_ENABLED)
.build(false);
return RenderType.makeType(API.MOD_ID + ":network_cable",
DefaultVertexFormats.POSITION_COLOR_LIGHTMAP,

View File

@@ -0,0 +1,91 @@
package li.cil.oc2.client.renderer.tileentity;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import li.cil.oc2.api.API;
import li.cil.oc2.client.renderer.CustomRenderType;
import li.cil.oc2.common.tileentity.ChargerTileEntity;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.model.RenderMaterial;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.inventory.container.PlayerContainer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Matrix4f;
public final class ChargerTileEntityRenderer extends TileEntityRenderer<ChargerTileEntity> {
public static final ResourceLocation EFFECT_LOCATION = new ResourceLocation(API.MOD_ID, "block/charger/effect");
private static final RenderMaterial TEXTURE_EFFECT = new RenderMaterial(PlayerContainer.LOCATION_BLOCKS_TEXTURE, EFFECT_LOCATION);
private static final int EFFECT_LAYERS = 3;
private static final float EFFECT_HEIGHT = 0.5f;
private static final float EFFECT_SPEED = 0.1f;
private static final float EFFECT_SCALE_START = 0.6f;
private static final float EFFECT_SCALE_END = 0.8f;
///////////////////////////////////////////////////////////////////
private float offset = 0;
///////////////////////////////////////////////////////////////////
public ChargerTileEntityRenderer(final TileEntityRendererDispatcher dispatcher) {
super(dispatcher);
}
///////////////////////////////////////////////////////////////////
@Override
public void render(final ChargerTileEntity tileEntity, final float partialTicks, final MatrixStack matrixStack, final IRenderTypeBuffer buffer, final int light, final int overlay) {
offset = (offset + EFFECT_SPEED * partialTicks / 20f) % (float) (Math.PI * 2);
matrixStack.push();
matrixStack.translate(0.5, 1.1, 0.5);
final IVertexBuilder builder = TEXTURE_EFFECT.getBuffer(buffer, CustomRenderType::getUnlitBlock);
for (int i = 0; i < EFFECT_LAYERS; i++) {
final float relativeY = (1 + MathHelper.sin(offset + ((float) Math.PI * 2f * i / EFFECT_LAYERS))) * 0.5f;
final float y = relativeY * EFFECT_HEIGHT;
final float scale = EFFECT_SCALE_START + relativeY * (EFFECT_SCALE_END - EFFECT_SCALE_START);
matrixStack.push();
matrixStack.translate(0, y, 0);
renderScaledQuad(matrixStack, builder, scale);
matrixStack.pop();
}
matrixStack.pop();
}
private static void renderScaledQuad(final MatrixStack matrixStack, final IVertexBuilder builder, final float scale) {
matrixStack.push();
matrixStack.scale(scale, scale, scale);
renderQuad(matrixStack.getLast().getMatrix(), builder);
matrixStack.pop();
}
private static void renderQuad(final Matrix4f matrix, final IVertexBuilder builder) {
// NB: We may get a SpriteAwareVertexBuilder here. Sadly, its chaining is broken,
// because methods may return the underlying vertex builder, so e.g. calling
// buffer.pos(...).tex(...) will not actually call SpriteAwareVertexBuilder.tex(...)
// but SpriteAwareVertexBuilder.vertexBuilder.tex(...), skipping the UV remapping.
builder.pos(matrix, -0.5f, 0, -0.5f);
builder.tex(0, 0);
builder.endVertex();
builder.pos(matrix, -0.5f, 0, 0.5f);
builder.tex(0, 1);
builder.endVertex();
builder.pos(matrix, 0.5f, 0, 0.5f);
builder.tex(1, 1);
builder.endVertex();
builder.pos(matrix, 0.5f, 0, -0.5f);
builder.tex(1, 0);
builder.endVertex();
}
}

View File

@@ -203,22 +203,25 @@ public final class ComputerTileEntityRenderer extends TileEntityRenderer<Compute
renderQuad(matrix, TEXTURE_POWER.getBuffer(buffer, CustomRenderType::getUnlitBlock));
}
private static void renderQuad(final Matrix4f matrix, final IVertexBuilder buffer) {
private static void renderQuad(final Matrix4f matrix, final IVertexBuilder builder) {
// NB: We may get a SpriteAwareVertexBuilder here. Sadly, its chaining is broken,
// because methods may return the underlying vertex builder, so e.g. calling
// buffer.pos(...).tex(...) will not actually call SpriteAwareVertexBuilder.tex(...)
// but SpriteAwareVertexBuilder.vertexBuilder.tex(...), skipping the UV remapping.
buffer.pos(matrix, 0, 0, 0);
buffer.tex(0, 0);
buffer.endVertex();
buffer.pos(matrix, 0, 16, 0);
buffer.tex(0, 1);
buffer.endVertex();
buffer.pos(matrix, 16, 16, 0);
buffer.tex(1, 1);
buffer.endVertex();
buffer.pos(matrix, 16, 0, 0);
buffer.tex(1, 0);
buffer.endVertex();
builder.pos(matrix, 0, 0, 0);
builder.tex(0, 0);
builder.endVertex();
builder.pos(matrix, 0, 16, 0);
builder.tex(0, 1);
builder.endVertex();
builder.pos(matrix, 16, 16, 0);
builder.tex(1, 1);
builder.endVertex();
builder.pos(matrix, 16, 0, 0);
builder.tex(1, 0);
builder.endVertex();
}
}

View File

@@ -26,6 +26,13 @@ public final class Config {
public static int maxFlashMemorySize = 4 * Constants.KILOBYTE;
public static int maxFloppySize = 512 * Constants.KILOBYTE;
public static int computerEnergyPerTick = 20;
public static int computerEnergyStorage = 4000;
public static int robotEnergyPerTick = 10;
public static int robotEnergyStorage = 600000;
public static int chargerEnergyPerTick = 2500;
public static int chargerEnergyStorage = 50000;
public static int blockOperationsModuleToolLevel = Items.DIAMOND_PICKAXE.getHarvestLevel(new ItemStack(Items.DIAMOND_PICKAXE), ToolType.PICKAXE, null, null);
public static UUID fakePlayerUUID = UUID.fromString("e39dd9a7-514f-4a2d-aa5e-b6030621416d");
@@ -44,6 +51,18 @@ public final class Config {
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, COMMON_SPEC);
}
public static boolean computersUseEnergy() {
return computerEnergyPerTick > 0 && computerEnergyStorage > 0;
}
public static boolean robotsUseEnergy() {
return robotEnergyPerTick > 0 && robotEnergyStorage > 0;
}
public static boolean chargerUseEnergy() {
return chargerEnergyPerTick > 0 && chargerEnergyStorage > 0;
}
///////////////////////////////////////////////////////////////////
@SubscribeEvent
@@ -54,6 +73,15 @@ public final class Config {
maxHardDriveSize = COMMON_INSTANCE.maxHardDriveSize.get();
maxFlashMemorySize = COMMON_INSTANCE.maxFlashMemorySize.get();
computerEnergyPerTick = COMMON_INSTANCE.computerEnergyPerTick.get();
computerEnergyStorage = COMMON_INSTANCE.computerEnergyStorage.get();
robotEnergyPerTick = COMMON_INSTANCE.robotEnergyPerTick.get();
robotEnergyStorage = COMMON_INSTANCE.robotEnergyStorage.get();
chargerEnergyPerTick = COMMON_INSTANCE.chargerEnergyPerTick.get();
chargerEnergyStorage = COMMON_INSTANCE.chargerEnergyStorage.get();
blockOperationsModuleToolLevel = COMMON_INSTANCE.blockOperationsModuleToolLevel.get();
fakePlayerUUID = UUID.fromString(COMMON_INSTANCE.fakePlayerUUID.get());
}
}
@@ -61,14 +89,21 @@ public final class Config {
///////////////////////////////////////////////////////////////////
private static final class CommonSettings {
public ForgeConfigSpec.LongValue maxAllocatedMemory;
public ForgeConfigSpec.IntValue maxMemorySize;
public ForgeConfigSpec.IntValue maxHardDriveSize;
public ForgeConfigSpec.IntValue maxFlashMemorySize;
public final ForgeConfigSpec.LongValue maxAllocatedMemory;
public final ForgeConfigSpec.IntValue maxMemorySize;
public final ForgeConfigSpec.IntValue maxHardDriveSize;
public final ForgeConfigSpec.IntValue maxFlashMemorySize;
public ForgeConfigSpec.IntValue blockOperationsModuleToolLevel;
public final ForgeConfigSpec.IntValue computerEnergyPerTick;
public final ForgeConfigSpec.IntValue computerEnergyStorage;
public final ForgeConfigSpec.IntValue robotEnergyPerTick;
public final ForgeConfigSpec.IntValue robotEnergyStorage;
public final ForgeConfigSpec.IntValue chargerEnergyPerTick;
public final ForgeConfigSpec.IntValue chargerEnergyStorage;
public ForgeConfigSpec.ConfigValue<String> fakePlayerUUID;
public final ForgeConfigSpec.IntValue blockOperationsModuleToolLevel;
public final ForgeConfigSpec.ConfigValue<String> fakePlayerUUID;
public CommonSettings(final ForgeConfigSpec.Builder builder) {
builder.push("vm");
@@ -95,6 +130,40 @@ public final class Config {
builder.pop();
builder.push("energy");
computerEnergyPerTick = builder
.translation(Constants.CONFIG_COMPUTER_ENERGY_PER_TICK)
.comment("The amount of energy (Forge Energy/RF) a computer draws per tick. Set to zero to disable.")
.defineInRange("computerEnergyPerTick", Config.computerEnergyPerTick, 0, Integer.MAX_VALUE);
computerEnergyStorage = builder
.translation(Constants.CONFIG_COMPUTER_ENERGY_STORAGE)
.comment("The amount of energy (Forge Energy/RF) a computer can store internally.")
.defineInRange("computerEnergyStorage", Config.computerEnergyStorage, 0, Integer.MAX_VALUE);
robotEnergyPerTick = builder
.translation(Constants.CONFIG_ROBOT_ENERGY_PER_TICK)
.comment("The amount of energy (Forge Energy/RF) a robot draws per tick. Set to zero to disable.")
.defineInRange("robotEnergyPerTick", Config.robotEnergyPerTick, 0, Integer.MAX_VALUE);
robotEnergyStorage = builder
.translation(Constants.CONFIG_ROBOT_ENERGY_STORAGE)
.comment("The amount of energy (Forge Energy/RF) a robot can store internally.")
.defineInRange("robotEnergyStorage", Config.robotEnergyStorage, 0, Integer.MAX_VALUE);
chargerEnergyPerTick = builder
.translation(Constants.CONFIG_CHARGER_ENERGY_PER_TICK)
.comment("The maximum amount of energy (Forge Energy/RF) a charger transfers per tick. Set to zero to disable.")
.defineInRange("chargerEnergyPerTick", Config.chargerEnergyPerTick, 0, Integer.MAX_VALUE);
chargerEnergyStorage = builder
.translation(Constants.CONFIG_CHARGER_ENERGY_STORAGE)
.comment("The amount of energy (Forge Energy/RF) a charger can store internally.")
.defineInRange("chargerEnergyStorage", Config.chargerEnergyStorage, 0, Integer.MAX_VALUE);
builder.pop();
builder.push("gameplay");
blockOperationsModuleToolLevel = builder

View File

@@ -1,5 +1,6 @@
package li.cil.oc2.common;
import li.cil.oc2.api.API;
import net.minecraft.util.Direction;
public final class Constants {
@@ -18,7 +19,9 @@ public final class Constants {
///////////////////////////////////////////////////////////////////
public static final String BLOCK_ENTITY_TAG_NAME_IN_ITEM = "BlockEntityTag";
public static final String INVENTORY_TAG_NAME = "items";
public static final String MOD_TAG_NAME = API.MOD_ID;
public static final String ITEMS_TAG_NAME = "items";
public static final String ENERGY_TAG_NAME = "energy";
///////////////////////////////////////////////////////////////////
@@ -28,6 +31,7 @@ public final class Constants {
public static final String NETWORK_HUB_BLOCK_NAME = "network_hub";
public static final String DISK_DRIVE_BLOCK_NAME = "disk_drive";
public static final String REDSTONE_INTERFACE_BLOCK_NAME = "redstone_interface";
public static final String CHARGER_BLOCK_NAME = "charger";
///////////////////////////////////////////////////////////////////
@@ -57,6 +61,7 @@ public final class Constants {
public static final String TOOLTIP_FLASH_MEMORY_MISSING = "tooltip.oc2.flash_memory_missing";
public static final String TOOLTIP_MEMORY_MISSING = "tooltip.oc2.memory_missing";
public static final String TOOLTIP_HARD_DRIVE_MISSING = "tooltip.oc2.hard_drive_missing";
public static final String TOOLTIP_ENERGY = "tooltip.oc2.energy";
///////////////////////////////////////////////////////////////////
@@ -66,6 +71,12 @@ public final class Constants {
public static final String CONFIG_MAX_FLASH_MEMORY_SIZE = "config.oc2.vm.maxFlashMemorySize";
public static final String CONFIG_BLOCK_OPERATIONS_MODULE_TOOL_LEVEL = "config.oc2.modules.block_operations.toolLevel";
public static final String CONFIG_FAKE_PLAYER_UUID = "config.oc2.admin.fakePlayerUUID";
public static final String CONFIG_COMPUTER_ENERGY_PER_TICK = "config.oc2.computerEnergyPerTick";
public static final String CONFIG_COMPUTER_ENERGY_STORAGE = "config.oc2.computerEnergyStorage";
public static final String CONFIG_ROBOT_ENERGY_PER_TICK = "config.oc2.robotEnergyPerTick";
public static final String CONFIG_ROBOT_ENERGY_STORAGE = "config.oc2.robotEnergyStorage";
public static final String CONFIG_CHARGER_ENERGY_PER_TICK = "config.oc2.chargerEnergyPerTick";
public static final String CONFIG_CHARGER_ENERGY_STORAGE = "config.oc2.chargerEnergyStorage";
///////////////////////////////////////////////////////////////////
@@ -79,6 +90,7 @@ public final class Constants {
public static final String COMPUTER_BUS_STATE_INCOMPLETE = "gui.oc2.computer.bus_state.incomplete";
public static final String COMPUTER_BUS_STATE_TOO_COMPLEX = "gui.oc2.computer.bus_state.too_complex";
public static final String COMPUTER_BUS_STATE_MULTIPLE_CONTROLLERS = "gui.oc2.computer.bus_state.multiple_controllers";
public static final String COMPUTER_ERROR_NOT_ENOUGH_ENERGY = "gui.oc2.computer.error.not_enough_energy";
///////////////////////////////////////////////////////////////////

View File

@@ -19,6 +19,7 @@ public final class Blocks {
public static final RegistryObject<NetworkHubBlock> NETWORK_HUB = BLOCKS.register(Constants.NETWORK_HUB_BLOCK_NAME, NetworkHubBlock::new);
public static final RegistryObject<RedstoneInterfaceBlock> REDSTONE_INTERFACE = BLOCKS.register(Constants.REDSTONE_INTERFACE_BLOCK_NAME, RedstoneInterfaceBlock::new);
public static final RegistryObject<DiskDriveBlock> DISK_DRIVE = BLOCKS.register(Constants.DISK_DRIVE_BLOCK_NAME, DiskDriveBlock::new);
public static final RegistryObject<ChargerBlock> CHARGER = BLOCKS.register(Constants.CHARGER_BLOCK_NAME, ChargerBlock::new);
///////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,62 @@
package li.cil.oc2.common.block;
import li.cil.oc2.common.tileentity.TileEntities;
import net.minecraft.block.*;
import net.minecraft.block.material.Material;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.world.IBlockReader;
import javax.annotation.Nullable;
public final class ChargerBlock extends BreakableBlock {
public ChargerBlock() {
super(Properties
.create(Material.IRON)
.sound(SoundType.METAL)
.hardnessAndResistance(1.5f, 6.0f));
setDefaultState(getStateContainer().getBaseState().with(HorizontalBlock.HORIZONTAL_FACING, Direction.NORTH));
}
///////////////////////////////////////////////////////////////////
@SuppressWarnings("deprecation")
@Override
public BlockState rotate(final BlockState state, final Rotation rot) {
return state.with(HorizontalBlock.HORIZONTAL_FACING, rot.rotate(state.get(HorizontalBlock.HORIZONTAL_FACING)));
}
@SuppressWarnings("deprecation")
@Override
public BlockState mirror(final BlockState state, final Mirror mirrorIn) {
return state.rotate(mirrorIn.toRotation(state.get(HorizontalBlock.HORIZONTAL_FACING)));
}
@Override
public boolean hasTileEntity(final BlockState state) {
return true;
}
@Nullable
@Override
public TileEntity createTileEntity(final BlockState state, final IBlockReader world) {
return TileEntities.CHARGER_TILE_ENTITY.get().create();
}
@Override
public BlockState getStateForPlacement(final BlockItemUseContext context) {
return super.getDefaultState().with(HorizontalBlock.HORIZONTAL_FACING, context.getPlacementHorizontalFacing().getOpposite());
}
///////////////////////////////////////////////////////////////////
@Override
protected void fillStateContainer(final StateContainer.Builder<Block, BlockState> builder) {
super.fillStateContainer(builder);
builder.add(HorizontalBlock.HORIZONTAL_FACING);
}
}

View File

@@ -12,7 +12,7 @@ import li.cil.oc2.common.integration.Wrenches;
import li.cil.oc2.common.item.Items;
import li.cil.oc2.common.tileentity.ComputerTileEntity;
import li.cil.oc2.common.tileentity.TileEntities;
import li.cil.oc2.common.util.ItemStackUtils;
import li.cil.oc2.common.util.NBTUtils;
import li.cil.oc2.common.util.TooltipUtils;
import li.cil.oc2.common.util.VoxelShapeUtils;
import net.minecraft.block.Block;
@@ -54,6 +54,8 @@ import net.minecraftforge.fml.network.NetworkHooks;
import javax.annotation.Nullable;
import java.util.List;
import static li.cil.oc2.common.Constants.BLOCK_ENTITY_TAG_NAME_IN_ITEM;
import static li.cil.oc2.common.Constants.ITEMS_TAG_NAME;
import static li.cil.oc2.common.util.NBTUtils.makeInventoryTag;
public final class ComputerBlock extends HorizontalBlock {
@@ -94,6 +96,7 @@ public final class ComputerBlock extends HorizontalBlock {
public void addInformation(final ItemStack stack, @Nullable final IBlockReader world, final List<ITextComponent> tooltip, final ITooltipFlag advanced) {
super.addInformation(stack, world, tooltip, advanced);
TooltipUtils.addTileEntityInventoryInformation(stack, tooltip);
TooltipUtils.addTileEntityEnergyInformation(stack, tooltip);
}
@Override
@@ -246,19 +249,19 @@ public final class ComputerBlock extends HorizontalBlock {
private ItemStack getPreconfiguredComputer() {
final ItemStack computer = new ItemStack(Items.COMPUTER.get());
final CompoundNBT computerItems = ItemStackUtils.getOrCreateTileEntityInventoryTag(computer);
computerItems.put(DeviceTypes.MEMORY.getRegistryName().toString(), makeInventoryTag(
final CompoundNBT itemsTag = NBTUtils.getOrCreateChildTag(computer.getOrCreateTag(), BLOCK_ENTITY_TAG_NAME_IN_ITEM, ITEMS_TAG_NAME);
itemsTag.put(DeviceTypes.MEMORY.getRegistryName().toString(), makeInventoryTag(
Items.MEMORY.get().withCapacity(8 * Constants.MEGABYTE),
Items.MEMORY.get().withCapacity(8 * Constants.MEGABYTE),
Items.MEMORY.get().withCapacity(8 * Constants.MEGABYTE)
));
computerItems.put(DeviceTypes.HARD_DRIVE.getRegistryName().toString(), makeInventoryTag(
itemsTag.put(DeviceTypes.HARD_DRIVE.getRegistryName().toString(), makeInventoryTag(
Items.HARD_DRIVE.get().withData(BlockDeviceDataRegistration.BUILDROOT.get())
));
computerItems.put(DeviceTypes.FLASH_MEMORY.getRegistryName().toString(), makeInventoryTag(
itemsTag.put(DeviceTypes.FLASH_MEMORY.getRegistryName().toString(), makeInventoryTag(
Items.FLASH_MEMORY.get().withFirmware(Firmwares.BUILDROOT.get())
));
computerItems.put(DeviceTypes.CARD.getRegistryName().toString(), makeInventoryTag(
itemsTag.put(DeviceTypes.CARD.getRegistryName().toString(), makeInventoryTag(
new ItemStack(Items.NETWORK_INTERFACE_CARD.get())
));

View File

@@ -49,31 +49,31 @@ public abstract class AbstractGroupingDeviceBusElement<TProvider extends IForgeR
@Override
public ListNBT serializeNBT() {
final ListNBT nbt = new ListNBT();
final ListNBT listTag = new ListNBT();
for (int i = 0; i < groupCount; i++) {
serializeDevices(i);
final CompoundNBT sideNbt = new CompoundNBT();
final CompoundNBT sideTag = new CompoundNBT();
sideNbt.putUniqueId(GROUP_ID_TAG_NAME, groupIds[i]);
sideNbt.put(GROUP_DATA_TAG_NAME, groupData[i]);
sideTag.putUniqueId(GROUP_ID_TAG_NAME, groupIds[i]);
sideTag.put(GROUP_DATA_TAG_NAME, groupData[i]);
nbt.add(sideNbt);
listTag.add(sideTag);
}
return nbt;
return listTag;
}
@Override
public void deserializeNBT(final ListNBT nbt) {
final int count = Math.min(groupCount, nbt.size());
for (int i = 0; i < count; i++) {
final CompoundNBT sideNbt = nbt.getCompound(i);
final CompoundNBT sideTag = nbt.getCompound(i);
if (sideNbt.hasUniqueId(GROUP_ID_TAG_NAME)) {
groupIds[i] = sideNbt.getUniqueId(GROUP_ID_TAG_NAME);
if (sideTag.hasUniqueId(GROUP_ID_TAG_NAME)) {
groupIds[i] = sideTag.getUniqueId(GROUP_ID_TAG_NAME);
}
if (sideNbt.contains(GROUP_DATA_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
groupData[i] = sideNbt.getCompound(GROUP_DATA_TAG_NAME);
if (sideTag.contains(GROUP_DATA_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
groupData[i] = sideTag.getCompound(GROUP_DATA_TAG_NAME);
}
}
}
@@ -110,14 +110,14 @@ public abstract class AbstractGroupingDeviceBusElement<TProvider extends IForgeR
oldDevices.removeAll(removedDevices);
oldDevices.addAll(newDevices);
final CompoundNBT devicesNbt = groupData[index];
final CompoundNBT devicesTag = groupData[index];
for (final TDeviceInfo deviceInfo : removedDevices) {
ItemDeviceUtils.getItemDeviceDataKey(deviceInfo.provider).ifPresent(devicesNbt::remove);
ItemDeviceUtils.getItemDeviceDataKey(deviceInfo.provider).ifPresent(devicesTag::remove);
}
for (final TDeviceInfo deviceInfo : addedDevices) {
ItemDeviceUtils.getItemDeviceDataKey(deviceInfo.provider).ifPresent(key -> {
if (devicesNbt.contains(key, NBTTagIds.TAG_COMPOUND)) {
deviceInfo.device.deserializeNBT(devicesNbt.getCompound(key));
if (devicesTag.contains(key, NBTTagIds.TAG_COMPOUND)) {
deviceInfo.device.deserializeNBT(devicesTag.getCompound(key));
}
});
}
@@ -128,16 +128,16 @@ public abstract class AbstractGroupingDeviceBusElement<TProvider extends IForgeR
///////////////////////////////////////////////////////////////////
private void serializeDevices(final int index) {
final CompoundNBT devicesNbt = new CompoundNBT();
final CompoundNBT devicesTag = new CompoundNBT();
for (final TDeviceInfo deviceInfo : groups.get(index)) {
ItemDeviceUtils.getItemDeviceDataKey(deviceInfo.provider).ifPresent(key -> {
final CompoundNBT deviceNbt = deviceInfo.device.serializeNBT();
if (!deviceNbt.isEmpty()) {
devicesNbt.put(key, deviceNbt);
final CompoundNBT deviceTag = deviceInfo.device.serializeNBT();
if (!deviceTag.isEmpty()) {
devicesTag.put(key, deviceTag);
}
});
}
groupData[index] = devicesNbt;
groupData[index] = devicesTag;
}
}

View File

@@ -40,32 +40,35 @@ public class ItemHandlerDeviceBusElement extends AbstractGroupingItemDeviceBusEl
return;
}
final CompoundNBT exportedNbt = new CompoundNBT();
final CompoundNBT exportedTag = new CompoundNBT();
for (final ItemDeviceInfo info : groups.get(slot)) {
ItemDeviceUtils.getItemDeviceDataKey(info.provider).ifPresent(key -> {
final CompoundNBT deviceNbt = new CompoundNBT();
info.device.exportToItemStack(deviceNbt);
if (!deviceNbt.isEmpty()) {
exportedNbt.put(key, deviceNbt);
final CompoundNBT deviceTag = new CompoundNBT();
info.device.exportToItemStack(deviceTag);
if (!deviceTag.isEmpty()) {
exportedTag.put(key, deviceTag);
}
});
}
ItemDeviceUtils.setItemDeviceData(stack, exportedNbt);
if (!exportedTag.isEmpty()) {
ItemDeviceUtils.setItemDeviceData(stack, exportedTag);
}
}
///////////////////////////////////////////////////////////////////
private void importDeviceDataFromItemStack(final ItemStack stack, final HashSet<ItemDeviceInfo> devices) {
ItemDeviceUtils.getItemDeviceData(stack).ifPresent(exportedNbt -> {
final CompoundNBT exportedTag = ItemDeviceUtils.getItemDeviceData(stack);
if (!exportedTag.isEmpty()) {
for (final ItemDeviceInfo info : devices) {
ItemDeviceUtils.getItemDeviceDataKey(info.provider).ifPresent(key -> {
if (exportedNbt.contains(key, NBTTagIds.TAG_COMPOUND)) {
info.device.importFromItemStack(exportedNbt.getCompound(key));
if (exportedTag.contains(key, NBTTagIds.TAG_COMPOUND)) {
info.device.importFromItemStack(exportedTag.getCompound(key));
}
});
}
});
}
}
private void insertItemNameDevice(final ItemStack stack, final HashSet<ItemDeviceInfo> devices) {

View File

@@ -41,7 +41,7 @@ public abstract class AbstractBlockDeviceVMDevice<TBlock extends BlockDevice, TI
// Online persisted data.
private final OptionalAddress address = new OptionalAddress();
private final OptionalInterrupt interrupt = new OptionalInterrupt();
private CompoundNBT deviceNbt;
private CompoundNBT deviceTag;
// Offline persisted data.
protected UUID blobHandle;
@@ -76,8 +76,8 @@ public abstract class AbstractBlockDeviceVMDevice<TBlock extends BlockDevice, TI
deserializeData();
if (deviceNbt != null) {
NBTSerialization.deserialize(deviceNbt, device);
if (deviceTag != null) {
NBTSerialization.deserialize(deviceTag, device);
}
return VMDeviceLoadResult.success();
@@ -95,7 +95,7 @@ public abstract class AbstractBlockDeviceVMDevice<TBlock extends BlockDevice, TI
jobHandle = null;
device = null;
deviceNbt = null;
deviceTag = null;
address.clear();
interrupt.clear();
}
@@ -128,10 +128,10 @@ public abstract class AbstractBlockDeviceVMDevice<TBlock extends BlockDevice, TI
serializeData();
if (device != null) {
deviceNbt = NBTSerialization.serialize(device);
deviceTag = NBTSerialization.serialize(device);
}
if (deviceNbt != null) {
tag.put(DEVICE_TAG_NAME, deviceNbt);
if (deviceTag != null) {
tag.put(DEVICE_TAG_NAME, deviceTag);
}
if (address.isPresent()) {
tag.putLong(ADDRESS_TAG_NAME, address.getAsLong());
@@ -154,7 +154,7 @@ public abstract class AbstractBlockDeviceVMDevice<TBlock extends BlockDevice, TI
}
if (tag.contains(DEVICE_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
deviceNbt = tag.getCompound(DEVICE_TAG_NAME);
deviceTag = tag.getCompound(DEVICE_TAG_NAME);
}
if (tag.contains(ADDRESS_TAG_NAME, NBTTagIds.TAG_LONG)) {
address.set(tag.getLong(ADDRESS_TAG_NAME));

View File

@@ -35,7 +35,7 @@ public final class ByteBufferFlashMemoryVMDevice extends IdentityProxy<ItemStack
///////////////////////////////////////////////////////////////
// Online persisted data.
private CompoundNBT deviceNbt;
private CompoundNBT deviceTag;
private final OptionalAddress address = new OptionalAddress();
///////////////////////////////////////////////////////////////
@@ -71,7 +71,7 @@ public final class ByteBufferFlashMemoryVMDevice extends IdentityProxy<ItemStack
memoryMap = null;
data = null;
device = null;
deviceNbt = null;
deviceTag = null;
address.clear();
}
@@ -113,10 +113,10 @@ public final class ByteBufferFlashMemoryVMDevice extends IdentityProxy<ItemStack
}
private void loadPersistedState() {
if (deviceNbt != null) {
if (deviceTag != null) {
data.clear();
final byte[] persistedData = deviceNbt.getByteArray(DATA_TAG_NAME);
final byte[] persistedData = deviceTag.getByteArray(DATA_TAG_NAME);
data.put(persistedData, 0, Math.min(persistedData.length, data.capacity()));
}
}

View File

@@ -82,19 +82,19 @@ public final class MemoryDevice extends IdentityProxy<ItemStack> implements VMDe
@Override
public CompoundNBT serializeNBT() {
final CompoundNBT nbt = new CompoundNBT();
final CompoundNBT tag = new CompoundNBT();
if (device != null) {
blobHandle = BlobStorage.validateHandle(blobHandle);
nbt.putUniqueId(BLOB_HANDLE_TAG_NAME, blobHandle);
tag.putUniqueId(BLOB_HANDLE_TAG_NAME, blobHandle);
jobHandle = BlobStorage.submitSave(blobHandle, new PhysicalMemoryInputStream(device));
}
if (address.isPresent()) {
nbt.putLong(ADDRESS_TAG_NAME, address.getAsLong());
tag.putLong(ADDRESS_TAG_NAME, address.getAsLong());
}
return nbt;
return tag;
}
@Override

View File

@@ -38,7 +38,7 @@ public final class NetworkInterfaceCardItemDevice extends IdentityProxy<ItemStac
private final OptionalAddress address = new OptionalAddress();
private final OptionalInterrupt interrupt = new OptionalInterrupt();
private CompoundNBT deviceNbt;
private CompoundNBT deviceTag;
///////////////////////////////////////////////////////////////
@@ -71,8 +71,8 @@ public final class NetworkInterfaceCardItemDevice extends IdentityProxy<ItemStac
return VMDeviceLoadResult.fail();
}
if (deviceNbt != null) {
NBTSerialization.deserialize(deviceNbt, device);
if (deviceTag != null) {
NBTSerialization.deserialize(deviceTag, device);
}
context.getEventBus().register(this);
@@ -103,10 +103,10 @@ public final class NetworkInterfaceCardItemDevice extends IdentityProxy<ItemStac
final CompoundNBT tag = new CompoundNBT();
if (device != null) {
deviceNbt = NBTSerialization.serialize(device);
deviceTag = NBTSerialization.serialize(device);
}
if (deviceNbt != null) {
tag.put(DEVICE_TAG_NAME, deviceNbt);
if (deviceTag != null) {
tag.put(DEVICE_TAG_NAME, deviceTag);
}
if (address.isPresent()) {
tag.putLong(ADDRESS_TAG_NAME, address.getAsLong());
@@ -121,7 +121,7 @@ public final class NetworkInterfaceCardItemDevice extends IdentityProxy<ItemStac
@Override
public void deserializeNBT(final CompoundNBT tag) {
if (tag.contains(DEVICE_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
deviceNbt = tag.getCompound(DEVICE_TAG_NAME);
deviceTag = tag.getCompound(DEVICE_TAG_NAME);
}
if (tag.contains(ADDRESS_TAG_NAME, NBTTagIds.TAG_LONG)) {
address.set(tag.getLong(ADDRESS_TAG_NAME));

View File

@@ -42,15 +42,15 @@ public class DeviceItemStackHandler extends FixedSizeItemStackHandler {
@Override
public CompoundNBT serializeNBT() {
final CompoundNBT nbt = super.serializeNBT();
nbt.put(BUS_ELEMENT_TAG_NAME, busElement.serializeNBT());
return nbt;
final CompoundNBT tag = super.serializeNBT();
tag.put(BUS_ELEMENT_TAG_NAME, busElement.serializeNBT());
return tag;
}
@Override
public void deserializeNBT(final CompoundNBT nbt) {
super.deserializeNBT(nbt);
busElement.deserializeNBT(nbt.getList(BUS_ELEMENT_TAG_NAME, NBTTagIds.TAG_COMPOUND));
public void deserializeNBT(final CompoundNBT tag) {
super.deserializeNBT(tag);
busElement.deserializeNBT(tag.getList(BUS_ELEMENT_TAG_NAME, NBTTagIds.TAG_COMPOUND));
for (int slot = 0; slot < getSlots(); slot++) {
busElement.updateDevices(slot, getStackInSlot(slot));
}

View File

@@ -0,0 +1,69 @@
package li.cil.oc2.common.energy;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.util.NBTUtils;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class EnergyStorageItemStack implements IEnergyStorage, ICapabilityProvider {
private final LazyOptional<IEnergyStorage> optional = LazyOptional.of(() -> this);
private final ItemStack stack;
private final int capacity;
private final String[] tagPath;
public EnergyStorageItemStack(final ItemStack stack, final int capacity, final String... tagPath) {
this.stack = stack;
this.capacity = capacity;
this.tagPath = tagPath;
}
@Override
public int receiveEnergy(final int maxReceive, final boolean simulate) {
final int stored = getEnergyStored();
final int receiveLimit = capacity - stored;
final int receive = Math.min(maxReceive, receiveLimit);
if (!simulate) {
NBTUtils.getOrCreateChildTag(stack.getOrCreateTag(), tagPath)
.putInt(FixedEnergyStorage.STORED_TAG_NAME, stored + receive);
}
return receive;
}
@Override
public int extractEnergy(final int maxExtract, final boolean simulate) {
return 0;
}
@Override
public int getEnergyStored() {
return NBTUtils.getChildTag(stack.getTag(), tagPath).getInt(FixedEnergyStorage.STORED_TAG_NAME);
}
@Override
public int getMaxEnergyStored() {
return capacity;
}
@Override
public boolean canExtract() {
return false; // We don't want our items to be usable as batteries.
}
@Override
public boolean canReceive() {
return true;
}
@NotNull
@Override
public <T> LazyOptional<T> getCapability(@NotNull final Capability<T> capability, @Nullable final Direction side) {
return Capabilities.ENERGY_STORAGE.orEmpty(capability, optional);
}
}

View File

@@ -0,0 +1,27 @@
package li.cil.oc2.common.energy;
import net.minecraft.nbt.CompoundNBT;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.energy.EnergyStorage;
public final class FixedEnergyStorage extends EnergyStorage implements INBTSerializable<CompoundNBT> {
public static final String STORED_TAG_NAME = "stored";
public static final String CAPACITY_TAG_NAME = "capacity";
public FixedEnergyStorage(final int capacity) {
super(capacity);
}
@Override
public CompoundNBT serializeNBT() {
final CompoundNBT tag = new CompoundNBT();
tag.putInt(STORED_TAG_NAME, energy);
tag.putInt(CAPACITY_TAG_NAME, capacity); // Mostly for tooltips.
return tag;
}
@Override
public void deserializeNBT(final CompoundNBT tag) {
energy = tag.getInt(STORED_TAG_NAME);
}
}

View File

@@ -0,0 +1,7 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package li.cil.oc2.common.energy;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -7,6 +7,7 @@ import li.cil.oc2.api.bus.device.object.Callback;
import li.cil.oc2.api.bus.device.object.ObjectDevice;
import li.cil.oc2.api.bus.device.object.Parameter;
import li.cil.oc2.api.capabilities.Robot;
import li.cil.oc2.common.Config;
import li.cil.oc2.common.Constants;
import li.cil.oc2.common.bus.AbstractDeviceBusElement;
import li.cil.oc2.common.bus.CommonDeviceBusController;
@@ -16,13 +17,17 @@ import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.container.FixedSizeItemStackHandler;
import li.cil.oc2.common.container.RobotContainer;
import li.cil.oc2.common.container.RobotTerminalContainer;
import li.cil.oc2.common.energy.FixedEnergyStorage;
import li.cil.oc2.common.entity.robot.*;
import li.cil.oc2.common.integration.Wrenches;
import li.cil.oc2.common.item.Items;
import li.cil.oc2.common.network.Network;
import li.cil.oc2.common.network.message.*;
import li.cil.oc2.common.serialization.NBTSerialization;
import li.cil.oc2.common.util.*;
import li.cil.oc2.common.util.NBTTagIds;
import li.cil.oc2.common.util.NBTUtils;
import li.cil.oc2.common.util.TerminalUtils;
import li.cil.oc2.common.util.WorldUtils;
import li.cil.oc2.common.vm.*;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -54,6 +59,7 @@ import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.api.distmarker.Dist;
@@ -61,7 +67,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.Constants.BlockFlags;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
@@ -74,6 +79,8 @@ import java.nio.ByteBuffer;
import java.util.*;
import java.util.function.Consumer;
import static li.cil.oc2.common.Constants.*;
public final class RobotEntity extends Entity implements Robot {
public static final DataParameter<BlockPos> TARGET_POSITION = EntityDataManager.createKey(RobotEntity.class, DataSerializers.BLOCK_POS);
public static final DataParameter<Direction> TARGET_DIRECTION = EntityDataManager.createKey(RobotEntity.class, DataSerializers.DIRECTION);
@@ -105,9 +112,10 @@ public final class RobotEntity extends Entity implements Robot {
private final RobotActionProcessor actionProcessor = new RobotActionProcessor();
private final Terminal terminal = new Terminal();
private final RobotVirtualMachine virtualMachine;
private final RobotItemStackHandlers deviceItems = new RobotItemStackHandlers();
private final ItemStackHandler inventory = new FixedSizeItemStackHandler(INVENTORY_SIZE);
private final RobotBusElement busElement = new RobotBusElement();
private final RobotItemStackHandlers deviceItems = new RobotItemStackHandlers();
private final FixedEnergyStorage energy = new FixedEnergyStorage(Config.robotEnergyStorage);
private final ItemStackHandler inventory = new FixedSizeItemStackHandler(INVENTORY_SIZE);
private long lastPistonMovement;
///////////////////////////////////////////////////////////////////
@@ -164,6 +172,9 @@ public final class RobotEntity extends Entity implements Robot {
if (capability == Capabilities.ITEM_HANDLER) {
return LazyOptional.of(() -> inventory).cast();
}
if (capability == Capabilities.ENERGY_STORAGE && Config.robotsUseEnergy()) {
return LazyOptional.of(() -> energy).cast();
}
if (capability == Capabilities.ROBOT) {
return LazyOptional.of(() -> this).cast();
}
@@ -342,17 +353,20 @@ public final class RobotEntity extends Entity implements Robot {
}
public void exportToItemStack(final ItemStack stack) {
final CompoundNBT tag = ItemStackUtils.getOrCreateEntityInventoryTag(stack);
deviceItems.serialize(tag);
tag.put(INVENTORY_TAG_NAME, inventory.serializeNBT());
final CompoundNBT itemsTag = NBTUtils.getOrCreateChildTag(stack.getOrCreateTag(), MOD_TAG_NAME, Constants.ITEMS_TAG_NAME);
deviceItems.serialize(itemsTag); // Puts one tag per device type, as expected by TooltipUtils.
itemsTag.put(INVENTORY_TAG_NAME, inventory.serializeNBT()); // Won't show up in tooltip.
NBTUtils.getOrCreateChildTag(stack.getOrCreateTag(), MOD_TAG_NAME)
.put(ENERGY_TAG_NAME, energy.serializeNBT());
}
public void importFromItemStack(final ItemStack stack) {
final CompoundNBT tag = ItemStackUtils.getEntityInventoryTag(stack);
if (tag != null) {
deviceItems.deserialize(tag);
inventory.deserializeNBT(tag.getCompound(INVENTORY_TAG_NAME));
}
final CompoundNBT itemsTag = NBTUtils.getChildTag(stack.getTag(), MOD_TAG_NAME, ITEMS_TAG_NAME);
deviceItems.deserialize(itemsTag);
inventory.deserializeNBT(itemsTag.getCompound(INVENTORY_TAG_NAME));
energy.deserializeNBT(NBTUtils.getChildTag(stack.getTag(), MOD_TAG_NAME, ENERGY_TAG_NAME));
}
///////////////////////////////////////////////////////////////////
@@ -371,7 +385,8 @@ public final class RobotEntity extends Entity implements Robot {
tag.put(TERMINAL_TAG_NAME, NBTSerialization.serialize(terminal));
tag.put(COMMAND_PROCESSOR_TAG_NAME, actionProcessor.serialize());
tag.put(BUS_ELEMENT_TAG_NAME, busElement.serialize());
tag.put(Constants.INVENTORY_TAG_NAME, deviceItems.serialize());
tag.put(Constants.ITEMS_TAG_NAME, deviceItems.serialize());
tag.put(ENERGY_TAG_NAME, energy.serializeNBT());
tag.put(INVENTORY_TAG_NAME, inventory.serializeNBT());
tag.putByte(SELECTED_SLOT_TAG_NAME, dataManager.get(SELECTED_SLOT));
}
@@ -382,11 +397,9 @@ public final class RobotEntity extends Entity implements Robot {
NBTSerialization.deserialize(tag.getCompound(TERMINAL_TAG_NAME), terminal);
actionProcessor.deserialize(tag.getCompound(COMMAND_PROCESSOR_TAG_NAME));
busElement.deserialize(tag.getCompound(BUS_ELEMENT_TAG_NAME));
deviceItems.deserialize(tag.getCompound(Constants.ITEMS_TAG_NAME));
energy.deserializeNBT(tag.getCompound(ENERGY_TAG_NAME));
inventory.deserializeNBT(tag.getCompound(INVENTORY_TAG_NAME));
if (tag.contains(Constants.INVENTORY_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
deviceItems.deserialize(tag.getCompound(Constants.INVENTORY_TAG_NAME));
}
setSelectedSlot(tag.getByte(SELECTED_SLOT_TAG_NAME));
}
@@ -780,8 +793,30 @@ public final class RobotEntity extends Entity implements Robot {
}
@Override
protected AbstractTerminalVMRunner createRunner() {
return new RobotVMRunner(this, terminal);
protected void load() {
if (Config.robotsUseEnergy()) {
// Don't even start running if we couldn't keep running.
if (energy.getEnergyStored() < Config.robotEnergyPerTick) {
error(new TranslationTextComponent(Constants.COMPUTER_ERROR_NOT_ENOUGH_ENERGY));
return;
}
}
super.load();
}
@Override
protected void run() {
if (Config.robotsUseEnergy()) {
if (energy.getEnergyStored() >= Config.robotEnergyPerTick) {
energy.extractEnergy(Config.robotEnergyPerTick, false);
} else {
error(new TranslationTextComponent(Constants.COMPUTER_ERROR_NOT_ENOUGH_ENERGY));
return;
}
}
super.run();
}
@Override
@@ -794,6 +829,11 @@ public final class RobotEntity extends Entity implements Robot {
actionProcessor.clear();
}
@Override
protected AbstractTerminalVMRunner createRunner() {
return new RobotVMRunner(this, terminal);
}
@Override
protected void handleBusStateChanged(final CommonDeviceBusController.BusState value) {
Network.sendToClientsTrackingEntity(new RobotBusStateMessage(RobotEntity.this), RobotEntity.this);

View File

@@ -7,6 +7,7 @@ import li.cil.oc2.common.util.NBTTagIds;
import li.cil.oc2.common.util.NBTUtils;
import net.minecraft.entity.MoverType;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
@@ -116,13 +117,13 @@ public final class RobotMovementAction extends AbstractRobotAction {
NBTUtils.putEnum(tag, DIRECTION_TAG_NAME, direction);
if (origin != null) {
NBTUtils.putBlockPos(tag, ORIGIN_TAG_NAME, origin);
tag.put(ORIGIN_TAG_NAME, NBTUtil.writeBlockPos(origin));
}
if (start != null) {
NBTUtils.putBlockPos(tag, START_TAG_NAME, start);
tag.put(START_TAG_NAME, NBTUtil.writeBlockPos(start));
}
if (target != null) {
NBTUtils.putBlockPos(tag, TARGET_TAG_NAME, target);
tag.put(TARGET_TAG_NAME, NBTUtil.writeBlockPos(target));
}
return tag;
@@ -134,13 +135,13 @@ public final class RobotMovementAction extends AbstractRobotAction {
direction = NBTUtils.getEnum(tag, DIRECTION_TAG_NAME, MovementDirection.class);
if (tag.contains(ORIGIN_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
origin = NBTUtils.getBlockPos(tag, ORIGIN_TAG_NAME);
origin = NBTUtil.readBlockPos(tag.getCompound(ORIGIN_TAG_NAME));
}
if (tag.contains(START_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
start = NBTUtils.getBlockPos(tag, START_TAG_NAME);
start = NBTUtil.readBlockPos(tag.getCompound(START_TAG_NAME));
}
if (tag.contains(TARGET_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
target = NBTUtils.getBlockPos(tag, TARGET_TAG_NAME);
target = NBTUtil.readBlockPos(tag.getCompound(TARGET_TAG_NAME));
targetPos = getTargetPositionInBlock(target);
}
}

View File

@@ -3,11 +3,10 @@ package li.cil.oc2.common.item;
import li.cil.oc2.api.bus.device.data.BlockDeviceData;
import li.cil.oc2.common.bus.device.data.BlockDeviceDataRegistration;
import li.cil.oc2.common.util.ItemStackUtils;
import li.cil.oc2.common.util.NBTTagIds;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.ResourceLocationException;
import net.minecraft.util.StringUtils;
import net.minecraft.util.text.ITextComponent;
import javax.annotation.Nullable;
@@ -24,13 +23,11 @@ public abstract class AbstractBlockDeviceItem extends AbstractStorageItem {
return null;
}
final CompoundNBT modNbt = ItemStackUtils.getModDataTag(stack);
if (modNbt == null || !modNbt.contains(DATA_TAG_NAME, NBTTagIds.TAG_STRING)) {
final String registryName = ItemStackUtils.getModDataTag(stack).getString(DATA_TAG_NAME);
if (StringUtils.isNullOrEmpty(registryName)) {
return null;
}
final String registryName = modNbt.getString(DATA_TAG_NAME);
try {
return BlockDeviceDataRegistration.REGISTRY.get().getValue(new ResourceLocation(registryName));
} catch (final ResourceLocationException ignored) {
@@ -58,12 +55,7 @@ public abstract class AbstractBlockDeviceItem extends AbstractStorageItem {
return false;
}
final CompoundNBT modNbt = ItemStackUtils.getModDataTag(stack);
if (modNbt == null) {
return false;
}
return modNbt.getBoolean(READONLY_TAG_NAME);
return ItemStackUtils.getModDataTag(stack).getBoolean(READONLY_TAG_NAME);
}
public static ItemStack withReadonly(final ItemStack stack, final boolean readonly) {

View File

@@ -26,13 +26,12 @@ public abstract class AbstractStorageItem extends ModItem {
return 0;
}
final CompoundNBT modNbt = ItemStackUtils.getModDataTag(stack);
if (modNbt == null || !modNbt.contains(CAPACITY_TAG_NAME, NBTTagIds.TAG_INT)) {
final AbstractStorageItem storageItem = (AbstractStorageItem) item;
return storageItem.defaultCapacity;
final CompoundNBT tag = ItemStackUtils.getModDataTag(stack);
if (!tag.contains(CAPACITY_TAG_NAME, NBTTagIds.TAG_INT)) {
return ((AbstractStorageItem) item).defaultCapacity;
}
return modNbt.getInt(CAPACITY_TAG_NAME);
return tag.getInt(CAPACITY_TAG_NAME);
}
public static ItemStack withCapacity(final ItemStack stack, final int capacity) {

View File

@@ -0,0 +1,22 @@
package li.cil.oc2.common.item;
import li.cil.oc2.common.Config;
import net.minecraft.block.Block;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
public final class ChargerItem extends ModBlockItem {
public ChargerItem(final Block block) {
super(block);
}
///////////////////////////////////////////////////////////////////
@Override
public void fillItemGroup(final ItemGroup group, final NonNullList<ItemStack> items) {
if (Config.chargerUseEnergy()) {
super.fillItemGroup(group, items);
}
}
}

View File

@@ -13,6 +13,7 @@ import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.ResourceLocationException;
import net.minecraft.util.StringUtils;
import net.minecraft.util.text.ITextComponent;
import javax.annotation.Nullable;
@@ -30,13 +31,11 @@ public final class FlashMemoryItem extends AbstractStorageItem {
return null;
}
final CompoundNBT modNbt = ItemStackUtils.getModDataTag(stack);
if (modNbt == null || !modNbt.contains(FIRMWARE_TAG_NAME, NBTTagIds.TAG_STRING)) {
final String registryName = ItemStackUtils.getModDataTag(stack).getString(FIRMWARE_TAG_NAME);
if (StringUtils.isNullOrEmpty(registryName)) {
return null;
}
final String registryName = modNbt.getString(FIRMWARE_TAG_NAME);
try {
return Firmwares.REGISTRY.get().getValue(new ResourceLocation(registryName));
} catch (final ResourceLocationException ignored) {

View File

@@ -25,6 +25,7 @@ public final class Items {
public static final RegistryObject<Item> NETWORK_HUB = register(Constants.NETWORK_HUB_BLOCK_NAME, Blocks.NETWORK_HUB);
public static final RegistryObject<Item> REDSTONE_INTERFACE = register(Constants.REDSTONE_INTERFACE_BLOCK_NAME, Blocks.REDSTONE_INTERFACE);
public static final RegistryObject<Item> DISK_DRIVE = register(Constants.DISK_DRIVE_BLOCK_NAME, Blocks.DISK_DRIVE);
public static final RegistryObject<Item> CHARGER = register(Constants.CHARGER_BLOCK_NAME, Blocks.CHARGER, ChargerItem::new);
///////////////////////////////////////////////////////////////////

View File

@@ -1,6 +1,8 @@
package li.cil.oc2.common.item;
import li.cil.oc2.client.renderer.tileentity.RobotItemStackRenderer;
import li.cil.oc2.common.Config;
import li.cil.oc2.common.energy.EnergyStorageItemStack;
import li.cil.oc2.common.entity.Entities;
import li.cil.oc2.common.entity.RobotEntity;
import li.cil.oc2.common.entity.robot.RobotActions;
@@ -11,6 +13,7 @@ import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.stats.Stats;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
@@ -18,10 +21,14 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import static li.cil.oc2.common.Constants.ENERGY_TAG_NAME;
import static li.cil.oc2.common.Constants.MOD_TAG_NAME;
public final class RobotItem extends ModItem {
public RobotItem() {
super(createProperties().setISTER(() -> RobotItemStackRenderer::new));
@@ -33,6 +40,17 @@ public final class RobotItem extends ModItem {
public void addInformation(final ItemStack stack, @Nullable final World world, final List<ITextComponent> tooltip, final ITooltipFlag flag) {
super.addInformation(stack, world, tooltip, flag);
TooltipUtils.addEntityInventoryInformation(stack, tooltip);
TooltipUtils.addEntityEnergyInformation(stack, tooltip);
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(final ItemStack stack, @Nullable final CompoundNBT nbt) {
if (Config.robotsUseEnergy()) {
return new EnergyStorageItemStack(stack, Config.robotEnergyStorage, MOD_TAG_NAME, ENERGY_TAG_NAME);
} else {
return null;
}
}
@Override

View File

@@ -16,38 +16,38 @@ import java.util.Map;
import java.util.UUID;
public final class NBTSerialization {
public static <T> void serialize(final CompoundNBT nbt, final T value, final Class<T> type) throws SerializationException {
Ceres.getSerializer(type).serialize(new Serializer(nbt), type, value);
public static <T> void serialize(final CompoundNBT tag, final T value, final Class<T> type) throws SerializationException {
Ceres.getSerializer(type).serialize(new Serializer(tag), type, value);
}
public static <T> void serialize(final CompoundNBT nbt, final T value) throws SerializationException {
public static <T> void serialize(final CompoundNBT tag, final T value) throws SerializationException {
@SuppressWarnings("unchecked") final Class<T> type = (Class<T>) value.getClass();
serialize(nbt, value, type);
serialize(tag, value, type);
}
public static <T> CompoundNBT serialize(final T value, final Class<T> type) throws SerializationException {
final CompoundNBT nbt = new CompoundNBT();
serialize(nbt, value, type);
return nbt;
final CompoundNBT tag = new CompoundNBT();
serialize(tag, value, type);
return tag;
}
public static <T> CompoundNBT serialize(final T value) throws SerializationException {
final CompoundNBT nbt = new CompoundNBT();
serialize(nbt, value);
return nbt;
final CompoundNBT tag = new CompoundNBT();
serialize(tag, value);
return tag;
}
public static <T> T deserialize(final CompoundNBT nbt, final Class<T> type, @Nullable final T into) throws SerializationException {
return Ceres.getSerializer(type).deserialize(new Deserializer(nbt), type, into);
public static <T> T deserialize(final CompoundNBT tag, final Class<T> type, @Nullable final T into) throws SerializationException {
return Ceres.getSerializer(type).deserialize(new Deserializer(tag), type, into);
}
public static <T> T deserialize(final CompoundNBT nbt, final Class<T> type) throws SerializationException {
return deserialize(nbt, type, null);
public static <T> T deserialize(final CompoundNBT tag, final Class<T> type) throws SerializationException {
return deserialize(tag, type, null);
}
public static <T> T deserialize(final CompoundNBT nbt, final T into) throws SerializationException {
public static <T> T deserialize(final CompoundNBT tag, final T into) throws SerializationException {
@SuppressWarnings("unchecked") final Class<T> type = (Class<T>) into.getClass();
return deserialize(nbt, type, into);
return deserialize(tag, type, into);
}
///////////////////////////////////////////////////////////////////
@@ -71,50 +71,50 @@ public final class NBTSerialization {
}
private static final class Serializer implements SerializationVisitor {
private final CompoundNBT nbt;
private final CompoundNBT tag;
private Serializer(final CompoundNBT nbt) {
this.nbt = nbt;
private Serializer(final CompoundNBT tag) {
this.tag = tag;
}
@Override
public void putBoolean(final String name, final boolean value) {
nbt.putBoolean(name, value);
tag.putBoolean(name, value);
}
@Override
public void putByte(final String name, final byte value) {
nbt.putByte(name, value);
tag.putByte(name, value);
}
@Override
public void putChar(final String name, final char value) {
nbt.putInt(name, value);
tag.putInt(name, value);
}
@Override
public void putShort(final String name, final short value) {
nbt.putShort(name, value);
tag.putShort(name, value);
}
@Override
public void putInt(final String name, final int value) {
nbt.putInt(name, value);
tag.putInt(name, value);
}
@Override
public void putLong(final String name, final long value) {
nbt.putLong(name, value);
tag.putLong(name, value);
}
@Override
public void putFloat(final String name, final float value) {
nbt.putFloat(name, value);
tag.putFloat(name, value);
}
@Override
public void putDouble(final String name, final double value) {
nbt.putDouble(name, value);
tag.putDouble(name, value);
}
@SuppressWarnings({"unchecked", "rawtypes"})
@@ -125,20 +125,20 @@ public final class NBTSerialization {
}
if (type.isArray()) {
nbt.put(name, putArray(name, type, value));
tag.put(name, putArray(name, type, value));
} else if (type.isEnum()) {
nbt.putString(name, ((Enum) value).name());
tag.putString(name, ((Enum) value).name());
} else if (type == String.class) {
nbt.putString(name, (String) value);
tag.putString(name, (String) value);
} else if (type == UUID.class) {
final CompoundNBT uuidNBT = new CompoundNBT();
uuidNBT.putUniqueId(name, (UUID) value);
nbt.put(name, uuidNBT);
final CompoundNBT uuidTag = new CompoundNBT();
uuidTag.putUniqueId(name, (UUID) value);
tag.put(name, uuidTag);
} else {
final CompoundNBT valueNBT = new CompoundNBT();
Ceres.getSerializer(type).serialize(new Serializer(valueNBT), (Class) type, value);
if (!valueNBT.isEmpty()) {
nbt.put(name, valueNBT);
final CompoundNBT valueTag = new CompoundNBT();
Ceres.getSerializer(type).serialize(new Serializer(valueTag), (Class) type, value);
if (!valueTag.isEmpty()) {
tag.put(name, valueTag);
}
}
}
@@ -162,13 +162,13 @@ public final class NBTSerialization {
} else {
final li.cil.ceres.api.Serializer<?> serializer = Ceres.getSerializer(componentType);
componentSerializer = (t, v) -> {
final CompoundNBT nbt = new CompoundNBT();
serializer.serialize(new Serializer(nbt), (Class) t, v);
return nbt;
final CompoundNBT tag = new CompoundNBT();
serializer.serialize(new Serializer(tag), (Class) t, v);
return tag;
};
}
final ListNBT listNBT = new ListNBT();
final ListNBT listTag = new ListNBT();
final IntArrayList nullIndices = new IntArrayList();
final Object[] data = (Object[]) value;
@@ -180,18 +180,18 @@ public final class NBTSerialization {
if (datum.getClass() != componentType) {
throw new SerializationException(String.format("Polymorphism detected in generic array [%s]. This is not supported.", name));
}
listNBT.add(componentSerializer.serialize(componentType, datum));
listTag.add(componentSerializer.serialize(componentType, datum));
}
}
if (nullIndices.isEmpty()) {
return listNBT;
return listTag;
} else {
final CompoundNBT arrayNbt = new CompoundNBT();
arrayNbt.put("value", listNBT);
arrayNbt.putIntArray("nulls", nullIndices);
final CompoundNBT arrayTag = new CompoundNBT();
arrayTag.put("value", listTag);
arrayTag.putIntArray("nulls", nullIndices);
return arrayNbt;
return arrayTag;
}
}
}
@@ -200,59 +200,59 @@ public final class NBTSerialization {
private boolean putIsNull(final String name, @Nullable final Object value) {
final boolean isNull = value == null;
if (isNull) {
final CompoundNBT nullNBT = new CompoundNBT();
nullNBT.putBoolean(IS_NULL_KEY, true);
nbt.put(name, nullNBT);
final CompoundNBT nullTag = new CompoundNBT();
nullTag.putBoolean(IS_NULL_KEY, true);
tag.put(name, nullTag);
}
return isNull;
}
}
private static final class Deserializer implements DeserializationVisitor {
private final CompoundNBT nbt;
private final CompoundNBT tag;
private Deserializer(final CompoundNBT nbt) {
this.nbt = nbt;
private Deserializer(final CompoundNBT tag) {
this.tag = tag;
}
@Override
public boolean getBoolean(final String name) {
return nbt.getBoolean(name);
return tag.getBoolean(name);
}
@Override
public byte getByte(final String name) {
return nbt.getByte(name);
return tag.getByte(name);
}
@Override
public char getChar(final String name) {
return (char) nbt.getInt(name);
return (char) tag.getInt(name);
}
@Override
public short getShort(final String name) {
return nbt.getShort(name);
return tag.getShort(name);
}
@Override
public int getInt(final String name) {
return nbt.getInt(name);
return tag.getInt(name);
}
@Override
public long getLong(final String name) {
return nbt.getLong(name);
return tag.getLong(name);
}
@Override
public float getFloat(final String name) {
return nbt.getFloat(name);
return tag.getFloat(name);
}
@Override
public double getDouble(final String name) {
return nbt.getDouble(name);
return tag.getDouble(name);
}
@SuppressWarnings({"unchecked", "rawtypes"})
@@ -264,40 +264,40 @@ public final class NBTSerialization {
}
// Do not overwrite values which were not serialized before.
if (!nbt.contains(name)) {
if (!tag.contains(name)) {
return into;
}
if (type.isArray()) {
final INBT arrayNbt = nbt.get(name);
assert arrayNbt != null;
return getArray(arrayNbt, type, into);
final INBT arrayTag = tag.get(name);
assert arrayTag != null;
return getArray(arrayTag, type, into);
} else if (type.isEnum()) {
return Enum.valueOf((Class) type, nbt.getString(name));
return Enum.valueOf((Class) type, tag.getString(name));
} else if (type == String.class) {
return nbt.getString(name);
return tag.getString(name);
} else if (type == UUID.class) {
return nbt.getCompound(name).getUniqueId(name);
return tag.getCompound(name).getUniqueId(name);
} else {
final CompoundNBT valueNBT = nbt.getCompound(name);
return Ceres.getSerializer(type).deserialize(new Deserializer(valueNBT), (Class) type, into);
final CompoundNBT valueTag = tag.getCompound(name);
return Ceres.getSerializer(type).deserialize(new Deserializer(valueTag), (Class) type, into);
}
}
@FunctionalInterface
private interface ArrayComponentDeserializer {
@Nullable
Object deserialize(INBT nbt, Class<?> type, @Nullable Object into);
Object deserialize(INBT tag, Class<?> type, @Nullable Object into);
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Nullable
private static Object getArray(final INBT nbt, final Class<?> type, final @Nullable Object into) {
private static Object getArray(final INBT tag, final Class<?> type, final @Nullable Object into) {
final Class<?> componentType = type.getComponentType();
final ArraySerializer arraySerializer = ARRAY_SERIALIZERS.get(componentType);
if (arraySerializer != null) {
return arraySerializer.deserialize(nbt, type, into);
return arraySerializer.deserialize(tag, type, into);
} else {
final ArrayComponentDeserializer componentDeserializer;
if (componentType.isArray()) {
@@ -308,24 +308,24 @@ public final class NBTSerialization {
}
Object[] data = (Object[]) into;
final ListNBT listNBT;
final ListNBT listTag;
final int[] nulls;
int nullsIndex = 0;
if (nbt instanceof ListNBT) {
listNBT = (ListNBT) nbt;
if (tag instanceof ListNBT) {
listTag = (ListNBT) tag;
nulls = new int[0];
} else if (nbt instanceof CompoundNBT) {
listNBT = (ListNBT) ((CompoundNBT) nbt).get("value");
nulls = ((CompoundNBT) nbt).getIntArray("nulls");
} else if (tag instanceof CompoundNBT) {
listTag = (ListNBT) ((CompoundNBT) tag).get("value");
nulls = ((CompoundNBT) tag).getIntArray("nulls");
} else {
return data;
}
if (listNBT == null) {
if (listTag == null) {
return data;
}
final int length = listNBT.size() + nulls.length;
final int length = listTag.size() + nulls.length;
if (data == null || data.length != length) {
data = (Object[]) Array.newInstance(componentType, length);
}
@@ -336,12 +336,12 @@ public final class NBTSerialization {
continue;
}
final INBT itemNBT = listNBT.get(i - nullsIndex);
if (itemNBT == null) {
final INBT itemTag = listTag.get(i - nullsIndex);
if (itemTag == null) {
continue;
}
data[i] = componentDeserializer.deserialize(itemNBT, componentType, data[i]);
data[i] = componentDeserializer.deserialize(itemTag, componentType, data[i]);
}
return data;
@@ -350,11 +350,11 @@ public final class NBTSerialization {
@Override
public boolean exists(final String name) {
return nbt.contains(name);
return tag.contains(name);
}
private boolean isNull(final String name) {
return nbt.getCompound(name).getBoolean(IS_NULL_KEY);
return tag.getCompound(name).getBoolean(IS_NULL_KEY);
}
}
@@ -364,7 +364,7 @@ public final class NBTSerialization {
INBT serialize(Object value);
@Nullable
Object deserialize(INBT nbt, final Class<?> type, @Nullable final Object into);
Object deserialize(INBT tag, final Class<?> type, @Nullable final Object into);
}
private static final class BooleanArraySerializer implements ArraySerializer {
@@ -379,10 +379,10 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
boolean[] data = (boolean[]) into;
if (nbt instanceof ByteArrayNBT) {
final byte[] convertedData = ((ByteArrayNBT) nbt).getByteArray();
if (tag instanceof ByteArrayNBT) {
final byte[] convertedData = ((ByteArrayNBT) tag).getByteArray();
if (data == null || data.length != convertedData.length) {
data = new boolean[convertedData.length];
}
@@ -401,10 +401,10 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
final byte[] data = (byte[]) into;
if (nbt instanceof ByteArrayNBT) {
final byte[] serializedData = ((ByteArrayNBT) nbt).getByteArray();
if (tag instanceof ByteArrayNBT) {
final byte[] serializedData = ((ByteArrayNBT) tag).getByteArray();
if (data == null || data.length != serializedData.length) {
return serializedData;
}
@@ -426,10 +426,10 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
char[] data = (char[]) into;
if (nbt instanceof IntArrayNBT) {
final int[] convertedData = ((IntArrayNBT) nbt).getIntArray();
if (tag instanceof IntArrayNBT) {
final int[] convertedData = ((IntArrayNBT) tag).getIntArray();
if (data == null || data.length != convertedData.length) {
data = new char[convertedData.length];
}
@@ -453,10 +453,10 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
short[] data = (short[]) into;
if (nbt instanceof IntArrayNBT) {
final int[] convertedData = ((IntArrayNBT) nbt).getIntArray();
if (tag instanceof IntArrayNBT) {
final int[] convertedData = ((IntArrayNBT) tag).getIntArray();
if (data == null || data.length != convertedData.length) {
data = new short[convertedData.length];
}
@@ -475,10 +475,10 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
final int[] data = (int[]) into;
if (nbt instanceof IntArrayNBT) {
final int[] serializedData = ((IntArrayNBT) nbt).getIntArray();
if (tag instanceof IntArrayNBT) {
final int[] serializedData = ((IntArrayNBT) tag).getIntArray();
if (data == null || data.length != serializedData.length) {
return serializedData;
}
@@ -495,10 +495,10 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
final long[] data = (long[]) into;
if (nbt instanceof LongArrayNBT) {
final long[] serializedData = ((LongArrayNBT) nbt).getAsLongArray();
if (tag instanceof LongArrayNBT) {
final long[] serializedData = ((LongArrayNBT) tag).getAsLongArray();
if (data == null || data.length != serializedData.length) {
return serializedData;
}
@@ -520,10 +520,10 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
float[] data = (float[]) into;
if (nbt instanceof IntArrayNBT) {
final int[] convertedData = ((IntArrayNBT) nbt).getIntArray();
if (tag instanceof IntArrayNBT) {
final int[] convertedData = ((IntArrayNBT) tag).getIntArray();
if (data == null || data.length != convertedData.length) {
data = new float[convertedData.length];
}
@@ -547,10 +547,10 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
double[] data = (double[]) into;
if (nbt instanceof LongArrayNBT) {
final long[] convertedData = ((LongArrayNBT) nbt).getAsLongArray();
if (tag instanceof LongArrayNBT) {
final long[] convertedData = ((LongArrayNBT) tag).getAsLongArray();
if (data == null || data.length != convertedData.length) {
data = new double[convertedData.length];
}
@@ -575,13 +575,13 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
final Class<?> componentType = type.getComponentType();
final Object[] enumConstants = componentType.getEnumConstants();
Enum[] data = (Enum[]) into;
if (nbt instanceof IntArrayNBT) {
final int[] serializedData = ((IntArrayNBT) nbt).getIntArray();
if (tag instanceof IntArrayNBT) {
final int[] serializedData = ((IntArrayNBT) tag).getIntArray();
if (data == null || data.length != serializedData.length) {
data = (Enum[]) Array.newInstance(componentType, serializedData.length);
}
@@ -605,10 +605,10 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
String[] data = (String[]) into;
if (nbt instanceof ListNBT) {
final ListNBT serializedData = (ListNBT) nbt;
if (tag instanceof ListNBT) {
final ListNBT serializedData = (ListNBT) tag;
if (serializedData.isEmpty() || serializedData.getTagType() == NBTTagIds.TAG_STRING) {
if (data == null || data.length != serializedData.size()) {
data = new String[serializedData.size()];
@@ -634,10 +634,10 @@ public final class NBTSerialization {
}
@Override
public Object deserialize(final INBT nbt, final Class<?> type, @Nullable final Object into) {
public Object deserialize(final INBT tag, final Class<?> type, @Nullable final Object into) {
UUID[] data = (UUID[]) into;
if (nbt instanceof ListNBT) {
final ListNBT serializedData = (ListNBT) nbt;
if (tag instanceof ListNBT) {
final ListNBT serializedData = (ListNBT) tag;
if (serializedData.isEmpty() || serializedData.getTagType() == NBTTagIds.TAG_STRING) {
if (data == null || data.length != serializedData.size()) {
data = new UUID[serializedData.size()];

View File

@@ -7,60 +7,60 @@ import net.minecraft.nbt.*;
import javax.annotation.Nullable;
public final class NBTToJsonConverter {
public static JsonElement convert(@Nullable final INBT nbt) {
if (nbt == null) {
public static JsonElement convert(@Nullable final INBT tag) {
if (tag == null) {
return JsonNull.INSTANCE;
}
switch (nbt.getId()) {
switch (tag.getId()) {
case NBTTagIds.TAG_BYTE: {
return new JsonPrimitive(((ByteNBT) nbt).getByte());
return new JsonPrimitive(((ByteNBT) tag).getByte());
}
case NBTTagIds.TAG_SHORT: {
return new JsonPrimitive(((ShortNBT) nbt).getShort());
return new JsonPrimitive(((ShortNBT) tag).getShort());
}
case NBTTagIds.TAG_INT: {
return new JsonPrimitive(((IntNBT) nbt).getInt());
return new JsonPrimitive(((IntNBT) tag).getInt());
}
case NBTTagIds.TAG_LONG: {
return new JsonPrimitive(((LongNBT) nbt).getLong());
return new JsonPrimitive(((LongNBT) tag).getLong());
}
case NBTTagIds.TAG_FLOAT: {
return new JsonPrimitive(((FloatNBT) nbt).getFloat());
return new JsonPrimitive(((FloatNBT) tag).getFloat());
}
case NBTTagIds.TAG_DOUBLE: {
return new JsonPrimitive(((DoubleNBT) nbt).getDouble());
return new JsonPrimitive(((DoubleNBT) tag).getDouble());
}
case NBTTagIds.TAG_BYTE_ARRAY: {
final JsonArray json = new JsonArray();
final byte[] array = ((ByteArrayNBT) nbt).getByteArray();
final byte[] array = ((ByteArrayNBT) tag).getByteArray();
for (int i = 0; i < array.length; i++) {
json.add(array[i]);
}
return json;
}
case NBTTagIds.TAG_STRING: {
return new JsonPrimitive(nbt.getString());
return new JsonPrimitive(tag.getString());
}
case NBTTagIds.TAG_LIST: {
final JsonArray json = new JsonArray();
final ListNBT list = (ListNBT) nbt;
for (final INBT item : list) {
final ListNBT listTag = (ListNBT) tag;
for (final INBT item : listTag) {
json.add(convert(item));
}
return json;
}
case NBTTagIds.TAG_COMPOUND: {
final JsonObject json = new JsonObject();
final CompoundNBT compound = (CompoundNBT) nbt;
for (final String key : compound.keySet()) {
json.add(key, convert(compound.get(key)));
final CompoundNBT compoundTag = (CompoundNBT) tag;
for (final String key : compoundTag.keySet()) {
json.add(key, convert(compoundTag.get(key)));
}
return json;
}
case NBTTagIds.TAG_INT_ARRAY: {
final JsonArray json = new JsonArray();
final int[] array = ((IntArrayNBT) nbt).getIntArray();
final int[] array = ((IntArrayNBT) tag).getIntArray();
for (int i = 0; i < array.length; i++) {
json.add(array[i]);
}
@@ -68,7 +68,7 @@ public final class NBTToJsonConverter {
}
case NBTTagIds.TAG_LONG_ARRAY: {
final JsonArray json = new JsonArray();
final long[] array = ((LongArrayNBT) nbt).getAsLongArray();
final long[] array = ((LongArrayNBT) tag).getAsLongArray();
for (int i = 0; i < array.length; i++) {
json.add(array[i]);
}

View File

@@ -0,0 +1,96 @@
package li.cil.oc2.common.tileentity;
import li.cil.oc2.common.Config;
import li.cil.oc2.common.Constants;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.energy.FixedEnergyStorage;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.IItemHandler;
import java.util.List;
public final class ChargerTileEntity extends TileEntity implements ITickableTileEntity {
private final FixedEnergyStorage energy = new FixedEnergyStorage(Config.chargerEnergyStorage);
///////////////////////////////////////////////////////////////////
ChargerTileEntity() {
super(TileEntities.CHARGER_TILE_ENTITY.get());
}
///////////////////////////////////////////////////////////////////
@Override
public void tick() {
chargeBlock();
chargeEntities();
}
@Override
public CompoundNBT write(CompoundNBT tag) {
tag = super.write(tag);
tag.put(Constants.ENERGY_TAG_NAME, energy.serializeNBT());
return tag;
}
@Override
public void read(final BlockState state, final CompoundNBT tag) {
super.read(state, tag);
energy.deserializeNBT(tag.getCompound(Constants.ENERGY_TAG_NAME));
}
///////////////////////////////////////////////////////////////////
private void chargeBlock() {
if (energy.getEnergyStored() == 0) {
return;
}
final TileEntity tileEntity = getWorld().getTileEntity(getPos().up());
if (tileEntity != null) {
chargeCapabilityProvider(tileEntity);
}
}
private void chargeEntities() {
if (energy.getEnergyStored() == 0) {
return;
}
final List<Entity> entities = getWorld().getEntitiesInAABBexcluding(null, new AxisAlignedBB(getPos().up()), null);
for (final Entity entity : entities) {
chargeCapabilityProvider(entity);
}
}
private void chargeCapabilityProvider(final ICapabilityProvider capabilityProvider) {
capabilityProvider.getCapability(Capabilities.ENERGY_STORAGE, Direction.DOWN).ifPresent(this::charge);
capabilityProvider.getCapability(Capabilities.ITEM_HANDLER, Direction.DOWN).ifPresent(this::chargeItems);
}
private void chargeItems(final IItemHandler itemHandler) {
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
final ItemStack stack = itemHandler.getStackInSlot(slot);
if (!stack.isEmpty()) {
stack.getCapability(Capabilities.ENERGY_STORAGE).ifPresent(this::charge);
}
}
}
private void charge(final IEnergyStorage energyStorage) {
final int amount = Math.min(energy.getEnergyStored(), Config.chargerEnergyPerTick);
energy.extractEnergy(energyStorage.receiveEnergy(amount, false), false);
}
}

View File

@@ -4,6 +4,7 @@ import li.cil.oc2.api.bus.DeviceBusElement;
import li.cil.oc2.api.bus.device.Device;
import li.cil.oc2.api.bus.device.DeviceTypes;
import li.cil.oc2.client.audio.LoopingSoundManager;
import li.cil.oc2.common.Config;
import li.cil.oc2.common.Constants;
import li.cil.oc2.common.block.ComputerBlock;
import li.cil.oc2.common.bus.CommonDeviceBusController;
@@ -14,6 +15,7 @@ import li.cil.oc2.common.bus.device.util.Devices;
import li.cil.oc2.common.bus.device.util.ItemDeviceInfo;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.container.DeviceItemStackHandler;
import li.cil.oc2.common.energy.FixedEnergyStorage;
import li.cil.oc2.common.network.Network;
import li.cil.oc2.common.network.message.ComputerBootErrorMessage;
import li.cil.oc2.common.network.message.ComputerBusStateMessage;
@@ -28,6 +30,7 @@ import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.common.capabilities.Capability;
@@ -41,6 +44,9 @@ import java.util.Collection;
import java.util.List;
import java.util.Optional;
import static li.cil.oc2.common.Constants.BLOCK_ENTITY_TAG_NAME_IN_ITEM;
import static li.cil.oc2.common.Constants.ITEMS_TAG_NAME;
public final class ComputerTileEntity extends AbstractTileEntity implements ITickableTileEntity {
private static final String BUS_ELEMENT_TAG_NAME = "busElement";
private static final String TERMINAL_TAG_NAME = "terminal";
@@ -62,8 +68,9 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
private final Terminal terminal = new Terminal();
private final TileEntityDeviceBusElement busElement = new ComputerBusElement();
private final ComputerItemStackHandlers items = new ComputerItemStackHandlers();
private final ComputerVirtualMachine virtualMachine = new ComputerVirtualMachine(new TileEntityDeviceBusController(busElement, this), items::getDeviceAddressBase);
private final ComputerItemStackHandlers deviceItems = new ComputerItemStackHandlers();
private final FixedEnergyStorage energy = new FixedEnergyStorage(Config.computerEnergyStorage);
private final ComputerVirtualMachine virtualMachine = new ComputerVirtualMachine(new TileEntityDeviceBusController(busElement, this), deviceItems::getDeviceAddressBase);
///////////////////////////////////////////////////////////////////
@@ -83,7 +90,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
}
public VMItemStackHandlers getItemStackHandlers() {
return items;
return deviceItems;
}
public void start() {
@@ -195,7 +202,8 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
tag.put(STATE_TAG_NAME, virtualMachine.serialize());
tag.put(TERMINAL_TAG_NAME, NBTSerialization.serialize(terminal));
tag.put(BUS_ELEMENT_TAG_NAME, NBTSerialization.serialize(busElement));
tag.put(Constants.INVENTORY_TAG_NAME, items.serialize());
tag.put(Constants.ITEMS_TAG_NAME, deviceItems.serialize());
tag.put(Constants.ENERGY_TAG_NAME, energy.serializeNBT());
return tag;
}
@@ -211,21 +219,24 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
NBTSerialization.deserialize(tag.getCompound(BUS_ELEMENT_TAG_NAME), busElement);
}
if (tag.contains(Constants.INVENTORY_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
items.deserialize(tag.getCompound(Constants.INVENTORY_TAG_NAME));
}
deviceItems.deserialize(tag.getCompound(Constants.ITEMS_TAG_NAME));
energy.deserializeNBT(tag.getCompound(Constants.ENERGY_TAG_NAME));
}
public void exportToItemStack(final ItemStack stack) {
items.serialize(ItemStackUtils.getOrCreateTileEntityInventoryTag(stack));
deviceItems.serialize(NBTUtils.getOrCreateChildTag(stack.getOrCreateTag(), BLOCK_ENTITY_TAG_NAME_IN_ITEM, ITEMS_TAG_NAME));
}
///////////////////////////////////////////////////////////////////
@Override
protected void collectCapabilities(final CapabilityCollector collector, @Nullable final Direction direction) {
collector.offer(Capabilities.ITEM_HANDLER, items.combinedItemHandlers);
collector.offer(Capabilities.ITEM_HANDLER, deviceItems.combinedItemHandlers);
collector.offer(Capabilities.DEVICE_BUS_ELEMENT, busElement);
if (Config.computersUseEnergy()) {
collector.offer(Capabilities.ENERGY_STORAGE, energy);
}
}
@Override
@@ -291,7 +302,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
public Optional<Collection<LazyOptional<DeviceBusElement>>> getNeighbors() {
return super.getNeighbors().map(neighbors -> {
final ArrayList<LazyOptional<DeviceBusElement>> list = new ArrayList<>(neighbors);
list.add(LazyOptional.of(() -> items.busElement));
list.add(LazyOptional.of(() -> deviceItems.busElement));
return list;
});
}
@@ -347,6 +358,33 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
super.tick();
}
@Override
protected void load() {
if (Config.computersUseEnergy()) {
// Don't even start running if we couldn't keep running.
if (energy.getEnergyStored() < Config.computerEnergyPerTick) {
error(new TranslationTextComponent(Constants.COMPUTER_ERROR_NOT_ENOUGH_ENERGY));
return;
}
}
super.load();
}
@Override
protected void run() {
if (Config.computersUseEnergy()) {
if (energy.getEnergyStored() >= Config.computerEnergyPerTick) {
energy.extractEnergy(Config.computerEnergyPerTick, false);
} else {
error(new TranslationTextComponent(Constants.COMPUTER_ERROR_NOT_ENOUGH_ENERGY));
return;
}
}
super.run();
}
@Override
public void stopRunnerAndReset() {
super.stopRunnerAndReset();

View File

@@ -112,21 +112,21 @@ public final class DiskDriveTileEntity extends AbstractTileEntity {
@Override
public CompoundNBT getUpdateTag() {
final CompoundNBT tag = super.getUpdateTag();
tag.put(Constants.INVENTORY_TAG_NAME, itemHandler.serializeNBT());
tag.put(Constants.ITEMS_TAG_NAME, itemHandler.serializeNBT());
return tag;
}
@Override
public void handleUpdateTag(final BlockState state, final CompoundNBT tag) {
super.handleUpdateTag(state, tag);
itemHandler.deserializeNBT(tag.getCompound(Constants.INVENTORY_TAG_NAME));
itemHandler.deserializeNBT(tag.getCompound(Constants.ITEMS_TAG_NAME));
}
@Override
public CompoundNBT write(CompoundNBT tag) {
tag = super.write(tag);
tag.put(Constants.INVENTORY_TAG_NAME, itemHandler.serializeNBT());
tag.put(Constants.ITEMS_TAG_NAME, itemHandler.serializeNBT());
return tag;
}
@@ -135,7 +135,7 @@ public final class DiskDriveTileEntity extends AbstractTileEntity {
public void read(final BlockState state, final CompoundNBT tag) {
super.read(state, tag);
itemHandler.deserializeNBT(tag.getCompound(Constants.INVENTORY_TAG_NAME));
itemHandler.deserializeNBT(tag.getCompound(Constants.ITEMS_TAG_NAME));
}
///////////////////////////////////////////////////////////////////

View File

@@ -24,6 +24,7 @@ public final class TileEntities {
public static final RegistryObject<TileEntityType<NetworkConnectorTileEntity>> NETWORK_CONNECTOR_TILE_ENTITY = register(Constants.NETWORK_CONNECTOR_BLOCK_NAME, Blocks.NETWORK_CONNECTOR, NetworkConnectorTileEntity::new);
public static final RegistryObject<TileEntityType<NetworkHubTileEntity>> NETWORK_HUB_TILE_ENTITY = register(Constants.NETWORK_HUB_BLOCK_NAME, Blocks.NETWORK_HUB, NetworkHubTileEntity::new);
public static final RegistryObject<TileEntityType<DiskDriveTileEntity>> DISK_DRIVE_TILE_ENTITY = register(Constants.DISK_DRIVE_BLOCK_NAME, Blocks.DISK_DRIVE, DiskDriveTileEntity::new);
public static final RegistryObject<TileEntityType<ChargerTileEntity>> CHARGER_TILE_ENTITY = register(Constants.CHARGER_BLOCK_NAME, Blocks.CHARGER, ChargerTileEntity::new);
///////////////////////////////////////////////////////////////////

View File

@@ -13,24 +13,11 @@ public final class ItemDeviceUtils {
///////////////////////////////////////////////////////////////////
public static Optional<CompoundNBT> getItemDeviceData(final ItemStack stack) {
if (stack.isEmpty()) {
return Optional.empty();
}
final CompoundNBT nbt = ItemStackUtils.getModDataTag(stack);
if (nbt == null) {
return Optional.empty();
}
return Optional.of(nbt.getCompound(ITEM_DEVICE_DATA_TAG_NAME));
public static CompoundNBT getItemDeviceData(final ItemStack stack) {
return ItemStackUtils.getModDataTag(stack).getCompound(ITEM_DEVICE_DATA_TAG_NAME);
}
public static void setItemDeviceData(final ItemStack stack, final CompoundNBT data) {
if (data.isEmpty()) {
return;
}
ItemStackUtils.getOrCreateModDataTag(stack).put(ITEM_DEVICE_DATA_TAG_NAME, data);
}

View File

@@ -1,6 +1,5 @@
package li.cil.oc2.common.util;
import li.cil.oc2.api.API;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
@@ -13,72 +12,15 @@ import javax.annotation.Nullable;
import java.util.Optional;
import java.util.Random;
import static li.cil.oc2.common.Constants.BLOCK_ENTITY_TAG_NAME_IN_ITEM;
import static li.cil.oc2.common.Constants.INVENTORY_TAG_NAME;
import static li.cil.oc2.common.Constants.MOD_TAG_NAME;
public final class ItemStackUtils {
private static final String MOD_TAG_NAME = API.MOD_ID;
@Nullable
public static CompoundNBT getModDataTag(final ItemStack stack) {
if (stack.isEmpty()) {
return null;
}
return stack.getChildTag(MOD_TAG_NAME);
return NBTUtils.getChildTag(stack.getTag(), MOD_TAG_NAME);
}
public static CompoundNBT getOrCreateModDataTag(final ItemStack stack) {
if (stack.isEmpty()) {
throw new IllegalArgumentException();
}
return stack.getOrCreateChildTag(MOD_TAG_NAME);
}
@Nullable
public static CompoundNBT getInventoryTag(@Nullable final CompoundNBT tag) {
return tag != null && tag.contains(INVENTORY_TAG_NAME, NBTTagIds.TAG_COMPOUND)
? tag.getCompound(INVENTORY_TAG_NAME) : null;
}
public static CompoundNBT getOrCreateInventoryTag(final CompoundNBT tag) {
if (tag.contains(INVENTORY_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
return tag.getCompound(INVENTORY_TAG_NAME);
}
final CompoundNBT inventoryTag = new CompoundNBT();
tag.put(INVENTORY_TAG_NAME, inventoryTag);
return inventoryTag;
}
@Nullable
public static CompoundNBT getTileEntityTag(final ItemStack stack) {
return stack.getChildTag(BLOCK_ENTITY_TAG_NAME_IN_ITEM);
}
public static CompoundNBT getOrCreateTileEntityTag(final ItemStack stack) {
return stack.getOrCreateChildTag(BLOCK_ENTITY_TAG_NAME_IN_ITEM);
}
@Nullable
public static CompoundNBT getTileEntityInventoryTag(final ItemStack stack) {
return getInventoryTag(getTileEntityTag(stack));
}
@Nullable
public static CompoundNBT getOrCreateTileEntityInventoryTag(final ItemStack stack) {
return getOrCreateInventoryTag(getOrCreateTileEntityTag(stack));
}
@Nullable
public static CompoundNBT getEntityInventoryTag(final ItemStack stack) {
return getInventoryTag(getModDataTag(stack));
}
@Nullable
public static CompoundNBT getOrCreateEntityInventoryTag(final ItemStack stack) {
return getOrCreateInventoryTag(getOrCreateModDataTag(stack));
return NBTUtils.getOrCreateChildTag(stack.getOrCreateTag(), MOD_TAG_NAME);
}
public static Optional<ItemEntity> spawnAsEntity(final World world, final BlockPos pos, final ItemStack stack) {

View File

@@ -2,8 +2,7 @@ package li.cil.oc2.common.util;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.NonNullList;
import net.minecraftforge.items.ItemStackHandler;
import javax.annotation.Nullable;
@@ -29,45 +28,34 @@ public final class NBTUtils {
}
}
public static void putBlockPos(final CompoundNBT tag, final String key, final BlockPos value) {
final CompoundNBT valueTag = new CompoundNBT();
valueTag.putInt("x", value.getX());
valueTag.putInt("y", value.getY());
valueTag.putInt("z", value.getZ());
tag.put(key, valueTag);
public static CompoundNBT getChildTag(@Nullable final CompoundNBT tag, final String... path) {
if (tag == null) {
return new CompoundNBT();
}
CompoundNBT childTag = tag;
for (final String tagName : path) {
if (!childTag.contains(tagName, NBTTagIds.TAG_COMPOUND)) {
return new CompoundNBT();
}
childTag = childTag.getCompound(tagName);
}
return childTag;
}
public static BlockPos getBlockPos(final CompoundNBT tag, final String key) {
final CompoundNBT valueTag = tag.getCompound(key);
return new BlockPos(
valueTag.getInt("x"),
valueTag.getInt("y"),
valueTag.getInt("z")
);
}
public static void putVector3d(final CompoundNBT tag, final String key, final Vector3d value) {
final CompoundNBT valueTag = new CompoundNBT();
valueTag.putDouble("x", value.getX());
valueTag.putDouble("y", value.getY());
valueTag.putDouble("z", value.getZ());
tag.put(key, valueTag);
}
public static Vector3d getVector3d(final CompoundNBT tag, final String key) {
final CompoundNBT valueTag = tag.getCompound(key);
return new Vector3d(
valueTag.getDouble("x"),
valueTag.getDouble("y"),
valueTag.getDouble("z")
);
public static CompoundNBT getOrCreateChildTag(final CompoundNBT tag, final String... path) {
CompoundNBT childTag = tag;
for (final String tagName : path) {
if (!childTag.contains(tagName, NBTTagIds.TAG_COMPOUND)) {
childTag.put(tagName, new CompoundNBT());
}
childTag = childTag.getCompound(tagName);
}
return childTag;
}
public static CompoundNBT makeInventoryTag(final ItemStack... items) {
final ItemStackHandler itemStackHandler = new ItemStackHandler(items.length);
for (int i = 0; i < items.length; i++) {
itemStackHandler.setStackInSlot(i, items[i]);
}
return itemStackHandler.serializeNBT();
return new ItemStackHandler(NonNullList.from(ItemStack.EMPTY, items)).serializeNBT();
}
}

View File

@@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import li.cil.oc2.api.bus.device.DeviceType;
import li.cil.oc2.common.Constants;
import li.cil.oc2.common.energy.FixedEnergyStorage;
import li.cil.oc2.common.tags.ItemTags;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -14,10 +15,11 @@ import net.minecraft.util.text.*;
import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.RegistryManager;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import static li.cil.oc2.common.Constants.*;
public final class TooltipUtils {
private static final ThreadLocal<List<ItemStack>> ITEM_STACKS = ThreadLocal.withInitial(ArrayList::new);
private static final ThreadLocal<IntList> ITEM_STACKS_SIZES = ThreadLocal.withInitial(IntArrayList::new);
@@ -47,40 +49,28 @@ public final class TooltipUtils {
}
public static void addTileEntityInventoryInformation(final ItemStack stack, final List<ITextComponent> tooltip) {
addInventoryInformation(ItemStackUtils.getTileEntityInventoryTag(stack), tooltip);
}
public static void addTileEntityInventoryInformation(final ItemStack stack, final List<ITextComponent> tooltip, final String... subInventoryNames) {
addInventoryInformation(ItemStackUtils.getTileEntityInventoryTag(stack), tooltip, subInventoryNames);
addInventoryInformation(NBTUtils.getChildTag(stack.getTag(), BLOCK_ENTITY_TAG_NAME_IN_ITEM, ITEMS_TAG_NAME), tooltip);
}
public static void addEntityInventoryInformation(final ItemStack stack, final List<ITextComponent> tooltip) {
addInventoryInformation(ItemStackUtils.getEntityInventoryTag(stack), tooltip);
addInventoryInformation(NBTUtils.getChildTag(stack.getTag(), MOD_TAG_NAME, ITEMS_TAG_NAME), tooltip);
}
public static void addEntityInventoryInformation(final ItemStack stack, final List<ITextComponent> tooltip, final String... subInventoryNames) {
addInventoryInformation(ItemStackUtils.getEntityInventoryTag(stack), tooltip, subInventoryNames);
public static void addInventoryInformation(final CompoundNBT itemsTag, final List<ITextComponent> tooltip) {
addInventoryInformation(itemsTag, tooltip, getDeviceTypeNames());
}
public static void addInventoryInformation(@Nullable final CompoundNBT inventoryTag, final List<ITextComponent> tooltip) {
addInventoryInformation(inventoryTag, tooltip, getDeviceTypeNames());
}
public static void addInventoryInformation(@Nullable final CompoundNBT inventoryTag, final List<ITextComponent> tooltip, final String... subInventoryNames) {
if (inventoryTag == null) {
return;
}
public static void addInventoryInformation(final CompoundNBT itemsTag, final List<ITextComponent> tooltip, final String... subInventoryNames) {
final List<ItemStack> itemStacks = ITEM_STACKS.get();
itemStacks.clear();
final IntList itemStackSizes = ITEM_STACKS_SIZES.get();
itemStackSizes.clear();
collectItemStacks(inventoryTag, itemStacks, itemStackSizes);
collectItemStacks(itemsTag, itemStacks, itemStackSizes);
for (final String subInventoryName : subInventoryNames) {
if (inventoryTag.contains(subInventoryName, NBTTagIds.TAG_COMPOUND)) {
collectItemStacks(inventoryTag.getCompound(subInventoryName), itemStacks, itemStackSizes);
if (itemsTag.contains(subInventoryName, NBTTagIds.TAG_COMPOUND)) {
collectItemStacks(itemsTag.getCompound(subInventoryName), itemStacks, itemStackSizes);
}
}
@@ -96,6 +86,30 @@ public final class TooltipUtils {
}
}
public static void addTileEntityEnergyInformation(final ItemStack stack, final List<ITextComponent> tooltip) {
addEnergyInformation(NBTUtils.getChildTag(stack.getTag(), BLOCK_ENTITY_TAG_NAME_IN_ITEM, ENERGY_TAG_NAME), tooltip);
}
public static void addEntityEnergyInformation(final ItemStack stack, final List<ITextComponent> tooltip) {
addEnergyInformation(NBTUtils.getChildTag(stack.getTag(), MOD_TAG_NAME, ENERGY_TAG_NAME), tooltip);
}
public static void addEnergyInformation(final CompoundNBT energyTag, final List<ITextComponent> tooltip) {
final int stored = energyTag.getInt(FixedEnergyStorage.STORED_TAG_NAME);
if (stored == 0) {
return;
}
final int capacity = energyTag.getInt(FixedEnergyStorage.CAPACITY_TAG_NAME);
if (capacity > 0) {
tooltip.add(new TranslationTextComponent(Constants.TOOLTIP_ENERGY, stored + "/" + capacity));
} else {
tooltip.add(new TranslationTextComponent(Constants.TOOLTIP_ENERGY, stored));
}
}
///////////////////////////////////////////////////////////////////
private static String[] getDeviceTypeNames() {
final ForgeRegistry<DeviceType> registry = RegistryManager.ACTIVE.getRegistry(DeviceType.REGISTRY);
if (registry != null) {
@@ -106,11 +120,11 @@ public final class TooltipUtils {
}
}
private static void collectItemStacks(final CompoundNBT nbt, final List<ItemStack> stacks, final IntList stackSizes) {
final ListNBT itemsNbt = nbt.getList("Items", NBTTagIds.TAG_COMPOUND);
for (int i = 0; i < itemsNbt.size(); i++) {
final CompoundNBT itemNbt = itemsNbt.getCompound(i);
final ItemStack itemStack = ItemStack.read(itemNbt);
private static void collectItemStacks(final CompoundNBT tag, final List<ItemStack> stacks, final IntList stackSizes) {
final ListNBT itemsTag = tag.getList("Items", NBTTagIds.TAG_COMPOUND);
for (int i = 0; i < itemsTag.size(); i++) {
final CompoundNBT itemTag = itemsTag.getCompound(i);
final ItemStack itemStack = ItemStack.read(itemTag);
boolean didMerge = false;
for (int j = 0; j < stacks.size(); j++) {

View File

@@ -36,6 +36,7 @@ public class ModBlockStateProvider extends BlockStateProvider {
.end();
horizontalBlock(Blocks.NETWORK_HUB, Items.NETWORK_HUB);
horizontalBlock(Blocks.DISK_DRIVE, Items.DISK_DRIVE);
horizontalBlock(Blocks.CHARGER, Items.CHARGER);
registerCableStates();
}

View File

@@ -30,7 +30,8 @@ public final class ModBlockTagsProvider extends BlockTagsProvider {
NETWORK_CONNECTOR.get(),
NETWORK_HUB.get(),
REDSTONE_INTERFACE.get(),
DISK_DRIVE.get()
DISK_DRIVE.get(),
CHARGER.get()
);
}
}

View File

@@ -21,8 +21,7 @@ import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import static java.util.Objects.requireNonNull;
import static li.cil.oc2.common.Constants.BLOCK_ENTITY_TAG_NAME_IN_ITEM;
import static li.cil.oc2.common.Constants.INVENTORY_TAG_NAME;
import static li.cil.oc2.common.Constants.*;
public final class ModLootTableProvider extends LootTableProvider {
public ModLootTableProvider(final DataGenerator generator) {
@@ -46,6 +45,7 @@ public final class ModLootTableProvider extends LootTableProvider {
registerDropSelfLootTable(Blocks.NETWORK_CONNECTOR.get());
registerDropSelfLootTable(Blocks.NETWORK_HUB.get());
registerDropSelfLootTable(Blocks.DISK_DRIVE.get());
registerDropSelfLootTable(Blocks.CHARGER.get());
registerLootTable(Blocks.COMPUTER.get(), ModBlockLootTables::droppingWithInventory);
}
@@ -64,8 +64,11 @@ public final class ModLootTableProvider extends LootTableProvider {
.rolls(ConstantRange.of(1))
.addEntry(ItemLootEntry.builder(block)
.acceptFunction(CopyNbt.builder(CopyNbt.Source.BLOCK_ENTITY)
.addOperation(INVENTORY_TAG_NAME,
concat(BLOCK_ENTITY_TAG_NAME_IN_ITEM, INVENTORY_TAG_NAME),
.addOperation(ITEMS_TAG_NAME,
concat(BLOCK_ENTITY_TAG_NAME_IN_ITEM, ITEMS_TAG_NAME),
CopyNbt.Action.REPLACE)
.addOperation(ENERGY_TAG_NAME,
concat(BLOCK_ENTITY_TAG_NAME_IN_ITEM, ENERGY_TAG_NAME),
CopyNbt.Action.REPLACE)
)
)

View File

@@ -0,0 +1,19 @@
{
"variants": {
"facing=north": {
"model": "oc2:block/charger"
},
"facing=south": {
"model": "oc2:block/charger",
"y": 180
},
"facing=west": {
"model": "oc2:block/charger",
"y": 270
},
"facing=east": {
"model": "oc2:block/charger",
"y": 90
}
}
}

View File

@@ -10,6 +10,8 @@
"block.oc2.redstone_interface": "Redstone Interface",
"block.oc2.disk_drive": "Disk Drive",
"block.oc2.disk_drive.desc": "Used to access Floppy Disks.",
"block.oc2.charger": "Charger",
"block.oc2.charger.desc": "Charges entities and items in containers on top of it.",
"item.oc2.wrench": "Scrench",
"item.oc2.wrench.desc": "Used to configure devices and to dismantle them (while sneaking).",
@@ -35,9 +37,14 @@
"config.oc2.vm.maxMemorySize:": "Maximum memory device size",
"config.oc2.vm.maxHardDriveSize": "Maximum hard drive device size",
"config.oc2.vm.maxFlashMemorySize:": "Maximum flash memory device size",
"config.oc2.computerEnergyPerTick": "Energy/tick used by computers",
"config.oc2.modules.block_operations.toolLevel": "Block operations module tool level",
"config.oc2.admin.fakePlayerUUID": "Fake Player UUID",
"config.oc2.computerEnergyPerTick": "Energy/tick used by computers",
"config.oc2.computerEnergyStorage": "Computer energy storage",
"config.oc2.robotEnergyPerTick": "Energy/tick used by robots",
"config.oc2.robotEnergyStorage": "Robot energy storage",
"config.oc2.chargerEnergyPerTick": "Energy/tick transferred by chargers",
"config.oc2.chargerEnergyStorage": "Charge energy storage",
"gui.oc2.computer.error.unknown": "Unknown Error",
"gui.oc2.computer.error.missing_firmware": "Missing Firmware",
@@ -65,6 +72,7 @@
"tooltip.oc2.flash_memory_missing": "A flash memory containing a firmware is required to boot.",
"tooltip.oc2.memory_missing": "Some memory is required to load the flash memory for execution to boot.",
"tooltip.oc2.hard_drive_missing": "Most systems will require a root file system to boot.",
"tooltip.oc2.energy": "Energy: %s",
"subtitles.oc2.computer": "Computer fans running",
"subtitles.oc2.floppy": "Floppy access",

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
{
"parent": "oc2:block/charger"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,19 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "oc2:charger"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View File

@@ -15,6 +15,11 @@
"source": "items",
"target": "BlockEntityTag.items",
"op": "replace"
},
{
"source": "energy",
"target": "BlockEntityTag.energy",
"op": "replace"
}
]
}

View File

@@ -6,6 +6,7 @@
"oc2:network_connector",
"oc2:network_hub",
"oc2:redstone_interface",
"oc2:disk_drive"
"oc2:disk_drive",
"oc2:charger"
]
}