Bus and item devices can (and do) contribute to energy consumption.
This commit is contained in:
@@ -10,29 +10,6 @@ import java.util.Collection;
|
||||
* these devices.
|
||||
*/
|
||||
public interface DeviceBus {
|
||||
/**
|
||||
* Adds a device to this device bus.
|
||||
* <p>
|
||||
* Adding a device to the bus does <em>not</em> 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.
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -30,10 +30,6 @@ public interface DeviceBusElement extends DeviceBus {
|
||||
* <p>
|
||||
* When {@link #scheduleScan()} is called, {@link DeviceBusController#scheduleBusScan()}
|
||||
* <em>must</em> be called for each registered controller.
|
||||
* <p>
|
||||
* When either {@link #addDevice(Device)} or {@link #removeDevice(Device)} are called,
|
||||
* {@link DeviceBusController#scanDevices()} <em>should</em> 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<UUID> getDeviceIdentifier(Device device);
|
||||
|
||||
/**
|
||||
* Returns the energy consumption of this bus element.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ItemDeviceProvid
|
||||
/**
|
||||
* Get a device for the specified query.
|
||||
*
|
||||
* @param query the query describing the object to get a {@link Device} for.
|
||||
* @param query the query describing the object to get an {@link ItemDevice} for.
|
||||
* @return a device for the specified query, if available.
|
||||
*/
|
||||
Optional<ItemDevice> getDevice(ItemDeviceQuery query);
|
||||
@@ -51,4 +50,17 @@ public interface ItemDeviceProvider extends IForgeRegistryEntry<ItemDeviceProvid
|
||||
default Optional<DeviceType> 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.
|
||||
* <p>
|
||||
* Return <code>0</code> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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<? extends ITextProperties> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ComputerTerminalContainer> {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<RobotTerminalCont
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerForegroundLayer(final MatrixStack matrixStack, final int x, final int y) {
|
||||
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, getRobot().getVirtualMachine().getBootError());
|
||||
RobotContainerScreen.renderSelection(matrixStack, getRobot().getSelectedSlot(), guiLeft + SLOTS_X + 4, guiTop + SLOTS_Y + 4, 12);
|
||||
terminalWidget.render(matrixStack, mouseX, mouseY, container.getRobot().getVirtualMachine().getBootError());
|
||||
RobotContainerScreen.renderSelection(matrixStack, container.getRobot().getSelectedSlot(), guiLeft + SLOTS_X + 4, guiTop + SLOTS_Y + 4, 12);
|
||||
renderHoveredTooltip(matrixStack, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@@ -95,12 +96,6 @@ public final class RobotTerminalScreen extends ContainerScreen<RobotTerminalCont
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private RobotEntity getRobot() {
|
||||
return container.getRobot();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final class RobotTerminalWidget extends AbstractTerminalWidget {
|
||||
public RobotTerminalWidget(final Terminal terminal) {
|
||||
super(RobotTerminalScreen.this, terminal);
|
||||
@@ -108,7 +103,7 @@ public final class RobotTerminalScreen extends ContainerScreen<RobotTerminalCont
|
||||
|
||||
@Override
|
||||
protected boolean isRunning() {
|
||||
return getRobot().getVirtualMachine().isRunning();
|
||||
return container.getRobot().getVirtualMachine().isRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -118,12 +113,12 @@ public final class RobotTerminalScreen extends ContainerScreen<RobotTerminalCont
|
||||
|
||||
@Override
|
||||
protected void sendPowerStateToServer(final boolean value) {
|
||||
Network.INSTANCE.sendToServer(new RobotPowerMessage(getRobot(), value));
|
||||
Network.INSTANCE.sendToServer(new RobotPowerMessage(container.getRobot(), value));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendTerminalInputToServer(final ByteBuffer input) {
|
||||
Network.INSTANCE.sendToServer(new RobotTerminalInputMessage(getRobot(), input));
|
||||
Network.INSTANCE.sendToServer(new RobotTerminalInputMessage(container.getRobot(), input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,10 @@ public final class Sprite extends AbstractGui {
|
||||
Minecraft.getInstance().getTextureManager().bindTexture(image);
|
||||
blit(stack, x, y, u0, v0, width, height, textureSize, textureSize);
|
||||
}
|
||||
|
||||
public void drawFillY(final MatrixStack stack, final int x, final int y, final float value) {
|
||||
Minecraft.getInstance().getTextureManager().bindTexture(image);
|
||||
final int h = (int) (this.height * value);
|
||||
blit(stack, x, y + (height - h), u0, v0 + (height - h), width, h, textureSize, textureSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,21 @@ public final class Config {
|
||||
public static int maxFlashMemorySize = 4 * Constants.KILOBYTE;
|
||||
public static int maxFloppySize = 512 * Constants.KILOBYTE;
|
||||
|
||||
public static int computerEnergyPerTick = 20;
|
||||
public static int computerEnergyStorage = 4000;
|
||||
public static int robotEnergyPerTick = 10;
|
||||
public static int robotEnergyStorage = 600000;
|
||||
public static double busCableEnergyPerTick = 0.1;
|
||||
public static double busInterfaceEnergyPerTick = 0.5;
|
||||
public static int computerEnergyPerTick = 10;
|
||||
public static int computerEnergyStorage = 2000;
|
||||
public static int robotEnergyPerTick = 5;
|
||||
public static int robotEnergyStorage = 750000;
|
||||
public static int chargerEnergyPerTick = 2500;
|
||||
public static int chargerEnergyStorage = 50000;
|
||||
public static int chargerEnergyStorage = 10000;
|
||||
|
||||
public static double memoryEnergyPerMegabytePerTick = 0.5;
|
||||
public static double hardDriveEnergyPerMegabytePerTick = 1;
|
||||
public static int networkInterfaceEnergyPerTick = 1;
|
||||
public static int redstoneInterfaceCardEnergyPerTick = 1;
|
||||
public static int blockOperationsModuleEnergyPerTick = 2;
|
||||
public static int inventoryOperationsModuleEnergyPerTick = 1;
|
||||
|
||||
public static int blockOperationsModuleToolLevel = Items.DIAMOND_PICKAXE.getHarvestLevel(new ItemStack(Items.DIAMOND_PICKAXE), ToolType.PICKAXE, null, null);
|
||||
|
||||
@@ -73,6 +82,9 @@ public final class Config {
|
||||
maxHardDriveSize = COMMON_INSTANCE.maxHardDriveSize.get();
|
||||
maxFlashMemorySize = COMMON_INSTANCE.maxFlashMemorySize.get();
|
||||
|
||||
busCableEnergyPerTick = COMMON_INSTANCE.busCableEnergyPerTick.get();
|
||||
busInterfaceEnergyPerTick = COMMON_INSTANCE.busInterfaceEnergyPerTick.get();
|
||||
|
||||
computerEnergyPerTick = COMMON_INSTANCE.computerEnergyPerTick.get();
|
||||
computerEnergyStorage = COMMON_INSTANCE.computerEnergyStorage.get();
|
||||
robotEnergyPerTick = COMMON_INSTANCE.robotEnergyPerTick.get();
|
||||
@@ -94,6 +106,8 @@ public final class Config {
|
||||
public final ForgeConfigSpec.IntValue maxHardDriveSize;
|
||||
public final ForgeConfigSpec.IntValue maxFlashMemorySize;
|
||||
|
||||
public final ForgeConfigSpec.DoubleValue busCableEnergyPerTick;
|
||||
public final ForgeConfigSpec.DoubleValue busInterfaceEnergyPerTick;
|
||||
public final ForgeConfigSpec.IntValue computerEnergyPerTick;
|
||||
public final ForgeConfigSpec.IntValue computerEnergyStorage;
|
||||
public final ForgeConfigSpec.IntValue robotEnergyPerTick;
|
||||
@@ -132,9 +146,19 @@ public final class Config {
|
||||
|
||||
builder.push("energy");
|
||||
|
||||
busCableEnergyPerTick = builder
|
||||
.translation(Constants.CONFIG_BUS_CABLE_COMPLEXITY)
|
||||
.comment("The amount of energy (Forge Energy/RF) a single bus cable consumes per tick.")
|
||||
.defineInRange("busCableEnergyPerTick", Config.busCableEnergyPerTick, 0, Double.MAX_VALUE);
|
||||
|
||||
busInterfaceEnergyPerTick = builder
|
||||
.translation(Constants.CONFIG_BUS_INTERFACE_COMPLEXITY)
|
||||
.comment("The amount of energy (Forge Energy/RF) a single bus interface consumes per tick.")
|
||||
.defineInRange("busInterfaceEnergyPerTick", Config.busInterfaceEnergyPerTick, 0, Double.MAX_VALUE);
|
||||
|
||||
computerEnergyPerTick = builder
|
||||
.translation(Constants.CONFIG_COMPUTER_ENERGY_PER_TICK)
|
||||
.comment("The amount of energy (Forge Energy/RF) a computer draws per tick. Set to zero to disable.")
|
||||
.comment("The amount of energy (Forge Energy/RF) a computer consumes per tick. Set to zero to disable.")
|
||||
.defineInRange("computerEnergyPerTick", Config.computerEnergyPerTick, 0, Integer.MAX_VALUE);
|
||||
|
||||
computerEnergyStorage = builder
|
||||
@@ -144,7 +168,7 @@ public final class Config {
|
||||
|
||||
robotEnergyPerTick = builder
|
||||
.translation(Constants.CONFIG_ROBOT_ENERGY_PER_TICK)
|
||||
.comment("The amount of energy (Forge Energy/RF) a robot draws per tick. Set to zero to disable.")
|
||||
.comment("The amount of energy (Forge Energy/RF) a robot consumes per tick. Set to zero to disable.")
|
||||
.defineInRange("robotEnergyPerTick", Config.robotEnergyPerTick, 0, Integer.MAX_VALUE);
|
||||
|
||||
robotEnergyStorage = builder
|
||||
|
||||
@@ -32,6 +32,7 @@ public final class Constants {
|
||||
public static final String DISK_DRIVE_BLOCK_NAME = "disk_drive";
|
||||
public static final String REDSTONE_INTERFACE_BLOCK_NAME = "redstone_interface";
|
||||
public static final String CHARGER_BLOCK_NAME = "charger";
|
||||
public static final String CREATIVE_ENERGY_BLOCK_NAME = "creative_energy";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -62,6 +63,7 @@ public final class Constants {
|
||||
public static final String TOOLTIP_MEMORY_MISSING = "tooltip.oc2.memory_missing";
|
||||
public static final String TOOLTIP_HARD_DRIVE_MISSING = "tooltip.oc2.hard_drive_missing";
|
||||
public static final String TOOLTIP_ENERGY = "tooltip.oc2.energy";
|
||||
public static final String TOOLTIP_ENERGY_CONSUMPTION = "tooltip.oc2.energyConsumption";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -71,6 +73,9 @@ public final class Constants {
|
||||
public static final String CONFIG_MAX_FLASH_MEMORY_SIZE = "config.oc2.vm.maxFlashMemorySize";
|
||||
public static final String CONFIG_BLOCK_OPERATIONS_MODULE_TOOL_LEVEL = "config.oc2.modules.block_operations.toolLevel";
|
||||
public static final String CONFIG_FAKE_PLAYER_UUID = "config.oc2.admin.fakePlayerUUID";
|
||||
public static final String CONFIG_BUS_CABLE_COMPLEXITY = "config.oc2.busCableComplexity";
|
||||
public static final String CONFIG_BUS_INTERFACE_COMPLEXITY = "config.oc2.busInterfaceComplexity";
|
||||
public static final String CONFIG_BUS_COMPLEXITY_ENERGY_PER_TICK = "config.oc2.complexityEnergyPerTick";
|
||||
public static final String CONFIG_COMPUTER_ENERGY_PER_TICK = "config.oc2.computerEnergyPerTick";
|
||||
public static final String CONFIG_COMPUTER_ENERGY_STORAGE = "config.oc2.computerEnergyStorage";
|
||||
public static final String CONFIG_ROBOT_ENERGY_PER_TICK = "config.oc2.robotEnergyPerTick";
|
||||
|
||||
@@ -20,6 +20,7 @@ public final class Blocks {
|
||||
public static final RegistryObject<RedstoneInterfaceBlock> REDSTONE_INTERFACE = BLOCKS.register(Constants.REDSTONE_INTERFACE_BLOCK_NAME, RedstoneInterfaceBlock::new);
|
||||
public static final RegistryObject<DiskDriveBlock> DISK_DRIVE = BLOCKS.register(Constants.DISK_DRIVE_BLOCK_NAME, DiskDriveBlock::new);
|
||||
public static final RegistryObject<ChargerBlock> CHARGER = BLOCKS.register(Constants.CHARGER_BLOCK_NAME, ChargerBlock::new);
|
||||
public static final RegistryObject<CreativeEnergyBlock> CREATIVE_ENERGY = BLOCKS.register(Constants.CREATIVE_ENERGY_BLOCK_NAME, CreativeEnergyBlock::new);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -89,6 +89,16 @@ public final class BusCableBlock extends Block {
|
||||
}
|
||||
}
|
||||
|
||||
public static int getInterfaceCount(final BlockState state) {
|
||||
int partCount = 0;
|
||||
for (final EnumProperty<ConnectionType> 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> 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;
|
||||
}
|
||||
|
||||
@@ -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<ITextComponent> 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());
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<Device> devices = new HashSet<>();
|
||||
protected final Object2IntArrayMap<Device> devices = new Object2IntArrayMap<>();
|
||||
protected final HashSet<DeviceBusController> 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<Device> 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<Device> entry : devices.object2IntEntrySet()) {
|
||||
accumulator += entry.getIntValue();
|
||||
}
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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<TProvider extends IForgeRegistryEntry<TProvider>, TDeviceInfo extends AbstractDeviceInfo<TProvider, ?>> extends AbstractDeviceBusElement implements INBTSerializable<ListNBT> {
|
||||
private static final String GROUP_ID_TAG_NAME = "groupId";
|
||||
@@ -101,11 +100,15 @@ public abstract class AbstractGroupingDeviceBusElement<TProvider extends IForgeR
|
||||
|
||||
final HashSet<TDeviceInfo> 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<TDeviceInfo> 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);
|
||||
|
||||
@@ -36,6 +36,7 @@ public class CommonDeviceBusController implements DeviceBusController {
|
||||
public final ParameterizedEvent<DevicesChangedEvent> onDevicesRemoved = new ParameterizedEvent<>();
|
||||
|
||||
private final DeviceBusElement root;
|
||||
private final int baseEnergyConsumption;
|
||||
|
||||
private final Set<DeviceBusElement> elements = new HashSet<>();
|
||||
private final HashSet<Device> 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 {
|
||||
|
||||
@@ -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<ItemStack, List<ItemDeviceInfo>> deviceLookup;
|
||||
private final Function<ItemStack, ItemDeviceQuery> queryFactory;
|
||||
|
||||
public ItemHandlerDeviceBusElement(final int slotCount, final Function<ItemStack, List<ItemDeviceInfo>> deviceLookup) {
|
||||
public ItemHandlerDeviceBusElement(final int slotCount, final Function<ItemStack, ItemDeviceQuery> queryFactory) {
|
||||
super(slotCount);
|
||||
this.deviceLookup = deviceLookup;
|
||||
this.queryFactory = queryFactory;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void updateDevices(final int slot, final ItemStack stack) {
|
||||
if (!stack.isEmpty()) {
|
||||
final HashSet<ItemDeviceInfo> newDevices = new HashSet<>(deviceLookup.apply(stack));
|
||||
final ItemDeviceQuery query = queryFactory.apply(stack);
|
||||
final HashSet<ItemDeviceInfo> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<BlockDeviceInfo> newDevices = new HashSet<>();
|
||||
if (canDetectDevicesTowards(direction)) {
|
||||
for (final LazyOptional<BlockDeviceInfo> deviceInfo : Devices.getDevices(world, pos, direction)) {
|
||||
final BlockDeviceQuery query = Devices.makeQuery(world, pos, direction);
|
||||
for (final LazyOptional<BlockDeviceInfo> deviceInfo : Devices.getDevices(query)) {
|
||||
deviceInfo.ifPresent(newDevices::add);
|
||||
deviceInfo.addListener(unused -> handleNeighborChanged(pos));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<DeviceType> 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<DeviceType> 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,11 @@ public abstract class AbstractItemDeviceProvider extends ForgeRegistryEntry<Item
|
||||
return matches(query) ? getItemDeviceType(query) : Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getEnergyConsumption(final ItemDeviceQuery query) {
|
||||
return matches(query) ? getItemDeviceEnergyConsumption(query) : 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected abstract Optional<ItemDevice> getItemDevice(final ItemDeviceQuery query);
|
||||
@@ -45,6 +50,10 @@ public abstract class AbstractItemDeviceProvider extends ForgeRegistryEntry<Item
|
||||
return Optional.of(DeviceTypes.CARD);
|
||||
}
|
||||
|
||||
protected int getItemDeviceEnergyConsumption(final ItemDeviceQuery query) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private boolean matches(final ItemDeviceQuery query) {
|
||||
|
||||
@@ -19,6 +19,10 @@ public abstract class AbstractDeviceInfo<TProvider extends IForgeRegistryEntry<T
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public int getEnergyConsumption() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
@@ -20,39 +20,32 @@ import net.minecraftforge.registries.IForgeRegistry;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public final class Devices {
|
||||
public static List<LazyOptional<BlockDeviceInfo>> 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<LazyOptional<BlockDeviceInfo>> 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<ItemDeviceInfo> getDevices(final ItemStack stack) {
|
||||
return getDevices(new ItemQuery(stack));
|
||||
public static ItemDeviceQuery makeQuery(final ItemStack stack) {
|
||||
return new ItemQuery(stack);
|
||||
}
|
||||
|
||||
public static List<ItemDeviceInfo> 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<ItemDeviceInfo> 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<DeviceType> getDeviceTypes(final ItemStack stack) {
|
||||
return getDeviceTypes(new ItemQuery(stack));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private static List<LazyOptional<BlockDeviceInfo>> getDevices(final BlockQuery query) {
|
||||
public static List<LazyOptional<BlockDeviceInfo>> getDevices(final BlockDeviceQuery query) {
|
||||
final IForgeRegistry<BlockDeviceProvider> registry = Providers.BLOCK_DEVICE_PROVIDER_REGISTRY.get();
|
||||
final ArrayList<LazyOptional<BlockDeviceInfo>> devices = new ArrayList<>();
|
||||
for (final BlockDeviceProvider provider : registry.getValues()) {
|
||||
@@ -66,17 +59,17 @@ public final class Devices {
|
||||
return devices;
|
||||
}
|
||||
|
||||
private static List<ItemDeviceInfo> getDevices(final ItemQuery query) {
|
||||
public static List<ItemDeviceInfo> getDevices(final ItemDeviceQuery query) {
|
||||
final IForgeRegistry<ItemDeviceProvider> registry = Providers.ITEM_DEVICE_PROVIDER_REGISTRY.get();
|
||||
final ArrayList<ItemDeviceInfo> devices = new ArrayList<>();
|
||||
for (final ItemDeviceProvider provider : registry.getValues()) {
|
||||
final Optional<ItemDevice> 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<DeviceType> getDeviceTypes(final ItemQuery query) {
|
||||
public static Collection<DeviceType> getDeviceTypes(final ItemDeviceQuery query) {
|
||||
final IForgeRegistry<ItemDeviceProvider> registry = Providers.ITEM_DEVICE_PROVIDER_REGISTRY.get();
|
||||
final HashSet<DeviceType> 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<ItemDeviceProvider> 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 {
|
||||
|
||||
@@ -6,7 +6,19 @@ import li.cil.oc2.api.bus.device.provider.ItemDeviceProvider;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ItemDeviceInfo extends AbstractDeviceInfo<ItemDeviceProvider, ItemDevice> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ public final class Containers {
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static final RegistryObject<ContainerType<ComputerContainer>> COMPUTER_CONTAINER = CONTAINERS.register(Constants.COMPUTER_BLOCK_NAME, () -> IForgeContainerType.create(ComputerContainer::create));
|
||||
public static final RegistryObject<ContainerType<ComputerTerminalContainer>> COMPUTER_TERMINAL_CONTAINER = CONTAINERS.register(Constants.COMPUTER_BLOCK_NAME + "_terminal", () -> IForgeContainerType.create(ComputerTerminalContainer::create));
|
||||
public static final RegistryObject<ContainerType<RobotContainer>> ROBOT_CONTAINER = CONTAINERS.register(Constants.ROBOT_ENTITY_NAME, () -> IForgeContainerType.create(RobotContainer::create));
|
||||
public static final RegistryObject<ContainerType<RobotTerminalContainer>> ROBOT_TERMINAL_CONTAINER = CONTAINERS.register(Constants.ROBOT_ENTITY_NAME + "_terminal", () -> IForgeContainerType.create(RobotTerminalContainer::create));
|
||||
|
||||
|
||||
@@ -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<ItemStack, List<ItemDeviceInfo>> deviceLookup) {
|
||||
this(NonNullList.withSize(size, ItemStack.EMPTY), deviceLookup);
|
||||
public DeviceItemStackHandler(final int size, final Function<ItemStack, ItemDeviceQuery> queryFactory) {
|
||||
this(NonNullList.withSize(size, ItemStack.EMPTY), queryFactory);
|
||||
}
|
||||
|
||||
public DeviceItemStackHandler(final NonNullList<ItemStack> stacks, final Function<ItemStack, List<ItemDeviceInfo>> deviceLookup) {
|
||||
public DeviceItemStackHandler(final NonNullList<ItemStack> stacks, final Function<ItemStack, ItemDeviceQuery> queryFactory) {
|
||||
super(stacks);
|
||||
this.busElement = new ItemHandlerDeviceBusElement(getSlots(), deviceLookup);
|
||||
this.busElement = new ItemHandlerDeviceBusElement(getSlots(), queryFactory);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<ItemStack, List<ItemDeviceInfo>> deviceLookup, final DeviceType deviceType) {
|
||||
super(size, deviceLookup);
|
||||
public TypedDeviceItemStackHandler(final int size, final Function<ItemStack, ItemDeviceQuery> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Item> 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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<IEnergyStorage> optional = LazyOptional.of(() -> this);
|
||||
@@ -61,9 +61,12 @@ public final class EnergyStorageItemStack implements IEnergyStorage, ICapability
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@NotNull final Capability<T> capability, @Nullable final Direction side) {
|
||||
return Capabilities.ENERGY_STORAGE.orEmpty(capability, optional);
|
||||
public <T> LazyOptional<T> getCapability(final Capability<T> capability, @Nullable final Direction side) {
|
||||
if (Capabilities.ENERGY_STORAGE != null && capability != null) {
|
||||
return Capabilities.ENERGY_STORAGE.orEmpty(capability, optional);
|
||||
} else {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <T> LazyOptional<T> getCapability(@NotNull final Capability<T> capability, @org.jetbrains.annotations.Nullable final Direction side) {
|
||||
public <T> LazyOptional<T> getCapability(final Capability<T> 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<ItemDeviceInfo> 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
|
||||
|
||||
@@ -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<ITextComponent> 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);
|
||||
|
||||
@@ -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<ITextComponent> 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<ItemStack> items) {
|
||||
if (isInGroup(group)) {
|
||||
items.add(new ItemStack(this));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToBlockToItemMap(final Map<Block, Item> map, final Item item) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFromBlockToItemMap(final Map<Block, Item> map, final Item item) {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -26,6 +26,7 @@ public final class Items {
|
||||
public static final RegistryObject<Item> REDSTONE_INTERFACE = register(Constants.REDSTONE_INTERFACE_BLOCK_NAME, Blocks.REDSTONE_INTERFACE);
|
||||
public static final RegistryObject<Item> DISK_DRIVE = register(Constants.DISK_DRIVE_BLOCK_NAME, Blocks.DISK_DRIVE);
|
||||
public static final RegistryObject<Item> CHARGER = register(Constants.CHARGER_BLOCK_NAME, Blocks.CHARGER, ChargerItem::new);
|
||||
public static final RegistryObject<Item> CREATIVE_ENERGY = register(Constants.CREATIVE_ENERGY_BLOCK_NAME, Blocks.CREATIVE_ENERGY);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -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<ITextComponent> tooltip, final ITooltipFlag flag) {
|
||||
TooltipUtils.tryAddDescription(stack, tooltip);
|
||||
this.getBlock().addInformation(stack, world, tooltip, flag);
|
||||
super.addInformation(stack, world, tooltip, flag);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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<ITextComponent> tooltip, final ITooltipFlag flag) {
|
||||
super.addInformation(stack, world, tooltip, flag);
|
||||
|
||||
@@ -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<ITextComponent> 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
|
||||
|
||||
@@ -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<MemoryRange> {
|
||||
@Override
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<BlockDeviceInfo> optional : Devices.getDevices(this, (Direction) null)) {
|
||||
final BlockDeviceQuery query = Devices.makeQuery(this, (Direction) null);
|
||||
for (final LazyOptional<BlockDeviceInfo> 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<ItemDeviceInfo> 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
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -25,6 +25,7 @@ public final class TileEntities {
|
||||
public static final RegistryObject<TileEntityType<NetworkHubTileEntity>> NETWORK_HUB_TILE_ENTITY = register(Constants.NETWORK_HUB_BLOCK_NAME, Blocks.NETWORK_HUB, NetworkHubTileEntity::new);
|
||||
public static final RegistryObject<TileEntityType<DiskDriveTileEntity>> DISK_DRIVE_TILE_ENTITY = register(Constants.DISK_DRIVE_BLOCK_NAME, Blocks.DISK_DRIVE, DiskDriveTileEntity::new);
|
||||
public static final RegistryObject<TileEntityType<ChargerTileEntity>> CHARGER_TILE_ENTITY = register(Constants.CHARGER_BLOCK_NAME, Blocks.CHARGER, ChargerTileEntity::new);
|
||||
public static final RegistryObject<TileEntityType<CreativeEnergyTileEntity>> CREATIVE_ENERGY_TILE_ENTITY = register(Constants.CREATIVE_ENERGY_BLOCK_NAME, Blocks.CREATIVE_ENERGY, CreativeEnergyTileEntity::new);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -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 + "]";
|
||||
|
||||
@@ -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<List<ItemStack>> ITEM_STACKS = ThreadLocal.withInitial(ArrayList::new);
|
||||
private static final ThreadLocal<IntList> 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<Item> 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<ITextComponent> 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<ITextComponent> 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<ITextComponent> 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<ITextComponent> 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)));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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<ItemDeviceInfo> 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<ItemStack, List<ItemDeviceInfo>> deviceLookup, final DeviceType deviceType) {
|
||||
super(size, deviceLookup, deviceType);
|
||||
public ItemHandler(final int size, final Function<ItemStack, ItemDeviceQuery> queryFactory, final DeviceType deviceType) {
|
||||
super(size, queryFactory, deviceType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<CreativeEnergyBlock> block, final RegistryObject<Item> item) {
|
||||
simpleBlock(block.get());
|
||||
itemModels().getBuilder(item.getId().getPath()).parent(models().getExistingFile(block.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "oc2:block/creative_energy"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "oc2:block/creative_energy"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"parent": "oc2:block/creative_energy"
|
||||
}
|
||||
BIN
src/main/resources/assets/oc2/textures/block/creative_energy.png
Normal file
BIN
src/main/resources/assets/oc2/textures/block/creative_energy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.6 KiB |
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user