From 8dfa967f7795275fbcb56c6c7bf01eab5c4be62c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sun, 14 Feb 2021 12:52:03 +0100 Subject: [PATCH] Bus and item devices can (and do) contribute to energy consumption. --- .../java/li/cil/oc2/api/bus/DeviceBus.java | 23 ---- .../li/cil/oc2/api/bus/DeviceBusElement.java | 22 +++- .../device/provider/ItemDeviceProvider.java | 16 ++- .../java/li/cil/oc2/client/ClientSetup.java | 2 + .../client/gui/AbstractTerminalWidget.java | 73 ++++++++++--- .../client/gui/ComputerTerminalScreen.java | 72 +++++++------ .../oc2/client/gui/RobotTerminalScreen.java | 21 ++-- .../li/cil/oc2/client/gui/widget/Sprite.java | 6 ++ src/main/java/li/cil/oc2/common/Config.java | 38 +++++-- .../java/li/cil/oc2/common/Constants.java | 5 + .../java/li/cil/oc2/common/block/Blocks.java | 1 + .../cil/oc2/common/block/BusCableBlock.java | 18 +++- .../cil/oc2/common/block/ComputerBlock.java | 50 +++------ .../oc2/common/block/CreativeEnergyBlock.java | 31 ++++++ .../cil/oc2/common/block/DiskDriveBlock.java | 3 - .../common/block/NetworkConnectorBlock.java | 2 - .../cil/oc2/common/block/NetworkHubBlock.java | 3 - .../common/block/RedstoneInterfaceBlock.java | 3 - .../common/bus/AbstractDeviceBusElement.java | 27 +++-- .../bus/AbstractGroupingDeviceBusElement.java | 9 +- .../common/bus/CommonDeviceBusController.java | 25 ++++- .../bus/ItemHandlerDeviceBusElement.java | 14 +-- .../bus/TileEntityDeviceBusController.java | 4 +- .../bus/TileEntityDeviceBusElement.java | 4 +- .../BlockOperationsModuleDeviceProvider.java | 6 ++ .../item/HardDriveItemDeviceProvider.java | 14 +++ ...ventoryOperationsModuleDeviceProvider.java | 6 ++ .../item/MemoryItemDeviceProvider.java | 9 ++ ...etworkInterfaceCardItemDeviceProvider.java | 6 ++ ...dstoneInterfaceCardItemDeviceProvider.java | 6 ++ .../util/AbstractItemDeviceProvider.java | 9 ++ .../bus/device/util/AbstractDeviceInfo.java | 4 + .../oc2/common/bus/device/util/Devices.java | 54 +++++----- .../bus/device/util/ItemDeviceInfo.java | 14 ++- .../container/ComputerTerminalContainer.java | 69 ++++++++++++ .../cil/oc2/common/container/Containers.java | 1 + .../container/DeviceItemStackHandler.java | 11 +- .../container/RobotTerminalContainer.java | 27 ++++- .../TypedDeviceItemStackHandler.java | 9 +- .../container/TypedItemStackHandler.java | 3 +- .../common/energy/EnergyStorageItemStack.java | 13 ++- .../li/cil/oc2/common/entity/RobotEntity.java | 69 ++++++------ .../li/cil/oc2/common/item/BusCableItem.java | 16 +++ .../cil/oc2/common/item/BusInterfaceItem.java | 44 +++++++- .../java/li/cil/oc2/common/item/Items.java | 1 + .../li/cil/oc2/common/item/ModBlockItem.java | 7 +- .../java/li/cil/oc2/common/item/ModItem.java | 5 +- .../li/cil/oc2/common/item/RobotItem.java | 5 +- .../serializers/MemoryRangeSerializer.java | 3 +- .../common/tileentity/BusCableTileEntity.java | 8 ++ .../common/tileentity/ChargerTileEntity.java | 10 +- .../common/tileentity/ComputerTileEntity.java | 100 +++++++++++++----- .../tileentity/CreativeEnergyTileEntity.java | 36 +++++++ .../tileentity/DiskDriveTileEntity.java | 4 +- .../oc2/common/tileentity/TileEntities.java | 1 + .../cil/oc2/common/util/FakePlayerUtils.java | 3 +- .../li/cil/oc2/common/util/TooltipUtils.java | 56 ++++++---- .../vm/AbstractVMItemStackHandlers.java | 11 +- .../oc2/common/vm/AbstractVirtualMachine.java | 43 +++++--- .../cil/oc2/data/ModBlockStateProvider.java | 7 ++ .../li/cil/oc2/data/ModBlockTagsProvider.java | 3 +- .../li/cil/oc2/data/ModItemTagsProvider.java | 3 +- .../oc2/blockstates/creative_energy.json | 7 ++ src/main/resources/assets/oc2/lang/en_us.json | 14 ++- .../oc2/models/block/creative_energy.json | 6 ++ .../oc2/models/item/creative_energy.json | 3 + .../oc2/textures/block/creative_energy.png | Bin 0 -> 1990 bytes .../oc2/textures/gui/screen/terminal.png | Bin 5443 -> 5724 bytes .../li/cil/oc2/common/bus/DeviceBusTests.java | 2 +- .../li/cil/oc2/common/bus/VMDeviceTests.java | 2 +- 70 files changed, 863 insertions(+), 339 deletions(-) create mode 100644 src/main/java/li/cil/oc2/common/block/CreativeEnergyBlock.java create mode 100644 src/main/java/li/cil/oc2/common/container/ComputerTerminalContainer.java create mode 100644 src/main/java/li/cil/oc2/common/tileentity/CreativeEnergyTileEntity.java create mode 100644 src/main/resources/assets/oc2/blockstates/creative_energy.json create mode 100644 src/main/resources/assets/oc2/models/block/creative_energy.json create mode 100644 src/main/resources/assets/oc2/models/item/creative_energy.json create mode 100644 src/main/resources/assets/oc2/textures/block/creative_energy.png diff --git a/src/main/java/li/cil/oc2/api/bus/DeviceBus.java b/src/main/java/li/cil/oc2/api/bus/DeviceBus.java index b4f69d88..6bb7f3ee 100644 --- a/src/main/java/li/cil/oc2/api/bus/DeviceBus.java +++ b/src/main/java/li/cil/oc2/api/bus/DeviceBus.java @@ -10,29 +10,6 @@ import java.util.Collection; * these devices. */ public interface DeviceBus { - /** - * Adds a device to this device bus. - *

- * Adding a device to the bus does not transfer ownership. In particular, - * the bus will not handle persisting devices that have been added to it. Also, - * the bus does not persist the list of devices. Instead, all devices that have - * been added to the bus must be added again after a load. It is the responsibility - * of {@link DeviceBusElement}s to detect and add devices to the bus. - * - * @param device the device to add to the bus. - */ - void addDevice(Device device); - - /** - * Removes a device from this device bus. - *

- * If the device has not been added with {@link #addDevice(Device)} before calling - * this method, this method is a no-op. - * - * @param device the device to remove from the bus. - */ - void removeDevice(Device device); - /** * The list of all devices currently registered with this device bus. * diff --git a/src/main/java/li/cil/oc2/api/bus/DeviceBusElement.java b/src/main/java/li/cil/oc2/api/bus/DeviceBusElement.java index dcf45779..ef2971d6 100644 --- a/src/main/java/li/cil/oc2/api/bus/DeviceBusElement.java +++ b/src/main/java/li/cil/oc2/api/bus/DeviceBusElement.java @@ -30,10 +30,6 @@ public interface DeviceBusElement extends DeviceBus { *

* When {@link #scheduleScan()} is called, {@link DeviceBusController#scheduleBusScan()} * must be called for each registered controller. - *

- * When either {@link #addDevice(Device)} or {@link #removeDevice(Device)} are called, - * {@link DeviceBusController#scanDevices()} should be called for each registered - * controller. * * @param controller the controller to add. */ @@ -98,4 +94,22 @@ public interface DeviceBusElement extends DeviceBus { * @return the stable id for the specified device. */ Optional getDeviceIdentifier(Device device); + + /** + * Returns the energy consumption of this bus element. + *

+ * Energy cost of a single bus element may vary depending on its configuration. For example, + * bus cables will also take into account the number of installed bus interfaces. Internal + * bus elements used to connect item devices will take into account the energy consumption of + * any connected item devices. + *

+ * Block devices that require a running amount of energy should use regular means of having + * energy injected into them. The device bus is not intended nor communicated as something + * that transfers power. + * + * @return the complexity of this bus element. + */ + default double getEnergyConsumption() { + return 0; + } } diff --git a/src/main/java/li/cil/oc2/api/bus/device/provider/ItemDeviceProvider.java b/src/main/java/li/cil/oc2/api/bus/device/provider/ItemDeviceProvider.java index 1e64a245..bb79c5ba 100644 --- a/src/main/java/li/cil/oc2/api/bus/device/provider/ItemDeviceProvider.java +++ b/src/main/java/li/cil/oc2/api/bus/device/provider/ItemDeviceProvider.java @@ -1,6 +1,5 @@ package li.cil.oc2.api.bus.device.provider; -import li.cil.oc2.api.bus.device.Device; import li.cil.oc2.api.bus.device.DeviceType; import li.cil.oc2.api.bus.device.DeviceTypes; import li.cil.oc2.api.bus.device.ItemDevice; @@ -43,7 +42,7 @@ public interface ItemDeviceProvider extends IForgeRegistryEntry getDevice(ItemDeviceQuery query); @@ -51,4 +50,17 @@ public interface ItemDeviceProvider extends IForgeRegistryEntry getDeviceType(final ItemDeviceQuery query) { return Optional.of(DeviceTypes.CARD); } + + /** + * The amount of energy the device that would be returned by {@link #getDevice(ItemDeviceQuery)} + * will consume per tick while the VM using it is running. + *

+ * Return 0 if no device would be provided. + * + * @param query the query describing the object to get an {@link ItemDevice} for. + * @return the amount of energy consumed by the device each tick. + */ + default int getEnergyConsumption(final ItemDeviceQuery query) { + return 0; + } } diff --git a/src/main/java/li/cil/oc2/client/ClientSetup.java b/src/main/java/li/cil/oc2/client/ClientSetup.java index cc91dd92..1b03eb6d 100644 --- a/src/main/java/li/cil/oc2/client/ClientSetup.java +++ b/src/main/java/li/cil/oc2/client/ClientSetup.java @@ -3,6 +3,7 @@ package li.cil.oc2.client; import li.cil.oc2.api.API; import li.cil.oc2.api.bus.device.DeviceType; import li.cil.oc2.client.gui.ComputerContainerScreen; +import li.cil.oc2.client.gui.ComputerTerminalScreen; import li.cil.oc2.client.gui.RobotContainerScreen; import li.cil.oc2.client.gui.RobotTerminalScreen; import li.cil.oc2.client.item.CustomItemColors; @@ -38,6 +39,7 @@ public final class ClientSetup { CustomItemColors.initialize(); ScreenManager.registerFactory(Containers.COMPUTER_CONTAINER.get(), ComputerContainerScreen::new); + ScreenManager.registerFactory(Containers.COMPUTER_TERMINAL_CONTAINER.get(), ComputerTerminalScreen::new); ScreenManager.registerFactory(Containers.ROBOT_CONTAINER.get(), RobotContainerScreen::new); ScreenManager.registerFactory(Containers.ROBOT_TERMINAL_CONTAINER.get(), RobotTerminalScreen::new); diff --git a/src/main/java/li/cil/oc2/client/gui/AbstractTerminalWidget.java b/src/main/java/li/cil/oc2/client/gui/AbstractTerminalWidget.java index 42c175be..51989436 100644 --- a/src/main/java/li/cil/oc2/client/gui/AbstractTerminalWidget.java +++ b/src/main/java/li/cil/oc2/client/gui/AbstractTerminalWidget.java @@ -15,11 +15,18 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.widget.Widget; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.ITextProperties; +import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TranslationTextComponent; +import net.minecraftforge.fml.client.gui.GuiUtils; import org.lwjgl.glfw.GLFW; import javax.annotation.Nullable; import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; + +import static li.cil.oc2.common.util.TooltipUtils.withColor; public abstract class AbstractTerminalWidget extends AbstractGui { public static final ResourceLocation BACKGROUND_LOCATION = new ResourceLocation(API.MOD_ID, "textures/gui/screen/terminal.png"); @@ -27,16 +34,23 @@ public abstract class AbstractTerminalWidget extends AbstractGui { public static final int TEXTURE_SIZE = 512; private static final Sprite BACKGROUND = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 336, 208, 0, 0); - private static final Sprite CONTROLS_BACKGROUND = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 19, 34, 80, 250); - private static final Sprite TERMINAL_FOCUSED = new Sprite(TERMINAL_FOCUSED_LOCATION, TEXTURE_SIZE, 336, 208, 0, 0); + + private static final Sprite CONTROLS_BACKGROUND = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 19, 34, 50, 250); + + private static final Sprite POWER_BASE = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 12, 15, 255); + private static final Sprite POWER_PRESSED = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 12, 29, 255); + private static final Sprite POWER_ACTIVE = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 12, 1, 255); private static final Sprite CAPTURE_INPUT_BASE = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 12, 15, 241); private static final Sprite CAPTURE_INPUT_PRESSED = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 12, 29, 241); private static final Sprite CAPTURE_INPUT_ACTIVE = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 12, 1, 241); - private static final Sprite POWER_BASE = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 12, 15, 255); - private static final Sprite POWER_PRESSED = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 12, 29, 255); - private static final Sprite POWER_ACTIVE = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 12, 1, 255); + private static final Sprite ENERGY_BACKGROUND = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 19, 34, 80, 250); + + private static final Sprite ENERGY_BASE = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 26, 110, 250); + private static final Sprite ENERGY_BAR = new Sprite(BACKGROUND_LOCATION, TEXTURE_SIZE, 12, 26, 125, 250); + + private static final Sprite TERMINAL_FOCUSED = new Sprite(TERMINAL_FOCUSED_LOCATION, TEXTURE_SIZE, 336, 208, 0, 0); public static final int TERMINAL_WIDTH = Terminal.WIDTH * Terminal.CHAR_WIDTH / 2; public static final int TERMINAL_HEIGHT = Terminal.HEIGHT * Terminal.CHAR_HEIGHT / 2; @@ -49,6 +63,7 @@ public abstract class AbstractTerminalWidget extends AbstractGui { public static final int HEIGHT = TERMINAL_HEIGHT + MARGIN_SIZE * 2; private static final int CONTROLS_TOP = 8; + private static final int ENERGY_TOP = CONTROLS_TOP + CONTROLS_BACKGROUND.height + 4; private static boolean isInputCaptureEnabled; @@ -59,6 +74,8 @@ public abstract class AbstractTerminalWidget extends AbstractGui { private int windowLeft, windowTop; private boolean isMouseOverTerminal; + private int currentEnergy, maxEnergy, energyConsumption; + /////////////////////////////////////////////////////////////////// protected AbstractTerminalWidget(final Screen parent, final Terminal terminal) { @@ -66,13 +83,27 @@ public abstract class AbstractTerminalWidget extends AbstractGui { this.terminal = terminal; } + public void setEnergyInfo(final int current, final int capacity, final int consumption) { + this.currentEnergy = current; + this.maxEnergy = capacity; + this.energyConsumption = consumption; + } + public void renderBackground(final MatrixStack matrixStack, final int mouseX, final int mouseY) { - isMouseOverTerminal = isOverTerminal(mouseX, mouseY); + isMouseOverTerminal = isMouseOverTerminal(mouseX, mouseY); RenderSystem.color4f(1f, 1f, 1f, 1f); getClient().getTextureManager().bindTexture(BACKGROUND_LOCATION); CONTROLS_BACKGROUND.draw(matrixStack, windowLeft - CONTROLS_BACKGROUND.width, windowTop + CONTROLS_TOP); + + if (maxEnergy > 0) { + final int x = windowLeft - ENERGY_BACKGROUND.width; + final int y = windowTop + ENERGY_TOP; + ENERGY_BACKGROUND.draw(matrixStack, x, y); + ENERGY_BASE.draw(matrixStack, x + 4, y + 4); + } + BACKGROUND.draw(matrixStack, windowLeft, windowTop); if (shouldCaptureInput()) { @@ -80,7 +111,7 @@ public abstract class AbstractTerminalWidget extends AbstractGui { } } - public void render(final MatrixStack matrixStack, @Nullable final ITextComponent error) { + public void render(final MatrixStack matrixStack, final int mouseX, final int mouseY, @Nullable final ITextComponent error) { if (isRunning()) { final MatrixStack stack = new MatrixStack(); stack.translate(windowLeft + TERMINAL_X, windowTop + TERMINAL_Y, getClient().getItemRenderer().zLevel); @@ -99,6 +130,18 @@ public abstract class AbstractTerminalWidget extends AbstractGui { 0xEE3322); } } + + if (maxEnergy > 0) { + ENERGY_BAR.drawFillY(matrixStack, windowLeft - ENERGY_BACKGROUND.width + 4, windowTop + ENERGY_TOP + 4, currentEnergy / (float) maxEnergy); + + if (isMouseOver(mouseX, mouseY, -ENERGY_BACKGROUND.width + 4, ENERGY_TOP + 4, ENERGY_BAR.width, ENERGY_BAR.height)) { + final List tooltip = Arrays.asList( + new TranslationTextComponent(Constants.TOOLTIP_ENERGY, withColor(currentEnergy + "/" + maxEnergy, TextFormatting.GREEN)), + new TranslationTextComponent(Constants.TOOLTIP_ENERGY_CONSUMPTION, withColor(String.valueOf(energyConsumption), TextFormatting.GREEN)) + ); + GuiUtils.drawHoveringText(matrixStack, tooltip, mouseX, mouseY, parent.width, parent.height, 200, getClient().fontRenderer); + } + } } public void tick() { @@ -209,12 +252,18 @@ public abstract class AbstractTerminalWidget extends AbstractGui { return isMouseOverTerminal && isInputCaptureEnabled && isRunning(); } - private boolean isOverTerminal(final int mouseX, final int mouseY) { + private boolean isMouseOverTerminal(final int mouseX, final int mouseY) { + return isMouseOver(mouseX, mouseY, + AbstractTerminalWidget.TERMINAL_X, AbstractTerminalWidget.TERMINAL_Y, + AbstractTerminalWidget.TERMINAL_WIDTH, AbstractTerminalWidget.TERMINAL_HEIGHT); + } + + private boolean isMouseOver(final int mouseX, final int mouseY, final int x, final int y, final int width, final int height) { final int localMouseX = mouseX - windowLeft; final int localMouseY = mouseY - windowTop; - return localMouseX >= AbstractTerminalWidget.TERMINAL_X && - localMouseX < AbstractTerminalWidget.TERMINAL_X + AbstractTerminalWidget.TERMINAL_WIDTH && - localMouseY >= AbstractTerminalWidget.TERMINAL_Y && - localMouseY < AbstractTerminalWidget.TERMINAL_Y + AbstractTerminalWidget.TERMINAL_HEIGHT; + return localMouseX >= x && + localMouseX < x + width && + localMouseY >= y && + localMouseY < y + height; } } diff --git a/src/main/java/li/cil/oc2/client/gui/ComputerTerminalScreen.java b/src/main/java/li/cil/oc2/client/gui/ComputerTerminalScreen.java index 74cfed90..be0ecb65 100644 --- a/src/main/java/li/cil/oc2/client/gui/ComputerTerminalScreen.java +++ b/src/main/java/li/cil/oc2/client/gui/ComputerTerminalScreen.java @@ -1,42 +1,50 @@ package li.cil.oc2.client.gui; import com.mojang.blaze3d.matrix.MatrixStack; +import li.cil.oc2.common.container.ComputerTerminalContainer; import li.cil.oc2.common.network.Network; import li.cil.oc2.common.network.message.ComputerPowerMessage; import li.cil.oc2.common.network.message.ComputerTerminalInputMessage; -import li.cil.oc2.common.tileentity.ComputerTileEntity; import li.cil.oc2.common.vm.Terminal; -import net.minecraft.client.entity.player.ClientPlayerEntity; -import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.inventory.ContainerScreen; import net.minecraft.client.gui.widget.Widget; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.client.util.InputMappings; +import net.minecraft.entity.player.PlayerInventory; import net.minecraft.util.text.ITextComponent; import java.nio.ByteBuffer; -public final class ComputerTerminalScreen extends Screen { - private final ComputerTileEntity computer; +public final class ComputerTerminalScreen extends ContainerScreen { private final ComputerTerminalWidget terminalWidget; /////////////////////////////////////////////////////////////////// - public ComputerTerminalScreen(final ComputerTileEntity computer, final ITextComponent title) { - super(title); - this.computer = computer; - this.terminalWidget = new ComputerTerminalWidget(computer.getTerminal()); + public ComputerTerminalScreen(final ComputerTerminalContainer container, final PlayerInventory playerInventory, final ITextComponent title) { + super(container, playerInventory, title); + this.terminalWidget = new ComputerTerminalWidget(container.getComputer().getTerminal()); + xSize = AbstractTerminalWidget.WIDTH; + ySize = AbstractTerminalWidget.HEIGHT; } /////////////////////////////////////////////////////////////////// @Override - public void render(final MatrixStack matrixStack, final int mouseX, final int mouseY, final float partialTicks) { - renderBackground(matrixStack); + protected void drawGuiContainerBackgroundLayer(final MatrixStack matrixStack, final float partialTicks, final int mouseX, final int mouseY) { terminalWidget.renderBackground(matrixStack, mouseX, mouseY); + } + @Override + protected void drawGuiContainerForegroundLayer(final MatrixStack matrixStack, final int mouseX, final int mouseY) { + } + + @Override + public void render(final MatrixStack matrixStack, final int mouseX, final int mouseY, final float partialTicks) { + terminalWidget.setEnergyInfo(container.getEnergy(), container.getEnergyCapacity(), container.getEnergyConsumption()); + + renderBackground(matrixStack); super.render(matrixStack, mouseX, mouseY, partialTicks); - terminalWidget.render(matrixStack, computer.getVirtualMachine().getBootError()); + terminalWidget.render(matrixStack, mouseX, mouseY, container.getComputer().getVirtualMachine().getBootError()); } @Override @@ -44,16 +52,6 @@ public final class ComputerTerminalScreen extends Screen { super.tick(); terminalWidget.tick(); - - final ClientPlayerEntity player = getMinecraft().player; - if (!player.isAlive() || !canInteractWith(player)) { - closeScreen(); - } - } - - @Override - public boolean isPauseScreen() { - return false; } @Override @@ -64,8 +62,18 @@ public final class ComputerTerminalScreen extends Screen { @Override public boolean keyPressed(final int keyCode, final int scanCode, final int modifiers) { - return terminalWidget.keyPressed(keyCode, scanCode, modifiers) || - super.keyPressed(keyCode, scanCode, modifiers); + if (terminalWidget.keyPressed(keyCode, scanCode, modifiers)) { + return true; + } + + // Don't close with inventory binding since we usually want to use that as terminal input + // even without input capture enabled. + final InputMappings.Input input = InputMappings.getInputByCode(keyCode, scanCode); + if (this.minecraft.gameSettings.keyBindInventory.isActiveAndMatches(input)) { + return true; + } + + return super.keyPressed(keyCode, scanCode, modifiers); } @Override @@ -82,12 +90,6 @@ public final class ComputerTerminalScreen extends Screen { /////////////////////////////////////////////////////////////////// - private boolean canInteractWith(final PlayerEntity player) { - return Vector3d.copyCentered(computer.getPos()).isWithinDistanceOf(player.getPositionVec(), 8); - } - - /////////////////////////////////////////////////////////////////// - private final class ComputerTerminalWidget extends AbstractTerminalWidget { public ComputerTerminalWidget(final Terminal terminal) { super(ComputerTerminalScreen.this, terminal); @@ -95,7 +97,7 @@ public final class ComputerTerminalScreen extends Screen { @Override protected boolean isRunning() { - return computer.getVirtualMachine().isRunning(); + return container.getComputer().getVirtualMachine().isRunning(); } @Override @@ -105,12 +107,12 @@ public final class ComputerTerminalScreen extends Screen { @Override protected void sendPowerStateToServer(final boolean value) { - Network.INSTANCE.sendToServer(new ComputerPowerMessage(computer, value)); + Network.INSTANCE.sendToServer(new ComputerPowerMessage(container.getComputer(), value)); } @Override protected void sendTerminalInputToServer(final ByteBuffer input) { - Network.INSTANCE.sendToServer(new ComputerTerminalInputMessage(computer, input)); + Network.INSTANCE.sendToServer(new ComputerTerminalInputMessage(container.getComputer(), input)); } } } diff --git a/src/main/java/li/cil/oc2/client/gui/RobotTerminalScreen.java b/src/main/java/li/cil/oc2/client/gui/RobotTerminalScreen.java index d7c5cb48..8002676e 100644 --- a/src/main/java/li/cil/oc2/client/gui/RobotTerminalScreen.java +++ b/src/main/java/li/cil/oc2/client/gui/RobotTerminalScreen.java @@ -3,7 +3,6 @@ package li.cil.oc2.client.gui; import com.mojang.blaze3d.matrix.MatrixStack; import li.cil.oc2.client.gui.widget.Sprite; import li.cil.oc2.common.container.RobotTerminalContainer; -import li.cil.oc2.common.entity.RobotEntity; import li.cil.oc2.common.network.Network; import li.cil.oc2.common.network.message.RobotPowerMessage; import li.cil.oc2.common.network.message.RobotTerminalInputMessage; @@ -40,15 +39,17 @@ public final class RobotTerminalScreen extends ContainerScreen 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); + public static final RegistryObject CREATIVE_ENERGY = BLOCKS.register(Constants.CREATIVE_ENERGY_BLOCK_NAME, CreativeEnergyBlock::new); /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/block/BusCableBlock.java b/src/main/java/li/cil/oc2/common/block/BusCableBlock.java index 556f76f7..ae1f3412 100644 --- a/src/main/java/li/cil/oc2/common/block/BusCableBlock.java +++ b/src/main/java/li/cil/oc2/common/block/BusCableBlock.java @@ -89,6 +89,16 @@ public final class BusCableBlock extends Block { } } + public static int getInterfaceCount(final BlockState state) { + int partCount = 0; + for (final EnumProperty connectionType : FACING_TO_CONNECTION_MAP.values()) { + if (state.get(connectionType) == ConnectionType.INTERFACE) { + partCount++; + } + } + return partCount; + } + /////////////////////////////////////////////////////////////////// private final VoxelShape[] shapes; @@ -143,7 +153,6 @@ public final class BusCableBlock extends Block { return true; } - @Nullable @Override public TileEntity createTileEntity(final BlockState state, final IBlockReader world) { return TileEntities.BUS_CABLE_TILE_ENTITY.get().create(); @@ -257,10 +266,9 @@ public final class BusCableBlock extends Block { } private static int getPartCount(final BlockState state) { - int partCount = 0; - if (state.get(HAS_CABLE)) partCount++; - for (final EnumProperty connectionType : FACING_TO_CONNECTION_MAP.values()) { - if (state.get(connectionType) == ConnectionType.INTERFACE) partCount++; + int partCount = getInterfaceCount(state); + if (state.get(HAS_CABLE)) { + partCount++; } return partCount; } 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 217323ab..7461d997 100644 --- a/src/main/java/li/cil/oc2/common/block/ComputerBlock.java +++ b/src/main/java/li/cil/oc2/common/block/ComputerBlock.java @@ -2,12 +2,11 @@ package li.cil.oc2.common.block; import li.cil.oc2.api.bus.device.DeviceTypes; import li.cil.oc2.api.capabilities.RedstoneEmitter; -import li.cil.oc2.client.gui.ComputerTerminalScreen; +import li.cil.oc2.common.Config; import li.cil.oc2.common.Constants; import li.cil.oc2.common.bus.device.data.BlockDeviceDataRegistration; import li.cil.oc2.common.bus.device.data.Firmwares; import li.cil.oc2.common.capabilities.Capabilities; -import li.cil.oc2.common.container.ComputerContainer; import li.cil.oc2.common.integration.Wrenches; import li.cil.oc2.common.item.Items; import li.cil.oc2.common.tileentity.ComputerTileEntity; @@ -20,13 +19,9 @@ import net.minecraft.block.BlockState; import net.minecraft.block.HorizontalBlock; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.Minecraft; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.inventory.container.Container; -import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; @@ -43,13 +38,11 @@ import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.fml.network.NetworkHooks; import javax.annotation.Nullable; import java.util.List; @@ -95,6 +88,7 @@ public final class ComputerBlock extends HorizontalBlock { @Override public void addInformation(final ItemStack stack, @Nullable final IBlockReader world, final List tooltip, final ITooltipFlag advanced) { super.addInformation(stack, world, tooltip, advanced); + TooltipUtils.addEnergyConsumption(Config.computerEnergyPerTick, tooltip); TooltipUtils.addTileEntityInventoryInformation(stack, tooltip); } @@ -103,7 +97,6 @@ public final class ComputerBlock extends HorizontalBlock { return true; } - @Nullable @Override public TileEntity createTileEntity(final BlockState state, final IBlockReader world) { return TileEntities.COMPUTER_TILE_ENTITY.get().create(); @@ -177,15 +170,17 @@ public final class ComputerBlock extends HorizontalBlock { final ComputerTileEntity computer = (ComputerTileEntity) tileEntity; final ItemStack heldItem = player.getHeldItem(hand); - if (Wrenches.isWrench(heldItem)) { - if (!world.isRemote() && player instanceof ServerPlayerEntity) { - openContainerScreen(computer, player); - } - } else { - if (player.isSneaking()) { - computer.start(); - } else if (world.isRemote()) { - openTerminalScreen(computer); + if (!world.isRemote()) { + if (Wrenches.isWrench(heldItem)) { + if (player instanceof ServerPlayerEntity) { + computer.openContainerScreen((ServerPlayerEntity) player); + } + } else { + if (player.isSneaking()) { + computer.start(); + } else if (player instanceof ServerPlayerEntity) { + computer.openTerminalScreen((ServerPlayerEntity) player); + } } } @@ -226,25 +221,6 @@ public final class ComputerBlock extends HorizontalBlock { /////////////////////////////////////////////////////////////////// - @OnlyIn(Dist.CLIENT) - private void openTerminalScreen(final ComputerTileEntity computer) { - Minecraft.getInstance().displayGuiScreen(new ComputerTerminalScreen(computer, getTranslatedName())); - } - - private void openContainerScreen(final ComputerTileEntity tileEntity, final PlayerEntity player) { - NetworkHooks.openGui((ServerPlayerEntity) player, new INamedContainerProvider() { - @Override - public ITextComponent getDisplayName() { - return new TranslationTextComponent(getTranslationKey()); - } - - @Override - public Container createMenu(final int id, final PlayerInventory inventory, final PlayerEntity player) { - return new ComputerContainer(id, tileEntity, inventory); - } - }, tileEntity.getPos()); - } - private ItemStack getPreconfiguredComputer() { final ItemStack computer = new ItemStack(Items.COMPUTER.get()); diff --git a/src/main/java/li/cil/oc2/common/block/CreativeEnergyBlock.java b/src/main/java/li/cil/oc2/common/block/CreativeEnergyBlock.java new file mode 100644 index 00000000..b6000f40 --- /dev/null +++ b/src/main/java/li/cil/oc2/common/block/CreativeEnergyBlock.java @@ -0,0 +1,31 @@ +package li.cil.oc2.common.block; + +import li.cil.oc2.common.tileentity.TileEntities; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockReader; + +public final class CreativeEnergyBlock extends Block { + public CreativeEnergyBlock() { + super(Properties + .create(Material.IRON) + .sound(SoundType.METAL) + .hardnessAndResistance(-1, 3600000) + .noDrops()); + } + + /////////////////////////////////////////////////////////////////// + + @Override + public boolean hasTileEntity(final BlockState state) { + return true; + } + + @Override + public TileEntity createTileEntity(final BlockState state, final IBlockReader world) { + return TileEntities.CREATIVE_ENERGY_TILE_ENTITY.get().create(); + } +} diff --git a/src/main/java/li/cil/oc2/common/block/DiskDriveBlock.java b/src/main/java/li/cil/oc2/common/block/DiskDriveBlock.java index 0e4675af..a2eae5f0 100644 --- a/src/main/java/li/cil/oc2/common/block/DiskDriveBlock.java +++ b/src/main/java/li/cil/oc2/common/block/DiskDriveBlock.java @@ -21,8 +21,6 @@ import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; -import javax.annotation.Nullable; - public final class DiskDriveBlock extends HorizontalBlock { public DiskDriveBlock() { super(Properties @@ -44,7 +42,6 @@ public final class DiskDriveBlock extends HorizontalBlock { return true; } - @Nullable @Override public TileEntity createTileEntity(final BlockState state, final IBlockReader world) { return TileEntities.DISK_DRIVE_TILE_ENTITY.get().create(); diff --git a/src/main/java/li/cil/oc2/common/block/NetworkConnectorBlock.java b/src/main/java/li/cil/oc2/common/block/NetworkConnectorBlock.java index 92b982d7..4f3913b5 100644 --- a/src/main/java/li/cil/oc2/common/block/NetworkConnectorBlock.java +++ b/src/main/java/li/cil/oc2/common/block/NetworkConnectorBlock.java @@ -17,7 +17,6 @@ import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; -import javax.annotation.Nullable; import java.util.Objects; public final class NetworkConnectorBlock extends HorizontalFaceBlock { @@ -51,7 +50,6 @@ public final class NetworkConnectorBlock extends HorizontalFaceBlock { return true; } - @Nullable @Override public TileEntity createTileEntity(final BlockState state, final IBlockReader world) { return TileEntities.NETWORK_CONNECTOR_TILE_ENTITY.get().create(); diff --git a/src/main/java/li/cil/oc2/common/block/NetworkHubBlock.java b/src/main/java/li/cil/oc2/common/block/NetworkHubBlock.java index 7cffc36c..117effe0 100644 --- a/src/main/java/li/cil/oc2/common/block/NetworkHubBlock.java +++ b/src/main/java/li/cil/oc2/common/block/NetworkHubBlock.java @@ -15,8 +15,6 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; -import javax.annotation.Nullable; - public final class NetworkHubBlock extends HorizontalBlock { public NetworkHubBlock() { super(Properties @@ -38,7 +36,6 @@ public final class NetworkHubBlock extends HorizontalBlock { return true; } - @Nullable @Override public TileEntity createTileEntity(final BlockState state, final IBlockReader world) { return TileEntities.NETWORK_HUB_TILE_ENTITY.get().create(); diff --git a/src/main/java/li/cil/oc2/common/block/RedstoneInterfaceBlock.java b/src/main/java/li/cil/oc2/common/block/RedstoneInterfaceBlock.java index 5559eda1..21a3e5d7 100644 --- a/src/main/java/li/cil/oc2/common/block/RedstoneInterfaceBlock.java +++ b/src/main/java/li/cil/oc2/common/block/RedstoneInterfaceBlock.java @@ -15,8 +15,6 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldReader; -import javax.annotation.Nullable; - public final class RedstoneInterfaceBlock extends HorizontalBlock { public RedstoneInterfaceBlock() { super(Properties @@ -38,7 +36,6 @@ public final class RedstoneInterfaceBlock extends HorizontalBlock { return true; } - @Nullable @Override public TileEntity createTileEntity(final BlockState state, final IBlockReader world) { return TileEntities.REDSTONE_INTERFACE_TILE_ENTITY.get().create(); diff --git a/src/main/java/li/cil/oc2/common/bus/AbstractDeviceBusElement.java b/src/main/java/li/cil/oc2/common/bus/AbstractDeviceBusElement.java index e3b50a7f..cf5dac17 100644 --- a/src/main/java/li/cil/oc2/common/bus/AbstractDeviceBusElement.java +++ b/src/main/java/li/cil/oc2/common/bus/AbstractDeviceBusElement.java @@ -1,5 +1,7 @@ package li.cil.oc2.common.bus; +import it.unimi.dsi.fastutil.objects.Object2IntArrayMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; import li.cil.oc2.api.bus.DeviceBusController; import li.cil.oc2.api.bus.DeviceBusElement; import li.cil.oc2.api.bus.device.Device; @@ -9,11 +11,17 @@ import java.util.*; import java.util.stream.Collectors; public abstract class AbstractDeviceBusElement implements DeviceBusElement { - protected final HashSet devices = new HashSet<>(); + protected final Object2IntArrayMap devices = new Object2IntArrayMap<>(); protected final HashSet controllers = new HashSet<>(); /////////////////////////////////////////////////////////////////// + public void addDevice(final Device device) { + devices.put(device, 0); + scanDevices(); + } + + @Override public void addController(final DeviceBusController controller) { controllers.add(controller); } @@ -35,7 +43,7 @@ public abstract class AbstractDeviceBusElement implements DeviceBusElement { @Override public Collection getLocalDevices() { - return devices; + return devices.keySet(); } @Override @@ -44,15 +52,12 @@ public abstract class AbstractDeviceBusElement implements DeviceBusElement { } @Override - public void addDevice(final Device device) { - devices.add(device); - scanDevices(); - } - - @Override - public void removeDevice(final Device device) { - devices.remove(device); - scanDevices(); + public double getEnergyConsumption() { + long accumulator = 0; + for (final Object2IntMap.Entry entry : devices.object2IntEntrySet()) { + accumulator += entry.getIntValue(); + } + return accumulator; } @Override 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 d3b02f47..89ba55b9 100644 --- a/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java +++ b/src/main/java/li/cil/oc2/common/bus/AbstractGroupingDeviceBusElement.java @@ -10,7 +10,6 @@ import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.registries.IForgeRegistryEntry; import java.util.*; -import java.util.stream.Collectors; public abstract class AbstractGroupingDeviceBusElement, TDeviceInfo extends AbstractDeviceInfo> extends AbstractDeviceBusElement implements INBTSerializable { private static final String GROUP_ID_TAG_NAME = "groupId"; @@ -101,11 +100,15 @@ public abstract class AbstractGroupingDeviceBusElement removedDevices = new HashSet<>(oldDevices); removedDevices.removeAll(newDevices); - devices.removeAll(removedDevices.stream().map(info -> info.device).collect(Collectors.toList())); + for (final TDeviceInfo info : removedDevices) { + devices.removeInt(info.device); + } final HashSet addedDevices = new HashSet<>(newDevices); addedDevices.removeAll(oldDevices); - devices.addAll(addedDevices.stream().map(info -> info.device).collect(Collectors.toList())); + for (final TDeviceInfo info : addedDevices) { + devices.put(info.device, info.getEnergyConsumption()); + } oldDevices.removeAll(removedDevices); oldDevices.addAll(newDevices); diff --git a/src/main/java/li/cil/oc2/common/bus/CommonDeviceBusController.java b/src/main/java/li/cil/oc2/common/bus/CommonDeviceBusController.java index 7a78f353..12581090 100644 --- a/src/main/java/li/cil/oc2/common/bus/CommonDeviceBusController.java +++ b/src/main/java/li/cil/oc2/common/bus/CommonDeviceBusController.java @@ -36,6 +36,7 @@ public class CommonDeviceBusController implements DeviceBusController { public final ParameterizedEvent onDevicesRemoved = new ParameterizedEvent<>(); private final DeviceBusElement root; + private final int baseEnergyConsumption; private final Set elements = new HashSet<>(); private final HashSet devices = new HashSet<>(); @@ -44,10 +45,13 @@ public class CommonDeviceBusController implements DeviceBusController { private BusState state = BusState.SCAN_PENDING; private int scanDelay; + private int energyConsumption; + /////////////////////////////////////////////////////////////////// - public CommonDeviceBusController(final DeviceBusElement root) { + public CommonDeviceBusController(final DeviceBusElement root, final int baseEnergyConsumption) { this.root = root; + this.baseEnergyConsumption = baseEnergyConsumption; } /////////////////////////////////////////////////////////////////// @@ -67,6 +71,10 @@ public class CommonDeviceBusController implements DeviceBusController { return state; } + public int getEnergyConsumption() { + return energyConsumption; + } + @Override public void scheduleBusScan() { scanDelay = 0; // scan as soon as possible @@ -206,6 +214,8 @@ public class CommonDeviceBusController implements DeviceBusController { scanDevices(); + updateEnergyConsumption(); + state = BusState.READY; } @@ -245,6 +255,19 @@ public class CommonDeviceBusController implements DeviceBusController { elements.clear(); } + private void updateEnergyConsumption() { + double accumulator = baseEnergyConsumption; + for (final DeviceBusElement element : elements) { + accumulator += Math.max(0, element.getEnergyConsumption()); + } + + if (accumulator > Integer.MAX_VALUE) { + energyConsumption = Integer.MAX_VALUE; + } else { + energyConsumption = (int) accumulator; + } + } + /////////////////////////////////////////////////////////////////// public static final class AfterDeviceScanEvent { 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 86116f3c..2331a7a0 100644 --- a/src/main/java/li/cil/oc2/common/bus/ItemHandlerDeviceBusElement.java +++ b/src/main/java/li/cil/oc2/common/bus/ItemHandlerDeviceBusElement.java @@ -1,7 +1,9 @@ package li.cil.oc2.common.bus; +import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; import li.cil.oc2.api.bus.device.rpc.RPCDevice; import li.cil.oc2.common.bus.device.rpc.TypeNameRPCDevice; +import li.cil.oc2.common.bus.device.util.Devices; import li.cil.oc2.common.bus.device.util.ItemDeviceInfo; import li.cil.oc2.common.util.ItemDeviceUtils; import li.cil.oc2.common.util.NBTTagIds; @@ -11,22 +13,22 @@ import net.minecraft.util.ResourceLocation; import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.function.Function; public class ItemHandlerDeviceBusElement extends AbstractGroupingItemDeviceBusElement { - private final Function> deviceLookup; + private final Function queryFactory; - public ItemHandlerDeviceBusElement(final int slotCount, final Function> deviceLookup) { + public ItemHandlerDeviceBusElement(final int slotCount, final Function queryFactory) { super(slotCount); - this.deviceLookup = deviceLookup; + this.queryFactory = queryFactory; } /////////////////////////////////////////////////////////////////// public void updateDevices(final int slot, final ItemStack stack) { if (!stack.isEmpty()) { - final HashSet newDevices = new HashSet<>(deviceLookup.apply(stack)); + final ItemDeviceQuery query = queryFactory.apply(stack); + final HashSet newDevices = new HashSet<>(Devices.getDevices(query)); insertItemNameDevice(stack, newDevices); importDeviceDataFromItemStack(stack, newDevices); setDevicesForGroup(slot, newDevices); @@ -75,7 +77,7 @@ public class ItemHandlerDeviceBusElement extends AbstractGroupingItemDeviceBusEl if (devices.stream().anyMatch(info -> info.device instanceof RPCDevice)) { final ResourceLocation registryName = stack.getItem().getRegistryName(); if (registryName != null) { - devices.add(new ItemDeviceInfo(null, new TypeNameRPCDevice(registryName.toString()))); + devices.add(new ItemDeviceInfo(null, new TypeNameRPCDevice(registryName.toString()), 0)); } } } diff --git a/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusController.java b/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusController.java index c83601f0..3f8837eb 100644 --- a/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusController.java +++ b/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusController.java @@ -19,8 +19,8 @@ public class TileEntityDeviceBusController extends CommonDeviceBusController { /////////////////////////////////////////////////////////////////// - public TileEntityDeviceBusController(final DeviceBusElement root, final TileEntity tileEntity) { - super(root); + public TileEntityDeviceBusController(final DeviceBusElement root, final int baseEnergyConsumption, final TileEntity tileEntity) { + super(root, baseEnergyConsumption); this.tileEntity = tileEntity; } diff --git a/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusElement.java b/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusElement.java index 49d3a61e..adefd8fd 100644 --- a/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusElement.java +++ b/src/main/java/li/cil/oc2/common/bus/TileEntityDeviceBusElement.java @@ -3,6 +3,7 @@ package li.cil.oc2.common.bus; import li.cil.oc2.api.bus.BlockDeviceBusElement; import li.cil.oc2.api.bus.DeviceBus; import li.cil.oc2.api.bus.DeviceBusElement; +import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery; import li.cil.oc2.api.bus.device.rpc.RPCDevice; import li.cil.oc2.common.Constants; import li.cil.oc2.common.bus.device.rpc.TypeNameRPCDevice; @@ -93,7 +94,8 @@ public class TileEntityDeviceBusElement extends AbstractGroupingBlockDeviceBusEl final HashSet newDevices = new HashSet<>(); if (canDetectDevicesTowards(direction)) { - for (final LazyOptional deviceInfo : Devices.getDevices(world, pos, direction)) { + final BlockDeviceQuery query = Devices.makeQuery(world, pos, direction); + for (final LazyOptional deviceInfo : Devices.getDevices(query)) { deviceInfo.ifPresent(newDevices::add); deviceInfo.addListener(unused -> handleNeighborChanged(pos)); } diff --git a/src/main/java/li/cil/oc2/common/bus/device/provider/item/BlockOperationsModuleDeviceProvider.java b/src/main/java/li/cil/oc2/common/bus/device/provider/item/BlockOperationsModuleDeviceProvider.java index df97f2ad..c0820c3e 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/provider/item/BlockOperationsModuleDeviceProvider.java +++ b/src/main/java/li/cil/oc2/common/bus/device/provider/item/BlockOperationsModuleDeviceProvider.java @@ -4,6 +4,7 @@ import li.cil.oc2.api.bus.device.DeviceType; import li.cil.oc2.api.bus.device.DeviceTypes; import li.cil.oc2.api.bus.device.ItemDevice; import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; +import li.cil.oc2.common.Config; import li.cil.oc2.common.bus.device.item.BlockOperationsModuleDevice; import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider; import li.cil.oc2.common.capabilities.Capabilities; @@ -29,4 +30,9 @@ public final class BlockOperationsModuleDeviceProvider extends AbstractItemDevic entity.getCapability(Capabilities.ROBOT).map(robot -> new BlockOperationsModuleDevice(query.getItemStack(), entity, robot))); } + + @Override + protected int getItemDeviceEnergyConsumption(final ItemDeviceQuery query) { + return Config.blockOperationsModuleEnergyPerTick; + } } diff --git a/src/main/java/li/cil/oc2/common/bus/device/provider/item/HardDriveItemDeviceProvider.java b/src/main/java/li/cil/oc2/common/bus/device/provider/item/HardDriveItemDeviceProvider.java index 2fba7059..c78e623f 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/provider/item/HardDriveItemDeviceProvider.java +++ b/src/main/java/li/cil/oc2/common/bus/device/provider/item/HardDriveItemDeviceProvider.java @@ -6,10 +6,12 @@ import li.cil.oc2.api.bus.device.ItemDevice; import li.cil.oc2.api.bus.device.data.BlockDeviceData; import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; import li.cil.oc2.common.Config; +import li.cil.oc2.common.Constants; import li.cil.oc2.common.bus.device.item.HardDriveVMDevice; import li.cil.oc2.common.bus.device.item.SparseHardDriveVMDevice; import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider; import li.cil.oc2.common.item.AbstractBlockDeviceItem; +import li.cil.oc2.common.item.HardDriveItem; import li.cil.oc2.common.item.Items; import li.cil.oc2.common.util.LocationSupplierUtils; import li.cil.sedna.api.device.BlockDevice; @@ -44,4 +46,16 @@ public final class HardDriveItemDeviceProvider extends AbstractItemDeviceProvide protected Optional getItemDeviceType(final ItemDeviceQuery query) { return Optional.of(DeviceTypes.HARD_DRIVE); } + + @Override + protected int getItemDeviceEnergyConsumption(final ItemDeviceQuery query) { + final BlockDeviceData data = HardDriveItem.getData(query.getItemStack()); + final long capacity; + if (data != null) { + capacity = data.getBlockDevice().getCapacity(); + } else { + capacity = HardDriveItem.getCapacity(query.getItemStack()); + } + return Math.max(1, (int) Math.round(capacity * Config.hardDriveEnergyPerMegabytePerTick / Constants.MEGABYTE)); + } } diff --git a/src/main/java/li/cil/oc2/common/bus/device/provider/item/InventoryOperationsModuleDeviceProvider.java b/src/main/java/li/cil/oc2/common/bus/device/provider/item/InventoryOperationsModuleDeviceProvider.java index dcf02809..dff25454 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/provider/item/InventoryOperationsModuleDeviceProvider.java +++ b/src/main/java/li/cil/oc2/common/bus/device/provider/item/InventoryOperationsModuleDeviceProvider.java @@ -4,6 +4,7 @@ import li.cil.oc2.api.bus.device.DeviceType; import li.cil.oc2.api.bus.device.DeviceTypes; import li.cil.oc2.api.bus.device.ItemDevice; import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; +import li.cil.oc2.common.Config; import li.cil.oc2.common.bus.device.item.InventoryOperationsModuleDevice; import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider; import li.cil.oc2.common.capabilities.Capabilities; @@ -29,4 +30,9 @@ public final class InventoryOperationsModuleDeviceProvider extends AbstractItemD entity.getCapability(Capabilities.ROBOT).map(robot -> new InventoryOperationsModuleDevice(query.getItemStack(), entity, robot))); } + + @Override + protected int getItemDeviceEnergyConsumption(final ItemDeviceQuery query) { + return Config.inventoryOperationsModuleEnergyPerTick; + } } diff --git a/src/main/java/li/cil/oc2/common/bus/device/provider/item/MemoryItemDeviceProvider.java b/src/main/java/li/cil/oc2/common/bus/device/provider/item/MemoryItemDeviceProvider.java index c39917af..ab1953bc 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/provider/item/MemoryItemDeviceProvider.java +++ b/src/main/java/li/cil/oc2/common/bus/device/provider/item/MemoryItemDeviceProvider.java @@ -4,9 +4,12 @@ import li.cil.oc2.api.bus.device.DeviceType; import li.cil.oc2.api.bus.device.DeviceTypes; import li.cil.oc2.api.bus.device.ItemDevice; import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; +import li.cil.oc2.common.Config; +import li.cil.oc2.common.Constants; import li.cil.oc2.common.bus.device.item.MemoryDevice; import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider; import li.cil.oc2.common.item.Items; +import li.cil.oc2.common.item.MemoryItem; import java.util.Optional; @@ -26,4 +29,10 @@ public final class MemoryItemDeviceProvider extends AbstractItemDeviceProvider { protected Optional getItemDeviceType(final ItemDeviceQuery query) { return Optional.of(DeviceTypes.MEMORY); } + + @Override + protected int getItemDeviceEnergyConsumption(final ItemDeviceQuery query) { + final int capacity = MemoryItem.getCapacity(query.getItemStack()); + return Math.max(1, (int) Math.round(capacity * Config.memoryEnergyPerMegabytePerTick / Constants.MEGABYTE)); + } } diff --git a/src/main/java/li/cil/oc2/common/bus/device/provider/item/NetworkInterfaceCardItemDeviceProvider.java b/src/main/java/li/cil/oc2/common/bus/device/provider/item/NetworkInterfaceCardItemDeviceProvider.java index b8666c5b..2a71b501 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/provider/item/NetworkInterfaceCardItemDeviceProvider.java +++ b/src/main/java/li/cil/oc2/common/bus/device/provider/item/NetworkInterfaceCardItemDeviceProvider.java @@ -2,6 +2,7 @@ package li.cil.oc2.common.bus.device.provider.item; import li.cil.oc2.api.bus.device.ItemDevice; import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; +import li.cil.oc2.common.Config; import li.cil.oc2.common.bus.device.item.NetworkInterfaceCardItemDevice; import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider; import li.cil.oc2.common.item.Items; @@ -20,4 +21,9 @@ public final class NetworkInterfaceCardItemDeviceProvider extends AbstractItemDe return query.getContainerTileEntity().map(tileEntity -> new NetworkInterfaceCardItemDevice(query.getItemStack())); } + + @Override + protected int getItemDeviceEnergyConsumption(final ItemDeviceQuery query) { + return Config.networkInterfaceEnergyPerTick; + } } diff --git a/src/main/java/li/cil/oc2/common/bus/device/provider/item/RedstoneInterfaceCardItemDeviceProvider.java b/src/main/java/li/cil/oc2/common/bus/device/provider/item/RedstoneInterfaceCardItemDeviceProvider.java index c0107c43..257440e1 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/provider/item/RedstoneInterfaceCardItemDeviceProvider.java +++ b/src/main/java/li/cil/oc2/common/bus/device/provider/item/RedstoneInterfaceCardItemDeviceProvider.java @@ -2,6 +2,7 @@ package li.cil.oc2.common.bus.device.provider.item; import li.cil.oc2.api.bus.device.ItemDevice; import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; +import li.cil.oc2.common.Config; import li.cil.oc2.common.bus.device.item.RedstoneInterfaceCardItemDevice; import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider; import li.cil.oc2.common.item.Items; @@ -20,4 +21,9 @@ public final class RedstoneInterfaceCardItemDeviceProvider extends AbstractItemD return query.getContainerTileEntity().map(tileEntity -> new RedstoneInterfaceCardItemDevice(query.getItemStack(), tileEntity)); } + + @Override + protected int getItemDeviceEnergyConsumption(final ItemDeviceQuery query) { + return Config.redstoneInterfaceCardEnergyPerTick; + } } diff --git a/src/main/java/li/cil/oc2/common/bus/device/provider/util/AbstractItemDeviceProvider.java b/src/main/java/li/cil/oc2/common/bus/device/provider/util/AbstractItemDeviceProvider.java index 2292ebf3..3c3b3fcc 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/provider/util/AbstractItemDeviceProvider.java +++ b/src/main/java/li/cil/oc2/common/bus/device/provider/util/AbstractItemDeviceProvider.java @@ -37,6 +37,11 @@ public abstract class AbstractItemDeviceProvider extends ForgeRegistryEntry getItemDevice(final ItemDeviceQuery query); @@ -45,6 +50,10 @@ public abstract class AbstractItemDeviceProvider extends ForgeRegistryEntry> getDevices(final TileEntity tileEntity, @Nullable final Direction side) { - final World world = tileEntity.getWorld(); + public static BlockDeviceQuery makeQuery(final TileEntity tileEntity, @Nullable final Direction side) { + final World world = requireNonNull(tileEntity.getWorld()); final BlockPos pos = tileEntity.getPos(); - - if (world == null) throw new IllegalArgumentException(); - - return getDevices(world, pos, side); + return new BlockQuery(world, pos, side); } - public static List> getDevices(final World world, final BlockPos pos, @Nullable final Direction side) { - return getDevices(new BlockQuery(world, pos, side)); + public static BlockDeviceQuery makeQuery(final World world, final BlockPos pos, @Nullable final Direction side) { + return new BlockQuery(world, pos, side); } - public static List getDevices(final ItemStack stack) { - return getDevices(new ItemQuery(stack)); + public static ItemDeviceQuery makeQuery(final ItemStack stack) { + return new ItemQuery(stack); } - public static List getDevices(final TileEntity tileEntity, final ItemStack stack) { - return getDevices(new ItemQuery(tileEntity, stack)); + public static ItemDeviceQuery makeQuery(final TileEntity tileEntity, final ItemStack stack) { + return new ItemQuery(tileEntity, stack); } - public static List getDevices(final Entity entity, final ItemStack stack) { - return getDevices(new ItemQuery(entity, stack)); + public static ItemDeviceQuery makeQuery(final Entity entity, final ItemStack stack) { + return new ItemQuery(entity, stack); } - public static Collection getDeviceTypes(final ItemStack stack) { - return getDeviceTypes(new ItemQuery(stack)); - } - - /////////////////////////////////////////////////////////////////// - - private static List> getDevices(final BlockQuery query) { + public static List> getDevices(final BlockDeviceQuery query) { final IForgeRegistry registry = Providers.BLOCK_DEVICE_PROVIDER_REGISTRY.get(); final ArrayList> devices = new ArrayList<>(); for (final BlockDeviceProvider provider : registry.getValues()) { @@ -66,17 +59,17 @@ public final class Devices { return devices; } - private static List getDevices(final ItemQuery query) { + public static List getDevices(final ItemDeviceQuery query) { final IForgeRegistry registry = Providers.ITEM_DEVICE_PROVIDER_REGISTRY.get(); final ArrayList devices = new ArrayList<>(); for (final ItemDeviceProvider provider : registry.getValues()) { final Optional device = provider.getDevice(query); - device.ifPresent(d -> devices.add(new ItemDeviceInfo(provider, d))); + device.ifPresent(d -> devices.add(new ItemDeviceInfo(provider, d, provider.getEnergyConsumption(query)))); } return devices; } - private static Collection getDeviceTypes(final ItemQuery query) { + public static Collection getDeviceTypes(final ItemDeviceQuery query) { final IForgeRegistry registry = Providers.ITEM_DEVICE_PROVIDER_REGISTRY.get(); final HashSet deviceTypes = new HashSet<>(); for (final ItemDeviceProvider provider : registry.getValues()) { @@ -86,6 +79,19 @@ public final class Devices { return deviceTypes; } + public static int getEnergyConsumption(final ItemDeviceQuery query) { + final IForgeRegistry registry = Providers.ITEM_DEVICE_PROVIDER_REGISTRY.get(); + long accumulator = 0; + for (final ItemDeviceProvider provider : registry.getValues()) { + accumulator += Math.max(0, provider.getEnergyConsumption(query)); + } + if (accumulator > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } else { + return (int) accumulator; + } + } + /////////////////////////////////////////////////////////////////// private static class BlockQuery implements BlockDeviceQuery { diff --git a/src/main/java/li/cil/oc2/common/bus/device/util/ItemDeviceInfo.java b/src/main/java/li/cil/oc2/common/bus/device/util/ItemDeviceInfo.java index d7701f61..af5ce090 100644 --- a/src/main/java/li/cil/oc2/common/bus/device/util/ItemDeviceInfo.java +++ b/src/main/java/li/cil/oc2/common/bus/device/util/ItemDeviceInfo.java @@ -6,7 +6,19 @@ import li.cil.oc2.api.bus.device.provider.ItemDeviceProvider; import javax.annotation.Nullable; public class ItemDeviceInfo extends AbstractDeviceInfo { - public ItemDeviceInfo(@Nullable final ItemDeviceProvider itemDeviceProvider, final ItemDevice device) { + public final int energyConsumption; + + /////////////////////////////////////////////////////////////////// + + public ItemDeviceInfo(@Nullable final ItemDeviceProvider itemDeviceProvider, final ItemDevice device, final int energyConsumption) { super(itemDeviceProvider, device); + this.energyConsumption = energyConsumption; + } + + /////////////////////////////////////////////////////////////////// + + @Override + public int getEnergyConsumption() { + return energyConsumption; } } diff --git a/src/main/java/li/cil/oc2/common/container/ComputerTerminalContainer.java b/src/main/java/li/cil/oc2/common/container/ComputerTerminalContainer.java new file mode 100644 index 00000000..2454efce --- /dev/null +++ b/src/main/java/li/cil/oc2/common/container/ComputerTerminalContainer.java @@ -0,0 +1,69 @@ +package li.cil.oc2.common.container; + +import li.cil.oc2.common.block.Blocks; +import li.cil.oc2.common.tileentity.ComputerTileEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIntArray; +import net.minecraft.util.IWorldPosCallable; +import net.minecraft.util.IntArray; +import net.minecraft.util.math.BlockPos; + +import javax.annotation.Nullable; + +public final class ComputerTerminalContainer extends AbstractContainer { + private static final int ENERGY_INFO_SIZE = 3; + + /////////////////////////////////////////////////////////////////// + + @Nullable + public static ComputerTerminalContainer create(final int id, final PlayerInventory playerInventory, final PacketBuffer data) { + final BlockPos pos = data.readBlockPos(); + final TileEntity tileEntity = playerInventory.player.getEntityWorld().getTileEntity(pos); + if (!(tileEntity instanceof ComputerTileEntity)) { + return null; + } + return new ComputerTerminalContainer(id, (ComputerTileEntity) tileEntity, new IntArray(3)); + } + + /////////////////////////////////////////////////////////////////// + + private final ComputerTileEntity computer; + private final IIntArray energyInfo; + + /////////////////////////////////////////////////////////////////// + + public ComputerTerminalContainer(final int id, final ComputerTileEntity computer, final IIntArray energyInfo) { + super(Containers.COMPUTER_TERMINAL_CONTAINER.get(), id); + this.computer = computer; + this.energyInfo = energyInfo; + + assertIntArraySize(energyInfo, ENERGY_INFO_SIZE); + trackIntArray(energyInfo); + } + + /////////////////////////////////////////////////////////////////// + + public ComputerTileEntity getComputer() { + return computer; + } + + public int getEnergy() { + return energyInfo.get(0); + } + + public int getEnergyCapacity() { + return energyInfo.get(1); + } + + public int getEnergyConsumption() { + return energyInfo.get(2); + } + + @Override + public boolean canInteractWith(final PlayerEntity player) { + return isWithinUsableDistance(IWorldPosCallable.of(computer.getWorld(), computer.getPos()), player, Blocks.COMPUTER.get()); + } +} diff --git a/src/main/java/li/cil/oc2/common/container/Containers.java b/src/main/java/li/cil/oc2/common/container/Containers.java index 549fe5cf..f0969718 100644 --- a/src/main/java/li/cil/oc2/common/container/Containers.java +++ b/src/main/java/li/cil/oc2/common/container/Containers.java @@ -15,6 +15,7 @@ public final class Containers { /////////////////////////////////////////////////////////////////// public static final RegistryObject> COMPUTER_CONTAINER = CONTAINERS.register(Constants.COMPUTER_BLOCK_NAME, () -> IForgeContainerType.create(ComputerContainer::create)); + public static final RegistryObject> COMPUTER_TERMINAL_CONTAINER = CONTAINERS.register(Constants.COMPUTER_BLOCK_NAME + "_terminal", () -> IForgeContainerType.create(ComputerTerminalContainer::create)); public static final RegistryObject> ROBOT_CONTAINER = CONTAINERS.register(Constants.ROBOT_ENTITY_NAME, () -> IForgeContainerType.create(RobotContainer::create)); public static final RegistryObject> ROBOT_TERMINAL_CONTAINER = CONTAINERS.register(Constants.ROBOT_ENTITY_NAME + "_terminal", () -> IForgeContainerType.create(RobotTerminalContainer::create)); diff --git a/src/main/java/li/cil/oc2/common/container/DeviceItemStackHandler.java b/src/main/java/li/cil/oc2/common/container/DeviceItemStackHandler.java index dfc5260d..7b32af96 100644 --- a/src/main/java/li/cil/oc2/common/container/DeviceItemStackHandler.java +++ b/src/main/java/li/cil/oc2/common/container/DeviceItemStackHandler.java @@ -1,13 +1,12 @@ package li.cil.oc2.common.container; +import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; import li.cil.oc2.common.bus.ItemHandlerDeviceBusElement; -import li.cil.oc2.common.bus.device.util.ItemDeviceInfo; import li.cil.oc2.common.util.NBTTagIds; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.NonNullList; -import java.util.List; import java.util.function.Function; public class DeviceItemStackHandler extends FixedSizeItemStackHandler { @@ -19,13 +18,13 @@ public class DeviceItemStackHandler extends FixedSizeItemStackHandler { /////////////////////////////////////////////////////////////////// - public DeviceItemStackHandler(final int size, final Function> deviceLookup) { - this(NonNullList.withSize(size, ItemStack.EMPTY), deviceLookup); + public DeviceItemStackHandler(final int size, final Function queryFactory) { + this(NonNullList.withSize(size, ItemStack.EMPTY), queryFactory); } - public DeviceItemStackHandler(final NonNullList stacks, final Function> deviceLookup) { + public DeviceItemStackHandler(final NonNullList stacks, final Function queryFactory) { super(stacks); - this.busElement = new ItemHandlerDeviceBusElement(getSlots(), deviceLookup); + this.busElement = new ItemHandlerDeviceBusElement(getSlots(), queryFactory); } /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/container/RobotTerminalContainer.java b/src/main/java/li/cil/oc2/common/container/RobotTerminalContainer.java index 768e192c..99017eed 100644 --- a/src/main/java/li/cil/oc2/common/container/RobotTerminalContainer.java +++ b/src/main/java/li/cil/oc2/common/container/RobotTerminalContainer.java @@ -6,12 +6,18 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.network.PacketBuffer; +import net.minecraft.util.IIntArray; +import net.minecraft.util.IntArray; import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.SlotItemHandler; import javax.annotation.Nullable; public final class RobotTerminalContainer extends AbstractContainer { + private static final int ENERGY_INFO_SIZE = 3; + + /////////////////////////////////////////////////////////////////// + @Nullable public static RobotTerminalContainer create(final int id, final PlayerInventory inventory, final PacketBuffer data) { final int entityId = data.readVarInt(); @@ -19,18 +25,23 @@ public final class RobotTerminalContainer extends AbstractContainer { if (!(entity instanceof RobotEntity)) { return null; } - return new RobotTerminalContainer(id, (RobotEntity) entity); + return new RobotTerminalContainer(id, (RobotEntity) entity, new IntArray(3)); } /////////////////////////////////////////////////////////////////// private final RobotEntity robot; + private final IIntArray energyInfo; /////////////////////////////////////////////////////////////////// - public RobotTerminalContainer(final int id, final RobotEntity robot) { + public RobotTerminalContainer(final int id, final RobotEntity robot, final IIntArray energyInfo) { super(Containers.ROBOT_TERMINAL_CONTAINER.get(), id); this.robot = robot; + this.energyInfo = energyInfo; + + assertIntArraySize(energyInfo, ENERGY_INFO_SIZE); + trackIntArray(energyInfo); final ItemStackHandler inventory = robot.getInventory(); for (int slot = 0; slot < inventory.getSlots(); slot++) { @@ -45,6 +56,18 @@ public final class RobotTerminalContainer extends AbstractContainer { return robot; } + public int getEnergy() { + return energyInfo.get(0); + } + + public int getEnergyCapacity() { + return energyInfo.get(1); + } + + public int getEnergyConsumption() { + return energyInfo.get(2); + } + @Override public boolean canInteractWith(final PlayerEntity player) { return robot.isEntityInRange(player, 8); diff --git a/src/main/java/li/cil/oc2/common/container/TypedDeviceItemStackHandler.java b/src/main/java/li/cil/oc2/common/container/TypedDeviceItemStackHandler.java index a6aba62e..2c11b587 100644 --- a/src/main/java/li/cil/oc2/common/container/TypedDeviceItemStackHandler.java +++ b/src/main/java/li/cil/oc2/common/container/TypedDeviceItemStackHandler.java @@ -1,11 +1,10 @@ package li.cil.oc2.common.container; import li.cil.oc2.api.bus.device.DeviceType; +import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; import li.cil.oc2.common.bus.device.util.Devices; -import li.cil.oc2.common.bus.device.util.ItemDeviceInfo; import net.minecraft.item.ItemStack; -import java.util.List; import java.util.function.Function; public class TypedDeviceItemStackHandler extends DeviceItemStackHandler { @@ -13,8 +12,8 @@ public class TypedDeviceItemStackHandler extends DeviceItemStackHandler { /////////////////////////////////////////////////////////////////// - public TypedDeviceItemStackHandler(final int size, final Function> deviceLookup, final DeviceType deviceType) { - super(size, deviceLookup); + public TypedDeviceItemStackHandler(final int size, final Function queryFactory, final DeviceType deviceType) { + super(size, queryFactory); this.deviceType = deviceType; } @@ -22,6 +21,6 @@ public class TypedDeviceItemStackHandler extends DeviceItemStackHandler { @Override public boolean isItemValid(final int slot, final ItemStack stack) { - return super.isItemValid(slot, stack) && Devices.getDeviceTypes(stack).contains(deviceType); + return super.isItemValid(slot, stack) && Devices.getDeviceTypes(Devices.makeQuery(stack)).contains(deviceType); } } diff --git a/src/main/java/li/cil/oc2/common/container/TypedItemStackHandler.java b/src/main/java/li/cil/oc2/common/container/TypedItemStackHandler.java index f7dc5285..eb2c19e3 100644 --- a/src/main/java/li/cil/oc2/common/container/TypedItemStackHandler.java +++ b/src/main/java/li/cil/oc2/common/container/TypedItemStackHandler.java @@ -3,7 +3,6 @@ package li.cil.oc2.common.container; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tags.ITag; -import org.jetbrains.annotations.NotNull; public class TypedItemStackHandler extends FixedSizeItemStackHandler { private final ITag deviceType; @@ -18,7 +17,7 @@ public class TypedItemStackHandler extends FixedSizeItemStackHandler { /////////////////////////////////////////////////////////////////// @Override - public boolean isItemValid(final int slot, @NotNull final ItemStack stack) { + public boolean isItemValid(final int slot, final ItemStack stack) { return super.isItemValid(slot, stack) && !stack.isEmpty() && deviceType.contains(stack.getItem()); } } diff --git a/src/main/java/li/cil/oc2/common/energy/EnergyStorageItemStack.java b/src/main/java/li/cil/oc2/common/energy/EnergyStorageItemStack.java index 2f5ad00f..d5e5c8e6 100644 --- a/src/main/java/li/cil/oc2/common/energy/EnergyStorageItemStack.java +++ b/src/main/java/li/cil/oc2/common/energy/EnergyStorageItemStack.java @@ -8,8 +8,8 @@ import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.energy.IEnergyStorage; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; + +import javax.annotation.Nullable; public final class EnergyStorageItemStack implements IEnergyStorage, ICapabilityProvider { private final LazyOptional optional = LazyOptional.of(() -> this); @@ -61,9 +61,12 @@ public final class EnergyStorageItemStack implements IEnergyStorage, ICapability return true; } - @NotNull @Override - public LazyOptional getCapability(@NotNull final Capability capability, @Nullable final Direction side) { - return Capabilities.ENERGY_STORAGE.orEmpty(capability, optional); + public LazyOptional getCapability(final Capability capability, @Nullable final Direction side) { + if (Capabilities.ENERGY_STORAGE != null && capability != null) { + return Capabilities.ENERGY_STORAGE.orEmpty(capability, optional); + } else { + return LazyOptional.empty(); + } } } 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 f2bdff1b..4d8c467e 100644 --- a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java +++ b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java @@ -6,13 +6,13 @@ import li.cil.oc2.api.bus.device.DeviceTypes; import li.cil.oc2.api.bus.device.object.Callback; import li.cil.oc2.api.bus.device.object.ObjectDevice; import li.cil.oc2.api.bus.device.object.Parameter; +import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; 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; import li.cil.oc2.common.bus.device.util.Devices; -import li.cil.oc2.common.bus.device.util.ItemDeviceInfo; import li.cil.oc2.common.capabilities.Capabilities; import li.cil.oc2.common.container.FixedSizeItemStackHandler; import li.cil.oc2.common.container.RobotContainer; @@ -50,16 +50,13 @@ import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ActionResultType; -import net.minecraft.util.Direction; -import net.minecraft.util.Hand; +import net.minecraft.util.*; import net.minecraft.util.math.*; import net.minecraft.util.math.shapes.IBooleanFunction; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.world.World; import net.minecraft.world.server.ServerWorld; import net.minecraftforge.api.distmarker.Dist; @@ -72,7 +69,6 @@ import net.minecraftforge.event.world.ChunkEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.items.ItemStackHandler; -import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.nio.ByteBuffer; @@ -125,7 +121,7 @@ public final class RobotEntity extends Entity implements Robot { this.preventEntitySpawning = true; setNoGravity(true); - final CommonDeviceBusController busController = new CommonDeviceBusController(busElement); + final CommonDeviceBusController busController = new CommonDeviceBusController(busElement, Config.robotEnergyPerTick); virtualMachine = new RobotVirtualMachine(busController); virtualMachine.state.builtinDevices.rtcMinecraft.setWorld(world); @@ -166,9 +162,8 @@ public final class RobotEntity extends Entity implements Robot { getDataManager().set(SELECTED_SLOT, (byte) MathHelper.clamp(value, 0, INVENTORY_SIZE - 1)); } - @NotNull @Override - public LazyOptional getCapability(@NotNull final Capability capability, @org.jetbrains.annotations.Nullable final Direction side) { + public LazyOptional getCapability(final Capability capability, @Nullable final Direction side) { if (capability == Capabilities.ITEM_HANDLER) { return LazyOptional.of(() -> inventory).cast(); } @@ -471,7 +466,30 @@ public final class RobotEntity extends Entity implements Robot { @Override public Container createMenu(final int id, final PlayerInventory inventory, final PlayerEntity player) { - return new RobotTerminalContainer(id, RobotEntity.this); + return new RobotTerminalContainer(id, RobotEntity.this, new IIntArray() { + @Override + public int get(final int index) { + switch (index) { + case 0: + return energy.getEnergyStored(); + case 1: + return energy.getMaxEnergyStored(); + case 2: + return virtualMachine.busController.getEnergyConsumption(); + default: + return 0; + } + } + + @Override + public void set(final int index, final int value) { + } + + @Override + public int size() { + return 3; + } + }); } }, b -> b.writeVarInt(getEntityId())); } @@ -733,8 +751,8 @@ public final class RobotEntity extends Entity implements Robot { } @Override - protected List getDevices(final ItemStack stack) { - return Devices.getDevices(RobotEntity.this, stack); + protected ItemDeviceQuery getDeviceQuery(final ItemStack stack) { + return Devices.makeQuery(RobotEntity.this, stack); } } @@ -793,30 +811,17 @@ public final class RobotEntity extends Entity implements Robot { } @Override - 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; - } + protected boolean consumeEnergy(final int amount, final boolean simulate) { + if (!Config.robotsUseEnergy()) { + return true; } - 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; - } + if (amount > energy.getEnergyStored()) { + return false; } - super.run(); + energy.extractEnergy(amount, simulate); + return true; } @Override diff --git a/src/main/java/li/cil/oc2/common/item/BusCableItem.java b/src/main/java/li/cil/oc2/common/item/BusCableItem.java index 93c6b627..2150f31f 100644 --- a/src/main/java/li/cil/oc2/common/item/BusCableItem.java +++ b/src/main/java/li/cil/oc2/common/item/BusCableItem.java @@ -1,12 +1,15 @@ package li.cil.oc2.common.item; +import li.cil.oc2.common.Config; import li.cil.oc2.common.block.Blocks; import li.cil.oc2.common.block.BusCableBlock; +import li.cil.oc2.common.util.TooltipUtils; import li.cil.oc2.common.util.WorldUtils; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.SoundType; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.item.BlockItemUseContext; @@ -14,7 +17,13 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.util.ActionResultType; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +import javax.annotation.Nullable; +import java.util.List; public final class BusCableItem extends ModBlockItem { public BusCableItem(final Block block) { @@ -23,6 +32,13 @@ public final class BusCableItem extends ModBlockItem { /////////////////////////////////////////////////////////////////// + @OnlyIn(Dist.CLIENT) + @Override + public void addInformation(final ItemStack stack, final @Nullable World world, final List tooltip, final ITooltipFlag flag) { + super.addInformation(stack, world, tooltip, flag); + TooltipUtils.addEnergyConsumption(Config.busCableEnergyPerTick, tooltip); + } + @Override public ActionResultType onItemUse(final ItemUseContext context) { final ActionResultType result = tryAddToBlock(context); diff --git a/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java b/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java index 35d3cedd..73484bd5 100644 --- a/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java +++ b/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java @@ -1,25 +1,34 @@ package li.cil.oc2.common.item; +import li.cil.oc2.common.Config; import li.cil.oc2.common.block.Blocks; import li.cil.oc2.common.block.BusCableBlock; import li.cil.oc2.common.block.BusCableBlock.ConnectionType; +import li.cil.oc2.common.util.TooltipUtils; import li.cil.oc2.common.util.WorldUtils; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.SoundType; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.item.BlockItemUseContext; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUseContext; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.*; import net.minecraft.state.EnumProperty; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; +import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Map; public final class BusInterfaceItem extends ModBlockItem { public BusInterfaceItem(final Block block) { @@ -28,6 +37,13 @@ public final class BusInterfaceItem extends ModBlockItem { /////////////////////////////////////////////////////////////////// + @OnlyIn(Dist.CLIENT) + @Override + public void addInformation(final ItemStack stack, final @Nullable World world, final List tooltip, final ITooltipFlag flag) { + super.addInformation(stack, world, tooltip, flag); + TooltipUtils.addEnergyConsumption(Config.busInterfaceEnergyPerTick, tooltip); + } + @Override public ActionResultType onItemUse(final ItemUseContext context) { final Vector3d localHitPos = context.getHitVec().subtract(Vector3d.copyCentered(context.getPos())); @@ -42,6 +58,26 @@ public final class BusInterfaceItem extends ModBlockItem { return result.isSuccessOrConsume() ? result : super.tryPlace(context); } + @Override + public String getTranslationKey() { + return getDefaultTranslationKey(); + } + + @Override + public void fillItemGroup(final ItemGroup group, final NonNullList items) { + if (isInGroup(group)) { + items.add(new ItemStack(this)); + } + } + + @Override + public void addToBlockToItemMap(final Map map, final Item item) { + } + + @Override + public void removeFromBlockToItemMap(final Map map, final Item item) { + } + /////////////////////////////////////////////////////////////////// @Nullable 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 fda7155d..0501800a 100644 --- a/src/main/java/li/cil/oc2/common/item/Items.java +++ b/src/main/java/li/cil/oc2/common/item/Items.java @@ -26,6 +26,7 @@ public final class Items { 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); + public static final RegistryObject CREATIVE_ENERGY = register(Constants.CREATIVE_ENERGY_BLOCK_NAME, Blocks.CREATIVE_ENERGY); /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/item/ModBlockItem.java b/src/main/java/li/cil/oc2/common/item/ModBlockItem.java index d0818f24..9dffe063 100644 --- a/src/main/java/li/cil/oc2/common/item/ModBlockItem.java +++ b/src/main/java/li/cil/oc2/common/item/ModBlockItem.java @@ -7,8 +7,10 @@ import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import javax.annotation.Nullable; import java.util.List; public class ModBlockItem extends BlockItem { @@ -22,10 +24,11 @@ public class ModBlockItem extends BlockItem { /////////////////////////////////////////////////////////////////// + @OnlyIn(Dist.CLIENT) @Override public void addInformation(final ItemStack stack, @Nullable final World world, final List tooltip, final ITooltipFlag flag) { TooltipUtils.tryAddDescription(stack, tooltip); - this.getBlock().addInformation(stack, world, tooltip, flag); + super.addInformation(stack, world, tooltip, flag); } /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/item/ModItem.java b/src/main/java/li/cil/oc2/common/item/ModItem.java index d600b710..b0e2531b 100644 --- a/src/main/java/li/cil/oc2/common/item/ModItem.java +++ b/src/main/java/li/cil/oc2/common/item/ModItem.java @@ -6,8 +6,10 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import javax.annotation.Nullable; import java.util.List; public class ModItem extends Item { @@ -21,6 +23,7 @@ public class ModItem extends Item { /////////////////////////////////////////////////////////////////// + @OnlyIn(Dist.CLIENT) @Override public void addInformation(final ItemStack stack, @Nullable final World world, final List tooltip, final ITooltipFlag flag) { super.addInformation(stack, world, tooltip, flag); 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 b5b3beb2..3de03622 100644 --- a/src/main/java/li/cil/oc2/common/item/RobotItem.java +++ b/src/main/java/li/cil/oc2/common/item/RobotItem.java @@ -22,8 +22,8 @@ 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 javax.annotation.Nullable; import java.util.List; import static li.cil.oc2.common.Constants.ENERGY_TAG_NAME; @@ -39,8 +39,9 @@ public final class RobotItem extends ModItem { @Override public void addInformation(final ItemStack stack, @Nullable final World world, final List tooltip, final ITooltipFlag flag) { super.addInformation(stack, world, tooltip, flag); + TooltipUtils.addEnergyConsumption(Config.robotEnergyPerTick, tooltip); + TooltipUtils.addEntityEnergyInformation(stack, tooltip); TooltipUtils.addEntityInventoryInformation(stack, tooltip); - TooltipUtils.addEntityEnergyInformation(stack, tooltip, Config.robotEnergyStorage); } @Nullable diff --git a/src/main/java/li/cil/oc2/common/serialization/serializers/MemoryRangeSerializer.java b/src/main/java/li/cil/oc2/common/serialization/serializers/MemoryRangeSerializer.java index 5acd41c9..9b16db65 100644 --- a/src/main/java/li/cil/oc2/common/serialization/serializers/MemoryRangeSerializer.java +++ b/src/main/java/li/cil/oc2/common/serialization/serializers/MemoryRangeSerializer.java @@ -5,7 +5,8 @@ import li.cil.ceres.api.SerializationException; import li.cil.ceres.api.SerializationVisitor; import li.cil.ceres.api.Serializer; import li.cil.sedna.api.memory.MemoryRange; -import org.jetbrains.annotations.Nullable; + +import javax.annotation.Nullable; public final class MemoryRangeSerializer implements Serializer { @Override diff --git a/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java index 93c01a2e..62057e92 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java +++ b/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java @@ -1,6 +1,7 @@ package li.cil.oc2.common.tileentity; import li.cil.oc2.client.model.BusCableBakedModel; +import li.cil.oc2.common.Config; import li.cil.oc2.common.block.BusCableBlock; import li.cil.oc2.common.bus.TileEntityDeviceBusElement; import li.cil.oc2.common.capabilities.Capabilities; @@ -118,5 +119,12 @@ public final class BusCableTileEntity extends AbstractTileEntity { final BusCableBlock.ConnectionType connectionType = BusCableBlock.getConnectionType(getBlockState(), direction); return connectionType == BusCableBlock.ConnectionType.INTERFACE; } + + @Override + public double getEnergyConsumption() { + return super.getEnergyConsumption() + + Config.busCableEnergyPerTick + + BusCableBlock.getInterfaceCount(getBlockState()) * Config.busInterfaceEnergyPerTick; + } } } diff --git a/src/main/java/li/cil/oc2/common/tileentity/ChargerTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/ChargerTileEntity.java index 5e8f9ada..96280bc7 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/ChargerTileEntity.java +++ b/src/main/java/li/cil/oc2/common/tileentity/ChargerTileEntity.java @@ -16,9 +16,10 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.energy.IEnergyStorage; import net.minecraftforge.items.IItemHandler; +import javax.annotation.Nullable; import java.util.List; -public final class ChargerTileEntity extends TileEntity implements ITickableTileEntity { +public final class ChargerTileEntity extends AbstractTileEntity implements ITickableTileEntity { private final FixedEnergyStorage energy = new FixedEnergyStorage(Config.chargerEnergyStorage); /////////////////////////////////////////////////////////////////// @@ -53,6 +54,13 @@ public final class ChargerTileEntity extends TileEntity implements ITickableTile /////////////////////////////////////////////////////////////////// + @Override + protected void collectCapabilities(final CapabilityCollector collector, @Nullable final Direction direction) { + collector.offer(Capabilities.ENERGY_STORAGE, energy); + } + + /////////////////////////////////////////////////////////////////// + private void chargeBlock() { if (energy.getEnergyStored() == 0) { return; 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 5400df5a..3cfad315 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java +++ b/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java @@ -3,6 +3,8 @@ package li.cil.oc2.common.tileentity; import li.cil.oc2.api.bus.DeviceBusElement; import li.cil.oc2.api.bus.device.Device; import li.cil.oc2.api.bus.device.DeviceTypes; +import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery; +import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; import li.cil.oc2.client.audio.LoopingSoundManager; import li.cil.oc2.common.Config; import li.cil.oc2.common.Constants; @@ -12,8 +14,9 @@ import li.cil.oc2.common.bus.TileEntityDeviceBusController; import li.cil.oc2.common.bus.TileEntityDeviceBusElement; import li.cil.oc2.common.bus.device.util.BlockDeviceInfo; import li.cil.oc2.common.bus.device.util.Devices; -import li.cil.oc2.common.bus.device.util.ItemDeviceInfo; import li.cil.oc2.common.capabilities.Capabilities; +import li.cil.oc2.common.container.ComputerContainer; +import li.cil.oc2.common.container.ComputerTerminalContainer; import li.cil.oc2.common.container.DeviceItemStackHandler; import li.cil.oc2.common.energy.FixedEnergyStorage; import li.cil.oc2.common.network.Network; @@ -25,10 +28,16 @@ import li.cil.oc2.common.serialization.NBTSerialization; import li.cil.oc2.common.util.*; import li.cil.oc2.common.vm.*; import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.util.Direction; +import net.minecraft.util.IIntArray; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.world.World; @@ -36,12 +45,12 @@ import net.minecraft.world.chunk.Chunk; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fml.network.NetworkHooks; import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.Optional; import static li.cil.oc2.common.Constants.BLOCK_ENTITY_TAG_NAME_IN_ITEM; @@ -70,7 +79,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic private final TileEntityDeviceBusElement busElement = new ComputerBusElement(); 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); + private final ComputerVirtualMachine virtualMachine = new ComputerVirtualMachine(new TileEntityDeviceBusController(busElement, Config.computerEnergyPerTick, this), deviceItems::getDeviceAddressBase); /////////////////////////////////////////////////////////////////// @@ -111,6 +120,57 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic virtualMachine.stop(); } + public void openTerminalScreen(final ServerPlayerEntity player) { + NetworkHooks.openGui(player, new INamedContainerProvider() { + @Override + public ITextComponent getDisplayName() { + return new TranslationTextComponent(getBlockState().getBlock().getTranslationKey()); + } + + @Override + public Container createMenu(final int id, final PlayerInventory inventory, final PlayerEntity player) { + return new ComputerTerminalContainer(id, ComputerTileEntity.this, new IIntArray() { + @Override + public int get(final int index) { + switch (index) { + case 0: + return energy.getEnergyStored(); + case 1: + return energy.getMaxEnergyStored(); + case 2: + return virtualMachine.busController.getEnergyConsumption(); + default: + return 0; + } + } + + @Override + public void set(final int index, final int value) { + } + + @Override + public int size() { + return 3; + } + }); + } + }, getPos()); + } + + public void openContainerScreen(final ServerPlayerEntity player) { + NetworkHooks.openGui(player, new INamedContainerProvider() { + @Override + public ITextComponent getDisplayName() { + return new TranslationTextComponent(getBlockState().getBlock().getTranslationKey()); + } + + @Override + public Container createMenu(final int id, final PlayerInventory inventory, final PlayerEntity player) { + return new ComputerContainer(id, ComputerTileEntity.this, inventory); + } + }, getPos()); + } + public void handleNeighborChanged() { virtualMachine.busController.scheduleBusScan(); } @@ -150,7 +210,8 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic // adjacent cable. Because that would just be weird. if (!hasAddedOwnDevices) { hasAddedOwnDevices = true; - for (final LazyOptional optional : Devices.getDevices(this, (Direction) null)) { + final BlockDeviceQuery query = Devices.makeQuery(this, (Direction) null); + for (final LazyOptional optional : Devices.getDevices(query)) { optional.ifPresent(info -> busElement.addDevice(info.device)); } } @@ -279,8 +340,8 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic } @Override - protected List getDevices(final ItemStack stack) { - return Devices.getDevices(ComputerTileEntity.this, stack); + protected ItemDeviceQuery getDeviceQuery(final ItemStack stack) { + return Devices.makeQuery(ComputerTileEntity.this, stack); } @Override @@ -357,30 +418,17 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic } @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; - } + protected boolean consumeEnergy(final int amount, final boolean simulate) { + if (!Config.computersUseEnergy()) { + return true; } - 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; - } + if (amount > energy.getEnergyStored()) { + return false; } - super.run(); + energy.extractEnergy(amount, simulate); + return true; } @Override diff --git a/src/main/java/li/cil/oc2/common/tileentity/CreativeEnergyTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/CreativeEnergyTileEntity.java new file mode 100644 index 00000000..488f239e --- /dev/null +++ b/src/main/java/li/cil/oc2/common/tileentity/CreativeEnergyTileEntity.java @@ -0,0 +1,36 @@ +package li.cil.oc2.common.tileentity; + +import li.cil.oc2.common.capabilities.Capabilities; +import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; + +public final class CreativeEnergyTileEntity extends TileEntity implements ITickableTileEntity { + private final Direction[] SIDES = Direction.values(); + + /////////////////////////////////////////////////////////////////// + + public CreativeEnergyTileEntity() { + super(TileEntities.CREATIVE_ENERGY_TILE_ENTITY.get()); + } + + /////////////////////////////////////////////////////////////////// + + @Override + public void tick() { + for (final Direction side : SIDES) { + final BlockPos neighborPos = getPos().offset(side); + final ChunkPos neighborChunkPos = new ChunkPos(neighborPos); + if (getWorld().chunkExists(neighborChunkPos.x, neighborChunkPos.z)) { + final TileEntity tileEntity = getWorld().getTileEntity(neighborPos); + if (tileEntity != null) { + tileEntity.getCapability(Capabilities.ENERGY_STORAGE, side.getOpposite()).ifPresent(energy -> { + energy.receiveEnergy(Integer.MAX_VALUE, false); + }); + } + } + } + } +} 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 44b010c4..d73db0dc 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/DiskDriveTileEntity.java +++ b/src/main/java/li/cil/oc2/common/tileentity/DiskDriveTileEntity.java @@ -1,9 +1,9 @@ package li.cil.oc2.common.tileentity; import li.cil.oc2.api.bus.device.data.BlockDeviceData; -import li.cil.oc2.api.bus.device.vm.VMContext; import li.cil.oc2.api.bus.device.vm.VMDevice; import li.cil.oc2.api.bus.device.vm.VMDeviceLoadResult; +import li.cil.oc2.api.bus.device.vm.context.VMContext; import li.cil.oc2.common.Config; import li.cil.oc2.common.Constants; import li.cil.oc2.common.block.DiskDriveBlock; @@ -30,8 +30,8 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.Nullable; +import javax.annotation.Nullable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; 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 929aa57b..08235bcb 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/TileEntities.java +++ b/src/main/java/li/cil/oc2/common/tileentity/TileEntities.java @@ -25,6 +25,7 @@ public final class TileEntities { 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); + public static final RegistryObject> CREATIVE_ENERGY_TILE_ENTITY = register(Constants.CREATIVE_ENERGY_BLOCK_NAME, Blocks.CREATIVE_ENERGY, CreativeEnergyTileEntity::new); /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/util/FakePlayerUtils.java b/src/main/java/li/cil/oc2/common/util/FakePlayerUtils.java index 649f4c33..f4023e6b 100644 --- a/src/main/java/li/cil/oc2/common/util/FakePlayerUtils.java +++ b/src/main/java/li/cil/oc2/common/util/FakePlayerUtils.java @@ -14,7 +14,8 @@ import net.minecraft.network.play.ServerPlayNetHandler; import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayerFactory; -import org.jetbrains.annotations.Nullable; + +import javax.annotation.Nullable; public final class FakePlayerUtils { private static final String FAKE_PLAYER_NAME = "[" + API.MOD_ID + "]"; 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 f05cda38..a32093bf 100644 --- a/src/main/java/li/cil/oc2/common/util/TooltipUtils.java +++ b/src/main/java/li/cil/oc2/common/util/TooltipUtils.java @@ -3,8 +3,10 @@ package li.cil.oc2.common.util; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import li.cil.oc2.api.bus.device.DeviceType; +import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; import li.cil.oc2.common.Constants; -import li.cil.oc2.common.energy.FixedEnergyStorage; +import li.cil.oc2.common.bus.device.util.Devices; +import li.cil.oc2.common.capabilities.Capabilities; import li.cil.oc2.common.tags.ItemTags; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -15,12 +17,17 @@ import net.minecraft.util.text.*; import net.minecraftforge.registries.ForgeRegistry; import net.minecraftforge.registries.RegistryManager; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import static li.cil.oc2.common.Constants.*; public final class TooltipUtils { + private static final IFormattableTextComponent DEVICE_NEEDS_REBOOT = + new TranslationTextComponent(Constants.TOOLTIP_DEVICE_NEEDS_REBOOT) + .modifyStyle(s -> s.setColor(Color.fromTextFormatting(TextFormatting.YELLOW))); + private static final ThreadLocal> ITEM_STACKS = ThreadLocal.withInitial(ArrayList::new); private static final ThreadLocal ITEM_STACKS_SIZES = ThreadLocal.withInitial(IntArrayList::new); @@ -35,7 +42,7 @@ public final class TooltipUtils { final LanguageMap languagemap = LanguageMap.getInstance(); if (languagemap.func_230506_b_(translationKey)) { final TranslationTextComponent description = new TranslationTextComponent(translationKey); - tooltip.add(new StringTextComponent("").modifyStyle(s -> s.setColor(Color.fromTextFormatting(TextFormatting.GRAY))).append(description)); + tooltip.add(withColor(description, TextFormatting.GRAY)); } // Tooltips get queried very early in Minecraft initialization, meaning tags may not @@ -43,8 +50,14 @@ public final class TooltipUtils { // in that case, so we do the detour through the collection instead. final ITag tag = net.minecraft.tags.ItemTags.getCollection().get(ItemTags.DEVICE_NEEDS_REBOOT.getName()); if (tag != null && tag.contains(stack.getItem())) { - tooltip.add(new StringTextComponent("").modifyStyle(s -> s.setColor(Color.fromTextFormatting(TextFormatting.YELLOW))) - .append(new TranslationTextComponent(Constants.TOOLTIP_DEVICE_NEEDS_REBOOT))); + tooltip.add(DEVICE_NEEDS_REBOOT); + } + + final ItemDeviceQuery query = Devices.makeQuery(stack); + final int energyConsumption = Devices.getEnergyConsumption(query); + if (energyConsumption > 0) { + final IFormattableTextComponent energy = withColor(String.valueOf(energyConsumption), TextFormatting.GREEN); + tooltip.add(withColor(new TranslationTextComponent(Constants.TOOLTIP_ENERGY_CONSUMPTION, energy), TextFormatting.GRAY)); } } @@ -86,28 +99,29 @@ public final class TooltipUtils { } } - public static void addEntityEnergyInformation(final ItemStack stack, final List tooltip, final int defaultCapacity) { - addEnergyInformation(NBTUtils.getChildTag(stack.getTag(), MOD_TAG_NAME, ENERGY_TAG_NAME), tooltip, defaultCapacity); + public static void addEntityEnergyInformation(final ItemStack stack, final List tooltip) { + stack.getCapability(Capabilities.ENERGY_STORAGE).ifPresent(energy -> { + if (energy.getEnergyStored() == 0) { + return; + } + + final IFormattableTextComponent value = withColor(energy.getEnergyStored() + "/" + energy.getMaxEnergyStored(), TextFormatting.GREEN); + tooltip.add(withColor(new TranslationTextComponent(Constants.TOOLTIP_ENERGY, value), TextFormatting.GRAY)); + }); } - public static void addEnergyInformation(final CompoundNBT energyTag, final List tooltip, final int defaultCapacity) { - final int stored = energyTag.getInt(FixedEnergyStorage.STORED_TAG_NAME); - if (stored == 0) { - return; + public static void addEnergyConsumption(final double value, final List tooltip) { + if (value > 0) { + tooltip.add(withColor(new TranslationTextComponent(Constants.TOOLTIP_ENERGY_CONSUMPTION, withColor(new DecimalFormat("#.##").format(value), TextFormatting.GREEN)), TextFormatting.GRAY)); } + } - final int capacity; - if (energyTag.contains(FixedEnergyStorage.CAPACITY_TAG_NAME, NBTTagIds.TAG_INT)) { - capacity = energyTag.getInt(FixedEnergyStorage.CAPACITY_TAG_NAME); - } else { - capacity = defaultCapacity; - } + public static IFormattableTextComponent withColor(final String value, final TextFormatting formatting) { + return withColor(new StringTextComponent(value), formatting); + } - if (capacity > 0) { - tooltip.add(new TranslationTextComponent(Constants.TOOLTIP_ENERGY, stored + "/" + capacity)); - } else { - tooltip.add(new TranslationTextComponent(Constants.TOOLTIP_ENERGY, stored)); - } + public static IFormattableTextComponent withColor(final IFormattableTextComponent text, final TextFormatting formatting) { + return text.modifyStyle(s -> s.setColor(Color.fromTextFormatting(formatting))); } /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/vm/AbstractVMItemStackHandlers.java b/src/main/java/li/cil/oc2/common/vm/AbstractVMItemStackHandlers.java index d7bc1e30..496aea8e 100644 --- a/src/main/java/li/cil/oc2/common/vm/AbstractVMItemStackHandlers.java +++ b/src/main/java/li/cil/oc2/common/vm/AbstractVMItemStackHandlers.java @@ -3,6 +3,7 @@ package li.cil.oc2.common.vm; import li.cil.oc2.api.bus.DeviceBusElement; import li.cil.oc2.api.bus.device.DeviceType; import li.cil.oc2.api.bus.device.DeviceTypes; +import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery; import li.cil.oc2.api.bus.device.vm.VMDevice; import li.cil.oc2.common.bus.AbstractDeviceBusElement; import li.cil.oc2.common.bus.device.util.ItemDeviceInfo; @@ -42,7 +43,7 @@ public abstract class AbstractVMItemStackHandlers implements VMItemStackHandlers /////////////////////////////////////////////////////////////////// - public final DeviceBusElement busElement = new BusElement(); + public final AbstractDeviceBusElement busElement = new BusElement(); // NB: linked hash map such that order of parameters in constructor is retained. // This is relevant when assigning default addresses for devices. @@ -54,7 +55,7 @@ public abstract class AbstractVMItemStackHandlers implements VMItemStackHandlers public AbstractVMItemStackHandlers(final GroupDefinition... groups) { for (final GroupDefinition group : groups) { - itemHandlers.put(group.deviceType, new ItemHandler(group.count, this::getDevices, group.deviceType)); + itemHandlers.put(group.deviceType, new ItemHandler(group.count, this::getDeviceQuery, group.deviceType)); } combinedItemHandlers = new CombinedInvWrapper(itemHandlers.values().toArray(new IItemHandlerModifiable[0])); @@ -131,7 +132,7 @@ public abstract class AbstractVMItemStackHandlers implements VMItemStackHandlers /////////////////////////////////////////////////////////////////// - protected abstract List getDevices(final ItemStack stack); + protected abstract ItemDeviceQuery getDeviceQuery(final ItemStack stack); protected void onContentsChanged(final DeviceItemStackHandler itemHandler, final int slot) { } @@ -139,8 +140,8 @@ public abstract class AbstractVMItemStackHandlers implements VMItemStackHandlers /////////////////////////////////////////////////////////////////// private final class ItemHandler extends TypedDeviceItemStackHandler { - public ItemHandler(final int size, final Function> deviceLookup, final DeviceType deviceType) { - super(size, deviceLookup, deviceType); + public ItemHandler(final int size, final Function queryFactory, final DeviceType deviceType) { + super(size, queryFactory, deviceType); } @Override diff --git a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java index 79f3968b..71a290d9 100644 --- a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java +++ b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachine.java @@ -265,6 +265,8 @@ public abstract class AbstractVirtualMachine implements VirtualMachine { protected abstract AbstractTerminalVMRunner createRunner(); + protected abstract boolean consumeEnergy(final int amount, final boolean simulate); + protected void handleBusStateChanged(final CommonDeviceBusController.BusState value) { } @@ -274,12 +276,31 @@ public abstract class AbstractVirtualMachine implements VirtualMachine { protected void handleBootErrorChanged(@Nullable final ITextComponent value) { } - protected void load() { + protected void error(@Nullable final ITextComponent message) { + error(message, true); + } + + protected void error(@Nullable final ITextComponent message, final boolean reset) { + if (reset) { + stopRunnerAndReset(); + } + setBootError(message); + } + + /////////////////////////////////////////////////////////////////// + + private void load() { if (loadDevicesDelay > 0) { loadDevicesDelay--; return; } + if (!consumeEnergy(busController.getEnergyConsumption(), true)) { + // Don't even start running if we couldn't keep running. + error(new TranslationTextComponent(Constants.COMPUTER_ERROR_NOT_ENOUGH_ENERGY)); + return; + } + final VMDeviceLoadResult loadResult = state.vmAdapter.load(); if (!loadResult.wasSuccessful()) { if (loadResult.getErrorMessage() != null) { @@ -325,7 +346,7 @@ public abstract class AbstractVirtualMachine implements VirtualMachine { // initialization. This is used by devices to restore data from disk, for example. } - protected void run() { + private void run() { final ITextComponent runtimeError = runner.getRuntimeError(); if (runtimeError != null) { error(runtimeError); @@ -337,22 +358,14 @@ public abstract class AbstractVirtualMachine implements VirtualMachine { return; } + if (!consumeEnergy(busController.getEnergyConsumption(), false)) { + error(new TranslationTextComponent(Constants.COMPUTER_ERROR_NOT_ENOUGH_ENERGY)); + return; + } + runner.tick(); } - protected void error(@Nullable final ITextComponent message) { - error(message, true); - } - - protected void error(@Nullable final ITextComponent message, final boolean reset) { - if (reset) { - stopRunnerAndReset(); - } - setBootError(message); - } - - /////////////////////////////////////////////////////////////////// - private void setBusState(final CommonDeviceBusController.BusState value) { if (value == busState) { return; diff --git a/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java b/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java index 0784e424..c956881b 100644 --- a/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java +++ b/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java @@ -3,6 +3,7 @@ package li.cil.oc2.data; import li.cil.oc2.api.API; import li.cil.oc2.common.block.Blocks; import li.cil.oc2.common.block.BusCableBlock; +import li.cil.oc2.common.block.CreativeEnergyBlock; import li.cil.oc2.common.item.Items; import net.minecraft.block.Block; import net.minecraft.data.DataGenerator; @@ -37,6 +38,7 @@ public class ModBlockStateProvider extends BlockStateProvider { horizontalBlock(Blocks.NETWORK_HUB, Items.NETWORK_HUB); horizontalBlock(Blocks.DISK_DRIVE, Items.DISK_DRIVE); horizontalBlock(Blocks.CHARGER, Items.CHARGER); + simpleBlock(Blocks.CREATIVE_ENERGY, Items.CREATIVE_ENERGY); registerCableStates(); } @@ -157,4 +159,9 @@ public class ModBlockStateProvider extends BlockStateProvider { horizontalFaceBlock(block.get(), models().getBuilder(block.getId().getPath())); return itemModels().getBuilder(item.getId().getPath()).parent(models().getExistingFile(block.getId())); } + + private void simpleBlock(final RegistryObject block, final RegistryObject item) { + simpleBlock(block.get()); + itemModels().getBuilder(item.getId().getPath()).parent(models().getExistingFile(block.getId())); + } } diff --git a/src/main/java/li/cil/oc2/data/ModBlockTagsProvider.java b/src/main/java/li/cil/oc2/data/ModBlockTagsProvider.java index fdd972a1..1f36ddf7 100644 --- a/src/main/java/li/cil/oc2/data/ModBlockTagsProvider.java +++ b/src/main/java/li/cil/oc2/data/ModBlockTagsProvider.java @@ -4,7 +4,8 @@ import li.cil.oc2.api.API; import net.minecraft.data.BlockTagsProvider; import net.minecraft.data.DataGenerator; import net.minecraftforge.common.data.ExistingFileHelper; -import org.jetbrains.annotations.Nullable; + +import javax.annotation.Nullable; import static li.cil.oc2.common.block.Blocks.*; import static li.cil.oc2.common.tags.BlockTags.*; diff --git a/src/main/java/li/cil/oc2/data/ModItemTagsProvider.java b/src/main/java/li/cil/oc2/data/ModItemTagsProvider.java index fde64919..90b854fe 100644 --- a/src/main/java/li/cil/oc2/data/ModItemTagsProvider.java +++ b/src/main/java/li/cil/oc2/data/ModItemTagsProvider.java @@ -9,7 +9,8 @@ import net.minecraft.data.ItemTagsProvider; import net.minecraft.tags.ItemTags; import net.minecraftforge.common.Tags; import net.minecraftforge.common.data.ExistingFileHelper; -import org.jetbrains.annotations.Nullable; + +import javax.annotation.Nullable; import static li.cil.oc2.common.tags.ItemTags.*; diff --git a/src/main/resources/assets/oc2/blockstates/creative_energy.json b/src/main/resources/assets/oc2/blockstates/creative_energy.json new file mode 100644 index 00000000..da5d1f97 --- /dev/null +++ b/src/main/resources/assets/oc2/blockstates/creative_energy.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "oc2:block/creative_energy" + } + } +} \ 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 14a3576e..7b7dfebd 100644 --- a/src/main/resources/assets/oc2/lang/en_us.json +++ b/src/main/resources/assets/oc2/lang/en_us.json @@ -12,6 +12,8 @@ "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.", + "block.oc2.creative_energy": "Infinite Energy Cube", + "block.oc2.creative_energy.desc": "Provides unlimited energy to adjacent blocks. Intended for testing.", "item.oc2.wrench": "Scrench", "item.oc2.wrench.desc": "Used to configure devices and to dismantle them (while sneaking).", @@ -39,12 +41,15 @@ "config.oc2.vm.maxFlashMemorySize:": "Maximum flash memory device size", "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.busCableComplexity": "Bus Cable complexity", + "config.oc2.busInterfaceComplexity": "Bus Interface complexity", + "config.oc2.complexityEnergyPerTick": "Complexity energy/tick", + "config.oc2.computerEnergyPerTick": "Computer energy/tick", "config.oc2.computerEnergyStorage": "Computer energy storage", - "config.oc2.robotEnergyPerTick": "Energy/tick used by robots", + "config.oc2.robotEnergyPerTick": "Robot energy/tick", "config.oc2.robotEnergyStorage": "Robot energy storage", - "config.oc2.chargerEnergyPerTick": "Energy/tick transferred by chargers", - "config.oc2.chargerEnergyStorage": "Charge energy storage", + "config.oc2.chargerEnergyPerTick": "Charger energy/tick", + "config.oc2.chargerEnergyStorage": "Charger energy storage", "gui.oc2.computer.error.unknown": "Unknown Error", "gui.oc2.computer.error.missing_firmware": "Missing Firmware", @@ -73,6 +78,7 @@ "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", + "tooltip.oc2.energyConsumption": "Energy Consumption: %s", "subtitles.oc2.computer": "Computer fans running", "subtitles.oc2.floppy": "Floppy access", diff --git a/src/main/resources/assets/oc2/models/block/creative_energy.json b/src/main/resources/assets/oc2/models/block/creative_energy.json new file mode 100644 index 00000000..7a3a0d23 --- /dev/null +++ b/src/main/resources/assets/oc2/models/block/creative_energy.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "oc2:block/creative_energy" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/oc2/models/item/creative_energy.json b/src/main/resources/assets/oc2/models/item/creative_energy.json new file mode 100644 index 00000000..b9a5c584 --- /dev/null +++ b/src/main/resources/assets/oc2/models/item/creative_energy.json @@ -0,0 +1,3 @@ +{ + "parent": "oc2:block/creative_energy" +} \ No newline at end of file diff --git a/src/main/resources/assets/oc2/textures/block/creative_energy.png b/src/main/resources/assets/oc2/textures/block/creative_energy.png new file mode 100644 index 0000000000000000000000000000000000000000..61b8287e09abdc83bbf0368c12d87ab85db72da0 GIT binary patch literal 1990 zcmah~Yfuwc6kbYk1O-c>B2LwvMUm=|&4XYQ6L};ER6+wLJe9g68?s8WF}sjJm6wVL zjEK;&GDxYdTB9g}4-|#5P^D#RP|;SgTI&e5BdC>;`tIEXK}FjidEEPb=i76>bMD;@ z^5}3^m#Hog1i3~=NMph8d(3D2JK%d$xi%1j-rY|q66ge3lu$+LSeTkj#aU*Z0pJiM z3Njlo)e4-3Q}HxHFGlV(w<0j179;U|8CzzM;94Rg+lVjDj#j9$SEvMPBxr$)$Sec` zI-JH}vo2jv3C&`}rYi*hnQat-Z4`Qi7)g-HVF_u(VLpq`Vj~M&V3AR+5ynav4hMsk z7}3(SL5QLzlZj>Gu}EVY$`J?zD4UCNx&DCRPi5(8%9G4h7_k%M#4Z7q#kB8 zu~agH79$A2;bC#yOpL1Qsp0a05h#P892OgWnNAa$x6m164Ben5X_C^ChLHkZdBg}j zCJ@;7<`6SxcoSJB`)|5V_evQQ9hM1<7&i5loL)SDQe+u$G#01G45JDU%f$7xkIf0j z7onUm7;Qn7%ChD*)F>1wk;sjt zhDZk(6&oH3M}|oPIfB4Ie=f^j2xyuR#1fh;DMkYpm(At)v$_7900oCDMr*^JGAp=)4seNA!bF)q3XM9?{+6e^Rtqh zmPUqcS@-EWan%y}KNq`Icn(L9*o#&iitvLj#$oXd#VY0AZx5E%AOFzgyDdKFj;f{I z-Fl{QR%VH5y9ZJgjyeOZyiLiP0TOUf1`#`v^8pPgH%{86cn`>6In=w?rWXnXID z>?Nt8gH5FYPL0oVA6sURTYd8{x1jDI?^DT>emzpF2q?8m+We;F_q($izIbxMaY~NY ziG;IP9{+wNud%aua!>w!*)6mDo20?;h7HLc&Sr6bZ^N~6aY5TboEbrtZRyz=I^#x&JLs~p#e0-K|1@?O7$-m zF7NLzy-S83iy`*|mgSjBrIP0uth`-k891Z38y1k)cD;UjlC%&@DD#YJ^!|KC+3CaD zD&I#HTdRMz6wlcZ$m8{-S)J$R?fTlaWMfVAu9mRwimmP^e|zd> zm{zvsPF=q9#_qVooyRVvU*198vK~qKEVrlwU4NBT@Kf?tHuL(842zcT3td+5FT*a; A_y7O^ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/oc2/textures/gui/screen/terminal.png b/src/main/resources/assets/oc2/textures/gui/screen/terminal.png index b9f35776aa37c0faf2376a66512c37cc2773e5cd..c99c612fecf9207ca648d68d07d01efc5a33c974 100644 GIT binary patch delta 3490 zcma)8dpOi-8-8b;&x)`PQJcythdx$RjI0h?a%hM#Iv_(i6dGjAbW)p&c8YSE!743g zG9u$J!$#6nqns8otTl2Ps~LtF%=a5@-}mizUHe_%AHVB*uiyJV_j}*>^Stl#KL6&! zwkI_*YCE=D+Z?g7cd**wU~NTgk=gLqKb3r$B$$l7g%vSIPXDh{#4Nce#RBbbj{pF> zL{yVEz%vi+_0n#2ia2pM)YHW!SdNzOUd;O=%a$bj+ zsUnpKwd~8}t(Pz=*=Yf8L1Urh@A6snu~?=s|9QjMCEFi;cO;>mLTL8ewFPxtu5RFb zSeZ@7r94VWVQI(ktfKAoh6?gd<*6xqn>wqcgz6HW5{W zKIoct_3+g_*@2!5-JQXqDc1J>TuWlrfvuq1_k8fc)Eiof8Zo11Kx=Ua^~POq_`-COFC(M!>7 zIQs5`c<2M6l66C;|03W0V}fT|5yN2v;e@XXu&{st{wpD_YZ#Od?X=vdf;$W|0#Wi zAvW#kW4&E51f7r7b-adc@-NR(tab0d$qn|fO0$3cp%7tUf(f8DlMkYlynpjo{plrb ztM?|?8%ZPu#i0Wm7gK1aD+`}EU8R21^*%1FQCfE#f3f}#`gmMYOy4$EKxy!^d|D{p z_-BKSy9B+x!Uyh;2gl|O9WN*5KO&`w#($o1AXCn|nKdNxAI>-cc~dr@afq<*#iVgm zRFp?`#%2^Ztz~2J-S;6o%#u?$v92hC_=$iXPo!6Qe_t8(Wkvig{N!B*@vBP zkFvBIbmIrFefuKU+ioPN^b@urQiwCd8^mS>_g3$sd=oE3nm-M%UnXf7I|`8dAG;XW z;MjAEuyWc|LGndIG2b$P;F@9a0H(4DZD^SqfEQXbFl?q!35n^2^`W(JfHm=Xa0 z*Pwkf*p|g|oCLt(CmAU2RyS(JKXWcn8MLo60zmNq00e@etRjGo6ECW26OXAHoG?7G z1}}EhpcF8G*|~-Q$7E|AN@ZU)){%d#4V#{++@X zW$qv*${aKoNcW9|6Jk-YSM*cLS$h?T7gg48=#vFw)o_HN1Ei!KCmclBj@YiEL1b&L zJ4jCLis*uJef@83{a;o0A88~Kls4c?KD%PGQMzr>VsgH>TR2o&fy#}Gd~{oJ`=1Q| zv%Xf3gga>OhHo7cI9Xg(|H3*4K)C{EKT4rSXu2Ob9ITfDXfL=78{+XSMiU2-+W}(# z6ns_mXM6EYEggEbTUvqk0QX$Q(Kzq#v#MKbmz{%1>i*c*kLr;h&F~uWlTjkmgc}`) z`x8i_+R;h-wp=T?K>)ncU zefKMSc295lxZ&w5v9@pd$(s8`RNvC~J=(=$7nHf&$l37+8Mh+(s?nURV=4X@=+(yj=;q%DN@KpkLOYnDu}EsG|p_kx}s-Il*3nWQo)HUq3I z%Z}&IpTCQTftG!B8cTd939dRm$TfegO1Wg05%A{bC| zPr8`X_k+P;eWFikYE|t(DkD?;TT7Z7wXUJTy|Q|DM8hU#r=*ADeRizcCm zsb?f9ZW3nwOj3(eo(HK63Cu*bru8$SyAte)NVX)zdOc-IytDf6ssqHC zTkyvD0pQcew7f9zUNYNitTCt-s+B8}+7JmCIObIwkp*I8BVkkBTXs&t>M|esBlz_~6=*avonN(Ss+VwHI zhbftTcFIl*9B+p(p$6+$*;_WV1L&1_apa!1gqvQ0k!#bGz-c=>yF80%qusSZ7Qp80 zSs2;Uo%&hDj=@ zq5Q>UKEE~H*xbD`(Bd%C!_+@>8n@K0d*)t6yftN@ug7+#lv*lG=TZzRBL1Y_-RMPKZ+PCps%NU zMN&B8LKxNp1mZ4Nd`3<4Wy69)@WvlHd&B6_`g~}0g~Zsy8DKEDK2FGvar)ZpO<`(% z8$jSr@ul#+IYt&)0OSVdIPcZFdR`H1KRucDHd7Zo+5|j*K)_@CWeJ(uXyS^V_#p&k zO?uR!Sk$imr9qkq;g~i?_3!5=X%p^;Uj^YI;=zsx16hLBeTB;0=SF`Jlb9@bq0vowVEL_P3^IBT4f$jw{37FA_a&tUL_K4pO5| z9jSF-vIYWJ5pfR2f04 z(3qlvTBM^c(_nra%x z-qr!k(9Bz@mLJmpp=Euc4W<8MiZQ|2-TOEdwEy12!|N2M7%i{3o3b?PH}qX}a-taO z>fNzzGy7*9?&JOTLPw*2+zXs{5CTNK9qTSMm6z3J*9~rRZhs#*@Ou&y6K4}=yt#@z zSy-?ybn)$JlLmKf7o3-b$!r}zV#U71BN`8GlsrnuYE?a$nm^@k=YKaR$15bA)4iju!(xPJrfOyd=KA7*Lk*OzxDN*NAMGbN-sL=X>=DPe~7| zc>=bRaVIOS;OLt32^$(B{Vz0a`P_FVow28ZYlfUqcfE_|-a-u%Ffk9wqH|9wrF~OG zw^XBs)-V@6Mw9uQBE2Jy>qeNKt9Cv?jUVN@GNy(UITtAF-NQs{qM6#CYU5O-)O=|N zsky@duqEpe-u4Erp5TA4kx~9~)#qmHRqO7?# z+4gR2Q~I%2y1qB-TehfaY^kUw;o_33lit+XzEmq?zuzW?5*wVDcd2T^#>ikkFi^_j z!JOI{E2SjwF2C9iKSyrg@lpfB;LIUf$EhPWy&N+~{k>=X*oFkk%lof`YH0C+B^wiF z#)|2Ef4Pa5C*8Zz_GNyep$O$+mvBeEMr3#$yY`573g(Nt+m#m9SeTXOJudzzmtQ)c ze`RO)>x#nLdHJ~cS!eg8&@r07x#98k@;(u(A1cixChJBM2Z8ec0*( z6UIJmQIJni29Vef!bMjR2@r-!x6!JkVzl%zgL=G~icpz2p{0mr0KPA#@gL>Lm?cc* zXc(J~5+1nzNp^eH>Zl(VrWPJ9xbe4(3#iJO0?1xl+B%LTM!O(XrI!|%+CZ&bP0rM{ zr>>47{UNEWCWICeya}G(78l}8-SVHrQhxxk`{F>3d+D?N>@wzMQi-Gjnz@-V{XIeo zkz6g8n&fSGRtg?Jo&hND@4uY4Qh1s?fh;Ox=Q%3!jnXd!ULG#!c%uh^V$Z^GC-Q`L zb6M#D;-Pe;koos~p)QHfj(=2u_4R=5S^h5qkE3YH52e8a`;+LlRXUG zLGrM}Pw$&>BnDc6)Q?{F|AwTn@O}aoV$nnY%O0T#YY8}EQT^cX)pw?0Jm<$zd;` z(&;u9wvvu$(2@OjW#b4s5eoM69~FrC4X#D3v0VwjwZ*#3>%SWxzZS^GH|~o&Iu&}t zC7iYO$$_5O?uICZvFpXGl0wG{URzdJ8bzfO=akLP7$|T9YW&vBwd0kQ42n&dDWxzv zf4nfXVBGIc{y2+zNZP;pxxxU>+rswXTPwj!AA4hK$7=I1hijVN72&(j=AY!m#&Gb{ z)?;+E8*i57UeT_|4yq2=I%E*e?yi2fqE?$g(v{vtP`y~Ayeg7fsy4=7kTwGHl`F%nVCM807;*#TYkz6=2dyl?eWjyLm;mfd4X0zc9gYCnxWy7?3lv5&dn({Ca=r7K`_voEv9j zXzJe1${7@`7Ce8^P}pt>40A!iV|5Vwqz10_wt`wsSJWh*_vO&^*n99ek?}in@$;v_ z#1;I}R}(oijLBNIlHho01O=5|CoQ=7{&ZEeTk`wF*=<>j@M0Mbig-J0IRrKg6Y%&) zHO~fO=yqA|=&Sjb@0Tm*JjzHSwC!U~UG zJS%pEDjaNm2qA$sNDcu*xFGJ78y8WA9U46x&Q&*L zk0hcWncVE1!*!>}X7tgbQ)+p0F3qLshnu;R1NDv_?X1%YcZSO)`!@+MVyiRivxoB4 zKU9xwZaBR;Co))pnGPYltZU2Xa=HXtQm^6|vLOmXqFz>#$c z+BX1T!Y`{5P9#m6q(I-P+O}#Nm7G@7Fn!BDCGM%H)xp=eF8nPDxr54sgkHOIS zk=^>nJ=zGMQq3-0)LG7xg{V#zCPRHIXj=k##W|6FiUgSEDUkSz4IfGsh0uqlC9;_^ z-`@gNRR(gnu{5ZWSJZr8#xyVOIpMSrJJC!6Fl}dM%DyoXr(XQ($)!t|a_($w!<*TR z%^Jll%xK04c=Mhq79kUTw3`?^K5t_}X|pO-LU1WE zb0Yq&*sBdNlk4~A)NGV#h(<~&r{GDp6VkIkGy`>$6)vzMfm#w NmKKNh7VY*p|33x+hkgJ6 diff --git a/src/test/java/li/cil/oc2/common/bus/DeviceBusTests.java b/src/test/java/li/cil/oc2/common/bus/DeviceBusTests.java index 4c6b21a6..7a3f7cf9 100644 --- a/src/test/java/li/cil/oc2/common/bus/DeviceBusTests.java +++ b/src/test/java/li/cil/oc2/common/bus/DeviceBusTests.java @@ -43,7 +43,7 @@ public class DeviceBusTests { when(busControllerBusElement.getLocalDevices()).thenReturn(emptyList()); when(busControllerBusElement.getNeighbors()).thenReturn(Optional.empty()); - busController = new CommonDeviceBusController(busControllerBusElement); + busController = new CommonDeviceBusController(busControllerBusElement, 0); } @Test diff --git a/src/test/java/li/cil/oc2/common/bus/VMDeviceTests.java b/src/test/java/li/cil/oc2/common/bus/VMDeviceTests.java index a97c4192..b2552230 100644 --- a/src/test/java/li/cil/oc2/common/bus/VMDeviceTests.java +++ b/src/test/java/li/cil/oc2/common/bus/VMDeviceTests.java @@ -1,6 +1,6 @@ package li.cil.oc2.common.bus; -import li.cil.oc2.api.bus.device.vm.VMContext; +import li.cil.oc2.api.bus.device.vm.context.VMContext; import li.cil.oc2.api.bus.device.vm.VMDevice; import li.cil.oc2.api.bus.device.vm.VMDeviceLoadResult; import li.cil.oc2.common.vm.VMDeviceBusAdapter;