From f5f9ac79894e0fbfd56c5c4c02708e50ae1aa1c3 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Mon, 26 Aug 2019 20:17:16 +0200 Subject: [PATCH] Logistics Part II - Added Screens for Flexcrate and Stockswitch - Added Models for Flexcrate and Stockswitch - Added Container and Inventory to Flexcrate - Redstone bridges are now divided into senders and receivers - Fixed some GUI inconsistencies and repetitive code --- build.gradle | 4 +- .../java/com/simibubi/create/AllBlocks.java | 8 +- .../com/simibubi/create/AllContainers.java | 8 +- .../com/simibubi/create/AllTileEntities.java | 10 +- .../foundation/gui/AbstractSimiScreen.java | 6 +- .../foundation/gui/ScreenElementRenderer.java | 55 ++++ .../foundation/gui/ScreenResources.java | 21 +- .../foundation/gui/TextInputPromptScreen.java | 10 +- .../foundation/gui/widgets/ScrollInput.java | 155 ++--------- .../foundation/utility/ItemDescription.java | 2 +- .../placementHandgun/BuilderGunScreen.java | 10 +- .../modules/gardens/TreeFertilizerItem.java | 9 +- .../modules/logistics/FlexCrateBlock.java | 61 ++++- .../modules/logistics/FlexCrateContainer.java | 56 +++- .../modules/logistics/FlexCrateScreen.java | 80 +++++- .../logistics/FlexCrateTileEntity.java | 83 +++++- .../modules/logistics/FlexcrateBlock.java | 85 ++++++ .../modules/logistics/FlexcrateContainer.java | 79 ++++++ .../modules/logistics/FlexcrateScreen.java | 93 +++++++ .../logistics/FlexcrateTileEntity.java | 104 +++++++ .../logistics/RedstoneBridgeBlock.java | 254 +++++++++++++++++- .../logistics/RedstoneBridgeTileEntity.java | 117 +++++++- .../RedstoneBridgeTileEntityRenderer.java | 79 ++++++ .../logistics/StockpileSwitchBlock.java | 56 ---- .../logistics/StockpileSwitchScreen.java | 5 - .../logistics/StockpileSwitchTileEntity.java | 41 --- .../modules/logistics/StockswitchBlock.java | 108 ++++++++ .../modules/logistics/StockswitchScreen.java | 104 +++++++ .../logistics/StockswitchTileEntity.java | 48 ++++ .../block/SchematicTableScreen.java | 48 ++-- .../schematics/block/SchematicannonBlock.java | 2 +- .../client/BlueprintEditScreen.java | 10 +- .../modules/symmetry/SymmetryWandScreen.java | 16 +- .../assets/create/blockstates/flexcrate.json | 5 + .../create/blockstates/redstone_bridge.json | 38 ++- .../create/blockstates/stockswitch.json | 23 ++ .../resources/assets/create/lang/en_us.json | 4 +- .../create/models/block/flex_crate.json | 22 ++ .../create/models/block/redstone_bridge.json | 2 +- .../models/block/redstone_bridge_powered.json | 3 +- .../block/redstone_bridge_receiver.json | 66 +++++ .../redstone_bridge_receiver_powered.json | 8 + .../block/redstone_bridge_receiver_side.json | 70 +++++ ...redstone_bridge_receiver_side_powered.json | 8 + .../models/block/redstone_bridge_side.json | 54 ++-- .../block/redstone_bridge_side_powered.json | 3 +- .../create/models/block/stockpile_switch.json | 92 +++++++ .../models/block/stockpile_switch_1.json | 6 + .../models/block/stockpile_switch_2.json | 6 + .../models/block/stockpile_switch_3.json | 6 + .../models/block/stockpile_switch_4.json | 6 + .../models/block/stockpile_switch_5.json | 6 + .../models/block/stockpile_switch_6.json | 6 + .../assets/create/models/item/flexcrate.json | 3 + .../create/models/item/stockswitch.json | 10 + .../create/textures/block/indicator/0.png | Bin 0 -> 341 bytes .../create/textures/block/indicator/1.png | Bin 0 -> 350 bytes .../create/textures/block/indicator/2.png | Bin 0 -> 351 bytes .../create/textures/block/indicator/3.png | Bin 0 -> 351 bytes .../create/textures/block/indicator/4.png | Bin 0 -> 359 bytes .../create/textures/block/indicator/5.png | Bin 0 -> 364 bytes .../create/textures/block/indicator/6.png | Bin 0 -> 364 bytes .../textures/block/redstone_antenna.png | Bin 229 -> 297 bytes .../block/redstone_antenna_powered.png | Bin 231 -> 324 bytes .../textures/block/redstone_bridge_side.png | Bin 538 -> 543 bytes .../block/redstone_bridge_side_powered.png | Bin 544 -> 544 bytes .../gui/flex_crate_and_stockpile_switch.png | Bin 0 -> 13655 bytes 67 files changed, 1887 insertions(+), 387 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/FlexcrateBlock.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/FlexcrateContainer.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/FlexcrateScreen.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/FlexcrateTileEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeTileEntityRenderer.java delete mode 100644 src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchBlock.java delete mode 100644 src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchScreen.java delete mode 100644 src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchTileEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/StockswitchBlock.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/StockswitchScreen.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/StockswitchTileEntity.java create mode 100644 src/main/resources/assets/create/blockstates/flexcrate.json create mode 100644 src/main/resources/assets/create/blockstates/stockswitch.json create mode 100644 src/main/resources/assets/create/models/block/flex_crate.json create mode 100644 src/main/resources/assets/create/models/block/redstone_bridge_receiver.json create mode 100644 src/main/resources/assets/create/models/block/redstone_bridge_receiver_powered.json create mode 100644 src/main/resources/assets/create/models/block/redstone_bridge_receiver_side.json create mode 100644 src/main/resources/assets/create/models/block/redstone_bridge_receiver_side_powered.json create mode 100644 src/main/resources/assets/create/models/block/stockpile_switch.json create mode 100644 src/main/resources/assets/create/models/block/stockpile_switch_1.json create mode 100644 src/main/resources/assets/create/models/block/stockpile_switch_2.json create mode 100644 src/main/resources/assets/create/models/block/stockpile_switch_3.json create mode 100644 src/main/resources/assets/create/models/block/stockpile_switch_4.json create mode 100644 src/main/resources/assets/create/models/block/stockpile_switch_5.json create mode 100644 src/main/resources/assets/create/models/block/stockpile_switch_6.json create mode 100644 src/main/resources/assets/create/models/item/flexcrate.json create mode 100644 src/main/resources/assets/create/models/item/stockswitch.json create mode 100644 src/main/resources/assets/create/textures/block/indicator/0.png create mode 100644 src/main/resources/assets/create/textures/block/indicator/1.png create mode 100644 src/main/resources/assets/create/textures/block/indicator/2.png create mode 100644 src/main/resources/assets/create/textures/block/indicator/3.png create mode 100644 src/main/resources/assets/create/textures/block/indicator/4.png create mode 100644 src/main/resources/assets/create/textures/block/indicator/5.png create mode 100644 src/main/resources/assets/create/textures/block/indicator/6.png create mode 100644 src/main/resources/assets/create/textures/gui/flex_crate_and_stockpile_switch.png diff --git a/build.gradle b/build.gradle index 5dc1fea2d..76690cae7 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ archivesBaseName = 'create' sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' minecraft { - mappings channel: 'snapshot', version: '20190816-1.14.3' + mappings channel: 'snapshot', version: '20190825-1.14.3' runs { client { @@ -58,7 +58,7 @@ minecraft { } dependencies { - minecraft 'net.minecraftforge:forge:1.14.4-28.0.49' + minecraft 'net.minecraftforge:forge:1.14.4-28.0.55' } jar { diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index d95b7ecf3..6423356c9 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -25,9 +25,9 @@ import com.simibubi.create.modules.contraptions.relays.EncasedBeltBlock; import com.simibubi.create.modules.contraptions.relays.GearboxBlock; import com.simibubi.create.modules.contraptions.relays.GearshifterBlock; import com.simibubi.create.modules.gardens.CocoaLogBlock; -import com.simibubi.create.modules.logistics.FlexCrateBlock; +import com.simibubi.create.modules.logistics.FlexcrateBlock; import com.simibubi.create.modules.logistics.RedstoneBridgeBlock; -import com.simibubi.create.modules.logistics.StockpileSwitchBlock; +import com.simibubi.create.modules.logistics.StockswitchBlock; import com.simibubi.create.modules.schematics.block.CreativeCrateBlock; import com.simibubi.create.modules.schematics.block.SchematicTableBlock; import com.simibubi.create.modules.schematics.block.SchematicannonBlock; @@ -91,8 +91,8 @@ public enum AllBlocks { // Logistics REDSTONE_BRIDGE(new RedstoneBridgeBlock()), - STOCKPILE_SWITCH(new StockpileSwitchBlock()), - FLEX_CRATE(new FlexCrateBlock()), + STOCKSWITCH(new StockswitchBlock()), + FLEXCRATE(new FlexcrateBlock()), // Symmetry SYMMETRY_PLANE(new PlaneSymmetryBlock()), diff --git a/src/main/java/com/simibubi/create/AllContainers.java b/src/main/java/com/simibubi/create/AllContainers.java index 09bfa551c..4fcce3b8a 100644 --- a/src/main/java/com/simibubi/create/AllContainers.java +++ b/src/main/java/com/simibubi/create/AllContainers.java @@ -1,7 +1,7 @@ package com.simibubi.create; -import com.simibubi.create.modules.logistics.FlexCrateContainer; -import com.simibubi.create.modules.logistics.FlexCrateScreen; +import com.simibubi.create.modules.logistics.FlexcrateContainer; +import com.simibubi.create.modules.logistics.FlexcrateScreen; import com.simibubi.create.modules.schematics.block.SchematicTableContainer; import com.simibubi.create.modules.schematics.block.SchematicTableScreen; import com.simibubi.create.modules.schematics.block.SchematicannonContainer; @@ -28,7 +28,7 @@ public enum AllContainers { SchematicTable(SchematicTableContainer::new), Schematicannon(SchematicannonContainer::new), - FlexCrate(FlexCrateContainer::new), + FlexCrate(FlexcrateContainer::new), ; @@ -53,7 +53,7 @@ public enum AllContainers { public static void registerScreenFactories() { bind(SchematicTable, SchematicTableScreen::new); bind(Schematicannon, SchematicannonScreen::new); - bind(FlexCrate, FlexCrateScreen::new); + bind(FlexCrate, FlexcrateScreen::new); } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 02562b5cc..b1e0a8261 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -21,9 +21,10 @@ import com.simibubi.create.modules.contraptions.relays.GearboxTileEntity; import com.simibubi.create.modules.contraptions.relays.GearboxTileEntityRenderer; import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntity; import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntityRenderer; -import com.simibubi.create.modules.logistics.FlexCrateTileEntity; +import com.simibubi.create.modules.logistics.FlexcrateTileEntity; import com.simibubi.create.modules.logistics.RedstoneBridgeTileEntity; -import com.simibubi.create.modules.logistics.StockpileSwitchTileEntity; +import com.simibubi.create.modules.logistics.RedstoneBridgeTileEntityRenderer; +import com.simibubi.create.modules.logistics.StockswitchTileEntity; import com.simibubi.create.modules.schematics.block.SchematicTableTileEntity; import com.simibubi.create.modules.schematics.block.SchematicannonRenderer; import com.simibubi.create.modules.schematics.block.SchematicannonTileEntity; @@ -62,8 +63,8 @@ public enum AllTileEntities { // Logistics REDSTONE_BRIDGE(RedstoneBridgeTileEntity::new, AllBlocks.REDSTONE_BRIDGE), - STOCKPILE_SWITCH(StockpileSwitchTileEntity::new, AllBlocks.STOCKPILE_SWITCH), - FLEX_CRATE(FlexCrateTileEntity::new, AllBlocks.FLEX_CRATE), + STOCKSWITCH(StockswitchTileEntity::new, AllBlocks.STOCKSWITCH), + FLEXCRATE(FlexcrateTileEntity::new, AllBlocks.FLEXCRATE), ; @@ -105,6 +106,7 @@ public enum AllTileEntities { bind(DrillTileEntity.class, new KineticTileEntityRenderer()); bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer()); bind(WaterWheelTileEntity.class, new KineticTileEntityRenderer()); + bind(RedstoneBridgeTileEntity.class, new RedstoneBridgeTileEntityRenderer()); } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java index 324eb96c9..1ec2a4129 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java @@ -15,7 +15,7 @@ import net.minecraftforge.api.distmarker.OnlyIn; public abstract class AbstractSimiScreen extends Screen { protected int sWidth, sHeight; - protected int topLeftX, topLeftY; + protected int guiLeft, guiTop; protected List widgets; protected AbstractSimiScreen() { @@ -26,8 +26,8 @@ public abstract class AbstractSimiScreen extends Screen { protected void setWindowSize(int width, int height) { sWidth = width; sHeight = height; - topLeftX = (this.width - sWidth) / 2; - topLeftY = (this.height - sHeight) / 2; + guiLeft = (this.width - sWidth) / 2; + guiTop = (this.height - sHeight) / 2; } @Override diff --git a/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java b/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java new file mode 100644 index 000000000..f622f5739 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java @@ -0,0 +1,55 @@ +package com.simibubi.create.foundation.gui; + +import java.util.function.Supplier; + +import com.mojang.blaze3d.platform.GlStateManager; + +import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.texture.AtlasTexture; +import net.minecraft.item.ItemStack; + +public class ScreenElementRenderer { + + public static void render3DItem(Supplier transformsAndStack) { + GlStateManager.pushMatrix(); + + GlStateManager.enableBlend(); + GlStateManager.enableRescaleNormal(); + GlStateManager.enableAlphaTest(); + RenderHelper.enableGUIStandardItemLighting(); + GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); + + ItemStack stack = transformsAndStack.get(); + + Minecraft.getInstance().getItemRenderer().renderItemIntoGUI(stack, 0, 0); + GlStateManager.popMatrix(); + } + + public static void renderBlock(Supplier transformsAndState) { + GlStateManager.pushMatrix(); + + GlStateManager.enableBlend(); + GlStateManager.enableRescaleNormal(); + GlStateManager.enableAlphaTest(); + RenderHelper.enableGUIStandardItemLighting(); + GlStateManager.alphaFunc(516, 0.1F); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.translated(0, 0, 200); + + BlockState toRender = transformsAndState.get(); + + GlStateManager.scaled(50, -50, 50); + Minecraft mc = Minecraft.getInstance(); + mc.getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE); + mc.getBlockRendererDispatcher().renderBlockBrightness(toRender, 1); + + GlStateManager.disableAlphaTest(); + GlStateManager.disableRescaleNormal(); + + GlStateManager.popMatrix(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/ScreenResources.java b/src/main/java/com/simibubi/create/foundation/gui/ScreenResources.java index 833bf63b2..c65cc285a 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/ScreenResources.java +++ b/src/main/java/com/simibubi/create/foundation/gui/ScreenResources.java @@ -23,6 +23,17 @@ public enum ScreenResources { SCHEMATICANNON_HIGHLIGHT("schematicannon.png", 0, 182, 28, 28), SCHEMATICANNON_FUEL("schematicannon.png", 0, 215, 82, 4), + FLEXCRATE("flex_crate_and_stockpile_switch.png", 125, 129), + FLEXCRATE_LOCKED_SLOT("flex_crate_and_stockpile_switch.png", 138, 0, 18, 18), + + STOCKSWITCH("flex_crate_and_stockpile_switch.png", 0, 129, 205, 93), + STOCKSWITCH_INTERVAL("flex_crate_and_stockpile_switch.png", 0, 222, 198, 17), + STOCKSWITCH_INTERVAL_END("flex_crate_and_stockpile_switch.png", 0, 239, 198, 17), + STOCKSWITCH_CURSOR_ON("flex_crate_and_stockpile_switch.png", 218, 129, 8, 21), + STOCKSWITCH_CURSOR_OFF("flex_crate_and_stockpile_switch.png", 226, 129, 8, 21), + STOCKSWITCH_BOUND_LEFT("flex_crate_and_stockpile_switch.png", 234, 129, 7, 21), + STOCKSWITCH_BOUND_RIGHT("flex_crate_and_stockpile_switch.png", 241, 129, 7, 21), + // Widgets PALETTE_BUTTON("palette_picker.png", 0, 236, 20, 20), TEXT_INPUT("widgets.png", 0, 28, 194, 47), @@ -74,7 +85,9 @@ public enum ScreenResources { ICON_PATTERN_CHANCE_50("icons.png", 0, 112, 16, 16), ICON_PATTERN_CHANCE_75("icons.png", 16, 112, 16, 16), ICON_FOLLOW_DIAGONAL("icons.png", 32, 112, 16, 16), - ICON_FOLLOW_MATERIAL("icons.png", 48, 112, 16, 16); + ICON_FOLLOW_MATERIAL("icons.png", 48, 112, 16, 16), + + ; public static final int FONT_COLOR = 0x575F7A; @@ -92,8 +105,12 @@ public enum ScreenResources { this.startX = startX; this.startY = startY; } - public void draw(AbstractGui screen, int i, int j) { + public void bind() { Minecraft.getInstance().getTextureManager().bindTexture(location); + } + + public void draw(AbstractGui screen, int i, int j) { + bind(); screen.blit(i, j, startX, startY, width, height); } diff --git a/src/main/java/com/simibubi/create/foundation/gui/TextInputPromptScreen.java b/src/main/java/com/simibubi/create/foundation/gui/TextInputPromptScreen.java index 6fa8a552d..8b582a652 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/TextInputPromptScreen.java +++ b/src/main/java/com/simibubi/create/foundation/gui/TextInputPromptScreen.java @@ -37,20 +37,20 @@ public class TextInputPromptScreen extends AbstractSimiScreen { super.init(); setWindowSize(ScreenResources.TEXT_INPUT.width, ScreenResources.TEXT_INPUT.height + 30); - this.nameField = new TextFieldWidget(font, topLeftX + 33, topLeftY + 26, 128, 8, ""); + this.nameField = new TextFieldWidget(font, guiLeft + 33, guiTop + 26, 128, 8, ""); this.nameField.setTextColor(-1); this.nameField.setDisabledTextColour(-1); this.nameField.setEnableBackgroundDrawing(false); this.nameField.setMaxStringLength(35); this.nameField.changeFocus(true); - confirm = new Button(topLeftX - 5, topLeftY + 50, 100, 20, buttonTextConfirm, button -> { + confirm = new Button(guiLeft - 5, guiTop + 50, 100, 20, buttonTextConfirm, button -> { callback.accept(nameField.getText()); confirmed = true; minecraft.displayGuiScreen(null); }); - abort = new Button(topLeftX + 100, topLeftY + 50, 100, 20, buttonTextAbort, button -> { + abort = new Button(guiLeft + 100, guiTop + 50, 100, 20, buttonTextAbort, button -> { minecraft.displayGuiScreen(null); }); @@ -61,8 +61,8 @@ public class TextInputPromptScreen extends AbstractSimiScreen { @Override public void renderWindow(int mouseX, int mouseY, float partialTicks) { - ScreenResources.TEXT_INPUT.draw(this, topLeftX, topLeftY); - font.drawString(title, topLeftX + (sWidth / 2) - (font.getStringWidth(title) / 2), topLeftY + 11, + ScreenResources.TEXT_INPUT.draw(this, guiLeft, guiTop); + font.drawString(title, guiLeft + (sWidth / 2) - (font.getStringWidth(title) / 2), guiTop + 11, ScreenResources.FONT_COLOR); } diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java index 6076adcd3..c4dbd77ee 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java @@ -14,12 +14,14 @@ public class ScrollInput extends AbstractSimiWidget { protected Label displayLabel; protected int min, max; + protected int shiftStep; public ScrollInput(int xIn, int yIn, int widthIn, int heightIn) { super(xIn, yIn, widthIn, heightIn); state = 0; min = 0; max = 1; + shiftStep = 5; } public ScrollInput withRange(int min, int max) { @@ -57,6 +59,11 @@ public class ScrollInput extends AbstractSimiWidget { writeToLabel(); return this; } + + public ScrollInput withShiftStep(int step) { + shiftStep = step; + return this; + } @Override public boolean mouseScrolled(double mouseX, double mouseY, double delta) { @@ -64,9 +71,12 @@ public class ScrollInput extends AbstractSimiWidget { return false; int priorState = state; - int step = (int) Math.signum(delta) * (KeyboardHelper.isKeyDown(KeyboardHelper.LSHIFT) ? 5 : 1); - + boolean shifted = KeyboardHelper.isKeyDown(KeyboardHelper.LSHIFT); + int step = (int) Math.signum(delta) * (shifted ? shiftStep : 1); state += step; + if (shifted) + state -= state % shiftStep; + clampState(); if (priorState != state) @@ -82,7 +92,7 @@ public class ScrollInput extends AbstractSimiWidget { state = min; } - protected void onChanged() { + public void onChanged() { if (displayLabel != null) writeToLabel(); if (onScroll != null) @@ -97,143 +107,8 @@ public class ScrollInput extends AbstractSimiWidget { protected void updateTooltip() { toolTip.clear(); toolTip.add(TextFormatting.BLUE + title); + toolTip.add(TextFormatting.DARK_GRAY + "" + TextFormatting.ITALIC + "Scroll to Modify"); + toolTip.add(TextFormatting.DARK_GRAY + "" + TextFormatting.ITALIC + "Shift to Scroll faster"); } - -// public interface IScrollAction { -// public void onScroll(int position); -// } -// -// public interface ICancelableScrollAction extends IScrollAction { -// public void onScroll(int position); -// -// public boolean canScroll(int position); -// } -// -// private int x, y, width, height; -// private IScrollAction action; -// public boolean enabled; -// private Optional> tooltipContent; -// private int min, max; -// private boolean limitless; -// private boolean numeric; -// -// public ScrollArea(List options, IScrollAction action) { -// this(0, options.size(), action); -// this.tooltipContent = Optional.of(options); -// updateTooltip(); -// } -// -// public ScrollArea(int min, int max, IScrollAction action) { -// this(action); -// this.limitless = false; -// this.min = min; -// this.max = max; -// } -// -// public ScrollArea(IScrollAction action) { -// this.enabled = true; -// this.action = action; -// this.tooltipContent = Optional.absent(); -// this.limitless = true; -// this.numeric = false; -// } -// -// public void setBounds(int x, int y, int width, int height) { -// this.x = x; -// this.y = y; -// this.width = width; -// this.height = height; -// } -// -// public void setState(int state) { -// currentState = state; -// updateTooltip(); -// } -// -// public int getState() { -// return currentState; -// } -// -// public boolean isHovered(double x, double y) { -// return (x > this.x && x < this.x + this.width && y > this.y && y < this.y + this.height); -// } -// -// public void tryScroll(double mouseX, double mouseY, int amount) { -// if (enabled && isHovered(mouseX, mouseY)) { -// scroll(numeric? -amount : amount); -// } -// } -// -// public void setNumeric(boolean numeric) { -// this.numeric = numeric; -// } -// -// private void scroll(int amount) { -// if (enabled) { -// -// if (limitless) { -// if (!(action instanceof ICancelableScrollAction) -// || ((ICancelableScrollAction) action).canScroll(amount)) -// action.onScroll(amount); -// return; -// } -// -// if (!(action instanceof ICancelableScrollAction) -// || ((ICancelableScrollAction) action).canScroll(currentState + amount)) { -// currentState += amount; -// if (currentState < min) -// currentState = min; -// if (currentState >= max) -// currentState = max - 1; -// updateTooltip(); -// action.onScroll(currentState); -// } -// } -// } -// -// public void draw(Screen screen, int mouseX, int mouseY) { -// GlStateManager.pushLightingAttributes(); -// if (enabled && isHovered(mouseX, mouseY)) { -// GlStateManager.pushMatrix(); -// GlStateManager.translated(mouseX, mouseY,0); -// if (tooltipContent.isPresent()) -// screen.renderTooltip(getToolTip(), 0, 0); -// else -// screen.renderTooltip(TextFormatting.BLUE + title, 0, 0); -// GlStateManager.popMatrix(); -// } -// -// GlStateManager.popAttributes(); -// } -// -// public List getToolTip() { -// return tooltip; -// } -// -// public void setTitle(String title) { -// this.title = title; -// updateTooltip(); -// } -// -// private void updateTooltip() { -// tooltip = new LinkedList<>(); -// tooltip.add(TextFormatting.BLUE + title); -// -// if (tooltipContent.isPresent()) { -// for (int i = min; i < max; i++) { -// StringBuilder result = new StringBuilder(); -// if (i == currentState) -// result.append(TextFormatting.WHITE).append("-> ").append(tooltipContent.get().get(i)); -// else -// result.append(TextFormatting.GRAY).append("> ").append(tooltipContent.get().get(i)); -// tooltip.add(result.toString()); -// } -// -// } -// } -// -// public boolean isNumeric() { -// return numeric; -// } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/ItemDescription.java b/src/main/java/com/simibubi/create/foundation/utility/ItemDescription.java index 6a3a8f8c5..7106cae78 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/ItemDescription.java +++ b/src/main/java/com/simibubi/create/foundation/utility/ItemDescription.java @@ -67,7 +67,7 @@ public class ItemDescription { public ItemDescription withBehaviour(String condition, String behaviour) { add(linesOnShift, GRAY + condition); - add(linesOnShift, cutString(behaviour, palette.hColor, 1)); + add(linesOnShift, cutString(behaviour, palette.color, 1)); return this; } diff --git a/src/main/java/com/simibubi/create/modules/curiosities/placementHandgun/BuilderGunScreen.java b/src/main/java/com/simibubi/create/modules/curiosities/placementHandgun/BuilderGunScreen.java index d8e0de613..6c48b821c 100644 --- a/src/main/java/com/simibubi/create/modules/curiosities/placementHandgun/BuilderGunScreen.java +++ b/src/main/java/com/simibubi/create/modules/curiosities/placementHandgun/BuilderGunScreen.java @@ -62,8 +62,8 @@ public class BuilderGunScreen extends AbstractSimiScreen { animationProgress = 0; setWindowSize(ScreenResources.PLACEMENT_GUN.width + 40, ScreenResources.PLACEMENT_GUN.height); super.init(); - int i = topLeftX - 20; - int j = topLeftY; + int i = guiLeft - 20; + int j = guiTop; CompoundNBT nbt = item.getOrCreateTag(); @@ -169,8 +169,8 @@ public class BuilderGunScreen extends AbstractSimiScreen { @Override protected void renderWindow(int mouseX, int mouseY, float partialTicks) { - int i = topLeftX - 20; - int j = topLeftY; + int i = guiLeft - 20; + int j = guiTop; ScreenResources.PLACEMENT_GUN.draw(this, i, j); font.drawStringWithShadow("Handheld Blockzapper", i + 8, j + 10, 0xCCDDFF); @@ -213,7 +213,7 @@ public class BuilderGunScreen extends AbstractSimiScreen { GlStateManager.pushMatrix(); BufferBuilder buffer = Tessellator.getInstance().getBuffer(); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); - GlStateManager.translated(topLeftX + 1.7f, topLeftY - 49, 120); + GlStateManager.translated(guiLeft + 1.7f, guiTop - 49, 120); GlStateManager.rotatef(-30f, .5f, .9f, -.1f); GlStateManager.scaled(20, -20, 20); diff --git a/src/main/java/com/simibubi/create/modules/gardens/TreeFertilizerItem.java b/src/main/java/com/simibubi/create/modules/gardens/TreeFertilizerItem.java index fef154227..481774351 100644 --- a/src/main/java/com/simibubi/create/modules/gardens/TreeFertilizerItem.java +++ b/src/main/java/com/simibubi/create/modules/gardens/TreeFertilizerItem.java @@ -172,14 +172,15 @@ public class TreeFertilizerItem extends InfoItem { } @Override - public MapData func_217406_a(String p_217406_1_) { - return wrapped.func_217406_a(p_217406_1_); + public MapData getMapData(String mapName) { + return wrapped.getMapData(mapName); } @Override - public void func_217399_a(MapData p_217399_1_) { + public void registerMapData(MapData mapDataIn) { + wrapped.registerMapData(mapDataIn); } - + @Override public int getNextMapId() { return 0; diff --git a/src/main/java/com/simibubi/create/modules/logistics/FlexCrateBlock.java b/src/main/java/com/simibubi/create/modules/logistics/FlexCrateBlock.java index 01dfad287..fba8e41a2 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/FlexCrateBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/FlexCrateBlock.java @@ -6,31 +6,80 @@ import com.simibubi.create.foundation.utility.ItemDescription.Palette; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.inventory.InventoryHelper; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkHooks; -public class FlexCrateBlock extends InfoBlock { +public class FlexcrateBlock extends InfoBlock { - public FlexCrateBlock() { + public static final VoxelShape SHAPE = makeCuboidShape(1, 0, 1, 15, 14, 15); + + public FlexcrateBlock() { super(Properties.from(Blocks.ANDESITE)); } @Override - public boolean hasTileEntity() { + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + return SHAPE; + } + + @Override + public boolean hasTileEntity(BlockState state) { return true; } + @Override + public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + + if (worldIn.isRemote) { + return true; + } else { + FlexcrateTileEntity te = (FlexcrateTileEntity) worldIn.getTileEntity(pos); + if (te != null) + NetworkHooks.openGui((ServerPlayerEntity) player, te, te::sendToContainer); + return true; + } + } + @Override public TileEntity createTileEntity(BlockState state, IBlockReader world) { - return new FlexCrateTileEntity(); + return new FlexcrateTileEntity(); } @Override public ItemDescription getDescription() { Palette color = Palette.Yellow; return new ItemDescription(color) - .withSummary("This Storage Container allows Manual control over its capacity. Can hold up to " - + h("16 Stacks", color) + " of Items."); + .withSummary("This Storage Container allows Manual control over its capacity. It can hold up to " + + h("16 Stacks", color) + " of Items.") + .createTabs(); + } + + @Override + public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + if (worldIn.getTileEntity(pos) == null) + return; + + FlexcrateTileEntity te = (FlexcrateTileEntity) worldIn.getTileEntity(pos); + for (int slot = 0; slot < te.inventory.getSlots(); slot++) { + InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), + te.inventory.getStackInSlot(slot)); + } + + if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { + worldIn.removeTileEntity(pos); + } + } } diff --git a/src/main/java/com/simibubi/create/modules/logistics/FlexCrateContainer.java b/src/main/java/com/simibubi/create/modules/logistics/FlexCrateContainer.java index 75b811113..82c1ec111 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/FlexCrateContainer.java +++ b/src/main/java/com/simibubi/create/modules/logistics/FlexCrateContainer.java @@ -7,28 +7,68 @@ import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; +import net.minecraftforge.items.SlotItemHandler; -public class FlexCrateContainer extends Container { +public class FlexcrateContainer extends Container { - private FlexCrateTileEntity te; + public FlexcrateTileEntity te; + public PlayerInventory playerInventory; - public FlexCrateContainer(int id, PlayerInventory inv, PacketBuffer extraData) { - super(AllContainers.SchematicTable.type, id); + public FlexcrateContainer(int id, PlayerInventory inv, PacketBuffer extraData) { + super(AllContainers.FlexCrate.type, id); ClientWorld world = Minecraft.getInstance().world; - this.te = (FlexCrateTileEntity) world.getTileEntity(extraData.readBlockPos()); + this.te = (FlexcrateTileEntity) world.getTileEntity(extraData.readBlockPos()); this.te.handleUpdateTag(extraData.readCompoundTag()); + this.playerInventory = inv; init(); } - public FlexCrateContainer(int id, PlayerInventory inv, FlexCrateTileEntity te) { - super(AllContainers.SchematicTable.type, id); + public FlexcrateContainer(int id, PlayerInventory inv, FlexcrateTileEntity te) { + super(AllContainers.FlexCrate.type, id); this.te = te; + this.playerInventory = inv; init(); } private void init() { - + for (int row = 0; row < 4; ++row) { + for (int col = 0; col < 4; ++col) { + this.addSlot(new SlotItemHandler(te.inventory, col + row * 4, 124 + col * 18, 25 + row * 18)); + } + } + + // player Slots + int xOffset = 58; + int yOffset = 157; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 9; ++col) { + this.addSlot(new Slot(playerInventory, col + row * 9 + 9, xOffset + col * 18, yOffset + row * 18)); + } + } + + for (int hotbarSlot = 0; hotbarSlot < 9; ++hotbarSlot) { + this.addSlot(new Slot(playerInventory, hotbarSlot, xOffset + hotbarSlot * 18, yOffset + 58)); + } + + detectAndSendChanges(); + } + + @Override + public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) { + Slot clickedSlot = getSlot(index); + if (!clickedSlot.getHasStack()) + return ItemStack.EMPTY; + + ItemStack stack = clickedSlot.getStack(); + if (index < 16) + mergeItemStack(stack, 16, inventorySlots.size(), false); + else + mergeItemStack(stack, 0, 15, false); + + return ItemStack.EMPTY; } @Override diff --git a/src/main/java/com/simibubi/create/modules/logistics/FlexCrateScreen.java b/src/main/java/com/simibubi/create/modules/logistics/FlexCrateScreen.java index fb1926ab3..cf2fb3ace 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/FlexCrateScreen.java +++ b/src/main/java/com/simibubi/create/modules/logistics/FlexCrateScreen.java @@ -1,19 +1,93 @@ package com.simibubi.create.modules.logistics; -import com.simibubi.create.foundation.gui.AbstractSimiContainerScreen; +import static com.simibubi.create.foundation.gui.ScreenResources.FLEXCRATE; +import static com.simibubi.create.foundation.gui.ScreenResources.PLAYER_INVENTORY; +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.gui.AbstractSimiContainerScreen; +import com.simibubi.create.foundation.gui.ScreenElementRenderer; +import com.simibubi.create.foundation.gui.ScreenResources; +import com.simibubi.create.foundation.gui.widgets.Label; +import com.simibubi.create.foundation.gui.widgets.ScrollInput; + +import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.util.text.ITextComponent; -public class FlexCrateScreen extends AbstractSimiContainerScreen { +public class FlexcrateScreen extends AbstractSimiContainerScreen { - public FlexCrateScreen(FlexCrateContainer container, PlayerInventory inv, ITextComponent title) { + private FlexcrateTileEntity te; + private Label allowedItemsLabel; + private ScrollInput allowedItems; + private int lastModification; + + public FlexcrateScreen(FlexcrateContainer container, PlayerInventory inv, ITextComponent title) { super(container, inv, title); + te = container.te; + lastModification = -1; + } + + @Override + protected void init() { + setWindowSize(PLAYER_INVENTORY.width + 100, FLEXCRATE.height + PLAYER_INVENTORY.height + 20); + super.init(); + widgets.clear(); + + allowedItemsLabel = new Label(guiLeft + 100 + 70, guiTop + 107, "").colored(0xD3CBBE).withShadow(); + allowedItems = new ScrollInput(guiLeft + 100 + 65, guiTop + 104, 41, 14).titled("Storage Space") + .withRange(1, 1025).writingTo(allowedItemsLabel).withShiftStep(64).setState(te.allowedAmount) + .calling(s -> lastModification = 0); + allowedItems.onChanged(); + widgets.add(allowedItemsLabel); + widgets.add(allowedItems); } @Override protected void renderWindow(int mouseX, int mouseY, float partialTicks) { + int crateLeft = guiLeft + 100; + int crateTop = guiTop; + int invLeft = guiLeft + 50; + int invTop = crateTop + FLEXCRATE.height + 10; + int hFontColor = 0xD3CBBE; + int fontColor = 0x4B3A22; + + FLEXCRATE.draw(this, crateLeft, crateTop); + font.drawStringWithShadow("FlexCrate", crateLeft - 3 + (FLEXCRATE.width - font.getStringWidth("FlexCrate")) / 2, + crateTop + 10, hFontColor); + String itemCount = "" + te.itemCount; + font.drawString(itemCount, crateLeft + 53 - font.getStringWidth(itemCount), crateTop + 107, fontColor); + + PLAYER_INVENTORY.draw(this, invLeft, invTop); + font.drawString("Inventory", invLeft + 7, invTop + 6, 0x666666); + + for (int slot = 0; slot < 16; slot++) { + if (allowedItems.getState() > slot * 64) + continue; + int x = crateLeft + 23 + (slot % 4) * 18; + int y = crateTop + 24 + (slot / 4) * 18; + ScreenResources.FLEXCRATE_LOCKED_SLOT.draw(this, x, y); + } + + ScreenElementRenderer.renderBlock(this::getRenderedBlock); + } + + @Override + public void tick() { + super.tick(); + if (lastModification >= 0) + lastModification++; + if (lastModification >= 15) { + lastModification = -1; + + } + } + + public BlockState getRenderedBlock() { + GlStateManager.translated(guiLeft + FLEXCRATE.width + 145, guiTop + 115, 0); + GlStateManager.rotatef(50, -.5f, 1, -.2f); + return AllBlocks.FLEXCRATE.get().getDefaultState(); } } diff --git a/src/main/java/com/simibubi/create/modules/logistics/FlexCrateTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/FlexCrateTileEntity.java index 68c957aa1..3adf6f527 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/FlexCrateTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/FlexCrateTileEntity.java @@ -7,18 +7,80 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.ItemStackHandler; -public class FlexCrateTileEntity extends SyncedTileEntity implements INamedContainerProvider { +public class FlexcrateTileEntity extends SyncedTileEntity implements INamedContainerProvider { - public FlexCrateTileEntity() { - super(AllTileEntities.FLEX_CRATE.type); + public class Inv extends ItemStackHandler { + public Inv() { + super(16); + } + + @Override + public int getSlotLimit(int slot) { + if (slot < allowedAmount / 64) + return super.getSlotLimit(slot); + else if (slot == allowedAmount / 64) + return allowedAmount % 64; + return 0; + } + + @Override + public boolean isItemValid(int slot, ItemStack stack) { + if (slot > allowedAmount / 64) + return false; + return super.isItemValid(slot, stack); + } + + @Override + protected void onContentsChanged(int slot) { + super.onContentsChanged(slot); + markDirty(); + } + } + + public Inv inventory; + public int allowedAmount; + public int itemCount; + + public FlexcrateTileEntity() { + this(AllTileEntities.FLEXCRATE.type); + } + + public FlexcrateTileEntity(TileEntityType type) { + super(type); + allowedAmount = 512; + itemCount = 10; + inventory = new Inv(); } @Override public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player) { - return new FlexCrateContainer(id, inventory, this); + return new FlexcrateContainer(id, inventory, this); + } + + @Override + public CompoundNBT write(CompoundNBT compound) { + compound.putInt("AllowedAmount", allowedAmount); + compound.put("Inventory", inventory.serializeNBT()); + return super.write(compound); + } + + @Override + public void read(CompoundNBT compound) { + allowedAmount = compound.getInt("AllowedAmount"); + inventory.deserializeNBT(compound.getCompound("Inventory")); + super.read(compound); } @Override @@ -26,4 +88,17 @@ public class FlexCrateTileEntity extends SyncedTileEntity implements INamedConta return new StringTextComponent(getType().getRegistryName().toString()); } + public void sendToContainer(PacketBuffer buffer) { + buffer.writeBlockPos(getPos()); + buffer.writeCompoundTag(getUpdateTag()); + } + + @Override + public LazyOptional getCapability(Capability capability, Direction facing) { + if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { + return LazyOptional.of(() -> inventory).cast(); + } + return super.getCapability(capability, facing); + } + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/FlexcrateBlock.java b/src/main/java/com/simibubi/create/modules/logistics/FlexcrateBlock.java new file mode 100644 index 000000000..fba8e41a2 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/FlexcrateBlock.java @@ -0,0 +1,85 @@ +package com.simibubi.create.modules.logistics; + +import com.simibubi.create.foundation.block.InfoBlock; +import com.simibubi.create.foundation.utility.ItemDescription; +import com.simibubi.create.foundation.utility.ItemDescription.Palette; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.inventory.InventoryHelper; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkHooks; + +public class FlexcrateBlock extends InfoBlock { + + public static final VoxelShape SHAPE = makeCuboidShape(1, 0, 1, 15, 14, 15); + + public FlexcrateBlock() { + super(Properties.from(Blocks.ANDESITE)); + } + + @Override + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + return SHAPE; + } + + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + @Override + public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + + if (worldIn.isRemote) { + return true; + } else { + FlexcrateTileEntity te = (FlexcrateTileEntity) worldIn.getTileEntity(pos); + if (te != null) + NetworkHooks.openGui((ServerPlayerEntity) player, te, te::sendToContainer); + return true; + } + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return new FlexcrateTileEntity(); + } + + @Override + public ItemDescription getDescription() { + Palette color = Palette.Yellow; + return new ItemDescription(color) + .withSummary("This Storage Container allows Manual control over its capacity. It can hold up to " + + h("16 Stacks", color) + " of Items.") + .createTabs(); + } + + @Override + public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + if (worldIn.getTileEntity(pos) == null) + return; + + FlexcrateTileEntity te = (FlexcrateTileEntity) worldIn.getTileEntity(pos); + for (int slot = 0; slot < te.inventory.getSlots(); slot++) { + InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), + te.inventory.getStackInSlot(slot)); + } + + if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { + worldIn.removeTileEntity(pos); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/FlexcrateContainer.java b/src/main/java/com/simibubi/create/modules/logistics/FlexcrateContainer.java new file mode 100644 index 000000000..82c1ec111 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/FlexcrateContainer.java @@ -0,0 +1,79 @@ +package com.simibubi.create.modules.logistics; + +import com.simibubi.create.AllContainers; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.items.SlotItemHandler; + +public class FlexcrateContainer extends Container { + + public FlexcrateTileEntity te; + public PlayerInventory playerInventory; + + public FlexcrateContainer(int id, PlayerInventory inv, PacketBuffer extraData) { + super(AllContainers.FlexCrate.type, id); + ClientWorld world = Minecraft.getInstance().world; + this.te = (FlexcrateTileEntity) world.getTileEntity(extraData.readBlockPos()); + this.te.handleUpdateTag(extraData.readCompoundTag()); + this.playerInventory = inv; + init(); + } + + public FlexcrateContainer(int id, PlayerInventory inv, FlexcrateTileEntity te) { + super(AllContainers.FlexCrate.type, id); + this.te = te; + this.playerInventory = inv; + init(); + } + + private void init() { + for (int row = 0; row < 4; ++row) { + for (int col = 0; col < 4; ++col) { + this.addSlot(new SlotItemHandler(te.inventory, col + row * 4, 124 + col * 18, 25 + row * 18)); + } + } + + // player Slots + int xOffset = 58; + int yOffset = 157; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 9; ++col) { + this.addSlot(new Slot(playerInventory, col + row * 9 + 9, xOffset + col * 18, yOffset + row * 18)); + } + } + + for (int hotbarSlot = 0; hotbarSlot < 9; ++hotbarSlot) { + this.addSlot(new Slot(playerInventory, hotbarSlot, xOffset + hotbarSlot * 18, yOffset + 58)); + } + + detectAndSendChanges(); + } + + @Override + public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) { + Slot clickedSlot = getSlot(index); + if (!clickedSlot.getHasStack()) + return ItemStack.EMPTY; + + ItemStack stack = clickedSlot.getStack(); + if (index < 16) + mergeItemStack(stack, 16, inventorySlots.size(), false); + else + mergeItemStack(stack, 0, 15, false); + + return ItemStack.EMPTY; + } + + @Override + public boolean canInteractWith(PlayerEntity playerIn) { + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/FlexcrateScreen.java b/src/main/java/com/simibubi/create/modules/logistics/FlexcrateScreen.java new file mode 100644 index 000000000..cf2fb3ace --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/FlexcrateScreen.java @@ -0,0 +1,93 @@ +package com.simibubi.create.modules.logistics; + +import static com.simibubi.create.foundation.gui.ScreenResources.FLEXCRATE; +import static com.simibubi.create.foundation.gui.ScreenResources.PLAYER_INVENTORY; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.gui.AbstractSimiContainerScreen; +import com.simibubi.create.foundation.gui.ScreenElementRenderer; +import com.simibubi.create.foundation.gui.ScreenResources; +import com.simibubi.create.foundation.gui.widgets.Label; +import com.simibubi.create.foundation.gui.widgets.ScrollInput; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.util.text.ITextComponent; + +public class FlexcrateScreen extends AbstractSimiContainerScreen { + + private FlexcrateTileEntity te; + private Label allowedItemsLabel; + private ScrollInput allowedItems; + private int lastModification; + + public FlexcrateScreen(FlexcrateContainer container, PlayerInventory inv, ITextComponent title) { + super(container, inv, title); + te = container.te; + lastModification = -1; + } + + @Override + protected void init() { + setWindowSize(PLAYER_INVENTORY.width + 100, FLEXCRATE.height + PLAYER_INVENTORY.height + 20); + super.init(); + widgets.clear(); + + allowedItemsLabel = new Label(guiLeft + 100 + 70, guiTop + 107, "").colored(0xD3CBBE).withShadow(); + allowedItems = new ScrollInput(guiLeft + 100 + 65, guiTop + 104, 41, 14).titled("Storage Space") + .withRange(1, 1025).writingTo(allowedItemsLabel).withShiftStep(64).setState(te.allowedAmount) + .calling(s -> lastModification = 0); + allowedItems.onChanged(); + widgets.add(allowedItemsLabel); + widgets.add(allowedItems); + } + + @Override + protected void renderWindow(int mouseX, int mouseY, float partialTicks) { + int crateLeft = guiLeft + 100; + int crateTop = guiTop; + int invLeft = guiLeft + 50; + int invTop = crateTop + FLEXCRATE.height + 10; + int hFontColor = 0xD3CBBE; + int fontColor = 0x4B3A22; + + FLEXCRATE.draw(this, crateLeft, crateTop); + font.drawStringWithShadow("FlexCrate", crateLeft - 3 + (FLEXCRATE.width - font.getStringWidth("FlexCrate")) / 2, + crateTop + 10, hFontColor); + String itemCount = "" + te.itemCount; + font.drawString(itemCount, crateLeft + 53 - font.getStringWidth(itemCount), crateTop + 107, fontColor); + + PLAYER_INVENTORY.draw(this, invLeft, invTop); + font.drawString("Inventory", invLeft + 7, invTop + 6, 0x666666); + + for (int slot = 0; slot < 16; slot++) { + if (allowedItems.getState() > slot * 64) + continue; + int x = crateLeft + 23 + (slot % 4) * 18; + int y = crateTop + 24 + (slot / 4) * 18; + ScreenResources.FLEXCRATE_LOCKED_SLOT.draw(this, x, y); + } + + ScreenElementRenderer.renderBlock(this::getRenderedBlock); + } + + @Override + public void tick() { + super.tick(); + if (lastModification >= 0) + lastModification++; + + if (lastModification >= 15) { + lastModification = -1; + + } + } + + public BlockState getRenderedBlock() { + GlStateManager.translated(guiLeft + FLEXCRATE.width + 145, guiTop + 115, 0); + GlStateManager.rotatef(50, -.5f, 1, -.2f); + return AllBlocks.FLEXCRATE.get().getDefaultState(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/FlexcrateTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/FlexcrateTileEntity.java new file mode 100644 index 000000000..3adf6f527 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/FlexcrateTileEntity.java @@ -0,0 +1,104 @@ +package com.simibubi.create.modules.logistics; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.block.SyncedTileEntity; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.ItemStackHandler; + +public class FlexcrateTileEntity extends SyncedTileEntity implements INamedContainerProvider { + + public class Inv extends ItemStackHandler { + public Inv() { + super(16); + } + + @Override + public int getSlotLimit(int slot) { + if (slot < allowedAmount / 64) + return super.getSlotLimit(slot); + else if (slot == allowedAmount / 64) + return allowedAmount % 64; + return 0; + } + + @Override + public boolean isItemValid(int slot, ItemStack stack) { + if (slot > allowedAmount / 64) + return false; + return super.isItemValid(slot, stack); + } + + @Override + protected void onContentsChanged(int slot) { + super.onContentsChanged(slot); + markDirty(); + } + } + + public Inv inventory; + public int allowedAmount; + public int itemCount; + + public FlexcrateTileEntity() { + this(AllTileEntities.FLEXCRATE.type); + } + + public FlexcrateTileEntity(TileEntityType type) { + super(type); + allowedAmount = 512; + itemCount = 10; + inventory = new Inv(); + } + + @Override + public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player) { + return new FlexcrateContainer(id, inventory, this); + } + + @Override + public CompoundNBT write(CompoundNBT compound) { + compound.putInt("AllowedAmount", allowedAmount); + compound.put("Inventory", inventory.serializeNBT()); + return super.write(compound); + } + + @Override + public void read(CompoundNBT compound) { + allowedAmount = compound.getInt("AllowedAmount"); + inventory.deserializeNBT(compound.getCompound("Inventory")); + super.read(compound); + } + + @Override + public ITextComponent getDisplayName() { + return new StringTextComponent(getType().getRegistryName().toString()); + } + + public void sendToContainer(PacketBuffer buffer) { + buffer.writeBlockPos(getPos()); + buffer.writeCompoundTag(getUpdateTag()); + } + + @Override + public LazyOptional getCapability(Capability capability, Direction facing) { + if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { + return LazyOptional.of(() -> inventory).cast(); + } + return super.getCapability(capability, facing); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeBlock.java b/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeBlock.java index f2e3e7774..801e27483 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeBlock.java @@ -1,17 +1,28 @@ package com.simibubi.create.modules.logistics; +import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.tuple.Pair; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.block.ProperDirectionalBlock; import com.simibubi.create.foundation.utility.ITooltip; import com.simibubi.create.foundation.utility.ItemDescription; -import com.simibubi.create.foundation.utility.TooltipHolder; import com.simibubi.create.foundation.utility.ItemDescription.Palette; +import com.simibubi.create.foundation.utility.TessellatorHelper; +import com.simibubi.create.foundation.utility.TooltipHolder; +import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; import net.minecraft.state.BooleanProperty; @@ -20,37 +31,126 @@ import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Hand; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.IBlockReader; +import net.minecraft.world.IWorld; import net.minecraft.world.IWorldReader; +import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.DrawBlockHighlightEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +@EventBusSubscriber(value = Dist.CLIENT) public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITooltip { public static final BooleanProperty POWERED = BlockStateProperties.POWERED; + public static final BooleanProperty RECEIVER = BooleanProperty.create("receiver"); + private static final List> itemPositions = new ArrayList<>(Direction.values().length); public static final VoxelShape UP_SHAPE = makeCuboidShape(2, 0, 2, 14, 3, 14), DOWN_SHAPE = makeCuboidShape(2, 13, 2, 14, 16, 14); - public static final VoxelShape SOUTH_SHAPE = makeCuboidShape(3, 1, -1, 13, 15, 2), - NORTH_SHAPE = makeCuboidShape(3, 1, 14, 13, 15, 17), EAST_SHAPE = makeCuboidShape(-1, 1, 3, 2, 15, 13), - WEST_SHAPE = makeCuboidShape(14, 1, 3, 17, 15, 13); + public static final VoxelShape + SOUTH_SHAPE = makeCuboidShape(3, 1, -1, 13, 15, 3), + NORTH_SHAPE = makeCuboidShape(3, 1, 13, 13, 15, 17), + EAST_SHAPE = makeCuboidShape(-1, 1, 3, 3, 15, 13), + WEST_SHAPE = makeCuboidShape(13, 1, 3, 17, 15, 13); private TooltipHolder info; public RedstoneBridgeBlock() { super(Properties.from(Blocks.DARK_OAK_LOG)); info = new TooltipHolder(this); + cacheItemPositions(); + setDefaultState(getDefaultState().with(POWERED, false).with(RECEIVER, false)); + } + + @Override + public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, + boolean isMoving) { + Direction blockFacing = state.get(FACING); + + if (fromPos.equals(pos.offset(blockFacing.getOpposite()))) { + if (!isValidPosition(state, worldIn, pos)) { + worldIn.destroyBlock(pos, true); + return; + } + } + + if (worldIn.isRemote) + return; + if (state.get(RECEIVER)) + return; + + boolean previouslyPowered = state.get(POWERED); + if (previouslyPowered != worldIn.isBlockPowered(pos.offset(blockFacing.getOpposite()))) { + worldIn.setBlockState(pos, state.cycle(POWERED), 2); + + RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) worldIn.getTileEntity(pos); + if (te == null) + return; + te.blockChanged(); + } + } + + @Override + public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn, + BlockPos currentPos, BlockPos facingPos) { + boolean shouldPower = false; + Direction blockFacing = stateIn.get(FACING); + + if (worldIn.getWorld().isRemote) + return stateIn; + if (stateIn.get(RECEIVER)) + return stateIn; + + shouldPower = worldIn.getWorld().isBlockPowered(currentPos.offset(blockFacing.getOpposite())) + || worldIn.getWorld().isBlockPowered(currentPos); + if (stateIn.get(POWERED) != shouldPower) { + + RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) worldIn.getTileEntity(currentPos); + if (te == null) + return stateIn; + te.blockChanged(); + + return stateIn.with(POWERED, shouldPower); + } + return stateIn; + } + + @Override + public boolean canProvidePower(BlockState state) { + return state.get(POWERED) && state.get(RECEIVER); + } + + @Override + public int getStrongPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side) { + if (side != blockState.get(FACING)) + return 0; + return getWeakPower(blockState, blockAccess, pos, side); + } + + @Override + public int getWeakPower(BlockState state, IBlockReader blockAccess, BlockPos pos, Direction side) { + if (!state.get(RECEIVER)) + return 0; + return state.get(POWERED) ? 15 : 0; } @Override protected void fillStateContainer(Builder builder) { - builder.add(POWERED); + builder.add(POWERED, RECEIVER); super.fillStateContainer(builder); } @@ -64,6 +164,107 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool return new RedstoneBridgeTileEntity(); } + @Override + public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + Direction facing = state.get(FACING); + Pair positions = itemPositions.get(facing.getIndex()); + ItemStack stack = player.getHeldItem(handIn); + RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) worldIn.getTileEntity(pos); + + if (te == null) + return false; + + if (player.isSneaking()) { + if (!worldIn.isRemote) { + worldIn.setBlockState(pos, state.cycle(RECEIVER)); + te.blockChanged(); + } + return true; + } + + Vec3d vec = new Vec3d(pos); + Vec3d first = positions.getLeft().add(vec); + Vec3d second = positions.getRight().add(vec); + + if (new AxisAlignedBB(first, first).grow(2 / 16f).contains(hit.getHitVec())) { + if (worldIn.isRemote) + return true; + te.setFrequency(true, stack); + return true; + } + + if (new AxisAlignedBB(second, second).grow(2 / 16f).contains(hit.getHitVec())) { + if (worldIn.isRemote) + return true; + te.setFrequency(false, stack); + return true; + } + + return false; + } + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void onDrawBlockHighlight(DrawBlockHighlightEvent event) { + if (event.getTarget() == null || !(event.getTarget() instanceof BlockRayTraceResult)) + return; + + BlockRayTraceResult result = (BlockRayTraceResult) event.getTarget(); + ClientWorld world = Minecraft.getInstance().world; + BlockPos pos = result.getPos(); + BlockState state = world.getBlockState(pos); + + if (!AllBlocks.REDSTONE_BRIDGE.typeOf(state)) + return; + + Direction facing = state.get(FACING); + Pair positions = itemPositions.get(facing.getIndex()); + RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) world.getTileEntity(pos); + + if (te == null) + return; + + Vec3d vec = new Vec3d(pos); + Vec3d first = positions.getLeft().add(vec); + Vec3d second = positions.getRight().add(vec); + + AxisAlignedBB firstBB = new AxisAlignedBB(first, first).grow(2 / 16f); + AxisAlignedBB secondBB = new AxisAlignedBB(second, second).grow(2 / 16f); + + TessellatorHelper.prepareForDrawing(); + GlStateManager.enableBlend(); + GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, + GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, + GlStateManager.DestFactor.ZERO); + GlStateManager.disableTexture(); + GlStateManager.depthMask(false); + GlStateManager.matrixMode(5889); + + if (firstBB.contains(result.getHitVec())) { + GlStateManager.lineWidth(2); + WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), 1, 1, .5f, 1f); + } else { + GlStateManager.lineWidth(2); + WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), .5f, .5f, .2f, 1f); + } + + if (secondBB.contains(result.getHitVec())) { + GlStateManager.lineWidth(2); + WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), 1, 1, .5f, 1f); + } else { + GlStateManager.lineWidth(2); + WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), .5f, .5f, .2f, 1f); + } + + GlStateManager.matrixMode(5888); + GlStateManager.depthMask(true); + GlStateManager.enableTexture(); + GlStateManager.disableBlend(); + GlStateManager.lineWidth(1); + TessellatorHelper.cleanUpAfterDrawing(); + } + @Override public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, Direction side) { return state.get(FACING) == Direction.UP; @@ -108,6 +309,47 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool return VoxelShapes.empty(); } + private void cacheItemPositions() { + if (!itemPositions.isEmpty()) + return; + + Vec3d first = Vec3d.ZERO; + Vec3d second = Vec3d.ZERO; + Vec3d shift = VecHelper.getCenterOf(BlockPos.ZERO); + float zFightOffset = 1 / 128f; + + for (Direction facing : Direction.values()) { + if (facing.getAxis().isHorizontal()) { + first = new Vec3d(10 / 16f, 5.5f / 16f, 2f / 16f + zFightOffset); + second = new Vec3d(10 / 16f, 10.5f / 16f, 2f / 16f + zFightOffset); + + float angle = facing.getHorizontalAngle(); + if (facing.getAxis() == Axis.X) + angle = -angle; + + first = VecHelper.rotate(first.subtract(shift), angle, Axis.Y).add(shift); + second = VecHelper.rotate(second.subtract(shift), angle, Axis.Y).add(shift); + + } else { + first = new Vec3d(10 / 16f, 2f / 16f + zFightOffset, 5.5f / 16f); + second = new Vec3d(10 / 16f, 2f / 16f + zFightOffset, 10.5f / 16f); + + if (facing == Direction.DOWN) { + first = VecHelper.rotate(first.subtract(shift), 180, Axis.X).add(shift); + second = VecHelper.rotate(second.subtract(shift), 180, Axis.X).add(shift); + } + } + + itemPositions.add(Pair.of(first, second)); + } + + } + + public static Pair getFrequencyItemPositions(BlockState state) { + Direction facing = state.get(FACING); + return itemPositions.get(facing.getIndex()); + } + @Override @OnlyIn(value = Dist.CLIENT) public void addInformation(ItemStack stack, IBlockReader worldIn, List tooltip, @@ -128,6 +370,8 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool "Sets the " + h("Frequency", color) + " to that item. A total of " + h("two different items", color) + " can be used in combination for defining a Frequency.") + .withControl("When R-Clicked while Sneaking", + "Toggles between " + h("Receiver", color) + " and " + h("Transmitter", color) + " Mode. ") .createTabs(); } diff --git a/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeTileEntity.java index a61ead1ba..c2c032799 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeTileEntity.java @@ -1,6 +1,9 @@ package com.simibubi.create.modules.logistics; +import static net.minecraft.state.properties.BlockStateProperties.POWERED; + import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -12,8 +15,12 @@ import com.simibubi.create.foundation.block.SyncedTileEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; -public class RedstoneBridgeTileEntity extends SyncedTileEntity { +public class RedstoneBridgeTileEntity extends SyncedTileEntity implements ITickableTileEntity { public static final int RANGE = 128; @@ -50,11 +57,15 @@ public class RedstoneBridgeTileEntity extends SyncedTileEntity { public Frequency frequencyFirst; public Frequency frequencyLast; + public boolean networkChanged; public RedstoneBridgeTileEntity() { super(AllTileEntities.REDSTONE_BRIDGE.type); frequencyFirst = new Frequency(ItemStack.EMPTY); frequencyLast = new Frequency(ItemStack.EMPTY); + + if (connections == null) + connections = new HashMap<>(); } @Override @@ -63,26 +74,97 @@ public class RedstoneBridgeTileEntity extends SyncedTileEntity { if (world.isRemote) return; - Pair networkKey = getNetworkKey(); - List TEs = connections.getOrDefault(networkKey, new ArrayList<>()); - TEs.add(this); - connections.put(networkKey, TEs); + addToNetwork(); } @Override public void remove() { super.remove(); + if (world.isRemote) + return; - Pair networkKey = getNetworkKey(); - List TEs = connections.get(networkKey); - if (TEs != null) - TEs.remove(this); + removeFromNetwork(); + } + + public void setFrequency(boolean first, ItemStack stack) { + stack = stack.copy(); + stack.setCount(1); + ItemStack toCompare = first ? frequencyFirst.stack : frequencyLast.stack; + boolean changed = !ItemStack.areItemsEqual(stack, toCompare) + || !ItemStack.areItemStackTagsEqual(stack, toCompare); + + if (changed) + removeFromNetwork(); + + if (first) + frequencyFirst = new Frequency(stack); + else + frequencyLast = new Frequency(stack); + + if (!changed) + return; + + world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 18); + addToNetwork(); } protected Pair getNetworkKey() { return Pair.of(frequencyFirst, frequencyLast); } + protected void addToNetwork() { + Pair networkKey = getNetworkKey(); + List TEs = connections.getOrDefault(networkKey, new ArrayList<>()); + TEs.add(this); + connections.put(networkKey, TEs); + notifyNetwork(); + } + + protected void removeFromNetwork() { + Pair networkKey = getNetworkKey(); + List TEs = connections.get(networkKey); + if (TEs != null) + TEs.remove(this); + if (TEs.isEmpty()) { + connections.remove(networkKey); + return; + } + notifyNetwork(); + } + + protected boolean isNetworkPowered() { + List TEs = connections.get(getNetworkKey()); + for (RedstoneBridgeTileEntity te : TEs) { + if (te == this) + continue; + if (te.canProvideNetworkPower()) + return true; + } + return false; + } + + protected void notifyNetwork() { + for (RedstoneBridgeTileEntity te : connections.get(getNetworkKey())) + te.networkChanged = true; + } + + public boolean canProvideNetworkPower() { + return isBlockPowered() && isTransmitter(); + } + + public boolean isTransmitter() { + return !getBlockState().get(RedstoneBridgeBlock.RECEIVER); + } + + public boolean isBlockPowered() { + return getBlockState().get(POWERED); + } + + public void blockChanged() { + notifyNetwork(); + networkChanged = true; + } + @Override public CompoundNBT write(CompoundNBT compound) { compound.put("FrequencyFirst", frequencyFirst.getStack().write(new CompoundNBT())); @@ -97,4 +179,21 @@ public class RedstoneBridgeTileEntity extends SyncedTileEntity { super.read(compound); } + @Override + public void tick() { + if (!networkChanged) + return; + networkChanged = false; + + if (isTransmitter()) + return; + if (isNetworkPowered() != isBlockPowered()) { + world.setBlockState(pos, getBlockState().cycle(POWERED)); + Direction attachedFace = getBlockState().get(BlockStateProperties.FACING).getOpposite(); + BlockPos attachedPos = pos.offset(attachedFace); + world.notifyNeighbors(attachedPos, world.getBlockState(attachedPos).getBlock()); + return; + } + } + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeTileEntityRenderer.java new file mode 100644 index 000000000..91fb3ac7d --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/RedstoneBridgeTileEntityRenderer.java @@ -0,0 +1,79 @@ +package com.simibubi.create.modules.logistics; + +import org.apache.commons.lang3.tuple.Pair; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.foundation.utility.TessellatorHelper; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.model.IBakedModel; +import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType; +import net.minecraft.client.renderer.tileentity.TileEntityRenderer; +import net.minecraft.item.ItemStack; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +@SuppressWarnings("deprecation") +public class RedstoneBridgeTileEntityRenderer extends TileEntityRenderer { + + @Override + public void render(RedstoneBridgeTileEntity tileEntityIn, double x, double y, double z, float partialTicks, + int destroyStage) { + super.render(tileEntityIn, x, y, z, partialTicks, destroyStage); + + Direction facing = tileEntityIn.getBlockState().get(BlockStateProperties.FACING); + + TessellatorHelper.prepareForDrawing(); + + Pair itemPositions = RedstoneBridgeBlock.getFrequencyItemPositions(tileEntityIn.getBlockState()); + Vec3d first = itemPositions.getLeft(); + Vec3d second = itemPositions.getRight(); + BlockPos pos = tileEntityIn.getPos(); + GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); + + renderFrequencyItem(tileEntityIn.frequencyFirst.getStack(), first, facing); + renderFrequencyItem(tileEntityIn.frequencyLast.getStack(), second, facing); + + TessellatorHelper.cleanUpAfterDrawing(); + + } + + private void renderFrequencyItem(ItemStack stack, Vec3d position, Direction facing) { + ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); + boolean vertical = facing.getAxis().isVertical(); + + IBakedModel modelWithOverrides = itemRenderer.getModelWithOverrides(stack); + boolean blockItem = modelWithOverrides.isGui3d(); + + float offX = 0; + float offY = vertical && !blockItem ? 0 : 0; + float offZ = !blockItem ? 1/4f : 0; + if (vertical) + offZ = -offZ; + + float rotX = vertical ? 90 : 0; + float rotY = vertical ? 0 : facing.getHorizontalAngle() + (blockItem ? 180 : 0); + float rotZ = vertical && facing == Direction.DOWN ? 180 : 0; + if (facing.getAxis() == Axis.X) { +// offZ = -offZ; + rotY = -rotY; + } + + float scale = !blockItem ? .25f : .5f; + + GlStateManager.pushMatrix(); + GlStateManager.translated(position.x, position.y, position.z); + GlStateManager.scaled(scale, scale, scale); + GlStateManager.rotatef(rotZ, 0, 0, 1); + GlStateManager.rotatef(rotY, 0, 1, 0); + GlStateManager.rotatef(rotX, 1, 0, 0); + GlStateManager.translatef(offX, offY, offZ); + itemRenderer.renderItem(stack, TransformType.FIXED); + GlStateManager.popMatrix(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchBlock.java b/src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchBlock.java deleted file mode 100644 index 5e26c668e..000000000 --- a/src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchBlock.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.simibubi.create.modules.logistics; - -import java.util.List; - -import com.simibubi.create.foundation.block.ProperDirectionalBlock; -import com.simibubi.create.foundation.utility.ITooltip; -import com.simibubi.create.foundation.utility.ItemDescription; -import com.simibubi.create.foundation.utility.ItemDescription.Palette; -import com.simibubi.create.foundation.utility.TooltipHolder; - -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.world.IBlockReader; - -public class StockpileSwitchBlock extends ProperDirectionalBlock implements ITooltip { - - private TooltipHolder info; - - public StockpileSwitchBlock() { - super(Properties.from(Blocks.ANDESITE)); - info = new TooltipHolder(this); - } - - @Override - public void addInformation(ItemStack stack, IBlockReader worldIn, List tooltip, - ITooltipFlag flagIn) { - info.addInformation(tooltip); - } - - @Override - public boolean hasTileEntity() { - return true; - } - - @Override - public TileEntity createTileEntity(BlockState state, IBlockReader world) { - return new StockpileSwitchTileEntity(); - } - - @Override - public ItemDescription getDescription() { - Palette color = Palette.Yellow; - return new ItemDescription(color) - .withSummary("Toggles a Redstone signal based on the " + h("Storage Space", color) - + " in the attached Container.") - .withBehaviour("When below Lower Limit", "Stops providing " + h("Redstone Power", color)) - .withBehaviour("When above Upper Limit", - "Starts providing " + h("Redstone Power", color) + " until Lower Limit is reached again.") - .withControl("When R-Clicked", "Opens the " + h("Configuration Screen", color)).createTabs(); - } - -} diff --git a/src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchScreen.java b/src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchScreen.java deleted file mode 100644 index af70c616a..000000000 --- a/src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchScreen.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.simibubi.create.modules.logistics; - -public class StockpileSwitchScreen { - -} diff --git a/src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchTileEntity.java deleted file mode 100644 index 078e6f287..000000000 --- a/src/main/java/com/simibubi/create/modules/logistics/StockpileSwitchTileEntity.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.simibubi.create.modules.logistics; - -import com.simibubi.create.AllTileEntities; -import com.simibubi.create.foundation.block.SyncedTileEntity; - -import net.minecraft.nbt.CompoundNBT; - -public class StockpileSwitchTileEntity extends SyncedTileEntity { - - private float offWhenAbove; - private float onWhenBelow; -// private float currentLevel; - - public StockpileSwitchTileEntity() { - super(AllTileEntities.STOCKPILE_SWITCH.type); - } - - @Override - public void read(CompoundNBT compound) { - - offWhenAbove = compound.getFloat("OffAbove"); - onWhenBelow = compound.getFloat("OnBelow"); - updateCurrentLevel(); - - super.read(compound); - } - - @Override - public CompoundNBT write(CompoundNBT compound) { - - compound.putFloat("OffAbove", offWhenAbove); - compound.putFloat("OnBelow", onWhenBelow); - - return super.write(compound); - } - - private void updateCurrentLevel() { - - } - -} diff --git a/src/main/java/com/simibubi/create/modules/logistics/StockswitchBlock.java b/src/main/java/com/simibubi/create/modules/logistics/StockswitchBlock.java new file mode 100644 index 000000000..3acabde18 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/StockswitchBlock.java @@ -0,0 +1,108 @@ +package com.simibubi.create.modules.logistics; + +import java.util.List; + +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.foundation.utility.ITooltip; +import com.simibubi.create.foundation.utility.ItemDescription; +import com.simibubi.create.foundation.utility.ItemDescription.Palette; +import com.simibubi.create.foundation.utility.TooltipHolder; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.HorizontalBlock; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItemUseContext; +import net.minecraft.item.ItemStack; +import net.minecraft.state.IntegerProperty; +import net.minecraft.state.StateContainer.Builder; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.DistExecutor; + +public class StockswitchBlock extends HorizontalBlock implements ITooltip { + + public static final IntegerProperty INDICATOR = IntegerProperty.create("indicator", 0, 6); + private TooltipHolder info; + + public StockswitchBlock() { + super(Properties.from(Blocks.ANDESITE)); + info = new TooltipHolder(this); + } + + @Override + public boolean isSolid(BlockState state) { + return false; + } + + @Override + public void addInformation(ItemStack stack, IBlockReader worldIn, List tooltip, + ITooltipFlag flagIn) { + info.addInformation(tooltip); + } + + @Override + protected void fillStateContainer(Builder builder) { + builder.add(HORIZONTAL_FACING, INDICATOR); + super.fillStateContainer(builder); + } + + @Override + public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { + displayScreen((StockswitchTileEntity) worldIn.getTileEntity(pos)); + }); + return true; + } + + @OnlyIn(value = Dist.CLIENT) + protected void displayScreen(StockswitchTileEntity te) { + ScreenOpener.open(new StockswitchScreen(te)); + } + + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + BlockState state = getDefaultState(); + + if (context.getFace().getAxis().isHorizontal()) { + state = state.with(HORIZONTAL_FACING, context.getFace().getOpposite()); + } else { + state = state.with(HORIZONTAL_FACING, context.getPlacementHorizontalFacing()); + } + + return state; + } + + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return new StockswitchTileEntity(); + } + + @Override + public ItemDescription getDescription() { + Palette color = Palette.Yellow; + return new ItemDescription(color) + .withSummary("Toggles a Redstone signal based on the " + h("Storage Space", color) + + " in the attached Container.") + .withBehaviour("When below Lower Limit", "Stops providing " + h("Redstone Power", color)) + .withBehaviour("When above Upper Limit", + "Starts providing " + h("Redstone Power", color) + " until Lower Limit is reached again.") + .withControl("When R-Clicked", "Opens the " + h("Configuration Screen", color)).createTabs(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/StockswitchScreen.java b/src/main/java/com/simibubi/create/modules/logistics/StockswitchScreen.java new file mode 100644 index 000000000..9df29f301 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/StockswitchScreen.java @@ -0,0 +1,104 @@ +package com.simibubi.create.modules.logistics; + +import static com.simibubi.create.foundation.gui.ScreenResources.STOCKSWITCH; + +import java.util.Arrays; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; +import com.simibubi.create.foundation.gui.ScreenElementRenderer; +import com.simibubi.create.foundation.gui.ScreenResources; +import com.simibubi.create.foundation.gui.widgets.Label; +import com.simibubi.create.foundation.gui.widgets.ScrollInput; + +import net.minecraft.block.BlockState; + +public class StockswitchScreen extends AbstractSimiScreen { + + private ScrollInput offBelow; + private Label offBelowLabel; + private ScrollInput onAbove; + private Label onAboveLabel; + + private StockswitchTileEntity te; + + public StockswitchScreen(StockswitchTileEntity te) { + this.te = te; + } + + @Override + protected void init() { + setWindowSize(STOCKSWITCH.width + 50, STOCKSWITCH.height); + super.init(); + widgets.clear(); + + offBelowLabel = new Label(guiLeft + 116, guiTop + 72, "").colored(0xD3CBBE).withShadow(); + offBelow = new ScrollInput(guiLeft + 113, guiTop + 69, 33, 14).withRange(0, 96).titled("Lower Threshold") + .calling(state -> { + offBelowLabel.text = state + "%"; + if (onAbove.getState() - 4 <= state) { + onAbove.setState(state + 5); + onAbove.onChanged(); + } + }).setState((int) (te.offWhenBelow * 100)); + + onAboveLabel = new Label(guiLeft + 116, guiTop + 55, "").colored(0xD3CBBE).withShadow(); + onAbove = new ScrollInput(guiLeft + 113, guiTop + 52, 33, 14).withRange(5, 101).titled("Upper Threshold") + .calling(state -> { + onAboveLabel.text = state + "%"; + if (offBelow.getState() + 4 >= state) { + offBelow.setState(state - 5); + offBelow.onChanged(); + } + }).setState((int) (te.onWhenAbove * 100)); + + onAbove.onChanged(); + offBelow.onChanged(); + widgets.addAll(Arrays.asList(offBelowLabel, offBelow, onAbove, onAboveLabel)); + } + + @Override + protected void renderWindow(int mouseX, int mouseY, float partialTicks) { + int hFontColor = 0xD3CBBE; + int fontColor = 0x4B3A22; + STOCKSWITCH.draw(this, guiLeft, guiTop); + font.drawStringWithShadow("Stockpile Switch", + guiLeft - 3 + (STOCKSWITCH.width - font.getStringWidth("Stockpile Switch")) / 2, guiTop + 10, + hFontColor); + font.drawString("Start Signal " + (onAbove.getState() == 100 ? "at" : "above"), guiLeft + 13, guiTop + 55, + fontColor); + font.drawString("Stop Signal " + (offBelow.getState() == 0 ? "at" : "below"), guiLeft + 13, guiTop + 72, + fontColor); + + ScreenResources sprite = ScreenResources.STOCKSWITCH_INTERVAL; + float lowerBound = offBelow.getState() / 100f * (sprite.width - 20) + 10; + float upperBound = onAbove.getState() / 100f * (sprite.width - 20) + 10; + float cursorPos = te.currentLevel * (sprite.width - 20) + 10; + + sprite.bind(); + blit((int) (guiLeft + lowerBound), guiTop + 26, (int) (sprite.startX + lowerBound), sprite.startY, + (int) (upperBound - lowerBound), sprite.height); + + sprite = ScreenResources.STOCKSWITCH_INTERVAL_END; + sprite.bind(); + blit((int) (guiLeft + upperBound), guiTop + 26, (int) (sprite.startX + upperBound), sprite.startY, + (int) (sprite.width - upperBound), sprite.height); + + ScreenResources.STOCKSWITCH_BOUND_LEFT.draw(this, (int) (guiLeft + lowerBound) - 1, guiTop + 24); + ScreenResources.STOCKSWITCH_BOUND_RIGHT.draw(this, (int) (guiLeft + upperBound) - 5, guiTop + 24); + + ScreenResources cursor = te.getWorld().isBlockPowered(te.getPos()) ? ScreenResources.STOCKSWITCH_CURSOR_ON + : ScreenResources.STOCKSWITCH_CURSOR_OFF; + cursor.draw(this, (int) (guiLeft + cursorPos), guiTop + 24); + + ScreenElementRenderer.renderBlock(this::getRenderedBlock); + } + + public BlockState getRenderedBlock() { + GlStateManager.translated(guiLeft + STOCKSWITCH.width + 50, guiTop + 100, 0); + GlStateManager.rotatef(50, -.5f, 1, -.2f); + return AllBlocks.STOCKSWITCH.get().getDefaultState(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/StockswitchTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/StockswitchTileEntity.java new file mode 100644 index 000000000..da3bd7f31 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/StockswitchTileEntity.java @@ -0,0 +1,48 @@ +package com.simibubi.create.modules.logistics; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.block.SyncedTileEntity; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.TileEntityType; + +public class StockswitchTileEntity extends SyncedTileEntity { + + float onWhenAbove; + float offWhenBelow; + float currentLevel; + + public StockswitchTileEntity() { + this(AllTileEntities.STOCKSWITCH.type); + } + + public StockswitchTileEntity(TileEntityType typeIn) { + super(typeIn); + onWhenAbove = .75f; + offWhenBelow = .25f; + } + + @Override + public void read(CompoundNBT compound) { + + onWhenAbove = compound.getFloat("OnAbove"); + offWhenBelow = compound.getFloat("OffBelow"); + updateCurrentLevel(); + + super.read(compound); + } + + @Override + public CompoundNBT write(CompoundNBT compound) { + + compound.putFloat("OnAbove", onWhenAbove); + compound.putFloat("OffBelow", offWhenBelow); + + return super.write(compound); + } + + private void updateCurrentLevel() { + + } + +} diff --git a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableScreen.java b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableScreen.java index 7cc1578b2..0186be7d3 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableScreen.java +++ b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableScreen.java @@ -1,5 +1,8 @@ package com.simibubi.create.modules.schematics.block; +import static com.simibubi.create.foundation.gui.ScreenResources.SCHEMATIC_TABLE; +import static com.simibubi.create.foundation.gui.ScreenResources.SCHEMATIC_TABLE_PROGRESS; + import java.nio.file.Paths; import java.util.List; @@ -42,10 +45,10 @@ public class SchematicTableScreen extends AbstractSimiContainerScreen availableSchematics = Create.cSchematicLoader.getAvailableSchematics(); widgets.remove(schematicsArea); - + if (!availableSchematics.isEmpty()) { - schematicsArea = new SelectionScrollInput(guiLeft - 56 + 33, guiTop - 16 + 23, 134, 14).forOptions(availableSchematics) - .titled("Available Schematics").writingTo(schematicsLabel); + schematicsArea = new SelectionScrollInput(guiLeft - 56 + 33, guiTop - 16 + 23, 134, 14) + .forOptions(availableSchematics).titled("Available Schematics").writingTo(schematicsLabel); widgets.add(schematicsArea); } else { schematicsArea = null; diff --git a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonBlock.java b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonBlock.java index 26b0d7305..57e02a9ac 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonBlock.java +++ b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonBlock.java @@ -96,7 +96,7 @@ public class SchematicannonBlock extends InfoBlock { public ItemDescription getDescription() { Palette color = Palette.Blue; return new ItemDescription(color).withSummary("Prints a deployed " + h("Schematic", color) - + "into the world using blocks from inventories placed right next to it."); + + " into the world using blocks from inventories placed right next to it.").createTabs(); } } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/BlueprintEditScreen.java b/src/main/java/com/simibubi/create/modules/schematics/client/BlueprintEditScreen.java index afa15ad81..8babee2da 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/BlueprintEditScreen.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/BlueprintEditScreen.java @@ -34,8 +34,8 @@ public class BlueprintEditScreen extends AbstractSimiScreen { @Override protected void init() { setWindowSize(ScreenResources.SCHEMATIC.width + 50, ScreenResources.SCHEMATIC.height); - int x = topLeftX; - int y = topLeftY; + int x = guiLeft; + int y = guiTop; BlueprintHandler bh = BlueprintHandler.instance; xInput = new TextFieldWidget(font, x + 75, y + 32, 32, 10, ""); @@ -117,8 +117,8 @@ public class BlueprintEditScreen extends AbstractSimiScreen { @Override protected void renderWindow(int mouseX, int mouseY, float partialTicks) { - int x = topLeftX; - int y = topLeftY; + int x = guiLeft; + int y = guiTop; ScreenResources.SCHEMATIC.draw(this, x, y); BlueprintHandler bh = BlueprintHandler.instance; @@ -130,7 +130,7 @@ public class BlueprintEditScreen extends AbstractSimiScreen { font.drawString("Mirror", x + 10, y + 72, ScreenResources.FONT_COLOR); GlStateManager.pushMatrix(); - GlStateManager.translated(topLeftX + 220, topLeftY + 20, 0); + GlStateManager.translated(guiLeft + 220, guiTop + 20, 0); GlStateManager.scaled(3, 3, 3); itemRenderer.renderItemIntoGUI(new ItemStack(AllItems.BLUEPRINT.get()), 0, 0); GlStateManager.popMatrix(); diff --git a/src/main/java/com/simibubi/create/modules/symmetry/SymmetryWandScreen.java b/src/main/java/com/simibubi/create/modules/symmetry/SymmetryWandScreen.java index 23755ecea..f0888923a 100644 --- a/src/main/java/com/simibubi/create/modules/symmetry/SymmetryWandScreen.java +++ b/src/main/java/com/simibubi/create/modules/symmetry/SymmetryWandScreen.java @@ -56,12 +56,12 @@ public class SymmetryWandScreen extends AbstractSimiScreen { super.init(); this.setWindowSize(ScreenResources.WAND_SYMMETRY.width + 50, ScreenResources.WAND_SYMMETRY.height + 50); - labelType = new Label(topLeftX + 122, topLeftY + 15, "").colored(0xFFFFFFFF).withShadow(); - labelAlign = new Label(topLeftX + 122, topLeftY + 35, "").colored(0xFFFFFFFF).withShadow(); + labelType = new Label(guiLeft + 122, guiTop + 15, "").colored(0xFFFFFFFF).withShadow(); + labelAlign = new Label(guiLeft + 122, guiTop + 35, "").colored(0xFFFFFFFF).withShadow(); int state = currentElement instanceof TriplePlaneMirror ? 2 : currentElement instanceof CrossPlaneMirror ? 1 : 0; - areaType = new SelectionScrollInput(topLeftX + 119, topLeftY + 12, 70, 14) + areaType = new SelectionScrollInput(guiLeft + 119, guiTop + 12, 70, 14) .forOptions(SymmetryMirror.TOOLTIP_ELEMENTS).titled("Type of Mirror").writingTo(labelType) .setState(state); @@ -97,7 +97,7 @@ public class SymmetryWandScreen extends AbstractSimiScreen { widgets.remove(areaAlign); } - areaAlign = new SelectionScrollInput(topLeftX + 119, topLeftY + 32, 70, 14).forOptions(element.getAlignToolTips()) + areaAlign = new SelectionScrollInput(guiLeft + 119, guiTop + 32, 70, 14).forOptions(element.getAlignToolTips()) .titled("Direction").writingTo(labelAlign).setState(element.getOrientationIndex()) .calling(element::setOrientation); @@ -112,10 +112,10 @@ public class SymmetryWandScreen extends AbstractSimiScreen { @Override protected void renderWindow(int mouseX, int mouseY, float partialTicks) { - ScreenResources.WAND_SYMMETRY.draw(this, topLeftX, topLeftY); + ScreenResources.WAND_SYMMETRY.draw(this, guiLeft, guiTop); - int x = topLeftX + 63; - int y = topLeftY + 15; + int x = guiLeft + 63; + int y = guiTop + 15; font.drawString("Symmetry", x, y, ScreenResources.FONT_COLOR); font.drawString("Direction", x, y + 20, ScreenResources.FONT_COLOR); @@ -155,7 +155,7 @@ public class SymmetryWandScreen extends AbstractSimiScreen { GlStateManager.pushMatrix(); BufferBuilder buffer = Tessellator.getInstance().getBuffer(); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); - GlStateManager.translated(topLeftX + 15, topLeftY - 117, 20); + GlStateManager.translated(guiLeft + 15, guiTop - 117, 20); GlStateManager.rotatef(-22.5f, .3f, 1f, 0f); GlStateManager.scaled(32, -32, 32); minecraft.getBlockRendererDispatcher().renderBlock(currentElement.getModel(), new BlockPos(0, -5, 0), diff --git a/src/main/resources/assets/create/blockstates/flexcrate.json b/src/main/resources/assets/create/blockstates/flexcrate.json new file mode 100644 index 000000000..6dfa15028 --- /dev/null +++ b/src/main/resources/assets/create/blockstates/flexcrate.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "create:block/flex_crate" } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/blockstates/redstone_bridge.json b/src/main/resources/assets/create/blockstates/redstone_bridge.json index bdc988d68..08162ed76 100644 --- a/src/main/resources/assets/create/blockstates/redstone_bridge.json +++ b/src/main/resources/assets/create/blockstates/redstone_bridge.json @@ -1,17 +1,31 @@ { "variants": { - "powered=false,facing=up": { "model": "create:block/redstone_bridge" }, - "powered=false,facing=down": { "model": "create:block/redstone_bridge", "x": 180 }, - "powered=false,facing=south": { "model": "create:block/redstone_bridge_side"}, - "powered=false,facing=north": { "model": "create:block/redstone_bridge_side", "y": 180 }, - "powered=false,facing=west": { "model": "create:block/redstone_bridge_side", "y": 90 }, - "powered=false,facing=east": { "model": "create:block/redstone_bridge_side", "y": 270 }, + "receiver=false,powered=false,facing=up": { "model": "create:block/redstone_bridge", "y": 180 }, + "receiver=false,powered=false,facing=down": { "model": "create:block/redstone_bridge", "x": 180, "y": 180 }, + "receiver=false,powered=false,facing=south": { "model": "create:block/redstone_bridge_side", "x": 270 }, + "receiver=false,powered=false,facing=north": { "model": "create:block/redstone_bridge_side", "x": 270 , "y": 180 }, + "receiver=false,powered=false,facing=west": { "model": "create:block/redstone_bridge_side", "x": 270 , "y": 90 }, + "receiver=false,powered=false,facing=east": { "model": "create:block/redstone_bridge_side", "x": 270 , "y": 270 }, - "powered=true,facing=up": { "model": "create:block/redstone_bridge_powered" }, - "powered=true,facing=down": { "model": "create:block/redstone_bridge_powered", "x": 180 }, - "powered=true,facing=south": { "model": "create:block/redstone_bridge_side_powered"}, - "powered=true,facing=north": { "model": "create:block/redstone_bridge_side_powered", "y": 180 }, - "powered=true,facing=west": { "model": "create:block/redstone_bridge_side_powered", "y": 90 }, - "powered=true,facing=east": { "model": "create:block/redstone_bridge_side_powered", "y": 270 } + "receiver=false,powered=true,facing=up": { "model": "create:block/redstone_bridge_powered", "y": 180 }, + "receiver=false,powered=true,facing=down": { "model": "create:block/redstone_bridge_powered", "x": 180, "y": 180 }, + "receiver=false,powered=true,facing=south": { "model": "create:block/redstone_bridge_side_powered", "x": 270 }, + "receiver=false,powered=true,facing=north": { "model": "create:block/redstone_bridge_side_powered", "x": 270 , "y": 180 }, + "receiver=false,powered=true,facing=west": { "model": "create:block/redstone_bridge_side_powered", "x": 270 , "y": 90 }, + "receiver=false,powered=true,facing=east": { "model": "create:block/redstone_bridge_side_powered", "x": 270 , "y": 270 }, + + "receiver=true,powered=false,facing=up": { "model": "create:block/redstone_bridge_receiver", "y": 180 }, + "receiver=true,powered=false,facing=down": { "model": "create:block/redstone_bridge_receiver", "x": 180, "y": 180 }, + "receiver=true,powered=false,facing=south": { "model": "create:block/redstone_bridge_receiver_side", "x": 270 }, + "receiver=true,powered=false,facing=north": { "model": "create:block/redstone_bridge_receiver_side", "x": 270 , "y": 180 }, + "receiver=true,powered=false,facing=west": { "model": "create:block/redstone_bridge_receiver_side", "x": 270 , "y": 90 }, + "receiver=true,powered=false,facing=east": { "model": "create:block/redstone_bridge_receiver_side", "x": 270 , "y": 270 }, + + "receiver=true,powered=true,facing=up": { "model": "create:block/redstone_bridge_receiver_powered", "y": 180 }, + "receiver=true,powered=true,facing=down": { "model": "create:block/redstone_bridge_receiver_powered", "x": 180, "y": 180 }, + "receiver=true,powered=true,facing=south": { "model": "create:block/redstone_bridge_receiver_side_powered", "x": 270 }, + "receiver=true,powered=true,facing=north": { "model": "create:block/redstone_bridge_receiver_side_powered", "x": 270 , "y": 180 }, + "receiver=true,powered=true,facing=west": { "model": "create:block/redstone_bridge_receiver_side_powered", "x": 270 , "y": 90 }, + "receiver=true,powered=true,facing=east": { "model": "create:block/redstone_bridge_receiver_side_powered", "x": 270 , "y": 270 } } } \ No newline at end of file diff --git a/src/main/resources/assets/create/blockstates/stockswitch.json b/src/main/resources/assets/create/blockstates/stockswitch.json new file mode 100644 index 000000000..15107fc1e --- /dev/null +++ b/src/main/resources/assets/create/blockstates/stockswitch.json @@ -0,0 +1,23 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "create:block/stockpile_switch" + }, + "variants": { + "indicator": { + "0": { "model": "create:block/stockpile_switch" }, + "1": { "model": "create:block/stockpile_switch_1" }, + "2": { "model": "create:block/stockpile_switch_2" }, + "3": { "model": "create:block/stockpile_switch_3" }, + "4": { "model": "create:block/stockpile_switch_4" }, + "5": { "model": "create:block/stockpile_switch_5" }, + "6": { "model": "create:block/stockpile_switch_6" } + }, + "facing": { + "south": { "y": 270 }, + "east": { "y": 180 }, + "north": { "y": 90 }, + "west": { "y": 0 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index 1ddc79efd..2b82309cf 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -35,8 +35,8 @@ "block.create.contact": "Redstone Contact", "block.create.redstone_bridge": "Redstone Bridge", - "block.create.stockpile_switch": "Stockpile Switch", - "block.create.flex_crate": "FlexCrate", + "block.create.stockswitch": "Stockpile Switch", + "block.create.flexcrate": "FlexCrate", "block.create.andesite_bricks": "Andesite Bricks", "block.create.diorite_bricks": "Diorite Bricks", diff --git a/src/main/resources/assets/create/models/block/flex_crate.json b/src/main/resources/assets/create/models/block/flex_crate.json new file mode 100644 index 000000000..c3d00528a --- /dev/null +++ b/src/main/resources/assets/create/models/block/flex_crate.json @@ -0,0 +1,22 @@ +{ + "parent": "block/block", + "textures": { + "particle": "create:block/flex_crate", + "flex_crate": "create:block/flex_crate" + }, + "elements": [ + { + "name": "Crate", + "from": [ 1, 0, 1 ], + "to": [ 15, 14, 15 ], + "faces": { + "north": { "texture": "#flex_crate", "uv": [ 1, 1, 15, 15 ] }, + "east": { "texture": "#flex_crate", "uv": [ 1, 1, 15, 15 ] }, + "south": { "texture": "#flex_crate", "uv": [ 1, 1, 15, 15 ] }, + "west": { "texture": "#flex_crate", "uv": [ 1, 1, 15, 15 ] }, + "up": { "texture": "#flex_crate", "uv": [ 1, 1, 15, 15 ] }, + "down": { "texture": "#flex_crate", "uv": [ 1, 1, 15, 15 ] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/redstone_bridge.json b/src/main/resources/assets/create/models/block/redstone_bridge.json index b06bd3eb6..3463ac2fe 100644 --- a/src/main/resources/assets/create/models/block/redstone_bridge.json +++ b/src/main/resources/assets/create/models/block/redstone_bridge.json @@ -11,7 +11,7 @@ "textures": { "redstone_antenna": "create:block/redstone_antenna", "redstone_bridge": "create:block/redstone_bridge", - "particle": "#redstone_bridge" + "particle": "create:block/redstone_bridge" }, "elements": [ { diff --git a/src/main/resources/assets/create/models/block/redstone_bridge_powered.json b/src/main/resources/assets/create/models/block/redstone_bridge_powered.json index 9365eb044..20e8b9390 100644 --- a/src/main/resources/assets/create/models/block/redstone_bridge_powered.json +++ b/src/main/resources/assets/create/models/block/redstone_bridge_powered.json @@ -2,6 +2,7 @@ "parent": "create:block/redstone_bridge", "textures": { "redstone_antenna": "create:block/redstone_antenna_powered", - "redstone_bridge": "create:block/redstone_bridge_powered" + "redstone_bridge": "create:block/redstone_bridge_powered", + "particle": "create:block/redstone_bridge_powered" } } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/redstone_bridge_receiver.json b/src/main/resources/assets/create/models/block/redstone_bridge_receiver.json new file mode 100644 index 000000000..d4a811669 --- /dev/null +++ b/src/main/resources/assets/create/models/block/redstone_bridge_receiver.json @@ -0,0 +1,66 @@ +{ + "__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)", + "parent": "block/block", + "display": { + "gui": { + "rotation": [ 30, 45, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.625, 0.625, 0.625 ] + } + }, + "textures": { + "redstone_antenna": "create:block/redstone_antenna", + "redstone_bridge": "create:block/redstone_bridge", + "particle": "create:block/redstone_bridge" + }, + "elements": [ + { + "name": "Controller", + "from": [ 2, 0, 2 ], + "to": [ 14, 3, 14 ], + "faces": { + "north": { "texture": "#redstone_bridge", "uv": [ 12, 0, 15, 12 ], "rotation": 90 }, + "east": { "texture": "#redstone_bridge", "uv": [ 0, 12, 12, 15 ] }, + "south": { "texture": "#redstone_bridge", "uv": [ 12, 0, 15, 12 ], "rotation": 90 }, + "west": { "texture": "#redstone_bridge", "uv": [ 0, 12, 12, 15 ] }, + "up": { "texture": "#redstone_bridge", "uv": [ 0, 0, 12, 12 ], "rotation": 270 } + } + }, + { + "name": "AntennaX", + "from": [ 0, 1, 4 ], + "to": [ 3, 11, 5 ], + "faces": { + "north": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] }, + "south": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] }, + "down": { "texture": "#redstone_antenna", "uv": [ 0, 9, 3, 10 ] } + } + }, + { + "name": "AntennaZ", + "from": [ 1, 1, 3 ], + "to": [ 2, 11, 6 ], + "faces": { + "east": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] }, + "west": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] } + } + }, + { + "name": "AntennaTop", + "from": [ 1, 9, 4 ], + "to": [ 2, 10, 5 ], + "faces": { + "up": { "texture": "#redstone_antenna", "uv": [ 1, 1, 2, 2 ] } + } + }, + { + "name": "Dish", + "from": [ -1, 7, 2 ], + "to": [ 4, 7, 7 ], + "faces": { + "up": { "texture": "#redstone_antenna", "uv": [ 4, 0, 9, 5 ] }, + "down": { "texture": "#redstone_antenna", "uv": [ 4, 0, 9, 5 ] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/redstone_bridge_receiver_powered.json b/src/main/resources/assets/create/models/block/redstone_bridge_receiver_powered.json new file mode 100644 index 000000000..e4390614c --- /dev/null +++ b/src/main/resources/assets/create/models/block/redstone_bridge_receiver_powered.json @@ -0,0 +1,8 @@ +{ + "parent": "create:block/redstone_bridge_receiver", + "textures": { + "redstone_antenna": "create:block/redstone_antenna_powered", + "redstone_bridge": "create:block/redstone_bridge_powered", + "particle": "create:block/redstone_bridge_powered" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/redstone_bridge_receiver_side.json b/src/main/resources/assets/create/models/block/redstone_bridge_receiver_side.json new file mode 100644 index 000000000..4e481b676 --- /dev/null +++ b/src/main/resources/assets/create/models/block/redstone_bridge_receiver_side.json @@ -0,0 +1,70 @@ +{ + "__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)", + "parent": "block/block", + "textures": { + "redstone_antenna": "create:block/redstone_antenna", + "redstone_bridge_side": "create:block/redstone_bridge_side", + "particle": "create:block/redstone_bridge_side" + }, + "elements": [ + { + "name": "Body", + "from": [ 3, 0, 1 ], + "to": [ 13, 3, 15 ], + "faces": { + "north": { "texture": "#redstone_bridge_side", "uv": [ 13, 2, 16, 12 ], "rotation": 90 }, + "east": { "texture": "#redstone_bridge_side", "uv": [ 10, 0, 13, 14 ], "rotation": 90 }, + "south": { "texture": "#redstone_bridge_side", "uv": [ 13, 2, 16, 12 ], "rotation": 90 }, + "west": { "texture": "#redstone_bridge_side", "uv": [ 10, 0, 13, 14 ], "rotation": 90 }, + "up": { "texture": "#redstone_bridge_side", "uv": [ 0, 0, 10, 14 ] } + } + }, + { + "name": "Bottom", + "from": [ 3, -1, 1 ], + "to": [ 13, 0, 15 ], + "faces": { + "north": { "texture": "#redstone_bridge_side", "uv": [ 15, 1, 16, 13 ], "rotation": 270 }, + "east": { "texture": "#redstone_bridge_side", "uv": [ 14, 0, 15, 14 ], "rotation": 270 }, + "south": { "texture": "#redstone_bridge_side", "uv": [ 15, 1, 16, 13 ], "rotation": 90 }, + "west": { "texture": "#redstone_bridge_side", "uv": [ 14, 0, 15, 14 ], "rotation": 90 } + } + }, + { + "name": "AntennaX", + "from": [ 3, 3, -5 ], + "to": [ 6, 4, 5 ], + "faces": { + "south": { "texture": "#redstone_antenna", "uv": [ 0, 9, 3, 10 ] }, + "up": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] }, + "down": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ], "rotation": 180 } + } + }, + { + "name": "AntennaZ", + "from": [ 4, 2, -5 ], + "to": [ 5, 5, 5 ], + "faces": { + "east": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ], "rotation": 90 }, + "west": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ], "rotation": 270 } + } + }, + { + "name": "AntennaTop", + "from": [ 4, 3, -4 ], + "to": [ 5, 4, -3 ], + "faces": { + "north": { "texture": "#redstone_antenna", "uv": [ 1, 1, 2, 2 ] } + } + }, + { + "name": "Dish", + "from": [ 2, 1, -1 ], + "to": [ 7, 6, -1 ], + "faces": { + "north": { "texture": "#redstone_antenna", "uv": [ 4, 0, 9, 5 ] }, + "south": { "texture": "#redstone_antenna", "uv": [ 4, 0, 9, 5 ] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/redstone_bridge_receiver_side_powered.json b/src/main/resources/assets/create/models/block/redstone_bridge_receiver_side_powered.json new file mode 100644 index 000000000..e395ee7bf --- /dev/null +++ b/src/main/resources/assets/create/models/block/redstone_bridge_receiver_side_powered.json @@ -0,0 +1,8 @@ +{ + "parent": "create:block/redstone_bridge_receiver_side", + "textures": { + "redstone_antenna": "create:block/redstone_antenna_powered", + "redstone_bridge_side": "create:block/redstone_bridge_side_powered", + "particle": "create:block/redstone_bridge_powered" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/redstone_bridge_side.json b/src/main/resources/assets/create/models/block/redstone_bridge_side.json index 41798dcc1..e57fc79bd 100644 --- a/src/main/resources/assets/create/models/block/redstone_bridge_side.json +++ b/src/main/resources/assets/create/models/block/redstone_bridge_side.json @@ -4,47 +4,57 @@ "textures": { "redstone_antenna": "create:block/redstone_antenna", "redstone_bridge_side": "create:block/redstone_bridge_side", - "particle": "#redstone_bridge_side" + "particle": "create:block/redstone_bridge_side" }, "elements": [ { - "name": "Controller", - "from": [ 3, 1, -1 ], - "to": [ 13, 15, 2 ], + "name": "Body", + "from": [ 3, 0, 1 ], + "to": [ 13, 3, 15 ], "faces": { - "north": { "texture": "#redstone_bridge_side", "uv": [ 0, 0, 10, 14 ] }, - "east": { "texture": "#redstone_bridge_side", "uv": [ 10, 0, 13, 14 ] }, - "south": { "texture": "#redstone_bridge_side", "uv": [ 0, 0, 10, 14 ] }, - "west": { "texture": "#redstone_bridge_side", "uv": [ 10, 0, 13, 14 ], "rotation": 180 }, - "up": { "texture": "#redstone_bridge_side", "uv": [ 13, 0, 16, 10 ], "rotation": 270 }, - "down": { "texture": "#redstone_bridge_side", "uv": [ 13, 0, 16, 10 ], "rotation": 90 } + "north": { "texture": "#redstone_bridge_side", "uv": [ 13, 2, 16, 12 ], "rotation": 90 }, + "east": { "texture": "#redstone_bridge_side", "uv": [ 10, 0, 13, 14 ], "rotation": 90 }, + "south": { "texture": "#redstone_bridge_side", "uv": [ 13, 2, 16, 12 ], "rotation": 90 }, + "west": { "texture": "#redstone_bridge_side", "uv": [ 10, 0, 13, 14 ], "rotation": 90 }, + "up": { "texture": "#redstone_bridge_side", "uv": [ 0, 0, 10, 14 ] } + } + }, + { + "name": "Bottom", + "from": [ 3, -1, 1 ], + "to": [ 13, 0, 15 ], + "faces": { + "north": { "texture": "#redstone_bridge_side", "uv": [ 15, 1, 16, 13 ], "rotation": 270 }, + "east": { "texture": "#redstone_bridge_side", "uv": [ 14, 0, 15, 14 ], "rotation": 270 }, + "south": { "texture": "#redstone_bridge_side", "uv": [ 15, 1, 16, 13 ], "rotation": 90 }, + "west": { "texture": "#redstone_bridge_side", "uv": [ 14, 0, 15, 14 ], "rotation": 90 } } }, { "name": "AntennaX", - "from": [ 3, 11, 2 ], - "to": [ 6, 21, 3 ], + "from": [ 3, 3, -5 ], + "to": [ 6, 4, 5 ], "faces": { - "north": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] }, - "south": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] }, - "down": { "texture": "#redstone_antenna", "uv": [ 0, 9, 3, 10 ] } + "south": { "texture": "#redstone_antenna", "uv": [ 0, 9, 3, 10 ] }, + "up": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] }, + "down": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ], "rotation": 180 } } }, { "name": "AntennaZ", - "from": [ 4, 11, 1 ], - "to": [ 5, 21, 4 ], + "from": [ 4, 2, -5 ], + "to": [ 5, 5, 5 ], "faces": { - "east": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] }, - "west": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] } + "east": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ], "rotation": 90 }, + "west": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ], "rotation": 270 } } }, { "name": "AntennaTop", - "from": [ 4, 19, 2 ], - "to": [ 5, 20, 3 ], + "from": [ 4, 3, -4 ], + "to": [ 5, 4, -3 ], "faces": { - "up": { "texture": "#redstone_antenna", "uv": [ 1, 1, 2, 2 ] } + "north": { "texture": "#redstone_antenna", "uv": [ 1, 1, 2, 2 ] } } } ] diff --git a/src/main/resources/assets/create/models/block/redstone_bridge_side_powered.json b/src/main/resources/assets/create/models/block/redstone_bridge_side_powered.json index c32b98bf0..67f6d2a4f 100644 --- a/src/main/resources/assets/create/models/block/redstone_bridge_side_powered.json +++ b/src/main/resources/assets/create/models/block/redstone_bridge_side_powered.json @@ -2,6 +2,7 @@ "parent": "create:block/redstone_bridge_side", "textures": { "redstone_antenna": "create:block/redstone_antenna_powered", - "redstone_bridge_side": "create:block/redstone_bridge_side_powered" + "redstone_bridge_side": "create:block/redstone_bridge_side_powered", + "particle": "create:block/redstone_bridge_powered" } } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/stockpile_switch.json b/src/main/resources/assets/create/models/block/stockpile_switch.json new file mode 100644 index 000000000..c30e2a3a3 --- /dev/null +++ b/src/main/resources/assets/create/models/block/stockpile_switch.json @@ -0,0 +1,92 @@ +{ + "__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)", + "parent": "block/block", + "textures": { + "progress": "create:block/indicator/0", + "brass_casing": "create:block/brass_casing", + "dark_oak_planks": "minecraft:block/dark_oak_planks", + "iron_block": "minecraft:block/iron_block", + "particle": "create:block/brass_casing" + }, + "elements": [ + { + "name": "Indicator", + "from": [ 1, 2, 13 ], + "to": [ 4, 14, 16 ], + "faces": { + "east": { "texture": "#progress", "uv": [ 0, 2, 3, 14 ] }, + "south": { "texture": "#progress", "uv": [ 1, 2, 4, 14 ] }, + "west": { "texture": "#progress", "uv": [ 0, 2, 3, 14 ] } + } + }, + { + "name": "Bottom Plate", + "from": [ 0, 0, 0 ], + "to": [ 16, 2, 16 ], + "faces": { + "north": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] }, + "east": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] }, + "south": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] }, + "west": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] }, + "up": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] }, + "down": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] } + } + }, + { + "name": "Top Plate", + "from": [ 0, 14, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "north": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] }, + "east": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] }, + "south": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] }, + "west": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] }, + "up": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] }, + "down": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] } + } + }, + { + "name": "Side Plate", + "from": [ 14, 2, 0 ], + "to": [ 16, 14, 16 ], + "faces": { + "north": { "texture": "#brass_casing", "uv": [ 0, 2, 2, 14 ] }, + "east": { "texture": "#brass_casing", "uv": [ 0, 2, 16, 14 ] }, + "south": { "texture": "#brass_casing", "uv": [ 14, 2, 16, 14 ] }, + "west": { "texture": "#brass_casing", "uv": [ 0, 2, 16, 14 ] } + } + }, + { + "name": "Center", + "from": [ 2, 2, 1 ], + "to": [ 14, 14, 15 ], + "faces": { + "north": { "texture": "#dark_oak_planks", "uv": [ 0, 0, 12, 12 ] }, + "south": { "texture": "#dark_oak_planks", "uv": [ 0, 0, 12, 12 ] }, + "west": { "texture": "#dark_oak_planks", "uv": [ 0, 0, 14, 12 ] } + } + }, + { + "name": "Indicator", + "from": [ -1, 2, 2 ], + "to": [ 1, 14, 14 ], + "faces": { + "north": { "texture": "#iron_block", "uv": [ 14, 2, 16, 14 ] }, + "south": { "texture": "#iron_block", "uv": [ 0, 2, 2, 14 ] }, + "west": { "texture": "#iron_block", "uv": [ 2, 2, 14, 14 ] }, + "up": { "texture": "#iron_block", "uv": [ 2, 0, 14, 2 ], "rotation": 270 }, + "down": { "texture": "#iron_block", "uv": [ 2, 14, 14, 16 ], "rotation": 90 } + } + }, + { + "name": "Indicator", + "from": [ 1, 2, 0 ], + "to": [ 4, 14, 3 ], + "faces": { + "north": { "texture": "#progress", "uv": [ 0, 2, 3, 14 ] }, + "east": { "texture": "#progress", "uv": [ 1, 2, 4, 14 ] }, + "west": { "texture": "#progress", "uv": [ 1, 2, 4, 14 ] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/stockpile_switch_1.json b/src/main/resources/assets/create/models/block/stockpile_switch_1.json new file mode 100644 index 000000000..f8d6edca1 --- /dev/null +++ b/src/main/resources/assets/create/models/block/stockpile_switch_1.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/stockpile_switch", + "textures": { + "progress": "create:block/indicator/1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/stockpile_switch_2.json b/src/main/resources/assets/create/models/block/stockpile_switch_2.json new file mode 100644 index 000000000..1e2d3278e --- /dev/null +++ b/src/main/resources/assets/create/models/block/stockpile_switch_2.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/stockpile_switch", + "textures": { + "progress": "create:block/indicator/2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/stockpile_switch_3.json b/src/main/resources/assets/create/models/block/stockpile_switch_3.json new file mode 100644 index 000000000..cc7518686 --- /dev/null +++ b/src/main/resources/assets/create/models/block/stockpile_switch_3.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/stockpile_switch", + "textures": { + "progress": "create:block/indicator/3" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/stockpile_switch_4.json b/src/main/resources/assets/create/models/block/stockpile_switch_4.json new file mode 100644 index 000000000..d3e052411 --- /dev/null +++ b/src/main/resources/assets/create/models/block/stockpile_switch_4.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/stockpile_switch", + "textures": { + "progress": "create:block/indicator/4" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/stockpile_switch_5.json b/src/main/resources/assets/create/models/block/stockpile_switch_5.json new file mode 100644 index 000000000..b99d92e0b --- /dev/null +++ b/src/main/resources/assets/create/models/block/stockpile_switch_5.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/stockpile_switch", + "textures": { + "progress": "create:block/indicator/5" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/stockpile_switch_6.json b/src/main/resources/assets/create/models/block/stockpile_switch_6.json new file mode 100644 index 000000000..d25d07ae7 --- /dev/null +++ b/src/main/resources/assets/create/models/block/stockpile_switch_6.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/stockpile_switch", + "textures": { + "progress": "create:block/indicator/6" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/flexcrate.json b/src/main/resources/assets/create/models/item/flexcrate.json new file mode 100644 index 000000000..8e844dbae --- /dev/null +++ b/src/main/resources/assets/create/models/item/flexcrate.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/flex_crate" +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/stockswitch.json b/src/main/resources/assets/create/models/item/stockswitch.json new file mode 100644 index 000000000..8c0271645 --- /dev/null +++ b/src/main/resources/assets/create/models/item/stockswitch.json @@ -0,0 +1,10 @@ +{ + "parent": "create:block/stockpile_switch_4", + "display": { + "gui": { + "rotation": [ 30, 45, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.625, 0.625, 0.625 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/indicator/0.png b/src/main/resources/assets/create/textures/block/indicator/0.png new file mode 100644 index 0000000000000000000000000000000000000000..587a8cf84c1ea7681bc15c1049483806c97a455a GIT binary patch literal 341 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!B?Ixjv*HQb0_cZJ7gfxa$K#^yU~G>b5`)J zD=RfCTS6)stW@T;b8)(gRPyh-5Z9F*RDASqpi6?bT3p?)uj;*~w+>02y|qZkJ2+JI z)h;&?*Att38X7$=Uuj9~SeEJG8n{7kf}_BL9k(Bq+&EmNcj>c@&(s4u-rBm`EU|qy z*UmRvSNi2|JH5FZiyDP^tZTpYY|VMmWdHJE_>VkQt)&K8rfO1K-1MeASgv0vry*6a zP-yvfvCZ1A|L$4H^8eU_H`g96W{$oaV3FsT-Mju=O|Y2VCA0kzYd6H?&)KH%$;N#B jdYR*flT;G7aNc1IIOgl;GJ6d#(ANx}u6{1-oD!M<^yi0C literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/indicator/1.png b/src/main/resources/assets/create/textures/block/indicator/1.png new file mode 100644 index 0000000000000000000000000000000000000000..99db8f66689e7ae3a755574492bfef23cd3153e5 GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!Oxy9jv*HQb0=@~J8U4(_J6m916zoQ*1@3E zvvb4~Pfp=9{IYPygn%Oxz9%S^oSn6kCs$ddLtFZ`)|nW)m)q;^7ud}|e`VX+x4Zai z?<=1+3JG-;a7c~3W#VhtmmF}}WD(0870$T%av%SF;(5PxLlBp@?+&AjnkvnIi(YTp zbS&CX=C~nS`krS3T02U1b*$N*fO7$OJvpSTmR~w+MEv*XDjn-XXF`Jc_|^X@6UQ<!U+nOOs*zMEXtHxzDOg2JwSlv$BjJ?U)OTK-Z^24kiXZ1h2Psc*l#|) znX#}s`{soAzbzz_P1(W^?!9>B^0iHc>@uE@6#f)WUoqv-p8StD4%sS;haaqSx^Y)i zykKGE?WC{QA3o(daXPglzkPw}v||yyjUm?;n)LqRVHCIGZuC#y_jcLydbMAswbkpj v&s@)z@wJX|nfLrx{glTRZj)4cGFjGffAqJkTdg=5=zj)JS3j3^P6>0TIsxVk1bU=sPzBvsSL&AOV8RHbWDFd?Tyv!?!Ufv6{l~9^K9PSv+DIN zQ{U!oxf4}5yA}lqEcj$oUMREp{qMlg&`z!Z5!Z_7^&dX|VtT(cK!9b38CQ6i|3sco z$9Z30i_AY7Akp?C@v&+9#%AtoJIn5MNphEnJcw@n+?G*pZ4=eJ{NRC-yCU=XCT^{G z@b3Nde}`sXyRqSBl7*TR$GL}nz1L+<@Gxh|J-sgCv2brtMf&HL`ZoNUU#cw}^yd}s vj9K*fxkq4X&wSRhz}y3#lO7}%cR&AaU9q;c*U;jQAm1{L2&)_X z?n1}&J_Yd}FYNIbw3~Loq;E&d;i<(2w{tfaQXn z^}~CWKHjv*HQb0-`6A2twZov$Bu#V16NJ2=8Y za>l08r{*p^GX4K;^vM7JV1Dy{%ZaN+{MLP~_p$kBsZj`%7#QxfJ#I%L0S#joVWu zY!Wjs*s`0sq>mIKB+QVi!LFL1tpSm47uUd<~X-(AHjv*HQb0_QiA8`<9n?E)Xy2RL9~&Mzb^YsE z%Q8D2&#*Z!%N8>&wa&il#jR;&cFT3VCpW%fVGJzvEeYOW-XW$E()^h-Ca1A{+3ETT zsS=-Tns3fdn=R3EESaxRCgW0m(t}^~#BJ6$C%De}KBvM$>fkq*_C%Ly-KTVxS zzs~#Vzu-l&b6c7&+exTM8(lNC%ldHSRk)$j3!XmHi21$~)?e-NdXOlv#$);J{g)rq z&3$3B=0tm*;*LE@NMhCVU!`dr&1uxO0M{?)+TobtfYGg@h z=SwxVMQGghCH{QkyfA>E10e(wLeMylVO>{zYntZmpHC#;Zgm}yo@~X&7@DSuhGE#p zVnA^3djw`#78E<@@NTVrjl_XKYmLB2DXFR|DvAQn91v{%GF05NQi{s5#G15in_L6X zbshTTg4mS;GsuyWKrqiU!WAIMO)~`q-g|^Ae4WHI_=LttZqZSACirO=QvAJu=mBpS VTQe_l1j7IT002ovPDHLkV1k&XVmAN) delta 151 zcmV;I0BHZI0_6daR)2a)L_t(IPt}sa3BVu>MYZQl;8q>dxtu}pDi*&z#G+}MTOTNX z#7ES4$7rqHtAY2^_L8GdX9)Ajuf!N3=oRpx0TrZ_5G+7YNoncql~UxbkYYfcq-KflE;!+wY*t9BPOc{r~^~ delta 153 zcmV;K0A~Nh0_OpcR)2g+L_t(IPwkRR4uBvG1zXnK(aUfccb>+Bkg&xnFKVKJf?Yca zpVx#5kg|x-#w<>RsRDDgeB;VtnI}lj+BeD#mSeg0@6p4RX$=9v0t6`~1Pc&&?-6SB zo&iA*O#(rT5y1ikBfs4Of}Asgg-4rdH)(a`&?jpA0-_z}tr9m|BY?Us00000NkvXX Hu0mjfOd3Ef diff --git a/src/main/resources/assets/create/textures/block/redstone_bridge_side.png b/src/main/resources/assets/create/textures/block/redstone_bridge_side.png index 28c13f8882573d9835e2981528f50813a6fe6416..772f9f8b6a011db4b3b4d422e43196b5aa06cdac 100644 GIT binary patch delta 480 zcmV<60U!RF1fK+uNq@os01m-);K7mG7?7z#r;aGXY$lp0FWhd}cdL?f=WAJ^2 zfy5dGtVBGf?7%fzIK(rt+(K1La;@RY%zs)SY$48e8#oz9#@ghBGvE;Oy!aWqLwW3z zt798H2Lq|%w?ndUh@1gQ;xCkCo4`DUZqLiFqV*0p#90||3xww&vFE_bOo|Hqa4)$l z-yS5p1?g7Wkh^eqbEV@{^tBvMPUK?k1M~FL*vF^WgUj^v8sk|cDJ|3d4~LWbGr%|X Wkjii6%XuFF00002PY=7Jf4$R z$7Aq&(4a1^U8${1WDl69m!)|7kYc=&;_y^?=IJsivQ+AZ*aNc#L&bx2vO~RiL71|9 z^CIyU%7}-%8@Y-|UqL7A(uZ|CxQP}jeh!9*kLmd}I=C&Q)N}ops#AXk_yx9o!ynd> Rf6xE`002ovPDHLkV1k*9;KTp` diff --git a/src/main/resources/assets/create/textures/block/redstone_bridge_side_powered.png b/src/main/resources/assets/create/textures/block/redstone_bridge_side_powered.png index 7edf512335daa35f1be0a3e78c6a55fa5d2e14cc..82d8928cee25fe96870fcbd7b60d5e9008fb679a 100644 GIT binary patch delta 497 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