mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-08-29 00:32:18 +00:00
help
This commit is contained in:
parent
7b400fdcdd
commit
cb549d8f43
@ -80,10 +80,10 @@ public final class ComputerCraft implements ModInitializer {
|
||||
public static int httpMaxWebsockets = 4;
|
||||
|
||||
public static boolean enableCommandBlock = false;
|
||||
public static int emRange = 64;
|
||||
public static int emHighAltitudeRange = 384;
|
||||
public static int emRangeDuringStorm = 64;
|
||||
public static int emHighAltitudeRangeDuringStorm = 384;
|
||||
public static int modemRange = 64;
|
||||
public static int modemHighAltitudeRange = 384;
|
||||
public static int modemRangeDuringStorm = 64;
|
||||
public static int modemHighAltitudeRangeDuringStorm = 384;
|
||||
public static int maxNotesPerTick = 8;
|
||||
public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST;
|
||||
public static double monitorDistanceSq = 4096;
|
||||
@ -111,8 +111,8 @@ public final class ComputerCraft implements ModInitializer {
|
||||
public static int monitorHeight = 6;
|
||||
|
||||
public static final class TurtleUpgrades {
|
||||
public static TurtleModem wirelessemNormal;
|
||||
public static TurtleModem wirelessemAdvanced;
|
||||
public static TurtleModem wirelessModemNormal;
|
||||
public static TurtleModem wirelessModemAdvanced;
|
||||
public static TurtleSpeaker speaker;
|
||||
|
||||
public static TurtleCraftingTable craftingTable;
|
||||
@ -124,8 +124,8 @@ public final class ComputerCraft implements ModInitializer {
|
||||
}
|
||||
|
||||
public static final class PocketUpgrades {
|
||||
public static PocketModem wirelessemNormal;
|
||||
public static PocketModem wirelessemAdvanced;
|
||||
public static PocketModem wirelessModemNormal;
|
||||
public static PocketModem wirelessModemAdvanced;
|
||||
public static PocketSpeaker speaker;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ public interface IPeripheral
|
||||
* @return A string identifying the type of peripheral.
|
||||
*/
|
||||
@Nonnull
|
||||
String getType();
|
||||
String getType0();
|
||||
|
||||
/**
|
||||
* Is called when when a computer is attaching to the peripheral.
|
||||
|
@ -3,32 +3,38 @@
|
||||
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER;
|
||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||
import dan200.computercraft.client.gui.widgets.WidgetWrapper;
|
||||
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
||||
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
public final class GuiComputer<T extends ScreenHandler & IContainerComputer> extends HandledScreen<T> {
|
||||
|
||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER;
|
||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
|
||||
|
||||
public final class GuiComputer<T extends ContainerComputerBase> extends HandledScreen<T>
|
||||
{
|
||||
private final ComputerFamily family;
|
||||
private final ClientComputer computer;
|
||||
private final int termWidth;
|
||||
@ -37,123 +43,102 @@ public final class GuiComputer<T extends ContainerComputerBase> extends HandledS
|
||||
private WidgetTerminal terminal;
|
||||
private WidgetWrapper terminalWrapper;
|
||||
|
||||
private GuiComputer(
|
||||
T container, PlayerInventory player, Text title, int termWidth, int termHeight
|
||||
)
|
||||
{
|
||||
super( container, player, title );
|
||||
family = container.getFamily();
|
||||
computer = (ClientComputer) container.getComputer();
|
||||
public GuiComputer(T container, PlayerInventory player, ComputerFamily family, ClientComputer computer, int termWidth, int termHeight) {
|
||||
super(container, player, new LiteralText(""));
|
||||
this.family = family;
|
||||
this.computer = computer;
|
||||
this.termWidth = termWidth;
|
||||
this.termHeight = termHeight;
|
||||
terminal = null;
|
||||
this.terminal = null;
|
||||
}
|
||||
|
||||
public static GuiComputer<ContainerComputer> create( ContainerComputer container, PlayerInventory inventory, Text component )
|
||||
{
|
||||
return new GuiComputer<>(
|
||||
container, inventory, component,
|
||||
ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight
|
||||
);
|
||||
private GuiComputer(T container, PlayerInventory player, ComputerFamily family, Text title, int termWidth, int termHeight) {
|
||||
super(container, player, title);
|
||||
this.family = family;
|
||||
this.computer = (ClientComputer) container.getComputer();
|
||||
this.termWidth = termWidth;
|
||||
this.termHeight = termHeight;
|
||||
this.terminal = null;
|
||||
}
|
||||
|
||||
public static GuiComputer<ContainerPocketComputer> createPocket( ContainerPocketComputer container, PlayerInventory inventory, Text component )
|
||||
{
|
||||
return new GuiComputer<>(
|
||||
container, inventory, component,
|
||||
ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight
|
||||
);
|
||||
|
||||
public static GuiComputer<ContainerComputer> create(int id, TileComputer computer, PlayerInventory player) {
|
||||
return create(new ContainerComputer(id, computer), player, computer.getDisplayName());
|
||||
}
|
||||
|
||||
public static GuiComputer<ContainerViewComputer> createView( ContainerViewComputer container, PlayerInventory inventory, Text component )
|
||||
{
|
||||
return new GuiComputer<>(
|
||||
container, inventory, component,
|
||||
container.getWidth(), container.getHeight()
|
||||
);
|
||||
public static GuiComputer<ContainerComputer> create(ContainerComputer container, PlayerInventory inventory, Text component) {
|
||||
return new GuiComputer<>(container, inventory, container.getFamily(), component, ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void init()
|
||||
{
|
||||
client.keyboard.setRepeatEvents( true );
|
||||
protected void init() {
|
||||
this.client.keyboard.setRepeatEvents(true);
|
||||
|
||||
int termPxWidth = termWidth * FixedWidthFontRenderer.FONT_WIDTH;
|
||||
int termPxHeight = termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
int termPxWidth = this.termWidth * FixedWidthFontRenderer.FONT_WIDTH;
|
||||
int termPxHeight = this.termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
|
||||
|
||||
backgroundWidth = termPxWidth + MARGIN * 2 + BORDER * 2;
|
||||
backgroundHeight = termPxHeight + MARGIN * 2 + BORDER * 2;
|
||||
this.backgroundWidth = termPxWidth + MARGIN * 2 + BORDER * 2;
|
||||
this.backgroundHeight = termPxHeight + MARGIN * 2 + BORDER * 2;
|
||||
|
||||
super.init();
|
||||
|
||||
terminal = new WidgetTerminal( client, () -> computer, termWidth, termHeight, MARGIN, MARGIN, MARGIN, MARGIN );
|
||||
terminalWrapper = new WidgetWrapper( terminal, MARGIN + BORDER + x, MARGIN + BORDER + y, termPxWidth, termPxHeight );
|
||||
this.terminal = new WidgetTerminal(this.client, () -> this.computer, this.termWidth, this.termHeight, MARGIN, MARGIN, MARGIN, MARGIN);
|
||||
this.terminalWrapper = new WidgetWrapper(this.terminal, MARGIN + BORDER + this.x, MARGIN + BORDER + this.y, termPxWidth, termPxHeight);
|
||||
|
||||
children.add( terminalWrapper );
|
||||
setFocused( terminalWrapper );
|
||||
this.children.add(this.terminalWrapper);
|
||||
this.setFocused(this.terminalWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed()
|
||||
{
|
||||
public void removed() {
|
||||
super.removed();
|
||||
children.remove( terminal );
|
||||
terminal = null;
|
||||
client.keyboard.setRepeatEvents( false );
|
||||
this.children.remove(this.terminal);
|
||||
this.terminal = null;
|
||||
this.client.keyboard.setRepeatEvents(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
public void tick() {
|
||||
super.tick();
|
||||
terminal.update();
|
||||
this.terminal.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed( int key, int scancode, int modifiers )
|
||||
{
|
||||
public boolean keyPressed(int key, int scancode, int modifiers) {
|
||||
// Forward the tab key to the terminal, rather than moving between controls.
|
||||
if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper )
|
||||
{
|
||||
return getFocused().keyPressed( key, scancode, modifiers );
|
||||
if (key == GLFW.GLFW_KEY_TAB && this.getFocused() != null && this.getFocused() == this.terminalWrapper) {
|
||||
return this.getFocused().keyPressed(key, scancode, modifiers);
|
||||
}
|
||||
|
||||
return super.keyPressed( key, scancode, modifiers );
|
||||
return super.keyPressed(key, scancode, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBackground( @Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY )
|
||||
{
|
||||
public void drawBackground(@Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY) {
|
||||
// Draw terminal
|
||||
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
|
||||
this.terminal.draw(this.terminalWrapper.getX(), this.terminalWrapper.getY());
|
||||
|
||||
// Draw a border around the terminal
|
||||
RenderSystem.color4f( 1, 1, 1, 1 );
|
||||
client.getTextureManager().bindTexture( ComputerBorderRenderer.getTexture( family ) );
|
||||
ComputerBorderRenderer.render(
|
||||
terminalWrapper.getX() - MARGIN, terminalWrapper.getY() - MARGIN, getZOffset(),
|
||||
terminalWrapper.getWidth() + MARGIN * 2, terminalWrapper.getHeight() + MARGIN * 2
|
||||
);
|
||||
RenderSystem.color4f(1, 1, 1, 1);
|
||||
this.client.getTextureManager()
|
||||
.bindTexture(ComputerBorderRenderer.getTexture(this.family));
|
||||
ComputerBorderRenderer.render(this.terminalWrapper.getX() - MARGIN, this.terminalWrapper.getY() - MARGIN,
|
||||
this.getZOffset(), this.terminalWrapper.getWidth() + MARGIN * 2, this.terminalWrapper.getHeight() + MARGIN * 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks )
|
||||
{
|
||||
super.render( stack, mouseX, mouseY, partialTicks );
|
||||
drawMouseoverTooltip( stack, mouseX, mouseY );
|
||||
public void render(@Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks) {
|
||||
super.render(stack, mouseX, mouseY, partialTicks);
|
||||
this.drawMouseoverTooltip(stack, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
|
||||
{
|
||||
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|
||||
|| super.mouseDragged( x, y, button, deltaX, deltaY );
|
||||
public boolean mouseDragged(double x, double y, int button, double deltaX, double deltaY) {
|
||||
return (this.getFocused() != null && this.getFocused().mouseDragged(x, y, button, deltaX, deltaY)) || super.mouseDragged(x, y, button, deltaX, deltaY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawForeground( @Nonnull MatrixStack transform, int mouseX, int mouseY )
|
||||
{
|
||||
protected void drawForeground(@Nonnull MatrixStack transform, int mouseX, int mouseY) {
|
||||
// Skip rendering labels.
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import dan200.computercraft.shared.Registry;
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
@ -18,9 +19,9 @@ public class GuiDiskDrive extends HandledScreen<ContainerDiskDrive>
|
||||
{
|
||||
private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/disk_drive.png" );
|
||||
|
||||
public GuiDiskDrive( ContainerDiskDrive container, PlayerInventory player, Text title )
|
||||
public GuiDiskDrive( ContainerDiskDrive container, PlayerInventory player)
|
||||
{
|
||||
super( container, player, title );
|
||||
super(container, player, Registry.ModBlocks.DISK_DRIVE.getName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class GuiPocketComputer extends GuiComputer<ContainerPocketComputer>
|
||||
{
|
||||
public GuiPocketComputer( ContainerPocketComputer container, PlayerInventory player )
|
||||
{
|
||||
super(
|
||||
container, player,
|
||||
getFamily( container.getStack() ),
|
||||
ItemPocketComputer.createClientComputer( container.getStack() ),
|
||||
ComputerCraft.terminalWidth_pocketComputer,
|
||||
ComputerCraft.terminalHeight_pocketComputer
|
||||
);
|
||||
}
|
||||
|
||||
private static ComputerFamily getFamily( ItemStack stack )
|
||||
{
|
||||
Item item = stack.getItem();
|
||||
return item instanceof ItemPocketComputer ? ((ItemPocketComputer) item).getFamily() : ComputerFamily.NORMAL;
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
package dan200.computercraft.client.gui;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import dan200.computercraft.shared.Registry;
|
||||
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
@ -18,9 +19,9 @@ public class GuiPrinter extends HandledScreen<ContainerPrinter>
|
||||
{
|
||||
private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/printer.png" );
|
||||
|
||||
public GuiPrinter( ContainerPrinter container, PlayerInventory player, Text title )
|
||||
public GuiPrinter( ContainerPrinter container, PlayerInventory player)
|
||||
{
|
||||
super( container, player, title );
|
||||
super(container, player, Registry.ModBlocks.PRINTER.getName());
|
||||
}
|
||||
|
||||
/*@Override
|
||||
|
@ -30,9 +30,9 @@ public class GuiPrintout extends HandledScreen<ContainerHeldItem>
|
||||
private final TextBuffer[] m_colours;
|
||||
private int m_page;
|
||||
|
||||
public GuiPrintout( ContainerHeldItem container, PlayerInventory player, Text title )
|
||||
public GuiPrintout( ContainerHeldItem container, PlayerInventory player )
|
||||
{
|
||||
super( container, player, title );
|
||||
super( container, player, container.getStack().getName() );
|
||||
|
||||
backgroundHeight = Y_SIZE;
|
||||
|
||||
|
@ -11,6 +11,7 @@ import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||
import dan200.computercraft.client.gui.widgets.WidgetWrapper;
|
||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
@ -34,12 +35,12 @@ public class GuiTurtle extends HandledScreen<ContainerTurtle>
|
||||
private WidgetTerminal terminal;
|
||||
private WidgetWrapper terminalWrapper;
|
||||
|
||||
public GuiTurtle( ContainerTurtle container, PlayerInventory player, Text title )
|
||||
public GuiTurtle(TileTurtle turtle, ContainerTurtle container, PlayerInventory player )
|
||||
{
|
||||
super( container, player, title );
|
||||
super( container, player, turtle.getDisplayName() );
|
||||
|
||||
m_container = container;
|
||||
m_family = container.getFamily();
|
||||
m_family = turtle.getFamily();
|
||||
m_computer = (ClientComputer) container.getComputer();
|
||||
|
||||
backgroundWidth = 254;
|
||||
@ -114,8 +115,8 @@ public class GuiTurtle extends HandledScreen<ContainerTurtle>
|
||||
int slotX = slot % 4;
|
||||
int slotY = slot / 4;
|
||||
drawTexture( transform,
|
||||
x + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18,
|
||||
y + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18,
|
||||
x + m_container.m_turtleInvStartX - 2 + slotX * 18,
|
||||
y + m_container.m_playerInvStartY - 2 + slotY * 18,
|
||||
0, 217, 24, 24
|
||||
);
|
||||
}
|
||||
|
@ -6,112 +6,83 @@
|
||||
|
||||
package dan200.computercraft.client.proxy;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.client.ClientRegistry;
|
||||
import dan200.computercraft.client.FrameInfo;
|
||||
import dan200.computercraft.client.gui.GuiComputer;
|
||||
import dan200.computercraft.client.gui.GuiDiskDrive;
|
||||
import dan200.computercraft.client.gui.GuiPocketComputer;
|
||||
import dan200.computercraft.client.gui.GuiPrinter;
|
||||
import dan200.computercraft.client.gui.GuiPrintout;
|
||||
import dan200.computercraft.client.gui.GuiTurtle;
|
||||
import dan200.computercraft.client.render.TileEntityMonitorRenderer;
|
||||
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
|
||||
import dan200.computercraft.client.render.TurtlePlayerRenderer;
|
||||
import dan200.computercraft.client.render.TurtleModelLoader;
|
||||
import dan200.computercraft.shared.Registry;
|
||||
import dan200.computercraft.shared.common.IColouredItem;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
||||
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
||||
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import dan200.computercraft.shared.network.container.ContainerType;
|
||||
import dan200.computercraft.shared.network.container.PocketComputerContainerType;
|
||||
import dan200.computercraft.shared.network.container.PrintoutContainerType;
|
||||
import dan200.computercraft.shared.network.container.TileEntityContainerType;
|
||||
import dan200.computercraft.shared.network.container.ViewComputerContainerType;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
||||
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreens;
|
||||
import net.minecraft.client.item.ModelPredicateProvider;
|
||||
import net.minecraft.client.item.ModelPredicateProviderRegistry;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.RenderLayers;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||
import net.minecraft.inventory.SimpleInventory;
|
||||
import net.minecraft.screen.ArrayPropertyDelegate;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
||||
import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry;
|
||||
import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback;
|
||||
import net.fabricmc.fabric.api.event.client.ClientTickCallback;
|
||||
|
||||
@SuppressWarnings ("MethodCallSideOnly")
|
||||
public final class ComputerCraftProxyClient implements ClientModInitializer {
|
||||
@SuppressWarnings ({
|
||||
"MethodCallSideOnly",
|
||||
"NewExpressionSideOnly"
|
||||
})
|
||||
public final class ComputerCraftProxyClient {
|
||||
public static void setup() {
|
||||
registerContainers();
|
||||
BlockEntityRendererRegistry.INSTANCE.register(Registry.ModTiles.MONITOR_NORMAL, TileEntityMonitorRenderer::new);
|
||||
BlockEntityRendererRegistry.INSTANCE.register(Registry.ModTiles.MONITOR_ADVANCED, TileEntityMonitorRenderer::new);
|
||||
BlockEntityRendererRegistry.INSTANCE.register(Registry.ModTiles.TURTLE_NORMAL, TileEntityTurtleRenderer::new);
|
||||
BlockEntityRendererRegistry.INSTANCE.register(Registry.ModTiles.TURTLE_ADVANCED, TileEntityTurtleRenderer::new);
|
||||
|
||||
@SafeVarargs
|
||||
private static void registerItemProperty(String name, ModelPredicateProvider getter, Supplier<? extends Item>... items) {
|
||||
Identifier id = new Identifier(ComputerCraft.MOD_ID, name);
|
||||
for (Supplier<? extends Item> item : items) {
|
||||
ModelPredicateProviderRegistry.register(item.get(), id, getter);
|
||||
}
|
||||
ClientSpriteRegistryCallback.event(SpriteAtlasTexture.BLOCK_ATLAS_TEX)
|
||||
.register(ClientRegistry::onTextureStitchEvent);
|
||||
ModelLoadingRegistry.INSTANCE.registerAppender(ClientRegistry::onModelBakeEvent);
|
||||
ModelLoadingRegistry.INSTANCE.registerResourceProvider(loader -> (name, context) -> TurtleModelLoader.INSTANCE.accepts(name) ?
|
||||
TurtleModelLoader.INSTANCE.loadModel(
|
||||
name) : null);
|
||||
|
||||
ClientTickCallback.EVENT.register(client -> FrameInfo.onTick());
|
||||
}
|
||||
|
||||
private static void registerContainers() {
|
||||
// My IDE doesn't think so, but we do actually need these generics.
|
||||
ContainerType.registerGui(TileEntityContainerType::computer,
|
||||
(id, packet, player) -> GuiComputer.create(id, (TileComputer) packet.getTileEntity(player), player.inventory));
|
||||
ContainerType.registerGui(TileEntityContainerType::diskDrive, GuiDiskDrive::new);
|
||||
ContainerType.registerGui(TileEntityContainerType::printer, GuiPrinter::new);
|
||||
ContainerType.registerGui(TileEntityContainerType::turtle, (id, packet, player) -> {
|
||||
TileTurtle turtle = (TileTurtle) packet.getTileEntity(player);
|
||||
return new GuiTurtle(turtle,
|
||||
new ContainerTurtle(id, player.inventory, new SimpleInventory(TileTurtle.INVENTORY_SIZE), new ArrayPropertyDelegate(1)),
|
||||
player.inventory);
|
||||
});
|
||||
|
||||
HandledScreens.<ContainerComputer, GuiComputer<ContainerComputer>>register(Registry.ModContainers.COMPUTER.get(), GuiComputer::create);
|
||||
HandledScreens.<ContainerPocketComputer, GuiComputer<ContainerPocketComputer>>register(Registry.ModContainers.POCKET_COMPUTER.get(),
|
||||
GuiComputer::createPocket);
|
||||
HandledScreens.register(Registry.ModContainers.TURTLE, GuiTurtle::new);
|
||||
|
||||
HandledScreens.register(Registry.ModContainers.PRINTER, GuiPrinter::new);
|
||||
HandledScreens.register(Registry.ModContainers.DISK_DRIVE, GuiDiskDrive::new);
|
||||
HandledScreens.register(Registry.ModContainers.PRINTOUT, GuiPrintout::new);
|
||||
|
||||
HandledScreens.<ContainerViewComputer, GuiComputer<ContainerViewComputer>>register(Registry.ModContainers.VIEW_COMPUTER.get(),
|
||||
GuiComputer::createView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
FrameInfo.init();
|
||||
registerContainers();
|
||||
|
||||
// While turtles themselves are not transparent, their upgrades may be.
|
||||
RenderLayers.setRenderLayer(Registry.ModBlocks.TURTLE_NORMAL.get(), RenderLayer.getTranslucent());
|
||||
RenderLayers.setRenderLayer(Registry.ModBlocks.TURTLE_ADVANCED.get(), RenderLayer.getTranslucent());
|
||||
|
||||
// Monitors' textures have transparent fronts and so count as cutouts.
|
||||
RenderLayers.setRenderLayer(Registry.ModBlocks.MONITOR_NORMAL.get(), RenderLayer.getCutout());
|
||||
RenderLayers.setRenderLayer(Registry.ModBlocks.MONITOR_ADVANCED.get(), RenderLayer.getCutout());
|
||||
|
||||
// Setup TESRs
|
||||
ClientRegistry.bindTileEntityRenderer(Registry.ModTiles.MONITOR_NORMAL.get(), TileEntityMonitorRenderer::new);
|
||||
ClientRegistry.bindTileEntityRenderer(Registry.ModTiles.MONITOR_ADVANCED.get(), TileEntityMonitorRenderer::new);
|
||||
ClientRegistry.bindTileEntityRenderer(Registry.ModTiles.TURTLE_NORMAL.get(), TileEntityTurtleRenderer::new);
|
||||
ClientRegistry.bindTileEntityRenderer(Registry.ModTiles.TURTLE_ADVANCED.get(), TileEntityTurtleRenderer::new);
|
||||
// TODO: ClientRegistry.bindTileEntityRenderer( TileCable.FACTORY, x -> new TileEntityCableRenderer() );
|
||||
|
||||
RenderingRegistry.registerEntityRenderingHandler(Registry.ModEntities.TURTLE_PLAYER.get(), TurtlePlayerRenderer::new);
|
||||
|
||||
registerItemProperty("state",
|
||||
(stack, world, player) -> ItemPocketComputer.getState(stack)
|
||||
.ordinal(),
|
||||
Registry.ModItems.POCKET_COMPUTER_NORMAL,
|
||||
Registry.ModItems.POCKET_COMPUTER_ADVANCED);
|
||||
registerItemProperty("state",
|
||||
(stack, world, player) -> IColouredItem.getColourBasic(stack) != -1 ? 1 : 0,
|
||||
Registry.ModItems.POCKET_COMPUTER_NORMAL,
|
||||
Registry.ModItems.POCKET_COMPUTER_ADVANCED);
|
||||
ClientRegistry.onItemColours();
|
||||
}
|
||||
|
||||
@Mod.EventBusSubscriber (modid = ComputerCraft.MOD_ID, value = Dist.CLIENT)
|
||||
public static final class ForgeHandlers {
|
||||
@SubscribeEvent
|
||||
public static void onWorldUnload(WorldEvent.Unload event) {
|
||||
if (event.getWorld()
|
||||
.isClient()) {
|
||||
ClientMonitor.destroyAll();
|
||||
ContainerType.registerGui(PocketComputerContainerType::new, GuiPocketComputer::new);
|
||||
ContainerType.registerGui(PrintoutContainerType::new, GuiPrintout::new);
|
||||
ContainerType.registerGui(ViewComputerContainerType::new, (id, packet, player) -> {
|
||||
ClientComputer computer = ComputerCraft.clientComputerRegistry.get(packet.instanceId);
|
||||
if (computer == null) {
|
||||
ComputerCraft.clientComputerRegistry.add(packet.instanceId, computer = new ClientComputer(packet.instanceId));
|
||||
}
|
||||
}
|
||||
ContainerViewComputer container = new ContainerViewComputer(id, computer);
|
||||
return new GuiComputer<>(container, player.inventory, packet.family, computer, packet.width, packet.height);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -36,8 +36,7 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
|
||||
|
||||
public static final TurtleModelLoader INSTANCE = new TurtleModelLoader();
|
||||
|
||||
private TurtleModelLoader()
|
||||
{
|
||||
private TurtleModelLoader() {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,6 +5,13 @@
|
||||
*/
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import dan200.computercraft.api.client.TransformedModel;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
@ -12,6 +19,8 @@ import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.shared.turtle.items.ItemTurtle;
|
||||
import dan200.computercraft.shared.util.Holiday;
|
||||
import dan200.computercraft.shared.util.HolidayUtil;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
@ -29,14 +38,12 @@ import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@SuppressWarnings ({
|
||||
"MethodCallSideOnly",
|
||||
"LocalVariableDeclarationSideOnly",
|
||||
"NewExpressionSideOnly"
|
||||
})
|
||||
public class TurtleSmartItemModel implements BakedModel
|
||||
{
|
||||
private static final AffineTransformation identity, flip;
|
||||
|
@ -46,7 +46,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
||||
this.peripheral = peripheral;
|
||||
attached = false;
|
||||
|
||||
type = Objects.requireNonNull( peripheral.getType(), "Peripheral type cannot be null" );
|
||||
type = Objects.requireNonNull(peripheral.getType0(), "Peripheral type cannot be null" );
|
||||
|
||||
methodMap = PeripheralAPI.getMethods( peripheral );
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package dan200.computercraft.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
|
||||
@Mixin (BlockEntityType.class)
|
||||
public interface BlockEntityTypeAccessor {
|
||||
@Invoker
|
||||
static <T extends BlockEntity> BlockEntityType<T> callCreate(String string, BlockEntityType.Builder<T> builder) { throw new UnsupportedOperationException(); }
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package dan200.computercraft.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
|
||||
@Mixin (ScreenHandlerType.class)
|
||||
public interface ScreenHandlerTypeAccessor {
|
||||
@Invoker
|
||||
static <T extends ScreenHandler> ScreenHandlerType<T> callRegister(String id, ScreenHandlerType.Factory<T> factory) { throw new UnsupportedOperationException(); }
|
||||
}
|
@ -3,71 +3,57 @@
|
||||
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.peripheral.IPeripheralProvider;
|
||||
import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
|
||||
import dan200.computercraft.shared.util.CapabilityUtil;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.common.util.NonNullConsumer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Objects;
|
||||
|
||||
import static dan200.computercraft.shared.Capabilities.CAPABILITY_PERIPHERAL;
|
||||
|
||||
public final class Peripherals
|
||||
{
|
||||
public final class Peripherals {
|
||||
private static final Collection<IPeripheralProvider> providers = new LinkedHashSet<>();
|
||||
|
||||
private Peripherals() {}
|
||||
|
||||
public static synchronized void register( @Nonnull IPeripheralProvider provider )
|
||||
{
|
||||
Objects.requireNonNull( provider, "provider cannot be null" );
|
||||
providers.add( provider );
|
||||
public static synchronized void register(@Nonnull IPeripheralProvider provider) {
|
||||
Objects.requireNonNull(provider, "provider cannot be null");
|
||||
providers.add(provider);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static IPeripheral getPeripheral( World world, BlockPos pos, Direction side, NonNullConsumer<LazyOptional<IPeripheral>> invalidate )
|
||||
{
|
||||
return World.method_24794( pos ) && !world.isClient ? getPeripheralAt( world, pos, side, invalidate ) : null;
|
||||
public static IPeripheral getPeripheral(World world, BlockPos pos, Direction side) {
|
||||
return World.method_24794(pos) && !world.isClient ? getPeripheralAt(world, pos, side) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static IPeripheral getPeripheralAt( World world, BlockPos pos, Direction side, NonNullConsumer<LazyOptional<IPeripheral>> invalidate )
|
||||
{
|
||||
BlockEntity block = world.getBlockEntity( pos );
|
||||
if( block != null )
|
||||
{
|
||||
LazyOptional<IPeripheral> peripheral = block.getCapability( CAPABILITY_PERIPHERAL, side );
|
||||
if( peripheral.isPresent() ) return CapabilityUtil.unwrap( peripheral, invalidate );
|
||||
}
|
||||
|
||||
private static IPeripheral getPeripheralAt(World world, BlockPos pos, Direction side) {
|
||||
// Try the handlers in order:
|
||||
for( IPeripheralProvider peripheralProvider : providers )
|
||||
{
|
||||
try
|
||||
{
|
||||
LazyOptional<IPeripheral> peripheral = peripheralProvider.getPeripheral( world, pos, side );
|
||||
if( peripheral.isPresent() ) return CapabilityUtil.unwrap( peripheral, invalidate );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
ComputerCraft.log.error( "Peripheral provider " + peripheralProvider + " errored.", e );
|
||||
for (IPeripheralProvider peripheralProvider : providers) {
|
||||
try {
|
||||
Optional<IPeripheral> peripheral = peripheralProvider.getPeripheral(world, pos, side);
|
||||
if (peripheral.isPresent()) {
|
||||
return peripheral.get();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ComputerCraft.log.error("Peripheral provider " + peripheralProvider + " errored.", e);
|
||||
}
|
||||
}
|
||||
|
||||
return CapabilityUtil.unwrap( GenericPeripheralProvider.getPeripheral( world, pos, side ), invalidate );
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ public final class CommandComputerCraft
|
||||
IPeripheral peripheral = computer.getPeripheral( side );
|
||||
if( peripheral != null )
|
||||
{
|
||||
table.row( header( "Peripheral " + side.getName() ), text( peripheral.getType() ) );
|
||||
table.row( header( "Peripheral " + side.getName() ), text( peripheral.getType0() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ public class ComputerPeripheral implements IPeripheral
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType()
|
||||
public String getType0()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
@ -3,21 +3,28 @@
|
||||
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.blocks;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.computer.ComputerSide;
|
||||
import dan200.computercraft.shared.BundledRedstone;
|
||||
import dan200.computercraft.shared.Peripherals;
|
||||
import dan200.computercraft.shared.common.TileGeneric;
|
||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.ComputerState;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import dan200.computercraft.shared.util.RedstoneUtil;
|
||||
import joptsimple.internal.Strings;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.RedstoneWireBlock;
|
||||
@ -39,14 +46,10 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class TileComputerBase extends TileGeneric implements IComputerTile, Tickable, Nameable, NamedScreenHandlerFactory
|
||||
{
|
||||
public abstract class TileComputerBase extends TileGeneric implements IComputerTile, Tickable, Nameable, NamedScreenHandlerFactory, IPeripheral {
|
||||
private static final String NBT_ID = "ComputerId";
|
||||
private static final String NBT_LABEL = "Label";
|
||||
private static final String NBT_INSTANCE = "InstanceId";
|
||||
private static final String NBT_ON = "On";
|
||||
|
||||
private int m_instanceID = -1;
|
||||
@ -58,71 +61,64 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
|
||||
private final ComputerFamily family;
|
||||
|
||||
public TileComputerBase( BlockEntityType<? extends TileGeneric> type, ComputerFamily family )
|
||||
{
|
||||
super( type );
|
||||
public TileComputerBase(BlockEntityType<? extends TileGeneric> type, ComputerFamily family) {
|
||||
super(type);
|
||||
this.family = family;
|
||||
}
|
||||
|
||||
protected void unload()
|
||||
{
|
||||
if( m_instanceID >= 0 )
|
||||
{
|
||||
if( !getWorld().isClient ) ComputerCraft.serverComputerRegistry.remove( m_instanceID );
|
||||
protected void unload() {
|
||||
if (m_instanceID >= 0) {
|
||||
if (!getWorld().isClient) {
|
||||
ComputerCraft.serverComputerRegistry.remove(m_instanceID);
|
||||
}
|
||||
m_instanceID = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void openGui(PlayerEntity entity);
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
public void destroy() {
|
||||
unload();
|
||||
for( Direction dir : DirectionUtil.FACINGS )
|
||||
{
|
||||
RedstoneUtil.propagateRedstoneOutput( getWorld(), getPos(), dir );
|
||||
for (Direction dir : DirectionUtil.FACINGS) {
|
||||
RedstoneUtil.propagateRedstoneOutput(getWorld(), getPos(), dir);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
/*@Override
|
||||
public void onChunkUnloaded()
|
||||
{
|
||||
unload();
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
@Override
|
||||
public void markRemoved()
|
||||
{
|
||||
public void markRemoved() {
|
||||
unload();
|
||||
super.markRemoved();
|
||||
}
|
||||
|
||||
protected boolean canNameWithTag( PlayerEntity player )
|
||||
{
|
||||
protected boolean canNameWithTag(PlayerEntity player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit )
|
||||
{
|
||||
ItemStack currentItem = player.getStackInHand( hand );
|
||||
if( !currentItem.isEmpty() && currentItem.getItem() == Items.NAME_TAG && canNameWithTag( player ) && currentItem.hasCustomName() )
|
||||
{
|
||||
public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
ItemStack currentItem = player.getStackInHand(hand);
|
||||
if (!currentItem.isEmpty() && currentItem.getItem() == Items.NAME_TAG && canNameWithTag(player) && currentItem.hasCustomName()) {
|
||||
// Label to rename computer
|
||||
if( !getWorld().isClient )
|
||||
{
|
||||
setLabel( currentItem.getName().getString() );
|
||||
currentItem.decrement( 1 );
|
||||
if (!getWorld().isClient) {
|
||||
setLabel(currentItem.getName()
|
||||
.getString());
|
||||
currentItem.decrement(1);
|
||||
}
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
else if( !player.isInSneakingPose() )
|
||||
{
|
||||
} else if (!player.isInSneakingPose()) {
|
||||
// Regular right click to activate computer
|
||||
if( !getWorld().isClient && isUsable( player, false ) )
|
||||
{
|
||||
if (!getWorld().isClient && isUsable(player, false)) {
|
||||
createServerComputer().turnOn();
|
||||
new ComputerContainerData( createServerComputer() ).open( player, this );
|
||||
openGui(player);
|
||||
}
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
@ -130,28 +126,25 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||
{
|
||||
updateInput( neighbour );
|
||||
public void onNeighbourChange(@Nonnull BlockPos neighbour) {
|
||||
updateInput(neighbour);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
||||
{
|
||||
updateInput( neighbour );
|
||||
public void onNeighbourTileEntityChange(@Nonnull BlockPos neighbour) {
|
||||
updateInput(neighbour);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if( !getWorld().isClient )
|
||||
{
|
||||
public void tick() {
|
||||
if (!getWorld().isClient) {
|
||||
ServerComputer computer = createServerComputer();
|
||||
if( computer == null ) return;
|
||||
if (computer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the computer isn't on and should be, then turn it on
|
||||
if( m_startOn || (m_fresh && m_on) )
|
||||
{
|
||||
if (m_startOn || (m_fresh && m_on)) {
|
||||
computer.turnOn();
|
||||
m_startOn = false;
|
||||
}
|
||||
@ -163,69 +156,74 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
label = computer.getLabel();
|
||||
m_on = computer.isOn();
|
||||
|
||||
if( computer.hasOutputChanged() ) updateOutput();
|
||||
if (computer.hasOutputChanged()) {
|
||||
updateOutput();
|
||||
}
|
||||
|
||||
// Update the block state if needed. We don't fire a block update intentionally,
|
||||
// as this only really is needed on the client side.
|
||||
updateBlockState( computer.getState() );
|
||||
updateBlockState(computer.getState());
|
||||
|
||||
if( computer.hasOutputChanged() ) updateOutput();
|
||||
if (computer.hasOutputChanged()) {
|
||||
updateOutput();
|
||||
}
|
||||
}
|
||||
/* else todo is needed?
|
||||
{
|
||||
ClientComputer computer = createClientComputer();
|
||||
if( computer != null && computer.hasOutputChanged() ) updateBlock();
|
||||
}*/
|
||||
}
|
||||
|
||||
protected abstract void updateBlockState( ComputerState newState );
|
||||
protected abstract void updateBlockState(ComputerState newState);
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public CompoundTag toTag( @Nonnull CompoundTag nbt )
|
||||
{
|
||||
public CompoundTag toTag(@Nonnull CompoundTag nbt) {
|
||||
// Save ID, label and power state
|
||||
if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID );
|
||||
if( label != null ) nbt.putString( NBT_LABEL, label );
|
||||
nbt.putBoolean( NBT_ON, m_on );
|
||||
if (m_computerID >= 0) {
|
||||
nbt.putInt(NBT_ID, m_computerID);
|
||||
}
|
||||
if (label != null) {
|
||||
nbt.putString(NBT_LABEL, label);
|
||||
}
|
||||
nbt.putBoolean(NBT_ON, m_on);
|
||||
|
||||
return super.toTag( nbt );
|
||||
return super.toTag(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt )
|
||||
{
|
||||
super.fromTag( state, nbt );
|
||||
public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) {
|
||||
super.fromTag(state, nbt);
|
||||
|
||||
// Load ID, label and power state
|
||||
m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
|
||||
label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
|
||||
m_on = m_startOn = nbt.getBoolean( NBT_ON );
|
||||
m_computerID = nbt.contains(NBT_ID) ? nbt.getInt(NBT_ID) : -1;
|
||||
label = nbt.contains(NBT_LABEL) ? nbt.getString(NBT_LABEL) : null;
|
||||
m_on = m_startOn = nbt.getBoolean(NBT_ON);
|
||||
}
|
||||
|
||||
protected boolean isPeripheralBlockedOnSide( ComputerSide localSide )
|
||||
{
|
||||
protected boolean isPeripheralBlockedOnSide(ComputerSide localSide) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract Direction getDirection();
|
||||
|
||||
protected ComputerSide remapToLocalSide( Direction globalSide )
|
||||
{
|
||||
return remapLocalSide( DirectionUtil.toLocal( getDirection(), globalSide ) );
|
||||
protected ComputerSide remapToLocalSide(Direction globalSide) {
|
||||
return remapLocalSide(DirectionUtil.toLocal(getDirection(), globalSide));
|
||||
}
|
||||
|
||||
protected ComputerSide remapLocalSide( ComputerSide localSide )
|
||||
{
|
||||
protected ComputerSide remapLocalSide(ComputerSide localSide) {
|
||||
return localSide;
|
||||
}
|
||||
|
||||
private void updateSideInput( ServerComputer computer, Direction dir, BlockPos offset )
|
||||
{
|
||||
private void updateSideInput(ServerComputer computer, Direction dir, BlockPos offset) {
|
||||
Direction offsetSide = dir.getOpposite();
|
||||
ComputerSide localDir = remapToLocalSide( dir );
|
||||
ComputerSide localDir = remapToLocalSide(dir);
|
||||
|
||||
computer.setRedstoneInput( localDir, getRedstoneInput( world, offset, dir ) );
|
||||
computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getWorld(), offset, offsetSide ) );
|
||||
if( !isPeripheralBlockedOnSide( localDir ) )
|
||||
{
|
||||
IPeripheral peripheral = Peripherals.getPeripheral( getWorld(), offset, offsetSide, o -> updateInput( dir ) );
|
||||
computer.setPeripheral( localDir, peripheral );
|
||||
computer.setRedstoneInput(localDir, getRedstoneInput(world, offset, dir));
|
||||
computer.setBundledRedstoneInput(localDir, BundledRedstone.getOutput(getWorld(), offset, offsetSide));
|
||||
if (!isPeripheralBlockedOnSide(localDir)) {
|
||||
computer.setPeripheral(localDir, Peripherals.getPeripheral(getWorld(), offset, offsetSide));
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,51 +231,52 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
* Gets the redstone input for an adjacent block.
|
||||
*
|
||||
* @param world The world we exist in
|
||||
* @param pos The position of the neighbour
|
||||
* @param side The side we are reading from
|
||||
* @param pos The position of the neighbour
|
||||
* @param side The side we are reading from
|
||||
* @return The effective redstone power
|
||||
* @see RedstoneDiodeBlock#calculateInputStrength(World, BlockPos, BlockState)
|
||||
*/
|
||||
protected static int getRedstoneInput( World world, BlockPos pos, Direction side )
|
||||
{
|
||||
int power = world.getEmittedRedstonePower( pos, side );
|
||||
if( power >= 15 ) return power;
|
||||
protected static int getRedstoneInput(World world, BlockPos pos, Direction side) {
|
||||
int power = world.getEmittedRedstonePower(pos, side);
|
||||
if (power >= 15) {
|
||||
return power;
|
||||
}
|
||||
|
||||
BlockState neighbour = world.getBlockState( pos );
|
||||
return neighbour.getBlock() == Blocks.REDSTONE_WIRE
|
||||
? Math.max( power, neighbour.get( RedstoneWireBlock.POWER ) )
|
||||
: power;
|
||||
BlockState neighbour = world.getBlockState(pos);
|
||||
return neighbour.getBlock() == Blocks.REDSTONE_WIRE ? Math.max(power, neighbour.get(RedstoneWireBlock.POWER)) : power;
|
||||
}
|
||||
|
||||
public void updateInput()
|
||||
{
|
||||
if( getWorld() == null || getWorld().isClient ) return;
|
||||
public void updateInput() {
|
||||
if (getWorld() == null || getWorld().isClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update all sides
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer == null ) return;
|
||||
if (computer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
BlockPos pos = computer.getPosition();
|
||||
for( Direction dir : DirectionUtil.FACINGS )
|
||||
{
|
||||
updateSideInput( computer, dir, pos.offset( dir ) );
|
||||
for (Direction dir : DirectionUtil.FACINGS) {
|
||||
updateSideInput(computer, dir, pos.offset(dir));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInput( BlockPos neighbour )
|
||||
{
|
||||
if( getWorld() == null || getWorld().isClient ) return;
|
||||
private void updateInput(BlockPos neighbour) {
|
||||
if (getWorld() == null || getWorld().isClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer == null ) return;
|
||||
if (computer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for( Direction dir : DirectionUtil.FACINGS )
|
||||
{
|
||||
BlockPos offset = pos.offset( dir );
|
||||
if( offset.equals( neighbour ) )
|
||||
{
|
||||
updateSideInput( computer, dir, offset );
|
||||
return;
|
||||
for (Direction dir : DirectionUtil.FACINGS) {
|
||||
BlockPos offset = pos.offset(dir);
|
||||
if (offset.equals(neighbour)) {
|
||||
updateSideInput(computer, dir, offset);
|
||||
return; // todo break;?
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,120 +284,110 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
updateInput();
|
||||
}
|
||||
|
||||
private void updateInput( Direction dir )
|
||||
{
|
||||
if( getWorld() == null || getWorld().isClient ) return;
|
||||
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer == null ) return;
|
||||
|
||||
updateSideInput( computer, dir, pos.offset( dir ) );
|
||||
}
|
||||
|
||||
public void updateOutput()
|
||||
{
|
||||
public void updateOutput() {
|
||||
// Update redstone
|
||||
updateBlock();
|
||||
for( Direction dir : DirectionUtil.FACINGS )
|
||||
{
|
||||
RedstoneUtil.propagateRedstoneOutput( getWorld(), getPos(), dir );
|
||||
for (Direction dir : DirectionUtil.FACINGS) {
|
||||
RedstoneUtil.propagateRedstoneOutput(getWorld(), getPos(), dir);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract ServerComputer createComputer( int instanceID, int id );
|
||||
public abstract ComputerProxy createProxy();
|
||||
|
||||
protected abstract ServerComputer createComputer(int instanceID, int id);
|
||||
|
||||
@Override
|
||||
public final int getComputerID()
|
||||
{
|
||||
public final int getComputerID() {
|
||||
return m_computerID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getLabel()
|
||||
{
|
||||
public final String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setComputerID( int id )
|
||||
{
|
||||
if( getWorld().isClient || m_computerID == id ) return;
|
||||
public final void setComputerID(int id) {
|
||||
if (getWorld().isClient || m_computerID == id) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_computerID = id;
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null ) computer.setID( m_computerID );
|
||||
if (computer != null) {
|
||||
computer.setID(m_computerID);
|
||||
}
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setLabel( String label )
|
||||
{
|
||||
if( getWorld().isClient || Objects.equals( this.label, label ) ) return;
|
||||
public final void setLabel(String label) {
|
||||
if (getWorld().isClient || Objects.equals(this.label, label)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.label = label;
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null ) computer.setLabel( label );
|
||||
if (computer != null) {
|
||||
computer.setLabel(label);
|
||||
}
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputerFamily getFamily()
|
||||
{
|
||||
public ComputerFamily getFamily() {
|
||||
return family;
|
||||
}
|
||||
|
||||
public ServerComputer createServerComputer()
|
||||
{
|
||||
if( getWorld().isClient ) return null;
|
||||
public ServerComputer createServerComputer() {
|
||||
if (getWorld().isClient) {
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
if( m_instanceID < 0 )
|
||||
{
|
||||
if (m_instanceID < 0) {
|
||||
m_instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
|
||||
changed = true;
|
||||
}
|
||||
if( !ComputerCraft.serverComputerRegistry.contains( m_instanceID ) )
|
||||
{
|
||||
ServerComputer computer = createComputer( m_instanceID, m_computerID );
|
||||
ComputerCraft.serverComputerRegistry.add( m_instanceID, computer );
|
||||
if (!ComputerCraft.serverComputerRegistry.contains(m_instanceID)) {
|
||||
ServerComputer computer = createComputer(m_instanceID, m_computerID);
|
||||
ComputerCraft.serverComputerRegistry.add(m_instanceID, computer);
|
||||
m_fresh = true;
|
||||
changed = true;
|
||||
}
|
||||
if( changed )
|
||||
{
|
||||
if (changed) {
|
||||
updateBlock();
|
||||
updateInput();
|
||||
}
|
||||
return ComputerCraft.serverComputerRegistry.get( m_instanceID );
|
||||
return ComputerCraft.serverComputerRegistry.get(m_instanceID);
|
||||
}
|
||||
|
||||
public ServerComputer getServerComputer()
|
||||
{
|
||||
return getWorld().isClient ? null : ComputerCraft.serverComputerRegistry.get( m_instanceID );
|
||||
public ServerComputer getServerComputer() {
|
||||
return getWorld().isClient ? null : ComputerCraft.serverComputerRegistry.get(m_instanceID);
|
||||
}
|
||||
|
||||
// Networking stuff
|
||||
|
||||
@Override
|
||||
protected void writeDescription( @Nonnull CompoundTag nbt )
|
||||
{
|
||||
super.writeDescription( nbt );
|
||||
if( label != null ) nbt.putString( NBT_LABEL, label );
|
||||
if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID );
|
||||
protected void writeDescription(@Nonnull CompoundTag nbt) {
|
||||
super.writeDescription(nbt);
|
||||
if (label != null) {
|
||||
nbt.putString(NBT_LABEL, label);
|
||||
}
|
||||
if (m_computerID >= 0) {
|
||||
nbt.putInt(NBT_ID, m_computerID);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readDescription( @Nonnull CompoundTag nbt )
|
||||
{
|
||||
super.readDescription( nbt );
|
||||
label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
|
||||
m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
|
||||
protected void readDescription(@Nonnull CompoundTag nbt) {
|
||||
super.readDescription(nbt);
|
||||
label = nbt.contains(NBT_LABEL) ? nbt.getString(NBT_LABEL) : null;
|
||||
m_computerID = nbt.contains(NBT_ID) ? nbt.getInt(NBT_ID) : -1;
|
||||
}
|
||||
|
||||
protected void transferStateFrom( TileComputerBase copy )
|
||||
{
|
||||
if( copy.m_computerID != m_computerID || copy.m_instanceID != m_instanceID )
|
||||
{
|
||||
protected void transferStateFrom(TileComputerBase copy) {
|
||||
if (copy.m_computerID != m_computerID || copy.m_instanceID != m_instanceID) {
|
||||
unload();
|
||||
m_instanceID = copy.m_instanceID;
|
||||
m_computerID = copy.m_computerID;
|
||||
@ -412,30 +401,25 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Text getName()
|
||||
{
|
||||
return hasCustomName()
|
||||
? new LiteralText( label )
|
||||
: new TranslatableText( getCachedState().getBlock().getTranslationKey() );
|
||||
public Text getName() {
|
||||
return hasCustomName() ? new LiteralText(label) : new TranslatableText(getCachedState().getBlock()
|
||||
.getTranslationKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName()
|
||||
{
|
||||
return !Strings.isNullOrEmpty( label );
|
||||
public boolean hasCustomName() {
|
||||
return !Strings.isNullOrEmpty(label);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Text getCustomName()
|
||||
{
|
||||
return hasCustomName() ? new LiteralText( label ) : null;
|
||||
public Text getCustomName() {
|
||||
return hasCustomName() ? new LiteralText(label) : null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Text getDisplayName()
|
||||
{
|
||||
public Text getDisplayName() {
|
||||
return Nameable.super.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
@ -3,62 +3,85 @@
|
||||
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.computer.inventory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.shared.Registry;
|
||||
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
||||
import dan200.computercraft.shared.computer.core.InputState;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.network.container.ViewComputerContainerData;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
public class ContainerViewComputer extends ScreenHandler implements IContainerComputer {
|
||||
private final IComputer computer;
|
||||
private final InputState input = new InputState(this);
|
||||
|
||||
public class ContainerViewComputer extends ContainerComputerBase implements IContainerComputer
|
||||
{
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
public ContainerViewComputer( int id, ServerComputer computer )
|
||||
{
|
||||
super( Registry.ModContainers.VIEW_COMPUTER.get(), id, player -> canInteractWith( computer, player ), computer, computer.getFamily() );
|
||||
this.width = this.height = 0;
|
||||
public ContainerViewComputer(int id, IComputer computer) {
|
||||
super(null, id);
|
||||
this.computer = computer;
|
||||
}
|
||||
|
||||
public ContainerViewComputer( int id, PlayerInventory player, ViewComputerContainerData data )
|
||||
{
|
||||
super( Registry.ModContainers.VIEW_COMPUTER.get(), id, player, data );
|
||||
this.width = data.getWidth();
|
||||
this.height = data.getHeight();
|
||||
}
|
||||
|
||||
private static boolean canInteractWith( @Nonnull ServerComputer computer, @Nonnull PlayerEntity player )
|
||||
{
|
||||
private static boolean canInteractWith(@Nonnull ServerComputer computer, @Nonnull PlayerEntity player) {
|
||||
// If this computer no longer exists then discard it.
|
||||
if( ComputerCraft.serverComputerRegistry.get( computer.getInstanceID() ) != computer )
|
||||
{
|
||||
if (ComputerCraft.serverComputerRegistry.get(computer.getInstanceID()) != computer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we're a command computer then ensure we're in creative
|
||||
if( computer.getFamily() == ComputerFamily.COMMAND && !TileCommandComputer.isUsable( player ) )
|
||||
{
|
||||
return false;
|
||||
return computer.getFamily() != ComputerFamily.COMMAND || TileCommandComputer.isUsable(player);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IComputer getComputer() {
|
||||
return this.computer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(PlayerEntity player) {
|
||||
if (this.computer instanceof ServerComputer) {
|
||||
ServerComputer serverComputer = (ServerComputer) this.computer;
|
||||
|
||||
// If this computer no longer exists then discard it.
|
||||
if (ComputerCraft.serverComputerRegistry.get(serverComputer.getInstanceID()) != serverComputer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we're a command computer then ensure we're in creative
|
||||
if (serverComputer.getFamily() == ComputerFamily.COMMAND) {
|
||||
MinecraftServer server = player.getServer();
|
||||
if (server == null || !server.areCommandBlocksEnabled()) {
|
||||
player.sendMessage(new TranslatableText("advMode.notEnabled"), false);
|
||||
return false;
|
||||
} else if (!player.isCreativeLevelTwoOp()) {
|
||||
player.sendMessage(new TranslatableText("advMode.notAllowed"), false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getWidth()
|
||||
{
|
||||
return width;
|
||||
@Nonnull
|
||||
@Override
|
||||
public InputState getInput() {
|
||||
return this.input;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return height;
|
||||
@Override
|
||||
public void close(PlayerEntity player) {
|
||||
super.close(player);
|
||||
this.input.close();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,109 @@
|
||||
package dan200.computercraft.shared.network;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.mixin.ScreenHandlerTypeAccessor;
|
||||
import dan200.computercraft.shared.common.ContainerHeldItem;
|
||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||
import dan200.computercraft.shared.network.container.ContainerType;
|
||||
import dan200.computercraft.shared.network.container.PocketComputerContainerType;
|
||||
import dan200.computercraft.shared.network.container.PrintoutContainerType;
|
||||
import dan200.computercraft.shared.network.container.TileEntityContainerType;
|
||||
import dan200.computercraft.shared.network.container.ViewComputerContainerType;
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
|
||||
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
||||
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
|
||||
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.util.Hand;
|
||||
|
||||
public final class Containers
|
||||
{
|
||||
private Containers()
|
||||
{
|
||||
}
|
||||
|
||||
public static void openDiskDriveGUI(PlayerEntity player, TileDiskDrive drive )
|
||||
{
|
||||
TileEntityContainerType.diskDrive( drive.getPos() ).open( player );
|
||||
}
|
||||
|
||||
public static void openComputerGUI( PlayerEntity player, TileComputer computer )
|
||||
{
|
||||
computer.createServerComputer().sendTerminalState( player );
|
||||
TileEntityContainerType.computer( computer.getPos() ).open( player );
|
||||
}
|
||||
|
||||
public static void openPrinterGUI( PlayerEntity player, TilePrinter printer )
|
||||
{
|
||||
TileEntityContainerType.printer( printer.getPos() ).open( player );
|
||||
}
|
||||
|
||||
public static void openTurtleGUI( PlayerEntity player, TileTurtle turtle )
|
||||
{
|
||||
turtle.createServerComputer().sendTerminalState( player );
|
||||
TileEntityContainerType.turtle( turtle.getPos() ).open( player );
|
||||
}
|
||||
|
||||
public static void openPrintoutGUI( PlayerEntity player, Hand hand )
|
||||
{
|
||||
ItemStack stack = player.getStackInHand( hand );
|
||||
Item item = stack.getItem();
|
||||
if (!(item instanceof ItemPrintout)) {
|
||||
return;
|
||||
}
|
||||
|
||||
new PrintoutContainerType( hand ).open( player );
|
||||
}
|
||||
|
||||
public static void openPocketComputerGUI( PlayerEntity player, Hand hand )
|
||||
{
|
||||
ItemStack stack = player.getStackInHand(hand );
|
||||
Item item = stack.getItem();
|
||||
if (!(item instanceof ItemPocketComputer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerComputer computer = ItemPocketComputer.getServerComputer(stack );
|
||||
if (computer != null) {
|
||||
computer.sendTerminalState(player);
|
||||
}
|
||||
|
||||
new PocketComputerContainerType( hand ).open( player );
|
||||
}
|
||||
|
||||
public static void openComputerGUI( PlayerEntity player, ServerComputer computer )
|
||||
{
|
||||
computer.sendTerminalState( player );
|
||||
new ViewComputerContainerType( computer ).open( player );
|
||||
}
|
||||
|
||||
public static void setup()
|
||||
{
|
||||
ContainerType.register(TileEntityContainerType::computer, (id, packet, player ) ->
|
||||
new ContainerComputer(id, (TileComputer) packet.getTileEntity(player ) ) );
|
||||
ContainerType.register( TileEntityContainerType::turtle, ( id, packet, player ) -> {
|
||||
TileTurtle turtle = (TileTurtle) packet.getTileEntity( player );
|
||||
return new ContainerTurtle(id, player.inventory, turtle.getAccess(), turtle.getServerComputer() );
|
||||
} );
|
||||
ContainerType.register(TileEntityContainerType::diskDrive, (id, packet, player ) ->
|
||||
new ContainerDiskDrive(id, player.inventory, (TileDiskDrive) packet.getTileEntity(player ) ) );
|
||||
ContainerType.register( TileEntityContainerType::printer, ( id, packet, player ) ->
|
||||
new ContainerPrinter(id, player.inventory, (TilePrinter) packet.getTileEntity(player ) ) );
|
||||
|
||||
ContainerType.register(PocketComputerContainerType::new, (id, packet, player ) -> new ContainerPocketComputer(id, player, packet.hand ) );
|
||||
ContainerType.register(PrintoutContainerType::new, (id, packet, player ) -> new ContainerHeldItem(id, player, packet.hand ) );
|
||||
ContainerType.register(ViewComputerContainerType::new, (id, packet, player ) -> new ContainerViewComputer(id, ComputerCraft.serverComputerRegistry.get(packet.instanceId ) ) );
|
||||
}
|
||||
}
|
@ -5,11 +5,12 @@
|
||||
*/
|
||||
package dan200.computercraft.shared.network;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
|
||||
import net.fabricmc.fabric.api.network.PacketContext;
|
||||
|
||||
/**
|
||||
* The base interface for any message which will be sent to the client or server.
|
||||
*
|
||||
@ -44,5 +45,5 @@ public interface NetworkMessage
|
||||
*
|
||||
* @param context The context with which to handle this message
|
||||
*/
|
||||
void handle( NetworkEvent.Context context );
|
||||
void handle( PacketContext context );
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public class CommandBlockPeripheral implements IPeripheral, ICapabilityProvider
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType()
|
||||
public String getType0()
|
||||
{
|
||||
return "command";
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public class DiskDrivePeripheral implements IPeripheral
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType()
|
||||
public String getType0()
|
||||
{
|
||||
return "drive";
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class GenericPeripheral implements IDynamicPeripheral
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType()
|
||||
public String getType0()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
@ -76,12 +76,12 @@ public class ItemData
|
||||
if( !ComputerCraft.genericPeripheral ) return data;
|
||||
|
||||
CompoundTag tag = stack.getTag();
|
||||
if( tag != null && tag.contains( "display", Constants.NBT.TAG_COMPOUND ) )
|
||||
if( tag != null && tag.contains( "display", NBTUtil.TAG_COMPOUND ) )
|
||||
{
|
||||
CompoundTag displayTag = tag.getCompound( "display" );
|
||||
if( displayTag.contains( "Lore", Constants.NBT.TAG_LIST ) )
|
||||
if( displayTag.contains( "Lore", NBTUtil.TAG_LIST ) )
|
||||
{
|
||||
ListTag loreTag = displayTag.getList( "Lore", Constants.NBT.TAG_STRING );
|
||||
ListTag loreTag = displayTag.getList( "Lore", NBTUtil.TAG_STRING );
|
||||
data.put( "lore", loreTag.stream()
|
||||
.map( ItemData::parseTextComponent )
|
||||
.filter( Objects::nonNull )
|
||||
|
@ -94,7 +94,7 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType()
|
||||
public String getType0()
|
||||
{
|
||||
return "modem";
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ public final class WiredModemLocalPeripheral
|
||||
}
|
||||
else
|
||||
{
|
||||
String type = peripheral.getType();
|
||||
String type = peripheral.getType0();
|
||||
int id = this.id;
|
||||
|
||||
if( id > 0 && this.type == null )
|
||||
@ -131,10 +131,10 @@ public final class WiredModemLocalPeripheral
|
||||
|
||||
public void read( @Nonnull CompoundTag tag, @Nonnull String suffix )
|
||||
{
|
||||
id = tag.contains( NBT_PERIPHERAL_ID + suffix, Constants.NBT.TAG_ANY_NUMERIC )
|
||||
id = tag.contains( NBT_PERIPHERAL_ID + suffix, NBTUtil.TAG_ANY_NUMERIC )
|
||||
? tag.getInt( NBT_PERIPHERAL_ID + suffix ) : -1;
|
||||
|
||||
type = tag.contains( NBT_PERIPHERAL_TYPE + suffix, Constants.NBT.TAG_STRING )
|
||||
type = tag.contains( NBT_PERIPHERAL_TYPE + suffix, NBTUtil.TAG_STRING )
|
||||
? tag.getString( NBT_PERIPHERAL_TYPE + suffix ) : null;
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW
|
||||
this.computer = computer;
|
||||
this.name = name;
|
||||
|
||||
type = Objects.requireNonNull( peripheral.getType(), "Peripheral type cannot be null" );
|
||||
type = Objects.requireNonNull(peripheral.getType0(), "Peripheral type cannot be null" );
|
||||
methodMap = PeripheralAPI.getMethods( peripheral );
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ public class MonitorPeripheral extends TermMethods implements IPeripheral
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType()
|
||||
public String getType0()
|
||||
{
|
||||
return "monitor";
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class PrinterPeripheral implements IPeripheral
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType()
|
||||
public String getType0()
|
||||
{
|
||||
return "printer";
|
||||
}
|
||||
|
@ -3,169 +3,173 @@
|
||||
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.peripheral.printer;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.shared.common.TileGeneric;
|
||||
import dan200.computercraft.shared.media.items.ItemPrintout;
|
||||
import dan200.computercraft.shared.util.*;
|
||||
import dan200.computercraft.shared.network.Containers;
|
||||
import dan200.computercraft.shared.util.ColourUtils;
|
||||
import dan200.computercraft.shared.util.DefaultSidedInventory;
|
||||
import dan200.computercraft.shared.util.ItemStorage;
|
||||
import dan200.computercraft.shared.util.NamedBlockEntityType;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventories;
|
||||
import net.minecraft.item.*;
|
||||
import net.minecraft.item.DyeItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.DyeColor;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Nameable;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||
import net.minecraftforge.items.wrapper.SidedInvWrapper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static dan200.computercraft.shared.Capabilities.CAPABILITY_PERIPHERAL;
|
||||
import static net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY;
|
||||
|
||||
public final class TilePrinter extends TileGeneric implements DefaultSidedInventory, Nameable, NamedScreenHandlerFactory
|
||||
{
|
||||
public final class TilePrinter extends TileGeneric implements DefaultSidedInventory, Nameable, NamedScreenHandlerFactory {
|
||||
private static final String NBT_NAME = "CustomName";
|
||||
private static final String NBT_PRINTING = "Printing";
|
||||
private static final String NBT_PAGE_TITLE = "PageTitle";
|
||||
public static final NamedBlockEntityType<TilePrinter> FACTORY = NamedBlockEntityType.create(new Identifier(ComputerCraft.MOD_ID, "printer"),
|
||||
TilePrinter::new);
|
||||
|
||||
static final int SLOTS = 13;
|
||||
|
||||
private static final int[] BOTTOM_SLOTS = new int[] { 7, 8, 9, 10, 11, 12 };
|
||||
private static final int[] TOP_SLOTS = new int[] { 1, 2, 3, 4, 5, 6 };
|
||||
private static final int[] SIDE_SLOTS = new int[] { 0 };
|
||||
private static final int[] BOTTOM_SLOTS = new int[] {
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12
|
||||
};
|
||||
private static final int[] TOP_SLOTS = new int[] {
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6
|
||||
};
|
||||
private static final int[] SIDE_SLOTS = new int[] {0};
|
||||
|
||||
Text customName;
|
||||
|
||||
private final DefaultedList<ItemStack> m_inventory = DefaultedList.ofSize( SLOTS, ItemStack.EMPTY );
|
||||
private final SidedCaps<IItemHandler> itemHandlerCaps =
|
||||
SidedCaps.ofNullable( facing -> facing == null ? new InvWrapper( this ) : new SidedInvWrapper( this, facing ) );
|
||||
private LazyOptional<IPeripheral> peripheralCap;
|
||||
private final DefaultedList<ItemStack> m_inventory = DefaultedList.ofSize(SLOTS, ItemStack.EMPTY);
|
||||
private final ItemStorage itemHandlerCaps = ItemStorage.wrap(this);
|
||||
|
||||
private final Terminal m_page = new Terminal( ItemPrintout.LINE_MAX_LENGTH, ItemPrintout.LINES_PER_PAGE );
|
||||
private final Terminal m_page = new Terminal(ItemPrintout.LINE_MAX_LENGTH, ItemPrintout.LINES_PER_PAGE);
|
||||
private String m_pageTitle = "";
|
||||
private boolean m_printing = false;
|
||||
|
||||
public TilePrinter( BlockEntityType<TilePrinter> type )
|
||||
{
|
||||
super( type );
|
||||
public TilePrinter(BlockEntityType<TilePrinter> type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
public void destroy() {
|
||||
ejectContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invalidateCaps()
|
||||
{
|
||||
super.invalidateCaps();
|
||||
itemHandlerCaps.invalidate();
|
||||
peripheralCap = CapabilityUtil.invalidate( peripheralCap );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit )
|
||||
{
|
||||
if( player.isInSneakingPose() ) return ActionResult.PASS;
|
||||
public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
if (player.isInSneakingPose()) {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
if( !getWorld().isClient ) NetworkHooks.openGui( (ServerPlayerEntity) player, this );
|
||||
if (!getWorld().isClient) {
|
||||
Containers.openPrinterGUI(player, this);
|
||||
}
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt )
|
||||
{
|
||||
super.fromTag( state, nbt );
|
||||
public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) {
|
||||
super.fromTag(state, nbt);
|
||||
|
||||
customName = nbt.contains( NBT_NAME ) ? Text.Serializer.fromJson( nbt.getString( NBT_NAME ) ) : null;
|
||||
customName = nbt.contains(NBT_NAME) ? Text.Serializer.fromJson(nbt.getString(NBT_NAME)) : null;
|
||||
|
||||
// Read page
|
||||
synchronized( m_page )
|
||||
{
|
||||
m_printing = nbt.getBoolean( NBT_PRINTING );
|
||||
m_pageTitle = nbt.getString( NBT_PAGE_TITLE );
|
||||
m_page.readFromNBT( nbt );
|
||||
synchronized (m_page) {
|
||||
m_printing = nbt.getBoolean(NBT_PRINTING);
|
||||
m_pageTitle = nbt.getString(NBT_PAGE_TITLE);
|
||||
m_page.readFromNBT(nbt);
|
||||
}
|
||||
|
||||
// Read inventory
|
||||
Inventories.fromTag( nbt, m_inventory );
|
||||
Inventories.fromTag(nbt, m_inventory);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public CompoundTag toTag( @Nonnull CompoundTag nbt )
|
||||
{
|
||||
if( customName != null ) nbt.putString( NBT_NAME, Text.Serializer.toJson( customName ) );
|
||||
public CompoundTag toTag(@Nonnull CompoundTag nbt) {
|
||||
if (customName != null) {
|
||||
nbt.putString(NBT_NAME, Text.Serializer.toJson(customName));
|
||||
}
|
||||
|
||||
// Write page
|
||||
synchronized( m_page )
|
||||
{
|
||||
nbt.putBoolean( NBT_PRINTING, m_printing );
|
||||
nbt.putString( NBT_PAGE_TITLE, m_pageTitle );
|
||||
m_page.writeToNBT( nbt );
|
||||
synchronized (m_page) {
|
||||
nbt.putBoolean(NBT_PRINTING, m_printing);
|
||||
nbt.putString(NBT_PAGE_TITLE, m_pageTitle);
|
||||
m_page.writeToNBT(nbt);
|
||||
}
|
||||
|
||||
// Write inventory
|
||||
Inventories.toTag( nbt, m_inventory );
|
||||
Inventories.toTag(nbt, m_inventory);
|
||||
|
||||
return super.toTag( nbt );
|
||||
return super.toTag(nbt);
|
||||
}
|
||||
|
||||
boolean isPrinting()
|
||||
{
|
||||
boolean isPrinting() {
|
||||
return m_printing;
|
||||
}
|
||||
|
||||
// IInventory implementation
|
||||
@Override
|
||||
public int size()
|
||||
{
|
||||
public int size() {
|
||||
return m_inventory.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
for( ItemStack stack : m_inventory )
|
||||
{
|
||||
if( !stack.isEmpty() ) return false;
|
||||
public boolean isEmpty() {
|
||||
for (ItemStack stack : m_inventory) {
|
||||
if (!stack.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getStack( int slot )
|
||||
{
|
||||
return m_inventory.get( slot );
|
||||
public ItemStack getStack(int slot) {
|
||||
return m_inventory.get(slot);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack removeStack( int slot )
|
||||
{
|
||||
ItemStack result = m_inventory.get( slot );
|
||||
m_inventory.set( slot, ItemStack.EMPTY );
|
||||
public ItemStack removeStack(int slot) {
|
||||
ItemStack result = m_inventory.get(slot);
|
||||
m_inventory.set(slot, ItemStack.EMPTY);
|
||||
markDirty();
|
||||
updateBlockState();
|
||||
return result;
|
||||
@ -173,21 +177,21 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack removeStack( int slot, int count )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( slot );
|
||||
if( stack.isEmpty() ) return ItemStack.EMPTY;
|
||||
public ItemStack removeStack(int slot, int count) {
|
||||
ItemStack stack = m_inventory.get(slot);
|
||||
if (stack.isEmpty()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if( stack.getCount() <= count )
|
||||
{
|
||||
setStack( slot, ItemStack.EMPTY );
|
||||
if (stack.getCount() <= count) {
|
||||
setStack(slot, ItemStack.EMPTY);
|
||||
return stack;
|
||||
}
|
||||
|
||||
ItemStack part = stack.split( count );
|
||||
if( m_inventory.get( slot ).isEmpty() )
|
||||
{
|
||||
m_inventory.set( slot, ItemStack.EMPTY );
|
||||
ItemStack part = stack.split(count);
|
||||
if (m_inventory.get(slot)
|
||||
.isEmpty()) {
|
||||
m_inventory.set(slot, ItemStack.EMPTY);
|
||||
updateBlockState();
|
||||
}
|
||||
markDirty();
|
||||
@ -195,171 +199,154 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStack( int slot, @Nonnull ItemStack stack )
|
||||
{
|
||||
m_inventory.set( slot, stack );
|
||||
public void setStack(int slot, @Nonnull ItemStack stack) {
|
||||
m_inventory.set(slot, stack);
|
||||
markDirty();
|
||||
updateBlockState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
for( int i = 0; i < m_inventory.size(); i++ ) m_inventory.set( i, ItemStack.EMPTY );
|
||||
public void clear() {
|
||||
for (int i = 0; i < m_inventory.size(); i++) {
|
||||
m_inventory.set(i, ItemStack.EMPTY);
|
||||
}
|
||||
markDirty();
|
||||
updateBlockState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid( int slot, @Nonnull ItemStack stack )
|
||||
{
|
||||
if( slot == 0 )
|
||||
{
|
||||
return isInk( stack );
|
||||
}
|
||||
else if( slot >= TOP_SLOTS[0] && slot <= TOP_SLOTS[TOP_SLOTS.length - 1] )
|
||||
{
|
||||
return isPaper( stack );
|
||||
}
|
||||
else
|
||||
{
|
||||
public boolean isValid(int slot, @Nonnull ItemStack stack) {
|
||||
if (slot == 0) {
|
||||
return isInk(stack);
|
||||
} else if (slot >= TOP_SLOTS[0] && slot <= TOP_SLOTS[TOP_SLOTS.length - 1]) {
|
||||
return isPaper(stack);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayerUse( @Nonnull PlayerEntity playerEntity )
|
||||
{
|
||||
return isUsable( playerEntity, false );
|
||||
public boolean canPlayerUse(@Nonnull PlayerEntity playerEntity) {
|
||||
return isUsable(playerEntity, false);
|
||||
}
|
||||
|
||||
// ISidedInventory implementation
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public int[] getAvailableSlots( @Nonnull Direction side )
|
||||
{
|
||||
switch( side )
|
||||
{
|
||||
case DOWN: // Bottom (Out tray)
|
||||
return BOTTOM_SLOTS;
|
||||
case UP: // Top (In tray)
|
||||
return TOP_SLOTS;
|
||||
default: // Sides (Ink)
|
||||
return SIDE_SLOTS;
|
||||
public int[] getAvailableSlots(@Nonnull Direction side) {
|
||||
switch (side) {
|
||||
case DOWN: // Bottom (Out tray)
|
||||
return BOTTOM_SLOTS;
|
||||
case UP: // Top (In tray)
|
||||
return TOP_SLOTS;
|
||||
default: // Sides (Ink)
|
||||
return SIDE_SLOTS;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Terminal getCurrentPage()
|
||||
{
|
||||
synchronized( m_page )
|
||||
{
|
||||
Terminal getCurrentPage() {
|
||||
synchronized (m_page) {
|
||||
return m_printing ? m_page : null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean startNewPage()
|
||||
{
|
||||
synchronized( m_page )
|
||||
{
|
||||
if( !canInputPage() ) return false;
|
||||
if( m_printing && !outputPage() ) return false;
|
||||
boolean startNewPage() {
|
||||
synchronized (m_page) {
|
||||
if (!canInputPage()) {
|
||||
return false;
|
||||
}
|
||||
if (m_printing && !outputPage()) {
|
||||
return false;
|
||||
}
|
||||
return inputPage();
|
||||
}
|
||||
}
|
||||
|
||||
boolean endCurrentPage()
|
||||
{
|
||||
synchronized( m_page )
|
||||
{
|
||||
boolean endCurrentPage() {
|
||||
synchronized (m_page) {
|
||||
return m_printing && outputPage();
|
||||
}
|
||||
}
|
||||
|
||||
int getInkLevel()
|
||||
{
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
return isInk( inkStack ) ? inkStack.getCount() : 0;
|
||||
int getInkLevel() {
|
||||
ItemStack inkStack = m_inventory.get(0);
|
||||
return isInk(inkStack) ? inkStack.getCount() : 0;
|
||||
}
|
||||
|
||||
int getPaperLevel()
|
||||
{
|
||||
int getPaperLevel() {
|
||||
int count = 0;
|
||||
for( int i = 1; i < 7; i++ )
|
||||
{
|
||||
ItemStack paperStack = m_inventory.get( i );
|
||||
if( isPaper( paperStack ) ) count += paperStack.getCount();
|
||||
for (int i = 1; i < 7; i++) {
|
||||
ItemStack paperStack = m_inventory.get(i);
|
||||
if (isPaper(paperStack)) {
|
||||
count += paperStack.getCount();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void setPageTitle( String title )
|
||||
{
|
||||
synchronized( m_page )
|
||||
{
|
||||
if( m_printing ) m_pageTitle = title;
|
||||
void setPageTitle(String title) {
|
||||
synchronized (m_page) {
|
||||
if (m_printing) {
|
||||
m_pageTitle = title;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInk( @Nonnull ItemStack stack )
|
||||
{
|
||||
private static boolean isInk(@Nonnull ItemStack stack) {
|
||||
return stack.getItem() instanceof DyeItem;
|
||||
}
|
||||
|
||||
private static boolean isPaper( @Nonnull ItemStack stack )
|
||||
{
|
||||
private static boolean isPaper(@Nonnull ItemStack stack) {
|
||||
Item item = stack.getItem();
|
||||
return item == Items.PAPER
|
||||
|| (item instanceof ItemPrintout && ((ItemPrintout) item).getType() == ItemPrintout.Type.PAGE);
|
||||
return item == Items.PAPER || (item instanceof ItemPrintout && ((ItemPrintout) item).getType() == ItemPrintout.Type.PAGE);
|
||||
}
|
||||
|
||||
private boolean canInputPage()
|
||||
{
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
return !inkStack.isEmpty() && isInk( inkStack ) && getPaperLevel() > 0;
|
||||
private boolean canInputPage() {
|
||||
ItemStack inkStack = m_inventory.get(0);
|
||||
return !inkStack.isEmpty() && isInk(inkStack) && getPaperLevel() > 0;
|
||||
}
|
||||
|
||||
private boolean inputPage()
|
||||
{
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
if( !isInk( inkStack ) ) return false;
|
||||
private boolean inputPage() {
|
||||
ItemStack inkStack = m_inventory.get(0);
|
||||
if (!isInk(inkStack)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int i = 1; i < 7; i++ )
|
||||
{
|
||||
ItemStack paperStack = m_inventory.get( i );
|
||||
if( paperStack.isEmpty() || !isPaper( paperStack ) ) continue;
|
||||
for (int i = 1; i < 7; i++) {
|
||||
ItemStack paperStack = m_inventory.get(i);
|
||||
if (paperStack.isEmpty() || !isPaper(paperStack)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Setup the new page
|
||||
DyeColor dye = ColourUtils.getStackColour( inkStack );
|
||||
m_page.setTextColour( dye != null ? dye.getId() : 15 );
|
||||
DyeColor dye = ColourUtils.getStackColour(inkStack);
|
||||
m_page.setTextColour(dye != null ? dye.getId() : 15);
|
||||
|
||||
m_page.clear();
|
||||
if( paperStack.getItem() instanceof ItemPrintout )
|
||||
{
|
||||
m_pageTitle = ItemPrintout.getTitle( paperStack );
|
||||
String[] text = ItemPrintout.getText( paperStack );
|
||||
String[] textColour = ItemPrintout.getColours( paperStack );
|
||||
for( int y = 0; y < m_page.getHeight(); y++ )
|
||||
{
|
||||
m_page.setLine( y, text[y], textColour[y], "" );
|
||||
if (paperStack.getItem() instanceof ItemPrintout) {
|
||||
m_pageTitle = ItemPrintout.getTitle(paperStack);
|
||||
String[] text = ItemPrintout.getText(paperStack);
|
||||
String[] textColour = ItemPrintout.getColours(paperStack);
|
||||
for (int y = 0; y < m_page.getHeight(); y++) {
|
||||
m_page.setLine(y, text[y], textColour[y], "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_pageTitle = "";
|
||||
}
|
||||
m_page.setCursorPos( 0, 0 );
|
||||
m_page.setCursorPos(0, 0);
|
||||
|
||||
// Decrement ink
|
||||
inkStack.decrement( 1 );
|
||||
if( inkStack.isEmpty() ) m_inventory.set( 0, ItemStack.EMPTY );
|
||||
inkStack.decrement(1);
|
||||
if (inkStack.isEmpty()) {
|
||||
m_inventory.set(0, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
// Decrement paper
|
||||
paperStack.decrement( 1 );
|
||||
if( paperStack.isEmpty() )
|
||||
{
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
paperStack.decrement(1);
|
||||
if (paperStack.isEmpty()) {
|
||||
m_inventory.set(i, ItemStack.EMPTY);
|
||||
updateBlockState();
|
||||
}
|
||||
|
||||
@ -370,23 +357,22 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean outputPage()
|
||||
{
|
||||
private boolean outputPage() {
|
||||
int height = m_page.getHeight();
|
||||
String[] lines = new String[height];
|
||||
String[] colours = new String[height];
|
||||
for( int i = 0; i < height; i++ )
|
||||
{
|
||||
lines[i] = m_page.getLine( i ).toString();
|
||||
colours[i] = m_page.getTextColourLine( i ).toString();
|
||||
for (int i = 0; i < height; i++) {
|
||||
lines[i] = m_page.getLine(i)
|
||||
.toString();
|
||||
colours[i] = m_page.getTextColourLine(i)
|
||||
.toString();
|
||||
}
|
||||
|
||||
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( m_pageTitle, lines, colours );
|
||||
for( int slot : BOTTOM_SLOTS )
|
||||
{
|
||||
if( m_inventory.get( slot ).isEmpty() )
|
||||
{
|
||||
setStack( slot, stack );
|
||||
ItemStack stack = ItemPrintout.createSingleFromTitleAndText(m_pageTitle, lines, colours);
|
||||
for (int slot : BOTTOM_SLOTS) {
|
||||
if (m_inventory.get(slot)
|
||||
.isEmpty()) {
|
||||
setStack(slot, stack);
|
||||
m_printing = false;
|
||||
return true;
|
||||
}
|
||||
@ -394,101 +380,84 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ejectContents()
|
||||
{
|
||||
for( int i = 0; i < 13; i++ )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
private void ejectContents() {
|
||||
for (int i = 0; i < 13; i++) {
|
||||
ItemStack stack = m_inventory.get(i);
|
||||
if (!stack.isEmpty()) {
|
||||
// Remove the stack from the inventory
|
||||
setStack( i, ItemStack.EMPTY );
|
||||
setStack(i, ItemStack.EMPTY);
|
||||
|
||||
// Spawn the item in the world
|
||||
WorldUtil.dropItemStack( stack, getWorld(), Vec3d.of( getPos() ).add( 0.5, 0.75, 0.5 ) );
|
||||
WorldUtil.dropItemStack(stack,
|
||||
getWorld(),
|
||||
Vec3d.of(getPos())
|
||||
.add(0.5, 0.75, 0.5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBlockState()
|
||||
{
|
||||
private void updateBlockState() {
|
||||
boolean top = false, bottom = false;
|
||||
for( int i = 1; i < 7; i++ )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
if( !stack.isEmpty() && isPaper( stack ) )
|
||||
{
|
||||
for (int i = 1; i < 7; i++) {
|
||||
ItemStack stack = m_inventory.get(i);
|
||||
if (!stack.isEmpty() && isPaper(stack)) {
|
||||
top = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for( int i = 7; i < 13; i++ )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
if( !stack.isEmpty() && isPaper( stack ) )
|
||||
{
|
||||
for (int i = 7; i < 13; i++) {
|
||||
ItemStack stack = m_inventory.get(i);
|
||||
if (!stack.isEmpty() && isPaper(stack)) {
|
||||
bottom = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
updateBlockState( top, bottom );
|
||||
updateBlockState(top, bottom);
|
||||
}
|
||||
|
||||
private void updateBlockState( boolean top, boolean bottom )
|
||||
{
|
||||
if( removed ) return;
|
||||
|
||||
BlockState state = getCachedState();
|
||||
if( state.get( BlockPrinter.TOP ) == top & state.get( BlockPrinter.BOTTOM ) == bottom ) return;
|
||||
|
||||
getWorld().setBlockState( getPos(), state.with( BlockPrinter.TOP, top ).with( BlockPrinter.BOTTOM, bottom ) );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability( @Nonnull Capability<T> capability, @Nullable Direction facing )
|
||||
{
|
||||
if( capability == ITEM_HANDLER_CAPABILITY ) return itemHandlerCaps.get( facing ).cast();
|
||||
if( capability == CAPABILITY_PERIPHERAL )
|
||||
{
|
||||
if( peripheralCap == null ) peripheralCap = LazyOptional.of( () -> new PrinterPeripheral( this ) );
|
||||
return peripheralCap.cast();
|
||||
private void updateBlockState(boolean top, boolean bottom) {
|
||||
if (removed) {
|
||||
return;
|
||||
}
|
||||
|
||||
return super.getCapability( capability, facing );
|
||||
BlockState state = getCachedState();
|
||||
if (state.get(BlockPrinter.TOP) == top & state.get(BlockPrinter.BOTTOM) == bottom) {
|
||||
return;
|
||||
}
|
||||
|
||||
getWorld().setBlockState(getPos(),
|
||||
state.with(BlockPrinter.TOP, top)
|
||||
.with(BlockPrinter.BOTTOM, bottom));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName()
|
||||
{
|
||||
public boolean hasCustomName() {
|
||||
return customName != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Text getCustomName()
|
||||
{
|
||||
public Text getCustomName() {
|
||||
return customName;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Text getName()
|
||||
{
|
||||
return customName != null ? customName : new TranslatableText( getCachedState().getBlock().getTranslationKey() );
|
||||
public Text getName() {
|
||||
return customName != null ? customName : new TranslatableText(getCachedState().getBlock()
|
||||
.getTranslationKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDisplayName()
|
||||
{
|
||||
public Text getDisplayName() {
|
||||
return Nameable.super.getDisplayName();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ScreenHandler createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player )
|
||||
{
|
||||
return new ContainerPrinter( id, inventory, this );
|
||||
public ScreenHandler createMenu(int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player) {
|
||||
return new ContainerPrinter(id, inventory, this);
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType()
|
||||
public String getType0()
|
||||
{
|
||||
return "speaker";
|
||||
}
|
||||
|
@ -15,16 +15,18 @@ import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.network.NetworkHandler;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import dan200.computercraft.shared.util.NBTUtil;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@ -33,6 +35,8 @@ import java.util.Map;
|
||||
|
||||
import static dan200.computercraft.shared.pocket.items.ItemPocketComputer.NBT_LIGHT;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
|
||||
public class PocketServerComputer extends ServerComputer implements IPocketAccess
|
||||
{
|
||||
private IPocketUpgrade m_upgrade;
|
||||
@ -84,7 +88,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
||||
public int getLight()
|
||||
{
|
||||
CompoundTag tag = getUserData();
|
||||
return tag.contains( NBT_LIGHT, Constants.NBT.TAG_ANY_NUMERIC ) ? tag.getInt( NBT_LIGHT ) : -1;
|
||||
return tag.contains(NBT_LIGHT, NBTUtil.TAG_ANY_NUMERIC) ? tag.getInt(NBT_LIGHT ) : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -93,13 +97,13 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
||||
CompoundTag tag = getUserData();
|
||||
if( colour >= 0 && colour <= 0xFFFFFF )
|
||||
{
|
||||
if( !tag.contains( NBT_LIGHT, Constants.NBT.TAG_ANY_NUMERIC ) || tag.getInt( NBT_LIGHT ) != colour )
|
||||
if( !tag.contains( NBT_LIGHT, NBTUtil.TAG_ANY_NUMERIC ) || tag.getInt( NBT_LIGHT ) != colour )
|
||||
{
|
||||
tag.putInt( NBT_LIGHT, colour );
|
||||
updateUserData();
|
||||
}
|
||||
}
|
||||
else if( tag.contains( NBT_LIGHT, Constants.NBT.TAG_ANY_NUMERIC ) )
|
||||
else if( tag.contains( NBT_LIGHT, NBTUtil.TAG_ANY_NUMERIC ) )
|
||||
{
|
||||
tag.remove( NBT_LIGHT );
|
||||
updateUserData();
|
||||
|
@ -3,8 +3,13 @@
|
||||
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
@ -19,175 +24,148 @@ import dan200.computercraft.shared.computer.blocks.TileComputerBase;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.ComputerState;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.network.Containers;
|
||||
import dan200.computercraft.shared.turtle.apis.TurtleAPI;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle.MoveState;
|
||||
import dan200.computercraft.shared.turtle.core.TurtleBrain;
|
||||
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
||||
import dan200.computercraft.shared.util.*;
|
||||
import dan200.computercraft.shared.util.DefaultInventory;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import dan200.computercraft.shared.util.NBTUtil;
|
||||
import dan200.computercraft.shared.util.NamedBlockEntityType;
|
||||
import dan200.computercraft.shared.util.RedstoneUtil;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.DyeItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.DyeColor;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Nameable;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
|
||||
import static dan200.computercraft.shared.Capabilities.CAPABILITY_PERIPHERAL;
|
||||
import static net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY;
|
||||
|
||||
public class TileTurtle extends TileComputerBase implements ITurtleTile, DefaultInventory
|
||||
{
|
||||
public class TileTurtle extends TileComputerBase implements ITurtleTile, DefaultInventory, Nameable {
|
||||
public static final int INVENTORY_SIZE = 16;
|
||||
public static final int INVENTORY_WIDTH = 4;
|
||||
public static final int INVENTORY_HEIGHT = 4;
|
||||
public static final NamedBlockEntityType<TileTurtle> FACTORY_NORMAL = NamedBlockEntityType.create(new Identifier(ComputerCraft.MOD_ID, "turtle_normal"),
|
||||
type -> new TileTurtle(type, ComputerFamily.NORMAL));
|
||||
|
||||
enum MoveState
|
||||
{
|
||||
NOT_MOVED,
|
||||
IN_PROGRESS,
|
||||
MOVED
|
||||
public static final NamedBlockEntityType<TileTurtle> FACTORY_ADVANCED = NamedBlockEntityType.create(new Identifier(ComputerCraft.MOD_ID,
|
||||
"turtle_advanced"),
|
||||
type -> new TileTurtle(type,
|
||||
ComputerFamily.ADVANCED));
|
||||
|
||||
enum MoveState {
|
||||
NOT_MOVED, IN_PROGRESS, MOVED
|
||||
}
|
||||
|
||||
private final DefaultedList<ItemStack> m_inventory = DefaultedList.ofSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
private final DefaultedList<ItemStack> m_previousInventory = DefaultedList.ofSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
private final IItemHandlerModifiable m_itemHandler = new InvWrapper( this );
|
||||
private LazyOptional<IItemHandlerModifiable> itemHandlerCap;
|
||||
private boolean m_inventoryChanged = false;
|
||||
private TurtleBrain m_brain = new TurtleBrain( this );
|
||||
private MoveState m_moveState = MoveState.NOT_MOVED;
|
||||
private LazyOptional<IPeripheral> peripheral;
|
||||
private DefaultedList<ItemStack> m_inventory;
|
||||
private DefaultedList<ItemStack> m_previousInventory;
|
||||
private boolean m_inventoryChanged;
|
||||
private TurtleBrain m_brain;
|
||||
private MoveState m_moveState;
|
||||
|
||||
public TileTurtle( BlockEntityType<? extends TileGeneric> type, ComputerFamily family )
|
||||
{
|
||||
super( type, family );
|
||||
public TileTurtle(BlockEntityType<? extends TileGeneric> type, ComputerFamily family) {
|
||||
super(type, family);
|
||||
this.m_inventory = DefaultedList.ofSize(INVENTORY_SIZE, ItemStack.EMPTY);
|
||||
this.m_previousInventory = DefaultedList.ofSize(INVENTORY_SIZE, ItemStack.EMPTY);
|
||||
this.m_inventoryChanged = false;
|
||||
this.m_brain = new TurtleBrain(this);
|
||||
this.m_moveState = MoveState.NOT_MOVED;
|
||||
}
|
||||
|
||||
private boolean hasMoved()
|
||||
{
|
||||
return m_moveState == MoveState.MOVED;
|
||||
private boolean hasMoved() {
|
||||
return this.m_moveState == MoveState.MOVED;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerComputer createComputer( int instanceID, int id )
|
||||
{
|
||||
ServerComputer computer = new ServerComputer(
|
||||
getWorld(), id, label, instanceID, getFamily(),
|
||||
ComputerCraft.turtleTermWidth, ComputerCraft.turtleTermHeight
|
||||
);
|
||||
computer.setPosition( getPos() );
|
||||
computer.addAPI( new TurtleAPI( computer.getAPIEnvironment(), getAccess() ) );
|
||||
m_brain.setupComputer( computer );
|
||||
protected ServerComputer createComputer(int instanceID, int id) {
|
||||
ServerComputer computer = new ServerComputer(this.getWorld(),
|
||||
id,
|
||||
this.label,
|
||||
instanceID,
|
||||
this.getFamily(),
|
||||
ComputerCraft.turtleTermWidth,
|
||||
ComputerCraft.turtleTermHeight);
|
||||
computer.setPosition(this.getPos());
|
||||
computer.addAPI(new TurtleAPI(computer.getAPIEnvironment(), this.getAccess()));
|
||||
this.m_brain.setupComputer(computer);
|
||||
return computer;
|
||||
}
|
||||
|
||||
public ComputerProxy createProxy()
|
||||
{
|
||||
return m_brain.getProxy();
|
||||
@Override
|
||||
public ComputerProxy createProxy() {
|
||||
return this.m_brain.getProxy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
if( !hasMoved() )
|
||||
{
|
||||
public void destroy() {
|
||||
if (!this.hasMoved()) {
|
||||
// Stop computer
|
||||
super.destroy();
|
||||
|
||||
// Drop contents
|
||||
if( !getWorld().isClient )
|
||||
{
|
||||
int size = size();
|
||||
for( int i = 0; i < size; i++ )
|
||||
{
|
||||
ItemStack stack = getStack( i );
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
WorldUtil.dropItemStack( stack, getWorld(), getPos() );
|
||||
if (!this.getWorld().isClient) {
|
||||
int size = this.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
ItemStack stack = this.getStack(i);
|
||||
if (!stack.isEmpty()) {
|
||||
WorldUtil.dropItemStack(stack, this.getWorld(), this.getPos());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Just turn off any redstone we had on
|
||||
for( Direction dir : DirectionUtil.FACINGS )
|
||||
{
|
||||
RedstoneUtil.propagateRedstoneOutput( getWorld(), getPos(), dir );
|
||||
for (Direction dir : DirectionUtil.FACINGS) {
|
||||
RedstoneUtil.propagateRedstoneOutput(this.getWorld(), this.getPos(), dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void unload()
|
||||
{
|
||||
if( !hasMoved() )
|
||||
{
|
||||
protected void unload() {
|
||||
if (!this.hasMoved()) {
|
||||
super.unload();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invalidateCaps()
|
||||
{
|
||||
super.invalidateCaps();
|
||||
itemHandlerCap = CapabilityUtil.invalidate( itemHandlerCap );
|
||||
peripheral = CapabilityUtil.invalidate( peripheral );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit )
|
||||
{
|
||||
public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
// Apply dye
|
||||
ItemStack currentItem = player.getStackInHand( hand );
|
||||
if( !currentItem.isEmpty() )
|
||||
{
|
||||
if( currentItem.getItem() instanceof DyeItem )
|
||||
{
|
||||
ItemStack currentItem = player.getStackInHand(hand);
|
||||
if (!currentItem.isEmpty()) {
|
||||
if (currentItem.getItem() instanceof DyeItem) {
|
||||
// Dye to change turtle colour
|
||||
if( !getWorld().isClient )
|
||||
{
|
||||
if (!this.getWorld().isClient) {
|
||||
DyeColor dye = ((DyeItem) currentItem.getItem()).getColor();
|
||||
if( m_brain.getDyeColour() != dye )
|
||||
{
|
||||
m_brain.setDyeColour( dye );
|
||||
if( !player.isCreative() )
|
||||
{
|
||||
currentItem.decrement( 1 );
|
||||
if (this.m_brain.getDyeColour() != dye) {
|
||||
this.m_brain.setDyeColour(dye);
|
||||
if (!player.isCreative()) {
|
||||
currentItem.decrement(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
else if( currentItem.getItem() == Items.WATER_BUCKET && m_brain.getColour() != -1 )
|
||||
{
|
||||
} else if (currentItem.getItem() == Items.WATER_BUCKET && this.m_brain.getColour() != -1) {
|
||||
// Water to remove turtle colour
|
||||
if( !getWorld().isClient )
|
||||
{
|
||||
if( m_brain.getColour() != -1 )
|
||||
{
|
||||
m_brain.setColour( -1 );
|
||||
if( !player.isCreative() )
|
||||
{
|
||||
player.setStackInHand( hand, new ItemStack( Items.BUCKET ) );
|
||||
if (!this.getWorld().isClient) {
|
||||
if (this.m_brain.getColour() != -1) {
|
||||
this.m_brain.setColour(-1);
|
||||
if (!player.isCreative()) {
|
||||
player.setStackInHand(hand, new ItemStack(Items.BUCKET));
|
||||
player.inventory.markDirty();
|
||||
}
|
||||
}
|
||||
@ -197,279 +175,271 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
}
|
||||
|
||||
// Open GUI or whatever
|
||||
return super.onActivate( player, hand, hit );
|
||||
return super.onActivate(player, hand, hit);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canNameWithTag( PlayerEntity player )
|
||||
{
|
||||
public void openGui(PlayerEntity entity) {
|
||||
Containers.openTurtleGUI(entity, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canNameWithTag(PlayerEntity player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double getInteractRange( PlayerEntity player )
|
||||
{
|
||||
protected double getInteractRange(PlayerEntity player) {
|
||||
return 12.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
public void tick() {
|
||||
super.tick();
|
||||
m_brain.update();
|
||||
if( !getWorld().isClient && m_inventoryChanged )
|
||||
{
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null ) computer.queueEvent( "turtle_inventory" );
|
||||
this.m_brain.update();
|
||||
if (!this.getWorld().isClient && this.m_inventoryChanged) {
|
||||
ServerComputer computer = this.getServerComputer();
|
||||
if (computer != null) {
|
||||
computer.queueEvent("turtle_inventory");
|
||||
}
|
||||
|
||||
m_inventoryChanged = false;
|
||||
for( int n = 0; n < size(); n++ )
|
||||
{
|
||||
m_previousInventory.set( n, getStack( n ).copy() );
|
||||
this.m_inventoryChanged = false;
|
||||
for (int n = 0; n < this.size(); n++) {
|
||||
this.m_previousInventory.set(n,
|
||||
this.getStack(n)
|
||||
.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateBlockState( ComputerState newState )
|
||||
{
|
||||
protected void updateBlockState(ComputerState newState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||
{
|
||||
if( m_moveState == MoveState.NOT_MOVED ) super.onNeighbourChange( neighbour );
|
||||
public void onNeighbourChange(@Nonnull BlockPos neighbour) {
|
||||
if (this.m_moveState == MoveState.NOT_MOVED) {
|
||||
super.onNeighbourChange(neighbour);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
||||
{
|
||||
if( m_moveState == MoveState.NOT_MOVED ) super.onNeighbourTileEntityChange( neighbour );
|
||||
public void onNeighbourTileEntityChange(@Nonnull BlockPos neighbour) {
|
||||
if (this.m_moveState == MoveState.NOT_MOVED) {
|
||||
super.onNeighbourTileEntityChange(neighbour);
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyMoveStart()
|
||||
{
|
||||
if( m_moveState == MoveState.NOT_MOVED ) m_moveState = MoveState.IN_PROGRESS;
|
||||
public void notifyMoveStart() {
|
||||
if (this.m_moveState == MoveState.NOT_MOVED) {
|
||||
this.m_moveState = MoveState.IN_PROGRESS;
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyMoveEnd()
|
||||
{
|
||||
public void notifyMoveEnd() {
|
||||
// MoveState.MOVED is final
|
||||
if( m_moveState == MoveState.IN_PROGRESS ) m_moveState = MoveState.NOT_MOVED;
|
||||
if (this.m_moveState == MoveState.IN_PROGRESS) {
|
||||
this.m_moveState = MoveState.NOT_MOVED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt )
|
||||
{
|
||||
super.fromTag( state, nbt );
|
||||
public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) {
|
||||
super.fromTag(state, nbt);
|
||||
|
||||
// Read inventory
|
||||
ListTag nbttaglist = nbt.getList( "Items", Constants.NBT.TAG_COMPOUND );
|
||||
m_inventory.clear();
|
||||
m_previousInventory.clear();
|
||||
for( int i = 0; i < nbttaglist.size(); i++ )
|
||||
{
|
||||
CompoundTag tag = nbttaglist.getCompound( i );
|
||||
int slot = tag.getByte( "Slot" ) & 0xff;
|
||||
if( slot < size() )
|
||||
{
|
||||
m_inventory.set( slot, ItemStack.fromTag( tag ) );
|
||||
m_previousInventory.set( slot, m_inventory.get( slot ).copy() );
|
||||
ListTag nbttaglist = nbt.getList("Items", NBTUtil.TAG_COMPOUND);
|
||||
this.m_inventory.clear();
|
||||
this.m_previousInventory.clear();
|
||||
for (int i = 0; i < nbttaglist.size(); i++) {
|
||||
CompoundTag tag = nbttaglist.getCompound(i);
|
||||
int slot = tag.getByte("Slot") & 0xff;
|
||||
if (slot < this.size()) {
|
||||
this.m_inventory.set(slot, ItemStack.fromTag(tag));
|
||||
this.m_previousInventory.set(slot,
|
||||
this.m_inventory.get(slot)
|
||||
.copy());
|
||||
}
|
||||
}
|
||||
|
||||
// Read state
|
||||
m_brain.readFromNBT( nbt );
|
||||
this.m_brain.readFromNBT(nbt);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public CompoundTag toTag( @Nonnull CompoundTag nbt )
|
||||
{
|
||||
public CompoundTag toTag(@Nonnull CompoundTag nbt) {
|
||||
// Write inventory
|
||||
ListTag nbttaglist = new ListTag();
|
||||
for( int i = 0; i < INVENTORY_SIZE; i++ )
|
||||
{
|
||||
if( !m_inventory.get( i ).isEmpty() )
|
||||
{
|
||||
for (int i = 0; i < INVENTORY_SIZE; i++) {
|
||||
if (!this.m_inventory.get(i)
|
||||
.isEmpty()) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putByte( "Slot", (byte) i );
|
||||
m_inventory.get( i ).toTag( tag );
|
||||
nbttaglist.add( tag );
|
||||
tag.putByte("Slot", (byte) i);
|
||||
this.m_inventory.get(i)
|
||||
.toTag(tag);
|
||||
nbttaglist.add(tag);
|
||||
}
|
||||
}
|
||||
nbt.put( "Items", nbttaglist );
|
||||
nbt.put("Items", nbttaglist);
|
||||
|
||||
// Write brain
|
||||
nbt = m_brain.writeToNBT( nbt );
|
||||
nbt = this.m_brain.writeToNBT(nbt);
|
||||
|
||||
return super.toTag( nbt );
|
||||
return super.toTag(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isPeripheralBlockedOnSide( ComputerSide localSide )
|
||||
{
|
||||
return hasPeripheralUpgradeOnSide( localSide );
|
||||
protected boolean isPeripheralBlockedOnSide(ComputerSide localSide) {
|
||||
return this.hasPeripheralUpgradeOnSide(localSide);
|
||||
}
|
||||
|
||||
// IDirectionalTile
|
||||
|
||||
@Override
|
||||
public Direction getDirection()
|
||||
{
|
||||
return getCachedState().get( BlockTurtle.FACING );
|
||||
public Direction getDirection() {
|
||||
return this.getCachedState()
|
||||
.get(BlockTurtle.FACING);
|
||||
}
|
||||
|
||||
public void setDirection( Direction dir )
|
||||
{
|
||||
if( dir.getAxis() == Direction.Axis.Y ) dir = Direction.NORTH;
|
||||
world.setBlockState( pos, getCachedState().with( BlockTurtle.FACING, dir ) );
|
||||
updateOutput();
|
||||
updateInput();
|
||||
onTileEntityChange();
|
||||
public void setDirection(Direction dir) {
|
||||
if (dir.getAxis() == Direction.Axis.Y) {
|
||||
dir = Direction.NORTH;
|
||||
}
|
||||
this.world.setBlockState(this.pos,
|
||||
this.getCachedState()
|
||||
.with(BlockTurtle.FACING, dir));
|
||||
this.updateOutput();
|
||||
this.updateInput();
|
||||
this.onTileEntityChange();
|
||||
}
|
||||
|
||||
// ITurtleTile
|
||||
|
||||
@Override
|
||||
public ITurtleUpgrade getUpgrade( TurtleSide side )
|
||||
{
|
||||
return m_brain.getUpgrade( side );
|
||||
public ITurtleUpgrade getUpgrade(TurtleSide side) {
|
||||
return this.m_brain.getUpgrade(side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColour()
|
||||
{
|
||||
return m_brain.getColour();
|
||||
public int getColour() {
|
||||
return this.m_brain.getColour();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getOverlay()
|
||||
{
|
||||
return m_brain.getOverlay();
|
||||
public Identifier getOverlay() {
|
||||
return this.m_brain.getOverlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtleAccess getAccess()
|
||||
{
|
||||
return m_brain;
|
||||
public ITurtleAccess getAccess() {
|
||||
return this.m_brain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3d getRenderOffset( float f )
|
||||
{
|
||||
return m_brain.getRenderOffset( f );
|
||||
public Vec3d getRenderOffset(float f) {
|
||||
return this.m_brain.getRenderOffset(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRenderYaw( float f )
|
||||
{
|
||||
return m_brain.getVisualYaw( f );
|
||||
public float getRenderYaw(float f) {
|
||||
return this.m_brain.getVisualYaw(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getToolRenderAngle( TurtleSide side, float f )
|
||||
{
|
||||
return m_brain.getToolRenderAngle( side, f );
|
||||
public float getToolRenderAngle(TurtleSide side, float f) {
|
||||
return this.m_brain.getToolRenderAngle(side, f);
|
||||
}
|
||||
|
||||
void setOwningPlayer( GameProfile player )
|
||||
{
|
||||
m_brain.setOwningPlayer( player );
|
||||
markDirty();
|
||||
void setOwningPlayer(GameProfile player) {
|
||||
this.m_brain.setOwningPlayer(player);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
// IInventory
|
||||
|
||||
@Override
|
||||
public int size()
|
||||
{
|
||||
public int size() {
|
||||
return INVENTORY_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
for( ItemStack stack : m_inventory )
|
||||
{
|
||||
if( !stack.isEmpty() ) return false;
|
||||
public boolean isEmpty() {
|
||||
for (ItemStack stack : this.m_inventory) {
|
||||
if (!stack.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getStack( int slot )
|
||||
{
|
||||
return slot >= 0 && slot < INVENTORY_SIZE ? m_inventory.get( slot ) : ItemStack.EMPTY;
|
||||
public ItemStack getStack(int slot) {
|
||||
return slot >= 0 && slot < INVENTORY_SIZE ? this.m_inventory.get(slot) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack removeStack( int slot )
|
||||
{
|
||||
ItemStack result = getStack( slot );
|
||||
setStack( slot, ItemStack.EMPTY );
|
||||
public ItemStack removeStack(int slot) {
|
||||
ItemStack result = this.getStack(slot);
|
||||
this.setStack(slot, ItemStack.EMPTY);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack removeStack( int slot, int count )
|
||||
{
|
||||
if( count == 0 ) return ItemStack.EMPTY;
|
||||
public ItemStack removeStack(int slot, int count) {
|
||||
if (count == 0) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
ItemStack stack = getStack( slot );
|
||||
if( stack.isEmpty() ) return ItemStack.EMPTY;
|
||||
ItemStack stack = this.getStack(slot);
|
||||
if (stack.isEmpty()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if( stack.getCount() <= count )
|
||||
{
|
||||
setStack( slot, ItemStack.EMPTY );
|
||||
if (stack.getCount() <= count) {
|
||||
this.setStack(slot, ItemStack.EMPTY);
|
||||
return stack;
|
||||
}
|
||||
|
||||
ItemStack part = stack.split( count );
|
||||
onInventoryDefinitelyChanged();
|
||||
ItemStack part = stack.split(count);
|
||||
this.onInventoryDefinitelyChanged();
|
||||
return part;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStack( int i, @Nonnull ItemStack stack )
|
||||
{
|
||||
if( i >= 0 && i < INVENTORY_SIZE && !InventoryUtil.areItemsEqual( stack, m_inventory.get( i ) ) )
|
||||
{
|
||||
m_inventory.set( i, stack );
|
||||
onInventoryDefinitelyChanged();
|
||||
public void setStack(int i, @Nonnull ItemStack stack) {
|
||||
if (i >= 0 && i < INVENTORY_SIZE && !InventoryUtil.areItemsEqual(stack, this.m_inventory.get(i))) {
|
||||
this.m_inventory.set(i, stack);
|
||||
this.onInventoryDefinitelyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
public void clear() {
|
||||
boolean changed = false;
|
||||
for( int i = 0; i < INVENTORY_SIZE; i++ )
|
||||
{
|
||||
if( !m_inventory.get( i ).isEmpty() )
|
||||
{
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
for (int i = 0; i < INVENTORY_SIZE; i++) {
|
||||
if (!this.m_inventory.get(i)
|
||||
.isEmpty()) {
|
||||
this.m_inventory.set(i, ItemStack.EMPTY);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( changed ) onInventoryDefinitelyChanged();
|
||||
if (changed) {
|
||||
this.onInventoryDefinitelyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty()
|
||||
{
|
||||
public void markDirty() {
|
||||
super.markDirty();
|
||||
if( !m_inventoryChanged )
|
||||
{
|
||||
for( int n = 0; n < size(); n++ )
|
||||
{
|
||||
if( !ItemStack.areEqual( getStack( n ), m_previousInventory.get( n ) ) )
|
||||
{
|
||||
m_inventoryChanged = true;
|
||||
if (!this.m_inventoryChanged) {
|
||||
for (int n = 0; n < this.size(); n++) {
|
||||
if (!ItemStack.areEqual(this.getStack(n), this.m_previousInventory.get(n))) {
|
||||
this.m_inventoryChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -477,103 +447,65 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayerUse( @Nonnull PlayerEntity player )
|
||||
{
|
||||
return isUsable( player, false );
|
||||
public boolean canPlayerUse(@Nonnull PlayerEntity player) {
|
||||
return this.isUsable(player, false);
|
||||
}
|
||||
|
||||
private void onInventoryDefinitelyChanged()
|
||||
{
|
||||
private void onInventoryDefinitelyChanged() {
|
||||
super.markDirty();
|
||||
m_inventoryChanged = true;
|
||||
this.m_inventoryChanged = true;
|
||||
}
|
||||
|
||||
public void onTileEntityChange()
|
||||
{
|
||||
public void onTileEntityChange() {
|
||||
super.markDirty();
|
||||
}
|
||||
|
||||
// Networking stuff
|
||||
|
||||
@Override
|
||||
protected void writeDescription( @Nonnull CompoundTag nbt )
|
||||
{
|
||||
super.writeDescription( nbt );
|
||||
m_brain.writeDescription( nbt );
|
||||
protected void writeDescription(@Nonnull CompoundTag nbt) {
|
||||
super.writeDescription(nbt);
|
||||
this.m_brain.writeDescription(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readDescription( @Nonnull CompoundTag nbt )
|
||||
{
|
||||
super.readDescription( nbt );
|
||||
m_brain.readDescription( nbt );
|
||||
protected void readDescription(@Nonnull CompoundTag nbt) {
|
||||
super.readDescription(nbt);
|
||||
this.m_brain.readDescription(nbt);
|
||||
}
|
||||
|
||||
// Privates
|
||||
|
||||
private boolean hasPeripheralUpgradeOnSide( ComputerSide side )
|
||||
{
|
||||
private boolean hasPeripheralUpgradeOnSide(ComputerSide side) {
|
||||
ITurtleUpgrade upgrade;
|
||||
switch( side )
|
||||
{
|
||||
case RIGHT:
|
||||
upgrade = getUpgrade( TurtleSide.RIGHT );
|
||||
break;
|
||||
case LEFT:
|
||||
upgrade = getUpgrade( TurtleSide.LEFT );
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
switch (side) {
|
||||
case RIGHT:
|
||||
upgrade = this.getUpgrade(TurtleSide.RIGHT);
|
||||
break;
|
||||
case LEFT:
|
||||
upgrade = this.getUpgrade(TurtleSide.LEFT);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return upgrade != null && upgrade.getType().isPeripheral();
|
||||
return upgrade != null && upgrade.getType()
|
||||
.isPeripheral();
|
||||
}
|
||||
|
||||
public void transferStateFrom( TileTurtle copy )
|
||||
{
|
||||
super.transferStateFrom( copy );
|
||||
Collections.copy( m_inventory, copy.m_inventory );
|
||||
Collections.copy( m_previousInventory, copy.m_previousInventory );
|
||||
m_inventoryChanged = copy.m_inventoryChanged;
|
||||
m_brain = copy.m_brain;
|
||||
m_brain.setOwner( this );
|
||||
public void transferStateFrom(TileTurtle copy) {
|
||||
super.transferStateFrom(copy);
|
||||
Collections.copy(this.m_inventory, copy.m_inventory);
|
||||
Collections.copy(this.m_previousInventory, copy.m_previousInventory);
|
||||
this.m_inventoryChanged = copy.m_inventoryChanged;
|
||||
this.m_brain = copy.m_brain;
|
||||
this.m_brain.setOwner(this);
|
||||
|
||||
// Mark the other turtle as having moved, and so its peripheral is dead.
|
||||
copy.m_moveState = MoveState.MOVED;
|
||||
copy.peripheral = CapabilityUtil.invalidate( copy.peripheral );
|
||||
}
|
||||
|
||||
public IItemHandlerModifiable getItemHandler()
|
||||
{
|
||||
return m_itemHandler;
|
||||
public IPeripheral getPeripheral(@Nonnull Direction side) {
|
||||
return hasMoved() ? null : new ComputerPeripheral("turtle", createProxy());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability( @Nonnull Capability<T> cap, @Nullable Direction side )
|
||||
{
|
||||
if( cap == ITEM_HANDLER_CAPABILITY )
|
||||
{
|
||||
if( itemHandlerCap == null ) itemHandlerCap = LazyOptional.of( () -> new InvWrapper( this ) );
|
||||
return itemHandlerCap.cast();
|
||||
}
|
||||
|
||||
if( cap == CAPABILITY_PERIPHERAL )
|
||||
{
|
||||
if( hasMoved() ) return LazyOptional.empty();
|
||||
if( peripheral == null )
|
||||
{
|
||||
peripheral = LazyOptional.of( () -> new ComputerPeripheral( "turtle", createProxy() ) );
|
||||
}
|
||||
return peripheral.cast();
|
||||
}
|
||||
|
||||
return super.getCapability( cap, side );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ScreenHandler createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player )
|
||||
{
|
||||
return new ContainerTurtle( id, inventory, m_brain );
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ public class TurtleBrain implements ITurtleAccess
|
||||
m_selectedSlot = nbt.getInt( NBT_SLOT );
|
||||
|
||||
// Read owner
|
||||
if( nbt.contains( "Owner", Constants.NBT.TAG_COMPOUND ) )
|
||||
if( nbt.contains( "Owner", NBTUtil.TAG_COMPOUND ) )
|
||||
{
|
||||
CompoundTag owner = nbt.getCompound( "Owner" );
|
||||
m_owningPlayer = new GameProfile(
|
||||
|
@ -3,16 +3,20 @@
|
||||
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.turtle.inventory;
|
||||
|
||||
import dan200.computercraft.shared.Registry;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.shared.computer.core.IComputer;
|
||||
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
||||
import dan200.computercraft.shared.computer.core.InputState;
|
||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.turtle.core.TurtleBrain;
|
||||
import dan200.computercraft.shared.util.SingleIntArray;
|
||||
import dan200.computercraft.shared.util.DefaultPropertyDelegate;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
@ -20,102 +24,94 @@ import net.minecraft.inventory.SimpleInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.ArrayPropertyDelegate;
|
||||
import net.minecraft.screen.PropertyDelegate;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ContainerTurtle extends ContainerComputerBase
|
||||
{
|
||||
public static final int PLAYER_START_Y = 134;
|
||||
public static final int TURTLE_START_X = 175;
|
||||
public class ContainerTurtle extends ScreenHandler implements IContainerComputer {
|
||||
private static final int PROPERTY_SLOT = 0;
|
||||
|
||||
public final int m_playerInvStartY;
|
||||
public final int m_turtleInvStartX;
|
||||
|
||||
private final Inventory inventory;
|
||||
private final PropertyDelegate properties;
|
||||
private IComputer computer;
|
||||
private final InputState input = new InputState(this);
|
||||
private int m_selectedSlot;
|
||||
|
||||
private ContainerTurtle(
|
||||
int id, Predicate<PlayerEntity> canUse, IComputer computer, ComputerFamily family,
|
||||
PlayerInventory playerInventory, Inventory inventory, PropertyDelegate properties
|
||||
)
|
||||
{
|
||||
super( Registry.ModContainers.TURTLE.get(), id, canUse, computer, family );
|
||||
private ContainerTurtle(int id, PlayerInventory playerInventory, Inventory inventory, PropertyDelegate properties, int playerInvStartY,
|
||||
int turtleInvStartX) {
|
||||
super(null, id);
|
||||
this.properties = properties;
|
||||
m_playerInvStartY = playerInvStartY;
|
||||
m_turtleInvStartX = turtleInvStartX;
|
||||
this.inventory = inventory;
|
||||
|
||||
addProperties( properties );
|
||||
addProperties(properties);
|
||||
|
||||
// Turtle inventory
|
||||
for( int y = 0; y < 4; y++ )
|
||||
{
|
||||
for( int x = 0; x < 4; x++ )
|
||||
{
|
||||
addSlot( new Slot( inventory, x + y * 4, TURTLE_START_X + 1 + x * 18, PLAYER_START_Y + 1 + y * 18 ) );
|
||||
for (int y = 0; y < 4; y++) {
|
||||
for (int x = 0; x < 4; x++) {
|
||||
addSlot(new Slot(inventory, x + y * 4, turtleInvStartX + 1 + x * 18, playerInvStartY + 1 + y * 18));
|
||||
}
|
||||
}
|
||||
|
||||
// Player inventory
|
||||
for( int y = 0; y < 3; y++ )
|
||||
{
|
||||
for( int x = 0; x < 9; x++ )
|
||||
{
|
||||
addSlot( new Slot( playerInventory, x + y * 9 + 9, 8 + x * 18, PLAYER_START_Y + 1 + y * 18 ) );
|
||||
for (int y = 0; y < 3; y++) {
|
||||
for (int x = 0; x < 9; x++) {
|
||||
addSlot(new Slot(playerInventory, x + y * 9 + 9, 8 + x * 18, playerInvStartY + 1 + y * 18));
|
||||
}
|
||||
}
|
||||
|
||||
// Player hotbar
|
||||
for( int x = 0; x < 9; x++ )
|
||||
{
|
||||
addSlot( new Slot( playerInventory, x, 8 + x * 18, PLAYER_START_Y + 3 * 18 + 5 ) );
|
||||
for (int x = 0; x < 9; x++) {
|
||||
addSlot(new Slot(playerInventory, x, 8 + x * 18, playerInvStartY + 3 * 18 + 5));
|
||||
}
|
||||
}
|
||||
|
||||
public ContainerTurtle( int id, PlayerInventory player, TurtleBrain turtle )
|
||||
{
|
||||
this(
|
||||
id, p -> turtle.getOwner().canPlayerUse( p ), turtle.getOwner().createServerComputer(), turtle.getFamily(),
|
||||
player, turtle.getInventory(), (SingleIntArray) turtle::getSelectedSlot
|
||||
);
|
||||
public ContainerTurtle(int id, PlayerInventory playerInventory, ITurtleAccess turtle, IComputer computer) {
|
||||
this(id, playerInventory, turtle.getInventory(), new DefaultPropertyDelegate() {
|
||||
@Override
|
||||
public int get(int id) {
|
||||
return id == PROPERTY_SLOT ? turtle.getSelectedSlot() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
this.computer = computer;
|
||||
}
|
||||
|
||||
public ContainerTurtle( int id, PlayerInventory player, ComputerContainerData data )
|
||||
{
|
||||
this(
|
||||
id, x -> true, getComputer( player, data ), data.getFamily(),
|
||||
player, new SimpleInventory( TileTurtle.INVENTORY_SIZE ), new ArrayPropertyDelegate( 1 )
|
||||
);
|
||||
public ContainerTurtle(int id, PlayerInventory playerInventory, Inventory inventory, PropertyDelegate properties) {
|
||||
this(id, playerInventory, inventory, properties, 134, 175);
|
||||
}
|
||||
|
||||
public int getSelectedSlot()
|
||||
{
|
||||
return properties.get( 0 );
|
||||
public int getSelectedSlot() {
|
||||
return properties.get(PROPERTY_SLOT);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private ItemStack tryItemMerge( PlayerEntity player, int slotNum, int firstSlot, int lastSlot, boolean reverse )
|
||||
{
|
||||
Slot slot = slots.get( slotNum );
|
||||
private ItemStack tryItemMerge(PlayerEntity player, int slotNum, int firstSlot, int lastSlot, boolean reverse) {
|
||||
Slot slot = slots.get(slotNum);
|
||||
ItemStack originalStack = ItemStack.EMPTY;
|
||||
if( slot != null && slot.hasStack() )
|
||||
{
|
||||
if (slot != null && slot.hasStack()) {
|
||||
ItemStack clickedStack = slot.getStack();
|
||||
originalStack = clickedStack.copy();
|
||||
if( !insertItem( clickedStack, firstSlot, lastSlot, reverse ) )
|
||||
{
|
||||
if (!insertItem(clickedStack, firstSlot, lastSlot, reverse)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if( clickedStack.isEmpty() )
|
||||
{
|
||||
slot.setStack( ItemStack.EMPTY );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clickedStack.isEmpty()) {
|
||||
slot.setStack(ItemStack.EMPTY);
|
||||
} else {
|
||||
slot.markDirty();
|
||||
}
|
||||
|
||||
if( clickedStack.getCount() != originalStack.getCount() )
|
||||
{
|
||||
slot.onTakeItem( player, clickedStack );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clickedStack.getCount() != originalStack.getCount()) {
|
||||
slot.onTakeItem(player, clickedStack);
|
||||
} else {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
@ -124,16 +120,35 @@ public class ContainerTurtle extends ContainerComputerBase
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack transferSlot( @Nonnull PlayerEntity player, int slotNum )
|
||||
{
|
||||
if( slotNum >= 0 && slotNum < 16 )
|
||||
{
|
||||
return tryItemMerge( player, slotNum, 16, 52, true );
|
||||
}
|
||||
else if( slotNum >= 16 )
|
||||
{
|
||||
return tryItemMerge( player, slotNum, 0, 16, false );
|
||||
public ItemStack transferSlot(@Nonnull PlayerEntity player, int slotNum) {
|
||||
if (slotNum >= 0 && slotNum < 16) {
|
||||
return tryItemMerge(player, slotNum, 16, 52, true);
|
||||
} else if (slotNum >= 16) {
|
||||
return tryItemMerge(player, slotNum, 0, 16, false);
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(PlayerEntity player) {
|
||||
return inventory.canPlayerUse(player);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IComputer getComputer() {
|
||||
return this.computer;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public InputState getInput() {
|
||||
return this.input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(PlayerEntity player) {
|
||||
super.close(player);
|
||||
this.input.close();
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class CraftingTablePeripheral implements IPeripheral
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType()
|
||||
public String getType0()
|
||||
{
|
||||
return "workbench";
|
||||
}
|
||||
|
@ -3,15 +3,9 @@
|
||||
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.util;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import net.minecraft.nbt.*;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
@ -21,194 +15,228 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.minecraftforge.common.util.Constants.NBT.*;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
|
||||
import net.minecraft.nbt.AbstractNumberTag;
|
||||
import net.minecraft.nbt.ByteArrayTag;
|
||||
import net.minecraft.nbt.ByteTag;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.DoubleTag;
|
||||
import net.minecraft.nbt.IntArrayTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
|
||||
public final class NBTUtil {
|
||||
public static final int TAG_END = NbtType.END;
|
||||
public static final int TAG_BYTE = NbtType.BYTE;
|
||||
public static final int TAG_SHORT = NbtType.SHORT;
|
||||
public static final int TAG_INT = NbtType.INT;
|
||||
public static final int TAG_LONG = NbtType.LONG;
|
||||
public static final int TAG_FLOAT = NbtType.FLOAT;
|
||||
public static final int TAG_DOUBLE = NbtType.DOUBLE;
|
||||
public static final int TAG_BYTE_ARRAY = NbtType.BYTE_ARRAY;
|
||||
public static final int TAG_STRING = NbtType.STRING;
|
||||
public static final int TAG_LIST = NbtType.LIST;
|
||||
public static final int TAG_COMPOUND = NbtType.COMPOUND;
|
||||
public static final int TAG_INT_ARRAY = NbtType.INT_ARRAY;
|
||||
public static final int TAG_LONG_ARRAY = NbtType.LONG_ARRAY;
|
||||
public static final int TAG_ANY_NUMERIC = NbtType.NUMBER;
|
||||
|
||||
public final class NBTUtil
|
||||
{
|
||||
private NBTUtil() {}
|
||||
|
||||
private static Tag toNBTTag( Object object )
|
||||
{
|
||||
if( object == null ) return null;
|
||||
if( object instanceof Boolean ) return ByteTag.of( (byte) ((boolean) (Boolean) object ? 1 : 0) );
|
||||
if( object instanceof Number ) return DoubleTag.of( ((Number) object).doubleValue() );
|
||||
if( object instanceof String ) return StringTag.of( object.toString() );
|
||||
if( object instanceof Map )
|
||||
{
|
||||
private static Tag toNBTTag(Object object) {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
if (object instanceof Boolean) {
|
||||
return ByteTag.of((byte) ((boolean) (Boolean) object ? 1 : 0));
|
||||
}
|
||||
if (object instanceof Number) {
|
||||
return DoubleTag.of(((Number) object).doubleValue());
|
||||
}
|
||||
if (object instanceof String) {
|
||||
return StringTag.of(object.toString());
|
||||
}
|
||||
if (object instanceof Map) {
|
||||
Map<?, ?> m = (Map<?, ?>) object;
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
int i = 0;
|
||||
for( Map.Entry<?, ?> entry : m.entrySet() )
|
||||
{
|
||||
Tag key = toNBTTag( entry.getKey() );
|
||||
Tag value = toNBTTag( entry.getKey() );
|
||||
if( key != null && value != null )
|
||||
{
|
||||
nbt.put( "k" + i, key );
|
||||
nbt.put( "v" + i, value );
|
||||
for (Map.Entry<?, ?> entry : m.entrySet()) {
|
||||
Tag key = toNBTTag(entry.getKey());
|
||||
Tag value = toNBTTag(entry.getKey());
|
||||
if (key != null && value != null) {
|
||||
nbt.put("k" + i, key);
|
||||
nbt.put("v" + i, value);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
nbt.putInt( "len", m.size() );
|
||||
nbt.putInt("len", m.size());
|
||||
return nbt;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static CompoundTag encodeObjects( Object[] objects )
|
||||
{
|
||||
if( objects == null || objects.length <= 0 ) return null;
|
||||
public static CompoundTag encodeObjects(Object[] objects) {
|
||||
if (objects == null || objects.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
nbt.putInt( "len", objects.length );
|
||||
for( int i = 0; i < objects.length; i++ )
|
||||
{
|
||||
Tag child = toNBTTag( objects[i] );
|
||||
if( child != null ) nbt.put( Integer.toString( i ), child );
|
||||
nbt.putInt("len", objects.length);
|
||||
for (int i = 0; i < objects.length; i++) {
|
||||
Tag child = toNBTTag(objects[i]);
|
||||
if (child != null) {
|
||||
nbt.put(Integer.toString(i), child);
|
||||
}
|
||||
}
|
||||
return nbt;
|
||||
}
|
||||
|
||||
private static Object fromNBTTag( Tag tag )
|
||||
{
|
||||
if( tag == null ) return null;
|
||||
switch( tag.getType() )
|
||||
{
|
||||
case TAG_BYTE:
|
||||
return ((ByteTag) tag).getByte() > 0;
|
||||
case TAG_DOUBLE:
|
||||
return ((DoubleTag) tag).getDouble();
|
||||
default:
|
||||
case TAG_STRING:
|
||||
return tag.asString();
|
||||
case TAG_COMPOUND:
|
||||
{
|
||||
CompoundTag c = (CompoundTag) tag;
|
||||
int len = c.getInt( "len" );
|
||||
Map<Object, Object> map = new HashMap<>( len );
|
||||
for( int i = 0; i < len; i++ )
|
||||
{
|
||||
Object key = fromNBTTag( c.get( "k" + i ) );
|
||||
Object value = fromNBTTag( c.get( "v" + i ) );
|
||||
if( key != null && value != null ) map.put( key, value );
|
||||
private static Object fromNBTTag(Tag tag) {
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
switch (tag.getType()) {
|
||||
case TAG_BYTE:
|
||||
return ((ByteTag) tag).getByte() > 0;
|
||||
case TAG_DOUBLE:
|
||||
return ((DoubleTag) tag).getDouble();
|
||||
default:
|
||||
case TAG_STRING:
|
||||
return tag.asString();
|
||||
case TAG_COMPOUND: {
|
||||
CompoundTag c = (CompoundTag) tag;
|
||||
int len = c.getInt("len");
|
||||
Map<Object, Object> map = new HashMap<>(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
Object key = fromNBTTag(c.get("k" + i));
|
||||
Object value = fromNBTTag(c.get("v" + i));
|
||||
if (key != null && value != null) {
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Object toLua( Tag tag )
|
||||
{
|
||||
if( tag == null ) return null;
|
||||
public static Object toLua(Tag tag) {
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte typeID = tag.getType();
|
||||
switch( typeID )
|
||||
switch (typeID) {
|
||||
case NBTUtil.TAG_BYTE:
|
||||
case NBTUtil.TAG_SHORT:
|
||||
case NBTUtil.TAG_INT:
|
||||
case NBTUtil.TAG_LONG:
|
||||
return ((AbstractNumberTag) tag).getLong();
|
||||
case NBTUtil.TAG_FLOAT:
|
||||
case NBTUtil.TAG_DOUBLE:
|
||||
return ((AbstractNumberTag) tag).getDouble();
|
||||
case NBTUtil.TAG_STRING: // String
|
||||
return tag.asString();
|
||||
case NBTUtil.TAG_COMPOUND: // Compound
|
||||
{
|
||||
case Constants.NBT.TAG_BYTE:
|
||||
case Constants.NBT.TAG_SHORT:
|
||||
case Constants.NBT.TAG_INT:
|
||||
case Constants.NBT.TAG_LONG:
|
||||
return ((AbstractNumberTag) tag).getLong();
|
||||
case Constants.NBT.TAG_FLOAT:
|
||||
case Constants.NBT.TAG_DOUBLE:
|
||||
return ((AbstractNumberTag) tag).getDouble();
|
||||
case Constants.NBT.TAG_STRING: // String
|
||||
return tag.asString();
|
||||
case Constants.NBT.TAG_COMPOUND: // Compound
|
||||
{
|
||||
CompoundTag compound = (CompoundTag) tag;
|
||||
Map<String, Object> map = new HashMap<>( compound.getSize() );
|
||||
for( String key : compound.getKeys() )
|
||||
{
|
||||
Object value = toLua( compound.get( key ) );
|
||||
if( value != null ) map.put( key, value );
|
||||
CompoundTag compound = (CompoundTag) tag;
|
||||
Map<String, Object> map = new HashMap<>(compound.getSize());
|
||||
for (String key : compound.getKeys()) {
|
||||
Object value = toLua(compound.get(key));
|
||||
if (value != null) {
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
case Constants.NBT.TAG_LIST:
|
||||
{
|
||||
ListTag list = (ListTag) tag;
|
||||
Map<Integer, Object> map = new HashMap<>( list.size() );
|
||||
for( int i = 0; i < list.size(); i++ ) map.put( i, toLua( list.get( i ) ) );
|
||||
return map;
|
||||
return map;
|
||||
}
|
||||
case NBTUtil.TAG_LIST: {
|
||||
ListTag list = (ListTag) tag;
|
||||
Map<Integer, Object> map = new HashMap<>(list.size());
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
map.put(i, toLua(list.get(i)));
|
||||
}
|
||||
case Constants.NBT.TAG_BYTE_ARRAY:
|
||||
{
|
||||
byte[] array = ((ByteArrayTag) tag).getByteArray();
|
||||
Map<Integer, Byte> map = new HashMap<>( array.length );
|
||||
for( int i = 0; i < array.length; i++ ) map.put( i + 1, array[i] );
|
||||
return map;
|
||||
return map;
|
||||
}
|
||||
case NBTUtil.TAG_BYTE_ARRAY: {
|
||||
byte[] array = ((ByteArrayTag) tag).getByteArray();
|
||||
Map<Integer, Byte> map = new HashMap<>(array.length);
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
map.put(i + 1, array[i]);
|
||||
}
|
||||
case Constants.NBT.TAG_INT_ARRAY:
|
||||
{
|
||||
int[] array = ((IntArrayTag) tag).getIntArray();
|
||||
Map<Integer, Integer> map = new HashMap<>( array.length );
|
||||
for( int i = 0; i < array.length; i++ ) map.put( i + 1, array[i] );
|
||||
return map;
|
||||
return map;
|
||||
}
|
||||
case NBTUtil.TAG_INT_ARRAY: {
|
||||
int[] array = ((IntArrayTag) tag).getIntArray();
|
||||
Map<Integer, Integer> map = new HashMap<>(array.length);
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
map.put(i + 1, array[i]);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
default:
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object[] decodeObjects( CompoundTag tag )
|
||||
{
|
||||
int len = tag.getInt( "len" );
|
||||
if( len <= 0 ) return null;
|
||||
public static Object[] decodeObjects(CompoundTag tag) {
|
||||
int len = tag.getInt("len");
|
||||
if (len <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object[] objects = new Object[len];
|
||||
for( int i = 0; i < len; i++ )
|
||||
{
|
||||
String key = Integer.toString( i );
|
||||
if( tag.contains( key ) )
|
||||
{
|
||||
objects[i] = fromNBTTag( tag.get( key ) );
|
||||
for (int i = 0; i < len; i++) {
|
||||
String key = Integer.toString(i);
|
||||
if (tag.contains(key)) {
|
||||
objects[i] = fromNBTTag(tag.get(key));
|
||||
}
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getNBTHash( @Nullable CompoundTag tag )
|
||||
{
|
||||
if( tag == null ) return null;
|
||||
|
||||
try
|
||||
{
|
||||
MessageDigest digest = MessageDigest.getInstance( "MD5" );
|
||||
DataOutput output = new DataOutputStream( new DigestOutputStream( digest ) );
|
||||
NbtIo.write( tag, output );
|
||||
byte[] hash = digest.digest();
|
||||
return new String( Hex.encodeHex( hash ) );
|
||||
public static String getNBTHash(@Nullable CompoundTag tag) {
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
catch( NoSuchAlgorithmException | IOException e )
|
||||
{
|
||||
ComputerCraft.log.error( "Cannot hash NBT", e );
|
||||
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
DataOutput output = new DataOutputStream(new DigestOutputStream(digest));
|
||||
NbtIo.write(tag, output);
|
||||
byte[] hash = digest.digest();
|
||||
return new String(Hex.encodeHex(hash));
|
||||
} catch (NoSuchAlgorithmException | IOException e) {
|
||||
ComputerCraft.log.error("Cannot hash NBT", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DigestOutputStream extends OutputStream
|
||||
{
|
||||
private static final class DigestOutputStream extends OutputStream {
|
||||
private final MessageDigest digest;
|
||||
|
||||
DigestOutputStream( MessageDigest digest )
|
||||
{
|
||||
DigestOutputStream(MessageDigest digest) {
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write( @Nonnull byte[] b, int off, int len )
|
||||
{
|
||||
digest.update( b, off, len );
|
||||
public void write(@Nonnull byte[] b, int off, int len) {
|
||||
this.digest.update(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write( int b )
|
||||
{
|
||||
digest.update( (byte) b );
|
||||
public void write(int b) {
|
||||
this.digest.update((byte) b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
src/main/resources/computercraft.mixin.json
Normal file
15
src/main/resources/computercraft.mixin.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "dan200.computercraft.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
"BlockEntityTypeAccessor",
|
||||
"ScreenHandlerTypeAccessor"
|
||||
],
|
||||
"client": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
@ -393,7 +393,7 @@ public class NetworkTest
|
||||
{
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType()
|
||||
public String getType0()
|
||||
{
|
||||
return "test";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user