Robots bootable and movable.
This commit is contained in:
@@ -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.RobotContainerScreen;
|
||||
import li.cil.oc2.client.item.CustomItemModelProperties;
|
||||
import li.cil.oc2.client.model.BusCableModelLoader;
|
||||
import li.cil.oc2.client.renderer.NetworkCableRenderer;
|
||||
@@ -32,6 +33,7 @@ public final class ClientSetup {
|
||||
CustomItemModelProperties.initialize();
|
||||
|
||||
ScreenManager.registerFactory(Containers.COMPUTER_CONTAINER.get(), ComputerContainerScreen::new);
|
||||
ScreenManager.registerFactory(Containers.ROBOT_CONTAINER.get(), RobotContainerScreen::new);
|
||||
|
||||
ClientRegistry.bindTileEntityRenderer(TileEntities.COMPUTER_TILE_ENTITY.get(), ComputerTileEntityRenderer::new);
|
||||
ClientRegistry.bindTileEntityRenderer(TileEntities.NETWORK_CONNECTOR_TILE_ENTITY.get(), NetworkConnectorTileEntityRenderer::new);
|
||||
|
||||
@@ -7,13 +7,11 @@ import li.cil.oc2.client.gui.terminal.TerminalInput;
|
||||
import li.cil.oc2.client.gui.widget.Sprite;
|
||||
import li.cil.oc2.client.gui.widget.ToggleImageButton;
|
||||
import li.cil.oc2.common.Constants;
|
||||
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 li.cil.oc2.common.vm.VirtualMachineState;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
@@ -23,7 +21,7 @@ import java.nio.ByteBuffer;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public final class TerminalScreen extends Screen {
|
||||
public abstract class AbstractTerminalScreen extends Screen {
|
||||
private static final ResourceLocation BACKGROUND = new ResourceLocation(API.MOD_ID, "textures/gui/screen/terminal.png");
|
||||
private static final ResourceLocation BACKGROUND_TERMINAL_FOCUSED = new ResourceLocation(API.MOD_ID, "textures/gui/screen/terminal_focused.png");
|
||||
private static final int TEXTURE_SIZE = 512;
|
||||
@@ -50,7 +48,7 @@ public final class TerminalScreen extends Screen {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final ComputerTileEntity tileEntity;
|
||||
private final VirtualMachineState state;
|
||||
private final Terminal terminal;
|
||||
private final int windowWidth, windowHeight;
|
||||
private int windowLeft, windowTop;
|
||||
@@ -58,10 +56,10 @@ public final class TerminalScreen extends Screen {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public TerminalScreen(final ComputerTileEntity tileEntity, final ITextComponent title) {
|
||||
public AbstractTerminalScreen(final VirtualMachineState state, final Terminal terminal, final ITextComponent title) {
|
||||
super(title);
|
||||
this.tileEntity = tileEntity;
|
||||
terminal = tileEntity.getTerminal();
|
||||
this.state = state;
|
||||
this.terminal = terminal;
|
||||
windowWidth = SCREEN_WIDTH;
|
||||
windowHeight = SCREEN_HEIGHT;
|
||||
}
|
||||
@@ -84,13 +82,13 @@ public final class TerminalScreen extends Screen {
|
||||
|
||||
super.render(matrixStack, mouseX, mouseY, partialTicks);
|
||||
|
||||
if (tileEntity.getState().isRunning()) {
|
||||
if (state.isRunning()) {
|
||||
final MatrixStack stack = new MatrixStack();
|
||||
stack.translate(windowLeft + TERMINAL_AREA_X, windowTop + TERMINAL_AREA_Y, this.itemRenderer.zLevel);
|
||||
stack.scale(TERMINAL_AREA_WIDTH / (float) terminal.getWidth(), TERMINAL_AREA_HEIGHT / (float) terminal.getHeight(), 1f);
|
||||
terminal.render(stack);
|
||||
} else {
|
||||
final ITextComponent bootError = tileEntity.getState().getBootError();
|
||||
final ITextComponent bootError = state.getBootError();
|
||||
if (bootError != null) {
|
||||
final int textWidth = font.getStringPropertyWidth(bootError);
|
||||
final int textOffsetX = (TERMINAL_AREA_WIDTH - textWidth) / 2;
|
||||
@@ -110,13 +108,13 @@ public final class TerminalScreen extends Screen {
|
||||
|
||||
final ByteBuffer input = terminal.getInput();
|
||||
if (input != null) {
|
||||
Network.INSTANCE.sendToServer(new ComputerTerminalInputMessage(tileEntity, input));
|
||||
sendTerminalInputToServer(input);
|
||||
}
|
||||
|
||||
assert minecraft != null;
|
||||
final ClientPlayerEntity player = minecraft.player;
|
||||
assert player != null;
|
||||
if (!player.isAlive() || !tileEntity.getPos().withinDistance(player.getPositionVec(), 8)) {
|
||||
if (!player.isAlive() || !canInteractWith(player)) {
|
||||
closeScreen();
|
||||
}
|
||||
}
|
||||
@@ -166,6 +164,12 @@ public final class TerminalScreen extends Screen {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
protected abstract void sendPowerStateToServer(boolean value);
|
||||
|
||||
protected abstract void sendTerminalInputToServer(final ByteBuffer input);
|
||||
|
||||
protected abstract boolean canInteractWith(PlayerEntity player);
|
||||
|
||||
protected void init() {
|
||||
super.init();
|
||||
this.windowLeft = (this.width - this.windowWidth) / 2;
|
||||
@@ -185,13 +189,12 @@ public final class TerminalScreen extends Screen {
|
||||
@Override
|
||||
public void onPress() {
|
||||
super.onPress();
|
||||
final ComputerPowerMessage message = new ComputerPowerMessage(tileEntity, !tileEntity.getState().isRunning());
|
||||
Network.INSTANCE.sendToServer(message);
|
||||
sendPowerStateToServer(!state.isRunning());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isToggled() {
|
||||
return tileEntity.getState().isRunning();
|
||||
return state.isRunning();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -220,7 +223,7 @@ public final class TerminalScreen extends Screen {
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private boolean shouldCaptureInput() {
|
||||
return isMouseOverTerminal && enableInputCapture && tileEntity.getState().isRunning();
|
||||
return isMouseOverTerminal && enableInputCapture && state.isRunning();
|
||||
}
|
||||
|
||||
private boolean isPointInRegion(final int x, final int y, final int width, final int height, double mouseX, double mouseY) {
|
||||
@@ -0,0 +1,38 @@
|
||||
package li.cil.oc2.client.gui;
|
||||
|
||||
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 net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class ComputerTerminalScreen extends AbstractTerminalScreen {
|
||||
private final ComputerTileEntity computer;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public ComputerTerminalScreen(final ComputerTileEntity computer, final ITextComponent title) {
|
||||
super(computer.getState(), computer.getTerminal(), title);
|
||||
this.computer = computer;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected void sendPowerStateToServer(final boolean value) {
|
||||
Network.INSTANCE.sendToServer(new ComputerPowerMessage(computer, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendTerminalInputToServer(final ByteBuffer input) {
|
||||
Network.INSTANCE.sendToServer(new ComputerTerminalInputMessage(computer, input));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canInteractWith(final PlayerEntity player) {
|
||||
return computer.getPos().withinDistance(player.getPositionVec(), 8);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package li.cil.oc2.client.gui;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import li.cil.oc2.api.API;
|
||||
import li.cil.oc2.common.container.RobotContainer;
|
||||
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public final class RobotContainerScreen extends ContainerScreen<RobotContainer> {
|
||||
private static final ResourceLocation BACKGROUND = new ResourceLocation(API.MOD_ID, "textures/gui/container/computer.png");
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public RobotContainerScreen(final RobotContainer container, final PlayerInventory inventory, final ITextComponent title) {
|
||||
super(container, inventory, title);
|
||||
xSize = 176;
|
||||
ySize = 197;
|
||||
playerInventoryTitleY = ySize - 94;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(final MatrixStack matrixStack, final int mouseX, final int mouseY, final float partialTicks) {
|
||||
renderBackground(matrixStack);
|
||||
super.render(matrixStack, mouseX, mouseY, partialTicks);
|
||||
renderHoveredTooltip(matrixStack, mouseX, mouseY);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer(final MatrixStack matrixStack, final float partialTicks, final int mouseX, final int mouseY) {
|
||||
RenderSystem.color4f(1f, 1f, 1f, 1f);
|
||||
requireNonNull(minecraft).getTextureManager().bindTexture(BACKGROUND);
|
||||
blit(matrixStack, guiLeft, guiTop, 0, 0, xSize, ySize);
|
||||
}
|
||||
}
|
||||
38
src/main/java/li/cil/oc2/client/gui/RobotTerminalScreen.java
Normal file
38
src/main/java/li/cil/oc2/client/gui/RobotTerminalScreen.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package li.cil.oc2.client.gui;
|
||||
|
||||
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;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class RobotTerminalScreen extends AbstractTerminalScreen {
|
||||
private final RobotEntity robot;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public RobotTerminalScreen(final RobotEntity robot, final ITextComponent title) {
|
||||
super(robot.getState(), robot.getTerminal(), title);
|
||||
this.robot = robot;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected void sendPowerStateToServer(final boolean value) {
|
||||
Network.INSTANCE.sendToServer(new RobotPowerMessage(robot, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendTerminalInputToServer(final ByteBuffer input) {
|
||||
Network.INSTANCE.sendToServer(new RobotTerminalInputMessage(robot, input));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canInteractWith(final PlayerEntity player) {
|
||||
return robot.isEntityInRange(player, 8);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import li.cil.oc2.api.API;
|
||||
import li.cil.oc2.common.entity.RobotEntity;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
@@ -13,11 +12,8 @@ import net.minecraft.client.renderer.entity.model.EntityModel;
|
||||
import net.minecraft.client.renderer.model.ModelRenderer;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.EntityRayTraceResult;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.vector.Vector3f;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraftforge.common.model.TransformationHelper;
|
||||
|
||||
public final class RobotEntityRenderer extends EntityRenderer<RobotEntity> {
|
||||
@@ -57,10 +53,10 @@ public final class RobotEntityRenderer extends EntityRenderer<RobotEntity> {
|
||||
|
||||
matrixStack.pop();
|
||||
|
||||
final RayTraceResult hit = Minecraft.getInstance().objectMouseOver;
|
||||
if (hit instanceof EntityRayTraceResult && entity == ((EntityRayTraceResult) hit).getEntity()) {
|
||||
super.renderName(entity, new StringTextComponent("hi"), matrixStack, buffer, packedLight);
|
||||
}
|
||||
// final RayTraceResult hit = Minecraft.getInstance().objectMouseOver;
|
||||
// if (hit instanceof EntityRayTraceResult && entity == ((EntityRayTraceResult) hit).getEntity()) {
|
||||
// super.renderName(entity, new StringTextComponent("hi"), matrixStack, buffer, packedLight);
|
||||
// }
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package li.cil.oc2.common.block;
|
||||
|
||||
import li.cil.oc2.api.capabilities.RedstoneEmitter;
|
||||
import li.cil.oc2.client.gui.TerminalScreen;
|
||||
import li.cil.oc2.client.gui.ComputerTerminalScreen;
|
||||
import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import li.cil.oc2.common.container.ComputerContainer;
|
||||
import li.cil.oc2.common.integration.Wrenches;
|
||||
@@ -9,7 +9,7 @@ import li.cil.oc2.common.item.Items;
|
||||
import li.cil.oc2.common.tileentity.ComputerTileEntity;
|
||||
import li.cil.oc2.common.tileentity.TileEntities;
|
||||
import li.cil.oc2.common.util.VoxelShapeUtils;
|
||||
import li.cil.oc2.common.vm.CommonVirtualMachineItemStackHandlers;
|
||||
import li.cil.oc2.common.vm.AbstractVirtualMachineItemStackHandlers;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
@@ -76,7 +76,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);
|
||||
CommonVirtualMachineItemStackHandlers.addInformation(stack, tooltip);
|
||||
AbstractVirtualMachineItemStackHandlers.addInformation(stack, tooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,8 +178,8 @@ public final class ComputerBlock extends HorizontalBlock {
|
||||
final TileEntity tileEntity = world.getTileEntity(pos);
|
||||
if (!world.isRemote() && tileEntity instanceof ComputerTileEntity) {
|
||||
final ComputerTileEntity computer = (ComputerTileEntity) tileEntity;
|
||||
if (!computer.getItemHandlers().isEmpty()) {
|
||||
computer.getItemHandlers().exportDeviceDataToItemStacks();
|
||||
if (!computer.getItemStackHandlers().isEmpty()) {
|
||||
computer.getItemStackHandlers().exportDeviceDataToItemStacks();
|
||||
|
||||
if (player.isCreative()) {
|
||||
final ItemStack stack = new ItemStack(Items.COMPUTER_ITEM.get());
|
||||
@@ -209,7 +209,7 @@ public final class ComputerBlock extends HorizontalBlock {
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private void openTerminalScreen(final ComputerTileEntity computer) {
|
||||
Minecraft.getInstance().displayGuiScreen(new TerminalScreen(computer, getTranslatedName()));
|
||||
Minecraft.getInstance().displayGuiScreen(new ComputerTerminalScreen(computer, getTranslatedName()));
|
||||
}
|
||||
|
||||
private void openContainerScreen(final ComputerTileEntity tileEntity, final PlayerEntity player) {
|
||||
|
||||
@@ -3,14 +3,13 @@ package li.cil.oc2.common.container;
|
||||
import li.cil.oc2.api.bus.device.DeviceTypes;
|
||||
import li.cil.oc2.common.block.Blocks;
|
||||
import li.cil.oc2.common.tileentity.ComputerTileEntity;
|
||||
import li.cil.oc2.common.vm.CommonVirtualMachineItemStackHandlers;
|
||||
import li.cil.oc2.common.vm.VirtualMachineItemStackHandlers;
|
||||
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.IWorldPosCallable;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -27,36 +26,35 @@ public final class ComputerContainer extends AbstractContainer {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final World world;
|
||||
private final BlockPos pos;
|
||||
private final ComputerTileEntity computer;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public ComputerContainer(final int id, final ComputerTileEntity tileEntity, final PlayerInventory inventory) {
|
||||
public ComputerContainer(final int id, final ComputerTileEntity computer, final PlayerInventory inventory) {
|
||||
super(Containers.COMPUTER_CONTAINER.get(), id);
|
||||
this.world = inventory.player.getEntityWorld();
|
||||
this.pos = tileEntity.getPos();
|
||||
this.computer = computer;
|
||||
|
||||
final CommonVirtualMachineItemStackHandlers itemHandlers = tileEntity.getItemHandlers();
|
||||
itemHandlers.getItemHandler(DeviceTypes.FLASH_MEMORY).ifPresent(itemHandler -> {
|
||||
final VirtualMachineItemStackHandlers handlers = computer.getItemStackHandlers();
|
||||
|
||||
handlers.getItemHandler(DeviceTypes.FLASH_MEMORY).ifPresent(itemHandler -> {
|
||||
if (itemHandler.getSlots() > 0) {
|
||||
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.FLASH_MEMORY, 0, 64, 78));
|
||||
}
|
||||
});
|
||||
|
||||
itemHandlers.getItemHandler(DeviceTypes.MEMORY).ifPresent(itemHandler -> {
|
||||
handlers.getItemHandler(DeviceTypes.MEMORY).ifPresent(itemHandler -> {
|
||||
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
|
||||
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.MEMORY, slot, 64 + slot * SLOT_SIZE, 24));
|
||||
}
|
||||
});
|
||||
|
||||
itemHandlers.getItemHandler(DeviceTypes.HARD_DRIVE).ifPresent(itemHandler -> {
|
||||
handlers.getItemHandler(DeviceTypes.HARD_DRIVE).ifPresent(itemHandler -> {
|
||||
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
|
||||
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.HARD_DRIVE, slot, 100 + (slot % 2) * SLOT_SIZE, 60 + (slot / 2) * SLOT_SIZE));
|
||||
}
|
||||
});
|
||||
|
||||
itemHandlers.getItemHandler(DeviceTypes.CARD).ifPresent(itemHandler -> {
|
||||
handlers.getItemHandler(DeviceTypes.CARD).ifPresent(itemHandler -> {
|
||||
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
|
||||
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.CARD, slot, 38, 24 + slot * SLOT_SIZE));
|
||||
}
|
||||
@@ -65,8 +63,10 @@ public final class ComputerContainer extends AbstractContainer {
|
||||
createPlayerInventoryAndHotbarSlots(inventory, 8, 115);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith(final PlayerEntity player) {
|
||||
return isWithinUsableDistance(IWorldPosCallable.of(world, pos), player, Blocks.COMPUTER_BLOCK.get());
|
||||
return isWithinUsableDistance(IWorldPosCallable.of(computer.getWorld(), computer.getPos()), player, Blocks.COMPUTER_BLOCK.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<RobotContainer>> ROBOT_CONTAINER = CONTAINERS.register(Constants.ROBOT_ENTITY_NAME, () -> IForgeContainerType.create(RobotContainer::create));
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package li.cil.oc2.common.container;
|
||||
|
||||
import li.cil.oc2.api.bus.device.DeviceTypes;
|
||||
import li.cil.oc2.common.entity.RobotEntity;
|
||||
import li.cil.oc2.common.vm.VirtualMachineItemStackHandlers;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class RobotContainer extends AbstractContainer {
|
||||
@Nullable
|
||||
public static RobotContainer create(final int id, final PlayerInventory inventory, final PacketBuffer data) {
|
||||
final int entityId = data.readVarInt();
|
||||
final Entity entity = inventory.player.getEntityWorld().getEntityByID(entityId);
|
||||
if (!(entity instanceof RobotEntity)) {
|
||||
return null;
|
||||
}
|
||||
return new RobotContainer(id, (RobotEntity) entity, inventory);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final RobotEntity robot;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public RobotContainer(final int id, final RobotEntity robot, final PlayerInventory inventory) {
|
||||
super(Containers.ROBOT_CONTAINER.get(), id);
|
||||
this.robot = robot;
|
||||
|
||||
final VirtualMachineItemStackHandlers handlers = robot.getItemStackHandlers();
|
||||
|
||||
handlers.getItemHandler(DeviceTypes.FLASH_MEMORY).ifPresent(itemHandler -> {
|
||||
if (itemHandler.getSlots() > 0) {
|
||||
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.FLASH_MEMORY, 0, 64, 78));
|
||||
}
|
||||
});
|
||||
|
||||
handlers.getItemHandler(DeviceTypes.MEMORY).ifPresent(itemHandler -> {
|
||||
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
|
||||
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.MEMORY, slot, 64 + slot * SLOT_SIZE, 24));
|
||||
}
|
||||
});
|
||||
|
||||
handlers.getItemHandler(DeviceTypes.HARD_DRIVE).ifPresent(itemHandler -> {
|
||||
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
|
||||
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.HARD_DRIVE, slot, 100 + (slot % 2) * SLOT_SIZE, 60 + (slot / 2) * SLOT_SIZE));
|
||||
}
|
||||
});
|
||||
|
||||
handlers.getItemHandler(DeviceTypes.CARD).ifPresent(itemHandler -> {
|
||||
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
|
||||
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.CARD, slot, 38, 24 + slot * SLOT_SIZE));
|
||||
}
|
||||
});
|
||||
|
||||
createPlayerInventoryAndHotbarSlots(inventory, 8, 115);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith(final PlayerEntity player) {
|
||||
return robot.isEntityInRange(player, 8);
|
||||
}
|
||||
}
|
||||
@@ -2,23 +2,33 @@ package li.cil.oc2.common.entity;
|
||||
|
||||
import li.cil.oc2.api.bus.DeviceBusElement;
|
||||
import li.cil.oc2.api.bus.device.Device;
|
||||
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.client.gui.RobotTerminalScreen;
|
||||
import li.cil.oc2.common.Constants;
|
||||
import li.cil.oc2.common.bus.AbstractDeviceBusController;
|
||||
import li.cil.oc2.common.bus.AbstractDeviceBusElement;
|
||||
import li.cil.oc2.common.bus.device.util.Devices;
|
||||
import li.cil.oc2.common.bus.device.util.ItemDeviceInfo;
|
||||
import li.cil.oc2.common.container.RobotContainer;
|
||||
import li.cil.oc2.common.entity.robot.*;
|
||||
import li.cil.oc2.common.integration.Wrenches;
|
||||
import li.cil.oc2.common.network.Network;
|
||||
import li.cil.oc2.common.network.message.RobotBootErrorMessage;
|
||||
import li.cil.oc2.common.network.message.RobotTerminalOutputMessage;
|
||||
import li.cil.oc2.common.network.message.*;
|
||||
import li.cil.oc2.common.serialization.NBTSerialization;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
import li.cil.oc2.common.util.WorldUtils;
|
||||
import li.cil.oc2.common.vm.*;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
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.nbt.ListNBT;
|
||||
@@ -27,25 +37,36 @@ import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public final class RobotEntity extends Entity {
|
||||
public static final DataParameter<BlockPos> TARGET_POSITION = EntityDataManager.createKey(RobotEntity.class, DataSerializers.BLOCK_POS);
|
||||
public static final DataParameter<Direction> TARGET_DIRECTION = EntityDataManager.createKey(RobotEntity.class, DataSerializers.DIRECTION);
|
||||
|
||||
private static final String TERMINAL_TAG_NAME = "terminal";
|
||||
private static final String STATE_TAG_NAME = "state";
|
||||
private static final String BUS_ELEMENT_TAG_NAME = "bus_element";
|
||||
private static final String COMMAND_PROCESSOR_TAG_NAME = "commands";
|
||||
|
||||
private static final DataParameter<Boolean> IS_RUNNING = EntityDataManager.createKey(RobotEntity.class, DataSerializers.BOOLEAN);
|
||||
private static final int MAX_QUEUED_ACTIONS = 16;
|
||||
private static final int MAX_QUEUED_ACTIONS = 15;
|
||||
|
||||
private static final int MEMORY_SLOTS = 4;
|
||||
private static final int HARD_DRIVE_SLOTS = 2;
|
||||
@@ -54,12 +75,15 @@ public final class RobotEntity extends Entity {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final Consumer<ChunkEvent.Unload> chunkUnloadListener = this::handleChunkUnload;
|
||||
private final Consumer<WorldEvent.Unload> worldUnloadListener = this::handleWorldUnload;
|
||||
|
||||
private final AnimationState animationState = new AnimationState();
|
||||
private final CommandProcessor commandProcessor = new CommandProcessor();
|
||||
private final Terminal terminal = new Terminal();
|
||||
|
||||
private final RobotVirtualMachineState state;
|
||||
private final RobotItemStackHandlers items = new RobotItemStackHandlers();
|
||||
private final RobotBusElement busElement = new RobotBusElement();
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -68,8 +92,11 @@ public final class RobotEntity extends Entity {
|
||||
this.preventEntitySpawning = true;
|
||||
setNoGravity(true);
|
||||
|
||||
final RobotBusController busController = new RobotBusController(items.busElement);
|
||||
final RobotBusController busController = new RobotBusController(busElement);
|
||||
state = new RobotVirtualMachineState(busController, new CommonVirtualMachine(busController));
|
||||
state.virtualMachine.rtcMinecraft.setWorld(world);
|
||||
|
||||
items.busElement.addDevice(new ObjectDevice(new RobotDevice(), "robot"));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
@@ -87,14 +114,10 @@ public final class RobotEntity extends Entity {
|
||||
return state;
|
||||
}
|
||||
|
||||
public CommonVirtualMachineItemStackHandlers getItemHandlers() {
|
||||
public VirtualMachineItemStackHandlers getItemStackHandlers() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return dataManager.get(IS_RUNNING);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
final World world = getEntityWorld();
|
||||
if (world == null || world.isRemote()) {
|
||||
@@ -115,8 +138,24 @@ public final class RobotEntity extends Entity {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (firstUpdate) {
|
||||
if (getEntityWorld().isRemote()) {
|
||||
requestInitialState();
|
||||
} else {
|
||||
registerListeners();
|
||||
RobotActions.initializeData(this);
|
||||
if (commandProcessor.action != null) {
|
||||
commandProcessor.action.initialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.tick();
|
||||
|
||||
if (!getEntityWorld().isRemote()) {
|
||||
state.tick();
|
||||
}
|
||||
|
||||
commandProcessor.tick();
|
||||
}
|
||||
|
||||
@@ -124,25 +163,19 @@ public final class RobotEntity extends Entity {
|
||||
public ActionResultType processInitialInteract(final PlayerEntity player, final Hand hand) {
|
||||
final ItemStack stack = player.getHeldItem(hand);
|
||||
if (Wrenches.isWrench(stack)) {
|
||||
if (!world.isRemote()) {
|
||||
if (!world.isRemote() && player instanceof ServerPlayerEntity) {
|
||||
if (player.isSneaking()) {
|
||||
remove();
|
||||
WorldUtils.playSound(world, getPosition(), SoundType.METAL, SoundType::getBreakSound);
|
||||
} else {
|
||||
// todo open container
|
||||
openContainerScreen(player);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (player.isSneaking()) {
|
||||
start();
|
||||
} else {
|
||||
// if (rand.nextBoolean()) {
|
||||
// commandProcessor.move(MovementDirection.values()[rand.nextInt(MovementDirection.values().length)]);
|
||||
// } else {
|
||||
// commandProcessor.rotate(rand.nextBoolean() ? RotationDirection.LEFT : RotationDirection.RIGHT);
|
||||
commandProcessor.rotate(RotationDirection.RIGHT);
|
||||
// }
|
||||
// TODO open terminal + inventory screen
|
||||
} else if (world.isRemote()) {
|
||||
openTerminalScreen();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,6 +187,18 @@ public final class RobotEntity extends Entity {
|
||||
return NetworkHooks.getEntitySpawningPacket(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(final boolean keepData) {
|
||||
super.remove(keepData);
|
||||
|
||||
handleUnload();
|
||||
|
||||
// Full unload to release out-of-nbt persisted runtime-only data such as ram.
|
||||
state.virtualMachine.vmAdapter.unload();
|
||||
|
||||
// TODO drop self as item
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeCollidedWith() {
|
||||
return true;
|
||||
@@ -182,7 +227,6 @@ public final class RobotEntity extends Entity {
|
||||
|
||||
@Override
|
||||
protected void registerData() {
|
||||
getDataManager().register(IS_RUNNING, false);
|
||||
RobotActions.registerData(getDataManager());
|
||||
}
|
||||
|
||||
@@ -191,6 +235,7 @@ public final class RobotEntity extends Entity {
|
||||
tag.put(STATE_TAG_NAME, state.serialize());
|
||||
tag.put(TERMINAL_TAG_NAME, NBTSerialization.serialize(terminal));
|
||||
tag.put(COMMAND_PROCESSOR_TAG_NAME, commandProcessor.serialize());
|
||||
tag.put(BUS_ELEMENT_TAG_NAME, busElement.serialize());
|
||||
tag.put(Constants.INVENTORY_TAG_NAME, items.serialize());
|
||||
}
|
||||
|
||||
@@ -199,6 +244,7 @@ public final class RobotEntity extends Entity {
|
||||
state.deserialize(tag.getCompound(STATE_TAG_NAME));
|
||||
NBTSerialization.deserialize(tag.getCompound(TERMINAL_TAG_NAME), terminal);
|
||||
commandProcessor.deserialize(tag.getCompound(COMMAND_PROCESSOR_TAG_NAME));
|
||||
busElement.deserialize(tag.getCompound(BUS_ELEMENT_TAG_NAME));
|
||||
|
||||
if (tag.contains(Constants.INVENTORY_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
|
||||
items.deserialize(tag.getCompound(Constants.INVENTORY_TAG_NAME));
|
||||
@@ -216,6 +262,69 @@ public final class RobotEntity extends Entity {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private void requestInitialState() {
|
||||
Network.INSTANCE.sendToServer(new RobotInitializationRequestMessage(this));
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private void openTerminalScreen() {
|
||||
Minecraft.getInstance().displayGuiScreen(new RobotTerminalScreen(this, getName()));
|
||||
}
|
||||
|
||||
private void registerListeners() {
|
||||
MinecraftForge.EVENT_BUS.addListener(chunkUnloadListener);
|
||||
MinecraftForge.EVENT_BUS.addListener(worldUnloadListener);
|
||||
}
|
||||
|
||||
private void unregisterListeners() {
|
||||
MinecraftForge.EVENT_BUS.unregister(chunkUnloadListener);
|
||||
MinecraftForge.EVENT_BUS.unregister(worldUnloadListener);
|
||||
}
|
||||
|
||||
private void handleChunkUnload(final ChunkEvent.Unload event) {
|
||||
if (event.getWorld() != getEntityWorld()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ChunkPos chunkPos = new ChunkPos(getPosition());
|
||||
if (!Objects.equals(chunkPos, event.getChunk().getPos())) {
|
||||
return;
|
||||
}
|
||||
|
||||
unregisterListeners();
|
||||
handleUnload();
|
||||
}
|
||||
|
||||
private void handleWorldUnload(final WorldEvent.Unload event) {
|
||||
if (event.getWorld() != getEntityWorld()) {
|
||||
return;
|
||||
}
|
||||
|
||||
unregisterListeners();
|
||||
handleUnload();
|
||||
}
|
||||
|
||||
private void handleUnload() {
|
||||
state.joinVirtualMachine();
|
||||
state.virtualMachine.vmAdapter.suspend();
|
||||
state.busController.dispose();
|
||||
}
|
||||
|
||||
private void openContainerScreen(final PlayerEntity player) {
|
||||
NetworkHooks.openGui((ServerPlayerEntity) player, new INamedContainerProvider() {
|
||||
@Override
|
||||
public ITextComponent getDisplayName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Container createMenu(final int id, final PlayerInventory inventory, final PlayerEntity player) {
|
||||
return new RobotContainer(id, RobotEntity.this, inventory);
|
||||
}
|
||||
}, b -> b.writeVarInt(getEntityId()));
|
||||
}
|
||||
|
||||
private static float lerpClamped(final float from, final float to, final float delta) {
|
||||
if (from < to) {
|
||||
return Math.min(from + delta, to);
|
||||
@@ -255,7 +364,7 @@ public final class RobotEntity extends Entity {
|
||||
public float topRenderHover = -(hashCode() & 0xFFFF); // init to "random" to avoid synchronous hovering
|
||||
|
||||
public void update(final float deltaTime, final Random random) {
|
||||
if (isRunning() || commandProcessor.hasQueuedActions()) {
|
||||
if (getState().isRunning() || commandProcessor.hasQueuedActions()) {
|
||||
topRenderHover = topRenderHover + deltaTime * HOVER_ANIMATION_SPEED;
|
||||
final float topOffsetY = MathHelper.sin(topRenderHover) / 32f;
|
||||
|
||||
@@ -287,6 +396,10 @@ public final class RobotEntity extends Entity {
|
||||
return action != null || !queue.isEmpty();
|
||||
}
|
||||
|
||||
public int getQueuedActionCount() {
|
||||
return (action != null ? 1 : 0) + queue.size();
|
||||
}
|
||||
|
||||
public boolean move(final MovementDirection direction) {
|
||||
return addAction(new RobotMovementAction(direction));
|
||||
}
|
||||
@@ -347,7 +460,6 @@ public final class RobotEntity extends Entity {
|
||||
|
||||
if (tag.contains(ACTION_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
|
||||
action = RobotActions.deserialize(tag.getCompound(ACTION_TAG_NAME));
|
||||
action.initialize(RobotEntity.this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +468,7 @@ public final class RobotEntity extends Entity {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isRunning()) {
|
||||
if (!getState().isRunning()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -369,7 +481,7 @@ public final class RobotEntity extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
private final class RobotItemStackHandlers extends CommonVirtualMachineItemStackHandlers {
|
||||
private final class RobotItemStackHandlers extends AbstractVirtualMachineItemStackHandlers {
|
||||
public RobotItemStackHandlers() {
|
||||
super(MEMORY_SLOTS, HARD_DRIVE_SLOTS, FLASH_MEMORY_SLOTS, CARD_SLOTS);
|
||||
}
|
||||
@@ -380,6 +492,43 @@ public final class RobotEntity extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
private final class RobotBusElement extends AbstractDeviceBusElement {
|
||||
private static final String DEVICE_ID_TAG_NAME = "device_id";
|
||||
|
||||
private final Device device = new ObjectDevice(new RobotDevice(), "robot");
|
||||
private UUID deviceId = UUID.randomUUID();
|
||||
|
||||
@Override
|
||||
public Optional<Collection<LazyOptional<DeviceBusElement>>> getNeighbors() {
|
||||
return Optional.of(Collections.singleton(LazyOptional.of(() -> items.busElement)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Device> getLocalDevices() {
|
||||
return Collections.singleton(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UUID> getDeviceIdentifier(final Device device) {
|
||||
if (device == this.device) {
|
||||
return Optional.of(deviceId);
|
||||
}
|
||||
return super.getDeviceIdentifier(device);
|
||||
}
|
||||
|
||||
public CompoundNBT serialize() {
|
||||
final CompoundNBT tag = new CompoundNBT();
|
||||
tag.putUniqueId(DEVICE_ID_TAG_NAME, deviceId);
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void deserialize(final CompoundNBT tag) {
|
||||
if (tag.hasUniqueId(DEVICE_ID_TAG_NAME)) {
|
||||
deviceId = tag.getUniqueId(DEVICE_ID_TAG_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class RobotBusController extends AbstractDeviceBusController {
|
||||
public RobotBusController(final DeviceBusElement root) {
|
||||
super(root);
|
||||
@@ -437,15 +586,41 @@ public final class RobotEntity extends Entity {
|
||||
commandProcessor.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleBusStateChanged(final AbstractDeviceBusController.BusState value) {
|
||||
Network.sendToClientsTrackingEntity(new RobotBusStateMessage(RobotEntity.this), RobotEntity.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleRunStateChanged(final RunState value) {
|
||||
dataManager.set(IS_RUNNING, isRunning());
|
||||
Network.sendToClientsTrackingEntity(new RobotRunStateMessage(RobotEntity.this), RobotEntity.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleBootErrorChanged(@Nullable final ITextComponent value) {
|
||||
final RobotBootErrorMessage message = new RobotBootErrorMessage(RobotEntity.this);
|
||||
Network.sendToClientsTrackingEntity(message, RobotEntity.this);
|
||||
Network.sendToClientsTrackingEntity(new RobotBootErrorMessage(RobotEntity.this), RobotEntity.this);
|
||||
}
|
||||
}
|
||||
|
||||
public final class RobotDevice {
|
||||
@Callback
|
||||
public boolean move(@Parameter("direction") @Nullable final MovementDirection direction) {
|
||||
if (direction == null) throw new IllegalArgumentException();
|
||||
return commandProcessor.move(direction);
|
||||
}
|
||||
|
||||
@Callback
|
||||
public boolean turn(@Parameter("direction") @Nullable final RotationDirection direction) {
|
||||
if (direction == null) throw new IllegalArgumentException();
|
||||
return commandProcessor.rotate(direction);
|
||||
}
|
||||
|
||||
@Callback
|
||||
public int getQueuedActionCount() {
|
||||
return commandProcessor.getQueuedActionCount();
|
||||
}
|
||||
|
||||
private RobotDevice() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@ import li.cil.oc2.common.util.NBTTagIds;
|
||||
import li.cil.oc2.common.util.NBTUtils;
|
||||
import net.minecraft.entity.MoverType;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
@@ -17,12 +14,11 @@ import net.minecraft.util.math.vector.Vector3d;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class RobotMovementAction extends AbstractRobotAction {
|
||||
public static final DataParameter<BlockPos> TARGET_POSITION = EntityDataManager.createKey(RobotEntity.class, DataSerializers.BLOCK_POS);
|
||||
public static final double TARGET_EPSILON = 0.0001;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private static final float MOVEMENT_SPEED = 0.5f / Constants.TICK_SECONDS; // In blocks per second.
|
||||
private static final float MOVEMENT_SPEED = 1f / Constants.TICK_SECONDS; // In blocks per second.
|
||||
|
||||
private static final String DIRECTION_TAG_NAME = "direction";
|
||||
private static final String START_TAG_NAME = "start";
|
||||
@@ -84,7 +80,7 @@ public final class RobotMovementAction extends AbstractRobotAction {
|
||||
target = getTargetPositionInBlock(targetPosition);
|
||||
}
|
||||
|
||||
robot.getDataManager().set(TARGET_POSITION, new BlockPos(target));
|
||||
robot.getDataManager().set(RobotEntity.TARGET_POSITION, new BlockPos(target));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,7 +95,7 @@ public final class RobotMovementAction extends AbstractRobotAction {
|
||||
if (didCollide && !robot.getEntityWorld().isRemote()) {
|
||||
if (start != null) {
|
||||
target = getTargetPositionInBlock(start);
|
||||
robot.getDataManager().set(TARGET_POSITION, start);
|
||||
robot.getDataManager().set(RobotEntity.TARGET_POSITION, start);
|
||||
|
||||
start = null;
|
||||
} else {
|
||||
|
||||
@@ -15,17 +15,17 @@ public final class RobotMovementActionType extends AbstractRobotActionType {
|
||||
|
||||
@Override
|
||||
public void registerData(final EntityDataManager dataManager) {
|
||||
dataManager.register(RobotMovementAction.TARGET_POSITION, BlockPos.ZERO);
|
||||
dataManager.register(RobotEntity.TARGET_POSITION, BlockPos.ZERO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeData(final RobotEntity robot) {
|
||||
robot.getDataManager().set(RobotMovementAction.TARGET_POSITION, robot.getPosition());
|
||||
robot.getDataManager().set(RobotEntity.TARGET_POSITION, robot.getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performClient(final RobotEntity robot) {
|
||||
final Vector3d target = RobotMovementAction.getTargetPositionInBlock(robot.getDataManager().get(RobotMovementAction.TARGET_POSITION));
|
||||
final Vector3d target = RobotMovementAction.getTargetPositionInBlock(robot.getDataManager().get(RobotEntity.TARGET_POSITION));
|
||||
if (robot.getPositionVec().squareDistanceTo(target) > RobotMovementAction.TARGET_EPSILON) {
|
||||
RobotMovementAction.moveTowards(robot, target);
|
||||
}
|
||||
|
||||
@@ -5,21 +5,17 @@ import li.cil.oc2.common.entity.RobotEntity;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
import li.cil.oc2.common.util.NBTUtils;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class RobotRotationAction extends AbstractRobotAction {
|
||||
public static final DataParameter<Direction> TARGET_DIRECTION = EntityDataManager.createKey(RobotEntity.class, DataSerializers.DIRECTION);
|
||||
public static final float TARGET_EPSILON = 0.0001f;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private static final float ROTATION_SPEED = 45f / Constants.TICK_SECONDS; // In degrees per second.
|
||||
private static final float ROTATION_SPEED = 90f / Constants.TICK_SECONDS; // In degrees per second.
|
||||
|
||||
private static final String DIRECTION_TAG_NAME = "direction";
|
||||
private static final String TARGET_TAG_NAME = "start";
|
||||
@@ -61,7 +57,7 @@ public final class RobotRotationAction extends AbstractRobotAction {
|
||||
}
|
||||
}
|
||||
|
||||
robot.getDataManager().set(TARGET_DIRECTION, target);
|
||||
robot.getDataManager().set(RobotEntity.TARGET_DIRECTION, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,17 +15,17 @@ public final class RobotRotationActionType extends AbstractRobotActionType {
|
||||
|
||||
@Override
|
||||
public void registerData(final EntityDataManager dataManager) {
|
||||
dataManager.register(RobotRotationAction.TARGET_DIRECTION, Direction.NORTH);
|
||||
dataManager.register(RobotEntity.TARGET_DIRECTION, Direction.NORTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeData(final RobotEntity robot) {
|
||||
robot.getDataManager().set(RobotRotationAction.TARGET_DIRECTION, robot.getHorizontalFacing());
|
||||
robot.getDataManager().set(RobotEntity.TARGET_DIRECTION, robot.getHorizontalFacing());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performClient(final RobotEntity robot) {
|
||||
final Direction target = robot.getDataManager().get(RobotRotationAction.TARGET_DIRECTION);
|
||||
final Direction target = robot.getDataManager().get(RobotEntity.TARGET_DIRECTION);
|
||||
if (MathHelper.degreesDifferenceAbs(robot.rotationYaw, target.getHorizontalAngle()) > RobotRotationAction.TARGET_EPSILON) {
|
||||
RobotRotationAction.rotateTowards(robot, target);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import li.cil.oc2.common.Constants;
|
||||
import li.cil.oc2.common.bus.device.data.BaseBlockDevices;
|
||||
import li.cil.oc2.common.bus.device.data.Firmwares;
|
||||
import li.cil.oc2.common.util.ItemStackUtils;
|
||||
import li.cil.oc2.common.vm.CommonVirtualMachineItemStackHandlers;
|
||||
import li.cil.oc2.common.vm.AbstractVirtualMachineItemStackHandlers;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.NonNullList;
|
||||
@@ -46,18 +46,18 @@ public final class ItemGroup {
|
||||
final ItemStack computer = new ItemStack(Items.COMPUTER_ITEM.get());
|
||||
|
||||
final CompoundNBT computerItems = ItemStackUtils.getOrCreateTileEntityInventoryTag(computer);
|
||||
computerItems.put(CommonVirtualMachineItemStackHandlers.MEMORY_TAG_NAME, makeInventoryTag(
|
||||
computerItems.put(AbstractVirtualMachineItemStackHandlers.MEMORY_TAG_NAME, makeInventoryTag(
|
||||
MemoryItem.withCapacity(8 * Constants.MEGABYTE),
|
||||
MemoryItem.withCapacity(8 * Constants.MEGABYTE),
|
||||
MemoryItem.withCapacity(8 * Constants.MEGABYTE)
|
||||
));
|
||||
computerItems.put(CommonVirtualMachineItemStackHandlers.HARD_DRIVE_TAG_NAME, makeInventoryTag(
|
||||
computerItems.put(AbstractVirtualMachineItemStackHandlers.HARD_DRIVE_TAG_NAME, makeInventoryTag(
|
||||
HardDriveItem.withBase(BaseBlockDevices.BUILDROOT.get())
|
||||
));
|
||||
computerItems.put(CommonVirtualMachineItemStackHandlers.FLASH_MEMORY_TAG_NAME, makeInventoryTag(
|
||||
computerItems.put(AbstractVirtualMachineItemStackHandlers.FLASH_MEMORY_TAG_NAME, makeInventoryTag(
|
||||
FlashMemoryItem.withFirmware(Firmwares.BUILDROOT.get())
|
||||
));
|
||||
computerItems.put(CommonVirtualMachineItemStackHandlers.CARD_TAG_NAME, makeInventoryTag(
|
||||
computerItems.put(AbstractVirtualMachineItemStackHandlers.CARD_TAG_NAME, makeInventoryTag(
|
||||
new ItemStack(Items.NETWORK_INTERFACE_CARD_ITEM.get())
|
||||
));
|
||||
|
||||
|
||||
@@ -81,11 +81,41 @@ public final class Network {
|
||||
.consumer(RobotTerminalInputMessage::handleMessage)
|
||||
.add();
|
||||
|
||||
INSTANCE.messageBuilder(RobotRunStateMessage.class, getNextPacketId(), NetworkDirection.PLAY_TO_CLIENT)
|
||||
.encoder(RobotRunStateMessage::toBytes)
|
||||
.decoder(RobotRunStateMessage::new)
|
||||
.consumer(RobotRunStateMessage::handleMessage)
|
||||
.add();
|
||||
|
||||
INSTANCE.messageBuilder(RobotBusStateMessage.class, getNextPacketId(), NetworkDirection.PLAY_TO_CLIENT)
|
||||
.encoder(RobotBusStateMessage::toBytes)
|
||||
.decoder(RobotBusStateMessage::new)
|
||||
.consumer(RobotBusStateMessage::handleMessage)
|
||||
.add();
|
||||
|
||||
INSTANCE.messageBuilder(RobotBootErrorMessage.class, getNextPacketId(), NetworkDirection.PLAY_TO_CLIENT)
|
||||
.encoder(RobotBootErrorMessage::toBytes)
|
||||
.decoder(RobotBootErrorMessage::new)
|
||||
.consumer(RobotBootErrorMessage::handleMessage)
|
||||
.add();
|
||||
|
||||
INSTANCE.messageBuilder(RobotPowerMessage.class, getNextPacketId(), NetworkDirection.PLAY_TO_SERVER)
|
||||
.encoder(RobotPowerMessage::toBytes)
|
||||
.decoder(RobotPowerMessage::new)
|
||||
.consumer(RobotPowerMessage::handleMessage)
|
||||
.add();
|
||||
|
||||
INSTANCE.messageBuilder(RobotInitializationRequestMessage.class, getNextPacketId(), NetworkDirection.PLAY_TO_SERVER)
|
||||
.encoder(RobotInitializationRequestMessage::toBytes)
|
||||
.decoder(RobotInitializationRequestMessage::new)
|
||||
.consumer(RobotInitializationRequestMessage::handleMessage)
|
||||
.add();
|
||||
|
||||
INSTANCE.messageBuilder(RobotInitializationMessage.class, getNextPacketId(), NetworkDirection.PLAY_TO_CLIENT)
|
||||
.encoder(RobotInitializationMessage::toBytes)
|
||||
.decoder(RobotInitializationMessage::new)
|
||||
.consumer(RobotInitializationMessage::handleMessage)
|
||||
.add();
|
||||
}
|
||||
|
||||
public static <T> void sendToClientsTrackingChunk(final T message, final Chunk chunk) {
|
||||
|
||||
@@ -11,13 +11,13 @@ import java.util.function.Supplier;
|
||||
|
||||
public final class ComputerBusStateMessage {
|
||||
private BlockPos pos;
|
||||
private AbstractDeviceBusController.BusState busState;
|
||||
private AbstractDeviceBusController.BusState value;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public ComputerBusStateMessage(final ComputerTileEntity tileEntity) {
|
||||
this.pos = tileEntity.getPos();
|
||||
this.busState = tileEntity.getState().getBusState();
|
||||
this.value = tileEntity.getState().getBusState();
|
||||
}
|
||||
|
||||
public ComputerBusStateMessage(final PacketBuffer buffer) {
|
||||
@@ -28,17 +28,17 @@ public final class ComputerBusStateMessage {
|
||||
|
||||
public static boolean handleMessage(final ComputerBusStateMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withClientTileEntityAt(message.pos, ComputerTileEntity.class,
|
||||
(tileEntity) -> tileEntity.getState().setBusStateClient(message.busState)));
|
||||
(tileEntity) -> tileEntity.getState().setBusStateClient(message.value)));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void fromBytes(final PacketBuffer buffer) {
|
||||
pos = buffer.readBlockPos();
|
||||
busState = buffer.readEnumValue(AbstractDeviceBusController.BusState.class);
|
||||
value = buffer.readEnumValue(AbstractDeviceBusController.BusState.class);
|
||||
}
|
||||
|
||||
public static void toBytes(final ComputerBusStateMessage message, final PacketBuffer buffer) {
|
||||
buffer.writeBlockPos(message.pos);
|
||||
buffer.writeEnumValue(message.busState);
|
||||
buffer.writeEnumValue(message.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ import java.util.function.Supplier;
|
||||
|
||||
public final class ComputerRunStateMessage {
|
||||
private BlockPos pos;
|
||||
private VirtualMachineState.RunState runState;
|
||||
private VirtualMachineState.RunState value;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public ComputerRunStateMessage(final ComputerTileEntity tileEntity) {
|
||||
this.pos = tileEntity.getPos();
|
||||
this.runState = tileEntity.getState().getRunState();
|
||||
this.value = tileEntity.getState().getRunState();
|
||||
}
|
||||
|
||||
public ComputerRunStateMessage(final PacketBuffer buffer) {
|
||||
@@ -28,17 +28,17 @@ public final class ComputerRunStateMessage {
|
||||
|
||||
public static boolean handleMessage(final ComputerRunStateMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withClientTileEntityAt(message.pos, ComputerTileEntity.class,
|
||||
(tileEntity) -> tileEntity.getState().setRunStateClient(message.runState)));
|
||||
(tileEntity) -> tileEntity.getState().setRunStateClient(message.value)));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void fromBytes(final PacketBuffer buffer) {
|
||||
pos = buffer.readBlockPos();
|
||||
runState = buffer.readEnumValue(VirtualMachineState.RunState.class);
|
||||
value = buffer.readEnumValue(VirtualMachineState.RunState.class);
|
||||
}
|
||||
|
||||
public static void toBytes(final ComputerRunStateMessage message, final PacketBuffer buffer) {
|
||||
buffer.writeBlockPos(message.pos);
|
||||
buffer.writeEnumValue(message.runState);
|
||||
buffer.writeEnumValue(message.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package li.cil.oc2.common.network.message;
|
||||
|
||||
import li.cil.oc2.common.bus.AbstractDeviceBusController;
|
||||
import li.cil.oc2.common.entity.RobotEntity;
|
||||
import li.cil.oc2.common.network.MessageUtils;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class RobotBusStateMessage {
|
||||
private int entityId;
|
||||
private AbstractDeviceBusController.BusState value;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public RobotBusStateMessage(final RobotEntity robot) {
|
||||
this.entityId = robot.getEntityId();
|
||||
this.value = robot.getState().getBusState();
|
||||
}
|
||||
|
||||
public RobotBusStateMessage(final PacketBuffer buffer) {
|
||||
fromBytes(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static boolean handleMessage(final RobotBusStateMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withClientEntity(message.entityId, RobotEntity.class,
|
||||
(robot) -> robot.getState().setBusStateClient(message.value)));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void fromBytes(final PacketBuffer buffer) {
|
||||
entityId = buffer.readVarInt();
|
||||
value = buffer.readEnumValue(AbstractDeviceBusController.BusState.class);
|
||||
}
|
||||
|
||||
public static void toBytes(final RobotBusStateMessage message, final PacketBuffer buffer) {
|
||||
buffer.writeVarInt(message.entityId);
|
||||
buffer.writeEnumValue(message.value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package li.cil.oc2.common.network.message;
|
||||
|
||||
import li.cil.oc2.common.bus.AbstractDeviceBusController;
|
||||
import li.cil.oc2.common.entity.RobotEntity;
|
||||
import li.cil.oc2.common.network.MessageUtils;
|
||||
import li.cil.oc2.common.serialization.NBTSerialization;
|
||||
import li.cil.oc2.common.vm.VirtualMachineState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class RobotInitializationMessage {
|
||||
private int entityId;
|
||||
private AbstractDeviceBusController.BusState busState;
|
||||
private VirtualMachineState.RunState runState;
|
||||
private ITextComponent bootError;
|
||||
private CompoundNBT terminal;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public RobotInitializationMessage(final RobotEntity robot) {
|
||||
this.entityId = robot.getEntityId();
|
||||
this.busState = robot.getState().getBusState();
|
||||
this.runState = robot.getState().getRunState();
|
||||
this.bootError = robot.getState().getBootError();
|
||||
this.terminal = NBTSerialization.serialize(robot.getTerminal());
|
||||
}
|
||||
|
||||
public RobotInitializationMessage(final PacketBuffer buffer) {
|
||||
fromBytes(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static boolean handleMessage(final RobotInitializationMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withClientEntity(message.entityId, RobotEntity.class,
|
||||
(robot) -> {
|
||||
robot.getState().setBusStateClient(message.busState);
|
||||
robot.getState().setRunStateClient(message.runState);
|
||||
robot.getState().setBootErrorClient(message.bootError);
|
||||
NBTSerialization.deserialize(message.terminal, robot.getTerminal());
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void fromBytes(final PacketBuffer buffer) {
|
||||
entityId = buffer.readVarInt();
|
||||
busState = buffer.readEnumValue(AbstractDeviceBusController.BusState.class);
|
||||
runState = buffer.readEnumValue(VirtualMachineState.RunState.class);
|
||||
bootError = buffer.readTextComponent();
|
||||
terminal = buffer.readCompoundTag();
|
||||
}
|
||||
|
||||
public static void toBytes(final RobotInitializationMessage message, final PacketBuffer buffer) {
|
||||
buffer.writeVarInt(message.entityId);
|
||||
buffer.writeEnumValue(message.busState);
|
||||
buffer.writeEnumValue(message.runState);
|
||||
buffer.writeTextComponent(message.bootError);
|
||||
buffer.writeCompoundTag(message.terminal);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package li.cil.oc2.common.network.message;
|
||||
|
||||
import li.cil.oc2.common.entity.RobotEntity;
|
||||
import li.cil.oc2.common.network.MessageUtils;
|
||||
import li.cil.oc2.common.network.Network;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class RobotInitializationRequestMessage {
|
||||
private int entityId;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public RobotInitializationRequestMessage(final RobotEntity robot) {
|
||||
this.entityId = robot.getEntityId();
|
||||
}
|
||||
|
||||
public RobotInitializationRequestMessage(final PacketBuffer buffer) {
|
||||
fromBytes(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static boolean handleMessage(final RobotInitializationRequestMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withServerEntity(context, message.entityId, RobotEntity.class,
|
||||
(robot) -> Network.INSTANCE.reply(new RobotInitializationMessage(robot), context.get())));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void fromBytes(final PacketBuffer buffer) {
|
||||
entityId = buffer.readVarInt();
|
||||
}
|
||||
|
||||
public static void toBytes(final RobotInitializationRequestMessage message, final PacketBuffer buffer) {
|
||||
buffer.writeVarInt(message.entityId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package li.cil.oc2.common.network.message;
|
||||
|
||||
import li.cil.oc2.common.entity.RobotEntity;
|
||||
import li.cil.oc2.common.network.MessageUtils;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class RobotPowerMessage {
|
||||
private int entityId;
|
||||
private boolean power;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public RobotPowerMessage(final RobotEntity robot, final boolean power) {
|
||||
this.entityId = robot.getEntityId();
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
public RobotPowerMessage(final PacketBuffer buffer) {
|
||||
fromBytes(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static boolean handleMessage(final RobotPowerMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withServerEntity(context, message.entityId, RobotEntity.class,
|
||||
(robot) -> {
|
||||
final ServerPlayerEntity player = context.get().getSender();
|
||||
if (player != null && robot.isEntityInRange(player, 8)) {
|
||||
if (message.power) {
|
||||
robot.start();
|
||||
} else {
|
||||
robot.stop();
|
||||
}
|
||||
}
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void fromBytes(final PacketBuffer buffer) {
|
||||
entityId = buffer.readVarInt();
|
||||
power = buffer.readBoolean();
|
||||
}
|
||||
|
||||
public static void toBytes(final RobotPowerMessage message, final PacketBuffer buffer) {
|
||||
buffer.writeVarInt(message.entityId);
|
||||
buffer.writeBoolean(message.power);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package li.cil.oc2.common.network.message;
|
||||
|
||||
import li.cil.oc2.common.entity.RobotEntity;
|
||||
import li.cil.oc2.common.network.MessageUtils;
|
||||
import li.cil.oc2.common.vm.VirtualMachineState;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class RobotRunStateMessage {
|
||||
private int entityId;
|
||||
private VirtualMachineState.RunState value;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public RobotRunStateMessage(final RobotEntity robot) {
|
||||
this.entityId = robot.getEntityId();
|
||||
this.value = robot.getState().getRunState();
|
||||
}
|
||||
|
||||
public RobotRunStateMessage(final PacketBuffer buffer) {
|
||||
fromBytes(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static boolean handleMessage(final RobotRunStateMessage message, final Supplier<NetworkEvent.Context> context) {
|
||||
context.get().enqueueWork(() -> MessageUtils.withClientEntity(message.entityId, RobotEntity.class,
|
||||
(robot) -> robot.getState().setRunStateClient(message.value)));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void fromBytes(final PacketBuffer buffer) {
|
||||
entityId = buffer.readVarInt();
|
||||
value = buffer.readEnumValue(VirtualMachineState.RunState.class);
|
||||
}
|
||||
|
||||
public static void toBytes(final RobotRunStateMessage message, final PacketBuffer buffer) {
|
||||
buffer.writeVarInt(message.entityId);
|
||||
buffer.writeEnumValue(message.value);
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
return state;
|
||||
}
|
||||
|
||||
public CommonVirtualMachineItemStackHandlers getItemHandlers() {
|
||||
public VirtualMachineItemStackHandlers getItemStackHandlers() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -162,7 +162,8 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
super.remove();
|
||||
|
||||
// Unload only suspends, but we want to do a full clean-up when we get
|
||||
// destroyed, so stuff inside us can delete out-of-nbt persisted data.
|
||||
// destroyed, so stuff inside us can delete out-of-nbt persisted runtime-
|
||||
// only data such as ram.
|
||||
state.virtualMachine.vmAdapter.unload();
|
||||
}
|
||||
|
||||
@@ -259,7 +260,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final class ComputerItemStackHandlers extends CommonVirtualMachineItemStackHandlers {
|
||||
private final class ComputerItemStackHandlers extends AbstractVirtualMachineItemStackHandlers {
|
||||
public ComputerItemStackHandlers() {
|
||||
super(MEMORY_SLOTS, HARD_DRIVE_SLOTS, FLASH_MEMORY_SLOTS, CARD_SLOTS);
|
||||
}
|
||||
@@ -364,8 +365,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
|
||||
@Override
|
||||
protected void handleBusStateChanged(final AbstractDeviceBusController.BusState value) {
|
||||
final ComputerBusStateMessage message = new ComputerBusStateMessage(ComputerTileEntity.this);
|
||||
Network.sendToClientsTrackingChunk(message, chunk);
|
||||
Network.sendToClientsTrackingChunk(new ComputerBusStateMessage(ComputerTileEntity.this), chunk);
|
||||
|
||||
if (value == AbstractDeviceBusController.BusState.READY) {
|
||||
// Bus just became ready, meaning new devices may be available, meaning new
|
||||
@@ -379,15 +379,13 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
// This method can be called from disposal logic, so if we are disposed quickly enough
|
||||
// chunk may not be initialized yet. Avoid resulting NRE in network logic.
|
||||
if (chunk != null) {
|
||||
final ComputerRunStateMessage message = new ComputerRunStateMessage(ComputerTileEntity.this);
|
||||
Network.sendToClientsTrackingChunk(message, chunk);
|
||||
Network.sendToClientsTrackingChunk(new ComputerRunStateMessage(ComputerTileEntity.this), chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleBootErrorChanged(@Nullable final ITextComponent value) {
|
||||
final ComputerBootErrorMessage message = new ComputerBootErrorMessage(ComputerTileEntity.this);
|
||||
Network.sendToClientsTrackingChunk(message, chunk);
|
||||
Network.sendToClientsTrackingChunk(new ComputerBootErrorMessage(ComputerTileEntity.this), chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class CommonVirtualMachineItemStackHandlers {
|
||||
public abstract class AbstractVirtualMachineItemStackHandlers implements VirtualMachineItemStackHandlers {
|
||||
private static final long ITEM_DEVICE_BASE_ADDRESS = 0x40000000L;
|
||||
private static final int ITEM_DEVICE_STRIDE = 0x1000;
|
||||
|
||||
@@ -52,10 +52,10 @@ public abstract class CommonVirtualMachineItemStackHandlers {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public CommonVirtualMachineItemStackHandlers(final int memorySlots,
|
||||
final int hardDriveSlots,
|
||||
final int flashMemorySlots,
|
||||
final int cardSlots) {
|
||||
public AbstractVirtualMachineItemStackHandlers(final int memorySlots,
|
||||
final int hardDriveSlots,
|
||||
final int flashMemorySlots,
|
||||
final int cardSlots) {
|
||||
memoryItemHandler = new ItemHandler(memorySlots, this::getDevices, DeviceTypes.MEMORY);
|
||||
hardDriveItemHandler = new ItemHandler(hardDriveSlots, this::getDevices, DeviceTypes.HARD_DRIVE);
|
||||
flashMemoryItemHandler = new ItemHandler(flashMemorySlots, this::getDevices, DeviceTypes.FLASH_MEMORY);
|
||||
@@ -66,6 +66,7 @@ public abstract class CommonVirtualMachineItemStackHandlers {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public Optional<IItemHandler> getItemHandler(final DeviceType deviceType) {
|
||||
if (deviceType == DeviceTypes.MEMORY) {
|
||||
return Optional.of(memoryItemHandler);
|
||||
@@ -79,6 +80,7 @@ public abstract class CommonVirtualMachineItemStackHandlers {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for (int slot = 0; slot < itemHandlers.getSlots(); slot++) {
|
||||
if (!itemHandlers.getStackInSlot(slot).isEmpty()) {
|
||||
@@ -116,6 +118,7 @@ public abstract class CommonVirtualMachineItemStackHandlers {
|
||||
return OptionalLong.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportDeviceDataToItemStacks() {
|
||||
memoryItemHandler.exportDeviceDataToItemStacks();
|
||||
hardDriveItemHandler.exportDeviceDataToItemStacks();
|
||||
@@ -166,7 +169,7 @@ public abstract class CommonVirtualMachineItemStackHandlers {
|
||||
@Override
|
||||
protected void onContentsChanged(final int slot) {
|
||||
super.onContentsChanged(slot);
|
||||
CommonVirtualMachineItemStackHandlers.this.onContentsChanged(this, slot);
|
||||
AbstractVirtualMachineItemStackHandlers.this.onContentsChanged(this, slot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package li.cil.oc2.common.vm;
|
||||
|
||||
import li.cil.oc2.api.bus.device.DeviceType;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface VirtualMachineItemStackHandlers {
|
||||
Optional<IItemHandler> getItemHandler(DeviceType deviceType);
|
||||
|
||||
boolean isEmpty();
|
||||
|
||||
void exportDeviceDataToItemStacks();
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
"item.oc2.redstone_interface_card": "Redstone Interface Card",
|
||||
"item.oc2.network_interface_card": "Network Interface Card",
|
||||
|
||||
"entity.oc2.robot": "Robot",
|
||||
|
||||
"config.oc2.maxAllocatedMemory": "Maximum allocated memory",
|
||||
"config.oc2.maxMemorySize:": "Maximum memory device size",
|
||||
"config.oc2.maxHardDriveSize": "Maximum hard drive device size",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.9 KiB |
Reference in New Issue
Block a user