diff --git a/src/main/java/li/cil/oc2/client/ClientSetup.java b/src/main/java/li/cil/oc2/client/ClientSetup.java index 41a0a69b..cc91dd92 100644 --- a/src/main/java/li/cil/oc2/client/ClientSetup.java +++ b/src/main/java/li/cil/oc2/client/ClientSetup.java @@ -10,6 +10,7 @@ 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 static void handleSetupEvent(final FMLClientSetupEvent event) { 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 static void handleTextureStitchEvent(final TextureStitchEvent.Pre event) event.addSprite(ComputerTileEntityRenderer.OVERLAY_POWER_LOCATION); event.addSprite(ComputerTileEntityRenderer.OVERLAY_STATUS_LOCATION); event.addSprite(ComputerTileEntityRenderer.OVERLAY_TERMINAL_LOCATION); + + event.addSprite(ChargerTileEntityRenderer.EFFECT_LOCATION); } } diff --git a/src/main/java/li/cil/oc2/client/item/CustomItemColors.java b/src/main/java/li/cil/oc2/client/item/CustomItemColors.java index 93745196..30943f3c 100644 --- a/src/main/java/li/cil/oc2/client/item/CustomItemColors.java +++ b/src/main/java/li/cil/oc2/client/item/CustomItemColors.java @@ -82,7 +82,7 @@ public static int getColorByDye(final DyeColor dye) { 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; diff --git a/src/main/java/li/cil/oc2/client/renderer/CustomRenderType.java b/src/main/java/li/cil/oc2/client/renderer/CustomRenderType.java index 708eeca7..07150e1b 100644 --- a/src/main/java/li/cil/oc2/client/renderer/CustomRenderType.java +++ b/src/main/java/li/cil/oc2/client/renderer/CustomRenderType.java @@ -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 static RenderType getUnlitBlock(final ResourceLocation location) { 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, diff --git a/src/main/java/li/cil/oc2/client/renderer/tileentity/ChargerTileEntityRenderer.java b/src/main/java/li/cil/oc2/client/renderer/tileentity/ChargerTileEntityRenderer.java new file mode 100644 index 00000000..236fe35d --- /dev/null +++ b/src/main/java/li/cil/oc2/client/renderer/tileentity/ChargerTileEntityRenderer.java @@ -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 { + 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(); + } +} diff --git a/src/main/java/li/cil/oc2/client/renderer/tileentity/ComputerTileEntityRenderer.java b/src/main/java/li/cil/oc2/client/renderer/tileentity/ComputerTileEntityRenderer.java index 29437ebe..a70c2c58 100644 --- a/src/main/java/li/cil/oc2/client/renderer/tileentity/ComputerTileEntityRenderer.java +++ b/src/main/java/li/cil/oc2/client/renderer/tileentity/ComputerTileEntityRenderer.java @@ -203,22 +203,25 @@ private void renderPower(final Matrix4f matrix, final IRenderTypeBuffer buffer) 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(); } } diff --git a/src/main/java/li/cil/oc2/common/Config.java b/src/main/java/li/cil/oc2/common/Config.java index 3c337271..36e6471f 100644 --- a/src/main/java/li/cil/oc2/common/Config.java +++ b/src/main/java/li/cil/oc2/common/Config.java @@ -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 static void initialize() { 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 static void handleModConfigEvent(final ModConfig.ModConfigEvent event) { 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 static void handleModConfigEvent(final ModConfig.ModConfigEvent event) { /////////////////////////////////////////////////////////////////// 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 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.IntValue blockOperationsModuleToolLevel; + public final ForgeConfigSpec.IntValue blockOperationsModuleToolLevel; - public ForgeConfigSpec.ConfigValue fakePlayerUUID; + public final ForgeConfigSpec.ConfigValue fakePlayerUUID; public CommonSettings(final ForgeConfigSpec.Builder builder) { builder.push("vm"); @@ -95,6 +130,40 @@ public CommonSettings(final ForgeConfigSpec.Builder builder) { 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 diff --git a/src/main/java/li/cil/oc2/common/Constants.java b/src/main/java/li/cil/oc2/common/Constants.java index 7b02c40e..98935c2f 100644 --- a/src/main/java/li/cil/oc2/common/Constants.java +++ b/src/main/java/li/cil/oc2/common/Constants.java @@ -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"; /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/block/Blocks.java b/src/main/java/li/cil/oc2/common/block/Blocks.java index 5341d674..69dc34a6 100644 --- a/src/main/java/li/cil/oc2/common/block/Blocks.java +++ b/src/main/java/li/cil/oc2/common/block/Blocks.java @@ -19,6 +19,7 @@ public final class Blocks { public static final RegistryObject NETWORK_HUB = BLOCKS.register(Constants.NETWORK_HUB_BLOCK_NAME, NetworkHubBlock::new); public static final RegistryObject REDSTONE_INTERFACE = BLOCKS.register(Constants.REDSTONE_INTERFACE_BLOCK_NAME, RedstoneInterfaceBlock::new); public static final RegistryObject DISK_DRIVE = BLOCKS.register(Constants.DISK_DRIVE_BLOCK_NAME, DiskDriveBlock::new); + public static final RegistryObject CHARGER = BLOCKS.register(Constants.CHARGER_BLOCK_NAME, ChargerBlock::new); /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/block/ChargerBlock.java b/src/main/java/li/cil/oc2/common/block/ChargerBlock.java new file mode 100644 index 00000000..76383a1c --- /dev/null +++ b/src/main/java/li/cil/oc2/common/block/ChargerBlock.java @@ -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 builder) { + super.fillStateContainer(builder); + builder.add(HorizontalBlock.HORIZONTAL_FACING); + } +} diff --git a/src/main/java/li/cil/oc2/common/block/ComputerBlock.java b/src/main/java/li/cil/oc2/common/block/ComputerBlock.java index cd49886c..1332d2a6 100644 --- a/src/main/java/li/cil/oc2/common/block/ComputerBlock.java +++ b/src/main/java/li/cil/oc2/common/block/ComputerBlock.java @@ -12,7 +12,7 @@ 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 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 void fillItemGroup(final ItemGroup group, final NonNullList it public void addInformation(final ItemStack stack, @Nullable final IBlockReader world, final List tooltip, final ITooltipFlag advanced) { super.addInformation(stack, world, tooltip, advanced); TooltipUtils.addTileEntityInventoryInformation(stack, tooltip); + TooltipUtils.addTileEntityEnergyInformation(stack, tooltip); } @Override @@ -246,19 +249,19 @@ public Container createMenu(final int id, final PlayerInventory inventory, final 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()) )); diff --git a/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java b/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java index 40d9d871..d3b02f47 100644 --- a/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java +++ b/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java @@ -49,31 +49,31 @@ public Collection getDeviceGroup(final int index) { @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 @@ protected final void setDevicesForGroup(final int index, final Set 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 @@ protected final void setDevicesForGroup(final int index, final Set /////////////////////////////////////////////////////////////////// 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; } } diff --git a/src/main/java/li/cil/oc2/common/bus/ItemHandlerDeviceBusElement.java b/src/main/java/li/cil/oc2/common/bus/ItemHandlerDeviceBusElement.java index 94d7ba9d..86116f3c 100644 --- a/src/main/java/li/cil/oc2/common/bus/ItemHandlerDeviceBusElement.java +++ b/src/main/java/li/cil/oc2/common/bus/ItemHandlerDeviceBusElement.java @@ -40,32 +40,35 @@ public void exportDeviceDataToItemStack(final int slot, final ItemStack stack) { 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 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 devices) { diff --git a/src/main/java/li/cil/oc2/common/bus/device/item/AbstractBlockDeviceVMDevice.java b/src/main/java/li/cil/oc2/common/bus/device/item/AbstractBlockDeviceVMDevice.java index 0993c486..e2a891a5 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/item/AbstractBlockDeviceVMDevice.java +++ b/src/main/java/li/cil/oc2/common/bus/device/item/AbstractBlockDeviceVMDevice.java @@ -41,7 +41,7 @@ public abstract class AbstractBlockDeviceVMDevice 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 LazyOptional getCapability(@NotNull final Capability capability, @Nullable final Direction side) { + return Capabilities.ENERGY_STORAGE.orEmpty(capability, optional); + } +} diff --git a/src/main/java/li/cil/oc2/common/energy/FixedEnergyStorage.java b/src/main/java/li/cil/oc2/common/energy/FixedEnergyStorage.java new file mode 100644 index 00000000..2a8a8c64 --- /dev/null +++ b/src/main/java/li/cil/oc2/common/energy/FixedEnergyStorage.java @@ -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 { + 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); + } +} diff --git a/src/main/java/li/cil/oc2/common/energy/package-info.java b/src/main/java/li/cil/oc2/common/energy/package-info.java new file mode 100644 index 00000000..6a2d105f --- /dev/null +++ b/src/main/java/li/cil/oc2/common/energy/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package li.cil.oc2.common.energy; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java index 6ea681b9..f2bdff1b 100644 --- a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java +++ b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java @@ -7,6 +7,7 @@ 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.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.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.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.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 TARGET_POSITION = EntityDataManager.createKey(RobotEntity.class, DataSerializers.BLOCK_POS); public static final DataParameter 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 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 final RobotBusElement busElement = new RobotBusElement(); private long lastPistonMovement; /////////////////////////////////////////////////////////////////// @@ -164,6 +172,9 @@ public LazyOptional getCapability(@NotNull final Capability capability 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 boolean shouldSpawnRunningEffects() { } 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 @@ protected void writeAdditional(final CompoundNBT tag) { 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 @@ protected void readAdditional(final CompoundNBT tag) { 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 @@ private RobotVirtualMachine(final CommonDeviceBusController busController) { } @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 void stopRunnerAndReset() { 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); diff --git a/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementAction.java b/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementAction.java index f86365de..852c2cdd 100644 --- a/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementAction.java +++ b/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementAction.java @@ -7,6 +7,7 @@ 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 CompoundNBT serialize() { 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 void deserialize(final CompoundNBT tag) { 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); } } diff --git a/src/main/java/li/cil/oc2/common/item/AbstractBlockDeviceItem.java b/src/main/java/li/cil/oc2/common/item/AbstractBlockDeviceItem.java index d77b9682..17560b73 100644 --- a/src/main/java/li/cil/oc2/common/item/AbstractBlockDeviceItem.java +++ b/src/main/java/li/cil/oc2/common/item/AbstractBlockDeviceItem.java @@ -3,11 +3,10 @@ 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 static BlockDeviceData getData(final ItemStack stack) { 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 static boolean isReadonly(final ItemStack stack) { 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) { diff --git a/src/main/java/li/cil/oc2/common/item/AbstractStorageItem.java b/src/main/java/li/cil/oc2/common/item/AbstractStorageItem.java index 8535e869..b8d88f91 100644 --- a/src/main/java/li/cil/oc2/common/item/AbstractStorageItem.java +++ b/src/main/java/li/cil/oc2/common/item/AbstractStorageItem.java @@ -26,13 +26,12 @@ public static int getCapacity(final ItemStack stack) { 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) { diff --git a/src/main/java/li/cil/oc2/common/item/ChargerItem.java b/src/main/java/li/cil/oc2/common/item/ChargerItem.java new file mode 100644 index 00000000..52947fcf --- /dev/null +++ b/src/main/java/li/cil/oc2/common/item/ChargerItem.java @@ -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 items) { + if (Config.chargerUseEnergy()) { + super.fillItemGroup(group, items); + } + } +} diff --git a/src/main/java/li/cil/oc2/common/item/FlashMemoryItem.java b/src/main/java/li/cil/oc2/common/item/FlashMemoryItem.java index c920901a..cf2e3772 100644 --- a/src/main/java/li/cil/oc2/common/item/FlashMemoryItem.java +++ b/src/main/java/li/cil/oc2/common/item/FlashMemoryItem.java @@ -13,6 +13,7 @@ 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 static Firmware getFirmware(final ItemStack stack) { 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) { diff --git a/src/main/java/li/cil/oc2/common/item/Items.java b/src/main/java/li/cil/oc2/common/item/Items.java index 9959c7fb..fda7155d 100644 --- a/src/main/java/li/cil/oc2/common/item/Items.java +++ b/src/main/java/li/cil/oc2/common/item/Items.java @@ -25,6 +25,7 @@ public final class Items { public static final RegistryObject NETWORK_HUB = register(Constants.NETWORK_HUB_BLOCK_NAME, Blocks.NETWORK_HUB); public static final RegistryObject REDSTONE_INTERFACE = register(Constants.REDSTONE_INTERFACE_BLOCK_NAME, Blocks.REDSTONE_INTERFACE); public static final RegistryObject DISK_DRIVE = register(Constants.DISK_DRIVE_BLOCK_NAME, Blocks.DISK_DRIVE); + public static final RegistryObject CHARGER = register(Constants.CHARGER_BLOCK_NAME, Blocks.CHARGER, ChargerItem::new); /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/item/RobotItem.java b/src/main/java/li/cil/oc2/common/item/RobotItem.java index 2c56808e..9a737bb9 100644 --- a/src/main/java/li/cil/oc2/common/item/RobotItem.java +++ b/src/main/java/li/cil/oc2/common/item/RobotItem.java @@ -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.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.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 RobotItem() { public void addInformation(final ItemStack stack, @Nullable final World world, final List 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 diff --git a/src/main/java/li/cil/oc2/common/serialization/NBTSerialization.java b/src/main/java/li/cil/oc2/common/serialization/NBTSerialization.java index b7491a85..1fadf3f4 100644 --- a/src/main/java/li/cil/oc2/common/serialization/NBTSerialization.java +++ b/src/main/java/li/cil/oc2/common/serialization/NBTSerialization.java @@ -16,38 +16,38 @@ import java.util.UUID; public final class NBTSerialization { - public static void serialize(final CompoundNBT nbt, final T value, final Class type) throws SerializationException { - Ceres.getSerializer(type).serialize(new Serializer(nbt), type, value); + public static void serialize(final CompoundNBT tag, final T value, final Class type) throws SerializationException { + Ceres.getSerializer(type).serialize(new Serializer(tag), type, value); } - public static void serialize(final CompoundNBT nbt, final T value) throws SerializationException { + public static void serialize(final CompoundNBT tag, final T value) throws SerializationException { @SuppressWarnings("unchecked") final Class type = (Class) value.getClass(); - serialize(nbt, value, type); + serialize(tag, value, type); } public static CompoundNBT serialize(final T value, final Class 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 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 deserialize(final CompoundNBT nbt, final Class type, @Nullable final T into) throws SerializationException { - return Ceres.getSerializer(type).deserialize(new Deserializer(nbt), type, into); + public static T deserialize(final CompoundNBT tag, final Class type, @Nullable final T into) throws SerializationException { + return Ceres.getSerializer(type).deserialize(new Deserializer(tag), type, into); } - public static T deserialize(final CompoundNBT nbt, final Class type) throws SerializationException { - return deserialize(nbt, type, null); + public static T deserialize(final CompoundNBT tag, final Class type) throws SerializationException { + return deserialize(tag, type, null); } - public static T deserialize(final CompoundNBT nbt, final T into) throws SerializationException { + public static T deserialize(final CompoundNBT tag, final T into) throws SerializationException { @SuppressWarnings("unchecked") final Class type = (Class) into.getClass(); - return deserialize(nbt, type, into); + return deserialize(tag, type, into); } /////////////////////////////////////////////////////////////////// @@ -71,50 +71,50 @@ public static T deserialize(final CompoundNBT nbt, final T into) throws Seri } 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 void putObject(final String name, final Class type, @Nullable final Ob } 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 @@ private INBT putArray(final String name, final Class type, final Object value } 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 @@ private INBT putArray(final String name, final Class type, final Object value 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 @@ private INBT putArray(final String name, final Class type, final Object value 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 Object getObject(final String name, final Class type, @Nullable final } // 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 @@ private static Object getArray(final INBT nbt, final Class type, final @Nulla } 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 @@ private static Object getArray(final INBT nbt, final Class type, final @Nulla 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 @@ private static Object getArray(final INBT nbt, final Class type, final @Nulla @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 @@ private interface ArraySerializer { 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 INBT serialize(final Object value) { } @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 INBT serialize(final Object value) { } @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 INBT serialize(final Object value) { } @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 INBT serialize(final Object value) { } @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 INBT serialize(final Object value) { } @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 INBT serialize(final Object value) { } @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 INBT serialize(final Object value) { } @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 INBT serialize(final Object value) { } @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 INBT serialize(final Object value) { } @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 INBT serialize(final Object value) { } @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 INBT serialize(final Object value) { } @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()]; diff --git a/src/main/java/li/cil/oc2/common/serialization/NBTToJsonConverter.java b/src/main/java/li/cil/oc2/common/serialization/NBTToJsonConverter.java index 512e1359..a4fa0b44 100644 --- a/src/main/java/li/cil/oc2/common/serialization/NBTToJsonConverter.java +++ b/src/main/java/li/cil/oc2/common/serialization/NBTToJsonConverter.java @@ -7,60 +7,60 @@ 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 static JsonElement convert(@Nullable final INBT nbt) { } 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]); } diff --git a/src/main/java/li/cil/oc2/common/tileentity/ChargerTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/ChargerTileEntity.java new file mode 100644 index 00000000..5e8f9ada --- /dev/null +++ b/src/main/java/li/cil/oc2/common/tileentity/ChargerTileEntity.java @@ -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 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); + } +} diff --git a/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java index 6f66f054..c670aee8 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java +++ b/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java @@ -4,6 +4,7 @@ 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.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.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.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 VirtualMachine getVirtualMachine() { } public VMItemStackHandlers getItemStackHandlers() { - return items; + return deviceItems; } public void start() { @@ -195,7 +202,8 @@ public CompoundNBT write(CompoundNBT tag) { 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 void read(final BlockState blockState, final CompoundNBT tag) { 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 ComputerBusElement() { public Optional>> getNeighbors() { return super.getNeighbors().map(neighbors -> { final ArrayList> list = new ArrayList<>(neighbors); - list.add(LazyOptional.of(() -> items.busElement)); + list.add(LazyOptional.of(() -> deviceItems.busElement)); return list; }); } @@ -347,6 +358,33 @@ public void tick() { 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(); diff --git a/src/main/java/li/cil/oc2/common/tileentity/DiskDriveTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/DiskDriveTileEntity.java index 2f74ea3b..44b010c4 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/DiskDriveTileEntity.java +++ b/src/main/java/li/cil/oc2/common/tileentity/DiskDriveTileEntity.java @@ -112,21 +112,21 @@ protected void collectCapabilities(final CapabilityCollector collector, @Nullabl @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 CompoundNBT write(CompoundNBT tag) { 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)); } /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/tileentity/TileEntities.java b/src/main/java/li/cil/oc2/common/tileentity/TileEntities.java index 1340e459..929aa57b 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/TileEntities.java +++ b/src/main/java/li/cil/oc2/common/tileentity/TileEntities.java @@ -24,6 +24,7 @@ public final class TileEntities { public static final RegistryObject> NETWORK_CONNECTOR_TILE_ENTITY = register(Constants.NETWORK_CONNECTOR_BLOCK_NAME, Blocks.NETWORK_CONNECTOR, NetworkConnectorTileEntity::new); public static final RegistryObject> NETWORK_HUB_TILE_ENTITY = register(Constants.NETWORK_HUB_BLOCK_NAME, Blocks.NETWORK_HUB, NetworkHubTileEntity::new); public static final RegistryObject> DISK_DRIVE_TILE_ENTITY = register(Constants.DISK_DRIVE_BLOCK_NAME, Blocks.DISK_DRIVE, DiskDriveTileEntity::new); + public static final RegistryObject> CHARGER_TILE_ENTITY = register(Constants.CHARGER_BLOCK_NAME, Blocks.CHARGER, ChargerTileEntity::new); /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/util/ItemDeviceUtils.java b/src/main/java/li/cil/oc2/common/util/ItemDeviceUtils.java index c19306a4..e48f8015 100644 --- a/src/main/java/li/cil/oc2/common/util/ItemDeviceUtils.java +++ b/src/main/java/li/cil/oc2/common/util/ItemDeviceUtils.java @@ -13,24 +13,11 @@ public final class ItemDeviceUtils { /////////////////////////////////////////////////////////////////// - public static Optional 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); } diff --git a/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java b/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java index 668822f0..03cde38a 100644 --- a/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java +++ b/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java @@ -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 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 spawnAsEntity(final World world, final BlockPos pos, final ItemStack stack) { diff --git a/src/main/java/li/cil/oc2/common/util/NBTUtils.java b/src/main/java/li/cil/oc2/common/util/NBTUtils.java index e43a4390..5e773087 100644 --- a/src/main/java/li/cil/oc2/common/util/NBTUtils.java +++ b/src/main/java/li/cil/oc2/common/util/NBTUtils.java @@ -2,8 +2,7 @@ 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 static > T getEnum(final CompoundNBT compound, final St } } - 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(); + } - 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") - ); - } + CompoundNBT childTag = tag; + for (final String tagName : path) { + if (!childTag.contains(tagName, NBTTagIds.TAG_COMPOUND)) { + return new CompoundNBT(); + } + childTag = childTag.getCompound(tagName); + } - 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); + return childTag; } - 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(); } } diff --git a/src/main/java/li/cil/oc2/common/util/TooltipUtils.java b/src/main/java/li/cil/oc2/common/util/TooltipUtils.java index 459a53d7..8e631f61 100644 --- a/src/main/java/li/cil/oc2/common/util/TooltipUtils.java +++ b/src/main/java/li/cil/oc2/common/util/TooltipUtils.java @@ -4,6 +4,7 @@ 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.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> ITEM_STACKS = ThreadLocal.withInitial(ArrayList::new); private static final ThreadLocal ITEM_STACKS_SIZES = ThreadLocal.withInitial(IntArrayList::new); @@ -47,40 +49,28 @@ public static void tryAddDescription(final ItemStack stack, final List tooltip) { - addInventoryInformation(ItemStackUtils.getTileEntityInventoryTag(stack), tooltip); - } - - public static void addTileEntityInventoryInformation(final ItemStack stack, final List 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 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 tooltip, final String... subInventoryNames) { - addInventoryInformation(ItemStackUtils.getEntityInventoryTag(stack), tooltip, subInventoryNames); + public static void addInventoryInformation(final CompoundNBT itemsTag, final List tooltip) { + addInventoryInformation(itemsTag, tooltip, getDeviceTypeNames()); } - public static void addInventoryInformation(@Nullable final CompoundNBT inventoryTag, final List tooltip) { - addInventoryInformation(inventoryTag, tooltip, getDeviceTypeNames()); - } - - public static void addInventoryInformation(@Nullable final CompoundNBT inventoryTag, final List tooltip, final String... subInventoryNames) { - if (inventoryTag == null) { - return; - } - + public static void addInventoryInformation(final CompoundNBT itemsTag, final List tooltip, final String... subInventoryNames) { final List 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 static void addInventoryInformation(@Nullable final CompoundNBT inventory } } + public static void addTileEntityEnergyInformation(final ItemStack stack, final List 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 tooltip) { + addEnergyInformation(NBTUtils.getChildTag(stack.getTag(), MOD_TAG_NAME, ENERGY_TAG_NAME), tooltip); + } + + public static void addEnergyInformation(final CompoundNBT energyTag, final List 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 registry = RegistryManager.ACTIVE.getRegistry(DeviceType.REGISTRY); if (registry != null) { @@ -106,11 +120,11 @@ private static String[] getDeviceTypeNames() { } } - private static void collectItemStacks(final CompoundNBT nbt, final List 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 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++) { diff --git a/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java b/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java index 0d0db995..0784e424 100644 --- a/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java +++ b/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java @@ -36,6 +36,7 @@ protected void registerStatesAndModels() { .end(); horizontalBlock(Blocks.NETWORK_HUB, Items.NETWORK_HUB); horizontalBlock(Blocks.DISK_DRIVE, Items.DISK_DRIVE); + horizontalBlock(Blocks.CHARGER, Items.CHARGER); registerCableStates(); } diff --git a/src/main/java/li/cil/oc2/data/ModBlockTagsProvider.java b/src/main/java/li/cil/oc2/data/ModBlockTagsProvider.java index 8de1d0a9..fdd972a1 100644 --- a/src/main/java/li/cil/oc2/data/ModBlockTagsProvider.java +++ b/src/main/java/li/cil/oc2/data/ModBlockTagsProvider.java @@ -30,7 +30,8 @@ protected void registerTags() { NETWORK_CONNECTOR.get(), NETWORK_HUB.get(), REDSTONE_INTERFACE.get(), - DISK_DRIVE.get() + DISK_DRIVE.get(), + CHARGER.get() ); } } diff --git a/src/main/java/li/cil/oc2/data/ModLootTableProvider.java b/src/main/java/li/cil/oc2/data/ModLootTableProvider.java index 1498018d..f653a765 100644 --- a/src/main/java/li/cil/oc2/data/ModLootTableProvider.java +++ b/src/main/java/li/cil/oc2/data/ModLootTableProvider.java @@ -21,8 +21,7 @@ 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 @@ protected void addTables() { 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 @@ private static LootTable.Builder droppingWithInventory(final Block block) { .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) ) ) diff --git a/src/main/resources/assets/oc2/blockstates/charger.json b/src/main/resources/assets/oc2/blockstates/charger.json new file mode 100644 index 00000000..77ef6577 --- /dev/null +++ b/src/main/resources/assets/oc2/blockstates/charger.json @@ -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 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/oc2/lang/en_us.json b/src/main/resources/assets/oc2/lang/en_us.json index 3f4ebe12..14a3576e 100644 --- a/src/main/resources/assets/oc2/lang/en_us.json +++ b/src/main/resources/assets/oc2/lang/en_us.json @@ -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", diff --git a/src/main/resources/assets/oc2/models/block/charger.json b/src/main/resources/assets/oc2/models/block/charger.json new file mode 100644 index 00000000..84664a15 --- /dev/null +++ b/src/main/resources/assets/oc2/models/block/charger.json @@ -0,0 +1 @@ +{"parent":"block/block","textures":{"atlas0":"oc2:block/charger/charger_atlas0","atlas1":"oc2:block/charger/charger_atlas1","atlas2":"oc2:block/charger/charger_atlas2","atlas3":"oc2:block/charger/charger_atlas3","particle":"#atlas0"},"elements":[{"from":[0,0,0],"to":[16,12,16],"faces":{"east":{"texture":"atlas0","cullface":"east","uv":[0.0,0.0,8.0,6.0]},"west":{"texture":"atlas0","cullface":"west","uv":[0.0,6.0,8.0,12.0]},"up":{"texture":"atlas1","uv":[0.0,0.0,8.0,8.0]},"down":{"texture":"atlas1","cullface":"down","uv":[0.0,8.0,8.0,16.0]},"north":{"texture":"atlas0","cullface":"north","uv":[8.0,6.0,16.0,12.0]},"south":{"texture":"atlas0","cullface":"south","uv":[8.0,0.0,16.0,6.0]}}},{"from":[0,12,15],"to":[3,13,16],"faces":{"east":{"texture":"atlas2","uv":[15.5,12.0,16.0,12.5]},"west":{"texture":"atlas2","cullface":"west","uv":[15.5,12.5,16.0,13.0]},"up":{"texture":"atlas2","uv":[14.0,7.5,15.5,8.0]},"down":{"texture":"atlas2","uv":[14.0,7.0,15.5,7.5]},"south":{"texture":"atlas2","cullface":"south","uv":[14.0,6.5,15.5,7.0]}}},{"from":[13,12,15],"to":[16,13,16],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[15.5,13.0,16.0,13.5]},"west":{"texture":"atlas2","uv":[15.5,13.5,16.0,14.0]},"up":{"texture":"atlas2","uv":[8.0,6.0,9.5,6.5]},"down":{"texture":"atlas2","uv":[9.5,6.0,11.0,6.5]},"south":{"texture":"atlas2","cullface":"south","uv":[11.0,6.0,12.5,6.5]}}},{"from":[0,12,13],"to":[16,13,15],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[15.0,10.5,16.0,11.0]},"west":{"texture":"atlas2","cullface":"west","uv":[15.0,10.0,16.0,10.5]},"up":{"texture":"atlas0","uv":[0.0,12.0,8.0,13.0]},"down":{"texture":"atlas0","uv":[0.0,13.0,8.0,14.0]},"north":{"texture":"atlas0","uv":[0.0,14.0,8.0,14.5]},"south":{"texture":"atlas0","uv":[0.0,14.5,8.0,15.0]}}},{"from":[1,12,3],"to":[15,13,13],"faces":{"east":{"texture":"atlas2","uv":[8.0,8.5,13.0,9.0]},"west":{"texture":"atlas2","uv":[8.0,9.0,13.0,9.5]},"up":{"texture":"atlas2","uv":[0.0,11.0,7.0,16.0]},"down":{"texture":"atlas2","uv":[7.0,11.0,14.0,16.0]},"north":{"texture":"atlas2","uv":[8.0,10.5,15.0,11.0]},"south":{"texture":"atlas2","uv":[8.0,10.0,15.0,10.5]}}},{"from":[0,12,1],"to":[16,13,3],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[11.0,4.5,12.0,5.0]},"west":{"texture":"atlas2","cullface":"west","uv":[12.0,4.5,13.0,5.0]},"up":{"texture":"atlas0","uv":[0.0,15.0,8.0,16.0]},"down":{"texture":"atlas0","uv":[8.0,15.0,16.0,16.0]},"north":{"texture":"atlas0","uv":[8.0,14.5,16.0,15.0]},"south":{"texture":"atlas0","uv":[8.0,14.0,16.0,14.5]}}},{"from":[0,12,0],"to":[3,13,1],"faces":{"east":{"texture":"atlas2","uv":[15.5,7.5,16.0,8.0]},"west":{"texture":"atlas2","cullface":"west","uv":[15.5,7.0,16.0,7.5]},"up":{"texture":"atlas2","uv":[12.5,6.0,14.0,6.5]},"down":{"texture":"atlas2","uv":[14.0,6.0,15.5,6.5]},"north":{"texture":"atlas2","cullface":"north","uv":[8.0,5.5,9.5,6.0]}}},{"from":[13,12,0],"to":[16,13,1],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[15.5,6.5,16.0,7.0]},"west":{"texture":"atlas2","uv":[15.5,6.0,16.0,6.5]},"up":{"texture":"atlas2","uv":[9.5,5.5,11.0,6.0]},"down":{"texture":"atlas2","uv":[11.0,5.5,12.5,6.0]},"north":{"texture":"atlas2","cullface":"north","uv":[12.5,5.5,14.0,6.0]}}},{"from":[0,13,0],"to":[16,15,16],"faces":{"east":{"texture":"atlas0","cullface":"east","uv":[8.0,13.0,16.0,14.0]},"west":{"texture":"atlas0","cullface":"west","uv":[8.0,12.0,16.0,13.0]},"up":{"texture":"atlas1","uv":[8.0,8.0,16.0,16.0]},"down":{"texture":"atlas1","uv":[8.0,0.0,16.0,8.0]},"north":{"texture":"atlas2","cullface":"north","uv":[0.0,0.0,8.0,1.0]},"south":{"texture":"atlas2","cullface":"south","uv":[0.0,1.0,8.0,2.0]}}},{"from":[0,15,13],"to":[16,16,16],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[14.0,5.5,15.5,6.0]},"west":{"texture":"atlas2","cullface":"west","uv":[8.0,4.5,9.5,5.0]},"up":{"texture":"atlas2","cullface":"up","uv":[0.0,2.0,8.0,3.5]},"north":{"texture":"atlas2","uv":[0.0,3.5,8.0,4.0]},"south":{"texture":"atlas2","cullface":"south","uv":[0.0,4.0,8.0,4.5]}}},{"from":[0,15,12],"to":[6,16,13],"faces":{"east":{"texture":"atlas2","uv":[15.5,5.5,16.0,6.0]},"west":{"texture":"atlas2","cullface":"west","uv":[15.5,5.0,16.0,5.5]},"up":{"texture":"atlas2","cullface":"up","uv":[8.0,9.5,11.0,10.0]},"north":{"texture":"atlas2","uv":[11.0,9.5,14.0,10.0]},"south":{"texture":"atlas2","uv":[13.0,9.0,16.0,9.5]}}},{"from":[10,15,12],"to":[16,16,13],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[13.0,4.0,13.5,4.5]},"west":{"texture":"atlas2","uv":[13.5,4.0,14.0,4.5]},"up":{"texture":"atlas2","cullface":"up","uv":[13.0,8.5,16.0,9.0]},"north":{"texture":"atlas2","uv":[8.0,8.0,11.0,8.5]},"south":{"texture":"atlas2","uv":[11.0,8.0,14.0,8.5]}}},{"from":[0,15,10],"to":[16,16,12],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[13.0,4.5,14.0,5.0]},"west":{"texture":"atlas2","cullface":"west","uv":[14.0,4.5,15.0,5.0]},"up":{"texture":"atlas2","cullface":"up","uv":[0.0,4.5,8.0,5.5]},"north":{"texture":"atlas2","uv":[0.0,5.5,8.0,6.0]},"south":{"texture":"atlas2","uv":[0.0,6.0,8.0,6.5]}}},{"from":[0,15,6],"to":[3,16,10],"faces":{"east":{"texture":"atlas2","uv":[14.0,11.0,16.0,11.5]},"west":{"texture":"atlas2","cullface":"west","uv":[14.0,11.5,16.0,12.0]},"up":{"texture":"atlas2","cullface":"up","uv":[14.0,12.0,15.5,14.0]},"north":{"texture":"atlas2","uv":[8.0,5.0,9.5,5.5]},"south":{"texture":"atlas2","uv":[9.5,5.0,11.0,5.5]}}},{"from":[4,15,6],"to":[6,16,10],"faces":{"east":{"texture":"atlas2","uv":[14.0,14.0,16.0,14.5]},"west":{"texture":"atlas2","uv":[14.0,14.5,16.0,15.0]},"up":{"texture":"atlas3","cullface":"up","uv":[0.0,0.0,1.0,2.0]},"north":{"texture":"atlas2","uv":[15.0,4.5,16.0,5.0]},"south":{"texture":"atlas2","uv":[8.0,4.0,9.0,4.5]}}},{"from":[10,15,6],"to":[12,16,10],"faces":{"east":{"texture":"atlas2","uv":[14.0,15.0,16.0,15.5]},"west":{"texture":"atlas2","uv":[14.0,15.5,16.0,16.0]},"up":{"texture":"atlas3","cullface":"up","uv":[1.0,0.0,2.0,2.0]},"north":{"texture":"atlas2","uv":[9.0,4.0,10.0,4.5]},"south":{"texture":"atlas2","uv":[10.0,4.0,11.0,4.5]}}},{"from":[13,15,6],"to":[16,16,10],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[14.0,9.5,16.0,10.0]},"west":{"texture":"atlas2","uv":[14.0,8.0,16.0,8.5]},"up":{"texture":"atlas3","cullface":"up","uv":[2.0,0.0,3.5,2.0]},"north":{"texture":"atlas2","uv":[11.0,5.0,12.5,5.5]},"south":{"texture":"atlas2","uv":[12.5,5.0,14.0,5.5]}}},{"from":[0,15,4],"to":[16,16,6],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[11.0,4.0,12.0,4.5]},"west":{"texture":"atlas2","cullface":"west","uv":[12.0,4.0,13.0,4.5]},"up":{"texture":"atlas2","cullface":"up","uv":[0.0,6.5,8.0,7.5]},"north":{"texture":"atlas2","uv":[0.0,7.5,8.0,8.0]},"south":{"texture":"atlas2","uv":[0.0,8.0,8.0,8.5]}}},{"from":[0,15,3],"to":[6,16,4],"faces":{"east":{"texture":"atlas2","uv":[14.0,4.0,14.5,4.5]},"west":{"texture":"atlas2","cullface":"west","uv":[14.5,4.0,15.0,4.5]},"up":{"texture":"atlas2","cullface":"up","uv":[8.0,7.5,11.0,8.0]},"north":{"texture":"atlas2","uv":[11.0,7.5,14.0,8.0]},"south":{"texture":"atlas2","uv":[8.0,6.5,11.0,7.0]}}},{"from":[10,15,3],"to":[16,16,4],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[15.0,4.0,15.5,4.5]},"west":{"texture":"atlas2","uv":[15.5,4.0,16.0,4.5]},"up":{"texture":"atlas2","cullface":"up","uv":[8.0,7.0,11.0,7.5]},"north":{"texture":"atlas2","uv":[11.0,7.0,14.0,7.5]},"south":{"texture":"atlas2","uv":[11.0,6.5,14.0,7.0]}}},{"from":[0,15,0],"to":[16,16,3],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[14.0,5.0,15.5,5.5]},"west":{"texture":"atlas2","cullface":"west","uv":[9.5,4.5,11.0,5.0]},"up":{"texture":"atlas2","cullface":"up","uv":[0.0,8.5,8.0,10.0]},"north":{"texture":"atlas2","cullface":"north","uv":[0.0,10.0,8.0,10.5]},"south":{"texture":"atlas2","uv":[0.0,10.5,8.0,11.0]}}}]} \ No newline at end of file diff --git a/src/main/resources/assets/oc2/models/item/charger.json b/src/main/resources/assets/oc2/models/item/charger.json new file mode 100644 index 00000000..07b7176c --- /dev/null +++ b/src/main/resources/assets/oc2/models/item/charger.json @@ -0,0 +1,3 @@ +{ + "parent": "oc2:block/charger" +} \ No newline at end of file diff --git a/src/main/resources/assets/oc2/textures/block/charger/charger_atlas0.png b/src/main/resources/assets/oc2/textures/block/charger/charger_atlas0.png new file mode 100644 index 00000000..c8d1da2d Binary files /dev/null and b/src/main/resources/assets/oc2/textures/block/charger/charger_atlas0.png differ diff --git a/src/main/resources/assets/oc2/textures/block/charger/charger_atlas1.png b/src/main/resources/assets/oc2/textures/block/charger/charger_atlas1.png new file mode 100644 index 00000000..f5116232 Binary files /dev/null and b/src/main/resources/assets/oc2/textures/block/charger/charger_atlas1.png differ diff --git a/src/main/resources/assets/oc2/textures/block/charger/charger_atlas2.png b/src/main/resources/assets/oc2/textures/block/charger/charger_atlas2.png new file mode 100644 index 00000000..c64768c8 Binary files /dev/null and b/src/main/resources/assets/oc2/textures/block/charger/charger_atlas2.png differ diff --git a/src/main/resources/assets/oc2/textures/block/charger/charger_atlas3.png b/src/main/resources/assets/oc2/textures/block/charger/charger_atlas3.png new file mode 100644 index 00000000..abf09286 Binary files /dev/null and b/src/main/resources/assets/oc2/textures/block/charger/charger_atlas3.png differ diff --git a/src/main/resources/assets/oc2/textures/block/charger/effect.png b/src/main/resources/assets/oc2/textures/block/charger/effect.png new file mode 100644 index 00000000..bb8e6ddd Binary files /dev/null and b/src/main/resources/assets/oc2/textures/block/charger/effect.png differ diff --git a/src/main/resources/data/oc2/loot_tables/blocks/charger.json b/src/main/resources/data/oc2/loot_tables/blocks/charger.json new file mode 100644 index 00000000..ec0b62bb --- /dev/null +++ b/src/main/resources/data/oc2/loot_tables/blocks/charger.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "oc2:charger" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/oc2/loot_tables/blocks/computer.json b/src/main/resources/data/oc2/loot_tables/blocks/computer.json index db543283..ccd39d8f 100644 --- a/src/main/resources/data/oc2/loot_tables/blocks/computer.json +++ b/src/main/resources/data/oc2/loot_tables/blocks/computer.json @@ -15,6 +15,11 @@ "source": "items", "target": "BlockEntityTag.items", "op": "replace" + }, + { + "source": "energy", + "target": "BlockEntityTag.energy", + "op": "replace" } ] } diff --git a/src/main/resources/data/oc2/tags/blocks/wrench_breakable.json b/src/main/resources/data/oc2/tags/blocks/wrench_breakable.json index 8896a027..ff9510d8 100644 --- a/src/main/resources/data/oc2/tags/blocks/wrench_breakable.json +++ b/src/main/resources/data/oc2/tags/blocks/wrench_breakable.json @@ -6,6 +6,7 @@ "oc2:network_connector", "oc2:network_hub", "oc2:redstone_interface", - "oc2:disk_drive" + "oc2:disk_drive", + "oc2:charger" ] } \ No newline at end of file