From 4e69d98ebc025a183c69b2e5865f531a014ceef3 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sun, 6 Oct 2019 21:49:44 +0200 Subject: [PATCH] Configurable Logistical Contollers - Added Containers and GUIs for Logistical Controllers --- .../com/simibubi/create/AllContainers.java | 4 + .../java/com/simibubi/create/AllPackets.java | 3 + .../com/simibubi/create/ScreenResources.java | 78 +++--- .../block/AbstractTileEntityContainer.java | 58 ++++ .../foundation/block/IWithContainer.java | 36 +++ .../block/IWithContainerTileEntity.java | 19 ++ .../gui/AbstractSimiContainerScreen.java | 88 ++++++ .../foundation/gui/ScreenElementRenderer.java | 22 +- .../foundation/type/CountedItemsList.java | 2 +- .../foundation/utility/ColorHelper.java | 21 +- .../placementHandgun/BuilderGunScreen.java | 6 +- .../placementHandgun/PlacementPatterns.java | 12 +- .../management/LogisticalNetwork.java | 57 +++- .../management/LogisticalNetworkHandler.java | 12 +- .../base/LogisticalCasingTileEntity.java | 1 + .../base/LogisticalControllerBlock.java | 34 ++- .../base/LogisticalControllerItem.java | 6 + .../base/LogisticalControllerTileEntity.java | 29 +- .../controller/CalculationTileEntity.java | 1 - ...gisticalControllerConfigurationPacket.java | 62 +++++ ...ogisticalInventoryControllerContainer.java | 55 ++++ .../LogisticalInventoryControllerScreen.java | 252 ++++++++++++++++++ ...gisticalInventoryControllerTileEntity.java | 47 +++- .../controller/RequestTileEntity.java | 1 - .../controller/StorageTileEntity.java | 1 - .../controller/SupplyTileEntity.java | 1 - .../index/LogisticalIndexScreen.java | 91 +------ .../index/LogisticalIndexTileEntity.java | 6 +- .../block/SchematicTableScreen.java | 6 +- .../block/SchematicannonScreen.java | 16 +- .../schematics/client/tools/Tools.java | 12 +- .../resources/assets/create/lang/en_us.json | 20 ++ .../assets/create/textures/gui/controller.png | Bin 0 -> 5313 bytes .../assets/create/textures/gui/icons.png | Bin 2320 -> 2394 bytes .../create/textures/gui/placement_handgun.pdn | Bin 8649 -> 0 bytes 35 files changed, 866 insertions(+), 193 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/block/AbstractTileEntityContainer.java create mode 100644 src/main/java/com/simibubi/create/foundation/block/IWithContainer.java create mode 100644 src/main/java/com/simibubi/create/foundation/block/IWithContainerTileEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalControllerConfigurationPacket.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerContainer.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerScreen.java rename src/main/java/com/simibubi/create/modules/logistics/management/{base => controller}/LogisticalInventoryControllerTileEntity.java (88%) create mode 100644 src/main/resources/assets/create/textures/gui/controller.png delete mode 100644 src/main/resources/assets/create/textures/gui/placement_handgun.pdn diff --git a/src/main/java/com/simibubi/create/AllContainers.java b/src/main/java/com/simibubi/create/AllContainers.java index 1b4fdc896..440c2e617 100644 --- a/src/main/java/com/simibubi/create/AllContainers.java +++ b/src/main/java/com/simibubi/create/AllContainers.java @@ -2,6 +2,8 @@ package com.simibubi.create; import com.simibubi.create.modules.logistics.block.inventories.FlexcrateContainer; import com.simibubi.create.modules.logistics.block.inventories.FlexcrateScreen; +import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerContainer; +import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerScreen; import com.simibubi.create.modules.logistics.management.index.LogisticalIndexContainer; import com.simibubi.create.modules.logistics.management.index.LogisticalIndexScreen; import com.simibubi.create.modules.schematics.block.SchematicTableContainer; @@ -32,6 +34,7 @@ public enum AllContainers { SCHEMATICANNON(SchematicannonContainer::new), FLEXCRATE(FlexcrateContainer::new), LOGISTICAL_INDEX(LogisticalIndexContainer::new), + LOGISTICAL_CONTROLLER(LogisticalInventoryControllerContainer::new), ; @@ -58,6 +61,7 @@ public enum AllContainers { bind(SCHEMATICANNON, SchematicannonScreen::new); bind(FLEXCRATE, FlexcrateScreen::new); bind(LOGISTICAL_INDEX, LogisticalIndexScreen::new); + bind(LOGISTICAL_CONTROLLER, LogisticalInventoryControllerScreen::new); } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/com/simibubi/create/AllPackets.java b/src/main/java/com/simibubi/create/AllPackets.java index 7dc2d2c6d..b6fa107e7 100644 --- a/src/main/java/com/simibubi/create/AllPackets.java +++ b/src/main/java/com/simibubi/create/AllPackets.java @@ -11,6 +11,7 @@ import com.simibubi.create.modules.contraptions.receivers.constructs.ConfigureCh import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunBeamPacket; import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket; import com.simibubi.create.modules.logistics.block.diodes.ConfigureFlexpeaterPacket; +import com.simibubi.create.modules.logistics.management.controller.LogisticalControllerConfigurationPacket; import com.simibubi.create.modules.logistics.management.index.IndexContainerUpdatePacket; import com.simibubi.create.modules.logistics.management.index.IndexOrderRequest; import com.simibubi.create.modules.logistics.packet.ConfigureFlexcratePacket; @@ -35,6 +36,8 @@ public enum AllPackets { CONFIGURE_CHASSIS(ConfigureChassisPacket.class, ConfigureChassisPacket::new), CONFIGURE_MOTOR(ConfigureMotorPacket.class, ConfigureMotorPacket::new), CONFIGURE_FLEXPEATER(ConfigureFlexpeaterPacket.class, ConfigureFlexpeaterPacket::new), + CONFIGURE_LOGISTICAL_CONTROLLER(LogisticalControllerConfigurationPacket.class, + LogisticalControllerConfigurationPacket::new), PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new), UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new), INDEX_ORDER_REQUEST(IndexOrderRequest.class, IndexOrderRequest::new), diff --git a/src/main/java/com/simibubi/create/ScreenResources.java b/src/main/java/com/simibubi/create/ScreenResources.java index 38baf178c..8dd812bf5 100644 --- a/src/main/java/com/simibubi/create/ScreenResources.java +++ b/src/main/java/com/simibubi/create/ScreenResources.java @@ -46,6 +46,13 @@ public enum ScreenResources { INDEX_SEARCH("index.png", 0, 99, 28, 19), INDEX_SEARCH_OVERLAY("widgets.png", 0, 81, 176, 20), + LOGISTICAL_CONTROLLER_TRIM("controller.png", 178, 6), + LOGISTICAL_CONTROLLER("controller.png", 0, 6, 185, 71), + + ITEM_COUNT_SCROLLAREA("controller.png", 62, 83, 22, 10), + BIG_SLOT("controller.png", 0, 83, 26, 26), + SHIPPING_SLOT("controller.png", 26, 83, 18, 21), + RECEIVING_SLOT("controller.png", 44, 83, 18, 21), SLOT_FRAME("index.png", 0, 118, 18, 18), SLOT_INNER("index.png", 18, 118, 18, 18), DISABLED_SLOT_FRAME("index.png", 0, 136, 18, 18), @@ -77,43 +84,50 @@ public enum ScreenResources { BLUEPRINT_SLOT("widgets.png", 90, 0, 24, 24), // Icons - ICON_NONE("icons.png", 16, 16, 16, 16), - ICON_ADD("icons.png", 16, 16), - ICON_TRASH("icons.png", 16, 0, 16, 16), - ICON_3x3("icons.png", 32, 0, 16, 16), - ICON_TARGET("icons.png", 48, 0, 16, 16), - ICON_CONFIRM("icons.png", 0, 16, 16, 16), + I_NONE(16, 16), + I_ADD(0, 0), + I_TRASH(16, 0), + I_3x3(32, 0), + I_TARGET(48, 0), + I_CONFIRM(0, 16), - ICON_OPEN_FOLDER("icons.png", 32, 16, 16, 16), - ICON_REFRESH("icons.png", 48, 16, 16, 16), + I_OPEN_FOLDER(32, 16), + I_REFRESH(48, 16), - ICON_DONT_REPLACE("icons.png", 0, 32, 16, 16), - ICON_REPLACE_SOLID("icons.png", 16, 32, 16, 16), - ICON_REPLACE_ANY("icons.png", 32, 32, 16, 16), - ICON_REPLACE_EMPTY("icons.png", 48, 32, 16, 16), + I_DONT_REPLACE(0, 32), + I_REPLACE_SOLID(16, 32), + I_REPLACE_ANY(32, 32), + I_REPLACE_EMPTY(48, 32), - ICON_TOOL_DEPLOY("icons.png", 0, 48, 16, 16), - ICON_SKIP_MISSING("icons.png", 16, 48, 16, 16), - ICON_SKIP_TILES("icons.png", 32, 48, 16, 16), + I_TOOL_DEPLOY(0, 48), + I_SKIP_MISSING(16, 48), + I_SKIP_TILES(32, 48), - ICON_TOOL_MOVE_XZ("icons.png", 0, 64, 16, 16), - ICON_TOOL_MOVE_Y("icons.png", 16, 64, 16, 16), - ICON_TOOL_ROTATE("icons.png", 32, 64, 16, 16), - ICON_TOOL_MIRROR("icons.png", 48, 64, 16, 16), + I_TOOL_MOVE_XZ(0, 64), + I_TOOL_MOVE_Y(16, 64), + I_TOOL_ROTATE(32, 64), + I_TOOL_MIRROR(48, 64), - ICON_PLAY("icons.png", 0, 80, 16, 16), - ICON_PAUSE("icons.png", 16, 80, 16, 16), - ICON_STOP("icons.png", 32, 80, 16, 16), + I_PLAY(0, 80), + I_PAUSE(16, 80), + I_STOP(32, 80), - ICON_PATTERN_SOLID("icons.png", 0, 96, 16, 16), - ICON_PATTERN_CHECKERED("icons.png", 16, 96, 16, 16), - ICON_PATTERN_CHECKERED_INVERSED("icons.png", 32, 96, 16, 16), - ICON_PATTERN_CHANCE_25("icons.png", 48, 96, 16, 16), - 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), + I_PATTERN_SOLID(0, 96), + I_PATTERN_CHECKERED(16, 96), + I_PATTERN_CHECKERED_INVERSED(32, 96), + I_PATTERN_CHANCE_25(48, 96), + I_PATTERN_CHANCE_50(0, 112), + I_PATTERN_CHANCE_75(16, 112), + I_FOLLOW_DIAGONAL(32, 112), + I_FOLLOW_MATERIAL(48, 112), + I_PRIORITY_VERY_LOW(64, 0), + I_PRIORITY_LOW(80, 0), + I_PRIORITY_HIGH(96, 0), + I_PRIORITY_VERY_HIGH(112, 0), + I_ACTIVE(64, 16), + I_PASSIVE(80, 16), + ; public static final int FONT_COLOR = 0x575F7A; @@ -126,6 +140,10 @@ public enum ScreenResources { this(location, 0, 0, width, height); } + private ScreenResources(int startX, int startY) { + this("icons.png", startX, startY, 16, 16); + } + private ScreenResources(String location, int startX, int startY, int width, int height) { this.location = new ResourceLocation(Create.ID, "textures/gui/" + location); this.width = width; diff --git a/src/main/java/com/simibubi/create/foundation/block/AbstractTileEntityContainer.java b/src/main/java/com/simibubi/create/foundation/block/AbstractTileEntityContainer.java new file mode 100644 index 000000000..f88f2b3b7 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/block/AbstractTileEntityContainer.java @@ -0,0 +1,58 @@ +package com.simibubi.create.foundation.block; + +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.minecraft.tileentity.TileEntity; + +public abstract class AbstractTileEntityContainer extends Container { + + public T te; + public PlayerEntity player; + + @SuppressWarnings("unchecked") + public AbstractTileEntityContainer(AllContainers containerType, int id, PlayerInventory inv, + PacketBuffer extraData) { + super(containerType.type, id); + ClientWorld world = Minecraft.getInstance().world; + this.te = (T) world.getTileEntity(extraData.readBlockPos()); + this.te.handleUpdateTag(extraData.readCompoundTag()); + this.player = inv.player; + init(); + } + + public AbstractTileEntityContainer(AllContainers containerType, int id, PlayerInventory inv, T te) { + super(containerType.type, id); + this.te = te; + this.player = inv.player; + init(); + } + + protected abstract void init(); + + protected void addPlayerSlots(int x, int y) { + for (int row = 0; row < 3; ++row) + for (int col = 0; col < 9; ++col) + this.addSlot(new Slot(player.inventory, col + row * 9 + 9, x + col * 18, y + row * 18)); + for (int hotbarSlot = 0; hotbarSlot < 9; ++hotbarSlot) + this.addSlot(new Slot(player.inventory, hotbarSlot, x + hotbarSlot * 18, y + 3 * 18 + 4)); + } + + @Override + public boolean canInteractWith(PlayerEntity playerIn) { + return true; + } + + @Override + public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) { + return ItemStack.EMPTY; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/block/IWithContainer.java b/src/main/java/com/simibubi/create/foundation/block/IWithContainer.java new file mode 100644 index 000000000..b57e86d09 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/block/IWithContainer.java @@ -0,0 +1,36 @@ +package com.simibubi.create.foundation.block; + +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.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; + +public interface IWithContainer> extends INamedContainerProvider { + + public IContainerFactory getContainerFactory(); + + @SuppressWarnings("unchecked") + @Override + default Container createMenu(int id, PlayerInventory inv, PlayerEntity player) { + return getContainerFactory().create(id, inv, ((T) this)); + } + + @Override + default ITextComponent getDisplayName() { + return new StringTextComponent(((TileEntity) this).getType().getRegistryName().toString()); + } + + public interface IContainerFactory> { + public C create(int id, PlayerInventory inv, T te); + } + + default void sendToContainer(PacketBuffer buffer) { + buffer.writeBlockPos(((TileEntity) this).getPos()); + buffer.writeCompoundTag(((TileEntity) this).getUpdateTag()); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/block/IWithContainerTileEntity.java b/src/main/java/com/simibubi/create/foundation/block/IWithContainerTileEntity.java new file mode 100644 index 000000000..94ea67e9f --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/block/IWithContainerTileEntity.java @@ -0,0 +1,19 @@ +package com.simibubi.create.foundation.block; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IWorld; +import net.minecraftforge.fml.network.NetworkHooks; + +public interface IWithContainerTileEntity> extends IWithTileEntity { + + default void open(IWorld world, BlockPos pos, PlayerEntity player) { + T te = getTileEntity(world, pos); + if (te == null || world.isRemote()) + return; + NetworkHooks.openGui((ServerPlayerEntity) player, te, te::sendToContainer); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiContainerScreen.java b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiContainerScreen.java index b64478e6f..3b73bace6 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiContainerScreen.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiContainerScreen.java @@ -3,14 +3,21 @@ package com.simibubi.create.foundation.gui; import java.util.ArrayList; import java.util.List; +import javax.annotation.Nullable; + import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.screen.inventory.ContainerScreen; import net.minecraft.client.gui.widget.Widget; +import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.Container; +import net.minecraft.item.ItemStack; import net.minecraft.util.text.ITextComponent; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -127,5 +134,86 @@ public abstract class AbstractSimiContainerScreen extends C } } } + + protected void renderItemOverlayIntoGUI(FontRenderer fr, ItemStack stack, int xPosition, int yPosition, + @Nullable String text, int textColor) { + if (!stack.isEmpty()) { + if (stack.getItem().showDurabilityBar(stack)) { + GlStateManager.disableLighting(); + GlStateManager.disableDepthTest(); + GlStateManager.disableTexture(); + GlStateManager.disableAlphaTest(); + GlStateManager.disableBlend(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + double health = stack.getItem().getDurabilityForDisplay(stack); + int i = Math.round(13.0F - (float) health * 13.0F); + int j = stack.getItem().getRGBDurabilityForDisplay(stack); + this.draw(bufferbuilder, xPosition + 2, yPosition + 13, 13, 2, 0, 0, 0, 255); + this.draw(bufferbuilder, xPosition + 2, yPosition + 13, i, 1, j >> 16 & 255, j >> 8 & 255, j & 255, + 255); + GlStateManager.enableBlend(); + GlStateManager.enableAlphaTest(); + GlStateManager.enableTexture(); + GlStateManager.enableLighting(); + GlStateManager.enableDepthTest(); + } + + if (stack.getCount() != 1 || text != null) { + String s = text == null ? String.valueOf(stack.getCount()) : text; + GlStateManager.disableLighting(); + GlStateManager.disableDepthTest(); + GlStateManager.disableBlend(); + GlStateManager.pushMatrix(); + + int guiScaleFactor = (int) minecraft.mainWindow.getGuiScaleFactor(); + GlStateManager.translated((float) (xPosition + 16.5f), (float) (yPosition + 16.5f), 0); + double scale = getItemCountTextScale(); + + GlStateManager.scaled(scale, scale, 0); + GlStateManager.translated(-fr.getStringWidth(s) - (guiScaleFactor > 1 ? 0 : -.5f), + -font.FONT_HEIGHT + (guiScaleFactor > 1 ? 1 : 1.75f), 0); + fr.drawStringWithShadow(s, 0, 0, textColor); + + GlStateManager.popMatrix(); + GlStateManager.enableBlend(); + GlStateManager.enableLighting(); + GlStateManager.enableDepthTest(); + GlStateManager.enableBlend(); + } + } + } + + public double getItemCountTextScale() { + int guiScaleFactor = (int) minecraft.mainWindow.getGuiScaleFactor(); + double scale = 1; + switch (guiScaleFactor) { + case 1: + scale = 2060 / 2048d; + break; + case 2: + scale = .5; + break; + case 3: + scale = .675; + break; + case 4: + scale = .75; + break; + default: + scale = ((float) guiScaleFactor - 1) / guiScaleFactor; + } + return scale; + } + + private void draw(BufferBuilder renderer, int x, int y, int width, int height, int red, int green, int blue, + int alpha) { + renderer.begin(7, DefaultVertexFormats.POSITION_COLOR); + renderer.pos((double) (x + 0), (double) (y + 0), 0.0D).color(red, green, blue, alpha).endVertex(); + renderer.pos((double) (x + 0), (double) (y + height), 0.0D).color(red, green, blue, alpha).endVertex(); + renderer.pos((double) (x + width), (double) (y + height), 0.0D).color(red, green, blue, alpha).endVertex(); + renderer.pos((double) (x + width), (double) (y + 0), 0.0D).color(red, green, blue, alpha).endVertex(); + Tessellator.getInstance().draw(); + } } diff --git a/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java b/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java index db6dad85a..85f3f8281 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java @@ -5,6 +5,7 @@ import java.util.function.Supplier; import org.lwjgl.opengl.GL11; import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.foundation.utility.ColorHelper; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; @@ -15,6 +16,7 @@ import net.minecraft.client.renderer.texture.AtlasTexture; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; public class ScreenElementRenderer { @@ -34,6 +36,10 @@ public class ScreenElementRenderer { } public static void renderBlock(Supplier transformsAndState) { + renderBlock(transformsAndState, -1); + } + + public static void renderBlock(Supplier transformsAndState, int color) { GlStateManager.pushMatrix(); GlStateManager.enableBlend(); @@ -50,7 +56,18 @@ public class ScreenElementRenderer { GlStateManager.scaled(50, -50, 50); Minecraft mc = Minecraft.getInstance(); mc.getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE); - mc.getBlockRendererDispatcher().renderBlockBrightness(toRender, 1); + + if (color == -1) { + mc.getBlockRendererDispatcher().renderBlockBrightness(toRender, 1); + } else { + GlStateManager.disableLighting(); + GlStateManager.rotated(90, 0, 1, 0); + Vec3d rgb = ColorHelper.getRGB(color); + mc.getBlockRendererDispatcher().getBlockModelRenderer().renderModelBrightnessColor( + mc.getBlockRendererDispatcher().getModelForState(toRender), 1, (float) rgb.x, (float) rgb.y, + (float) rgb.z); + GlStateManager.enableLighting(); + } if (!toRender.getFluidState().isEmpty()) { RenderHelper.disableStandardItemLighting(); @@ -58,7 +75,8 @@ public class ScreenElementRenderer { BufferBuilder bufferbuilder = tessellator.getBuffer(); bufferbuilder.setTranslation(0, -300, 0); bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); - mc.getBlockRendererDispatcher().renderFluid(new BlockPos(0, 300, 0), mc.world, bufferbuilder, toRender.getFluidState()); + mc.getBlockRendererDispatcher().renderFluid(new BlockPos(0, 300, 0), mc.world, bufferbuilder, + toRender.getFluidState()); Tessellator.getInstance().draw(); bufferbuilder.setTranslation(0, 0, 0); } diff --git a/src/main/java/com/simibubi/create/foundation/type/CountedItemsList.java b/src/main/java/com/simibubi/create/foundation/type/CountedItemsList.java index bb63a5e58..b4814fdee 100644 --- a/src/main/java/com/simibubi/create/foundation/type/CountedItemsList.java +++ b/src/main/java/com/simibubi/create/foundation/type/CountedItemsList.java @@ -144,7 +144,7 @@ public class CountedItemsList { return getItemSet(stack); } - public class ItemStackEntry implements Comparable { + public static class ItemStackEntry implements Comparable { public ItemStack stack; public int amount; diff --git a/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java b/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java index d987cbf87..dc3f25297 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java @@ -2,6 +2,8 @@ package com.simibubi.create.foundation.utility; import com.mojang.blaze3d.platform.GlStateManager; +import net.minecraft.util.math.Vec3d; + public class ColorHelper { public static int rainbowColor(int timeStep) { @@ -34,24 +36,29 @@ public class ColorHelper { int g2 = (color2 >> 8) & 0xFF; int b2 = color2 & 0xFF; - int color = ((int) (r1 + (r2 - r1) * w) << 16) - + ((int) (g1 + (g2 - g1) * w) << 8) - + (int) (b1 + (b2 - b1) * w); + int color = ((int) (r1 + (r2 - r1) * w) << 16) + ((int) (g1 + (g2 - g1) * w) << 8) + (int) (b1 + (b2 - b1) * w); return color; } - + public static void glColor(int color) { color = mixColors(color, 0xFFFFFF, .5f); int r = (color >> 16); int g = (color >> 8) & 0xFF; int b = color & 0xFF; - + GlStateManager.color4f(r / 256f, g / 256f, b / 256f, 1); } - + public static void glResetColor() { GlStateManager.color4f(1, 1, 1, 1); } - + + public static Vec3d getRGB(int color) { + int r = (color >> 16); + int g = (color >> 8) & 0xFF; + int b = color & 0xFF; + return new Vec3d(r, g, b).scale(1 / 256d); + } + } 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 d0dfc3a4a..61747f115 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 @@ -73,19 +73,19 @@ public class BuilderGunScreen extends AbstractSimiScreen { widgets.clear(); replaceModeIndicator = new Indicator(i + 51, j + 36, ""); - replaceModeButton = new IconButton(i + 51, j + 41, ScreenResources.ICON_REPLACE_SOLID); + replaceModeButton = new IconButton(i + 51, j + 41, ScreenResources.I_REPLACE_SOLID); if (nbt.contains("Replace") && nbt.getBoolean("Replace")) replaceModeIndicator.state = State.ON; replaceModeButton.setToolTip(Lang.translate("gui.blockzapper.replaceMode")); spreadDiagonallyIndicator = new Indicator(i + 74, j + 36, ""); - spreadDiagonallyButton = new IconButton(i + 74, j + 41, ScreenResources.ICON_FOLLOW_DIAGONAL); + spreadDiagonallyButton = new IconButton(i + 74, j + 41, ScreenResources.I_FOLLOW_DIAGONAL); if (nbt.contains("SearchDiagonal") && nbt.getBoolean("SearchDiagonal")) spreadDiagonallyIndicator.state = State.ON; spreadDiagonallyButton.setToolTip(Lang.translate("gui.blockzapper.searchDiagonal")); spreadMaterialIndicator = new Indicator(i + 92, j + 36, ""); - spreadMaterialButton = new IconButton(i + 92, j + 41, ScreenResources.ICON_FOLLOW_MATERIAL); + spreadMaterialButton = new IconButton(i + 92, j + 41, ScreenResources.I_FOLLOW_MATERIAL); if (nbt.contains("SearchFuzzy") && nbt.getBoolean("SearchFuzzy")) spreadMaterialIndicator.state = State.ON; spreadMaterialButton.setToolTip(Lang.translate("gui.blockzapper.searchFuzzy")); diff --git a/src/main/java/com/simibubi/create/modules/curiosities/placementHandgun/PlacementPatterns.java b/src/main/java/com/simibubi/create/modules/curiosities/placementHandgun/PlacementPatterns.java index 639bb7ed3..6ec552c55 100644 --- a/src/main/java/com/simibubi/create/modules/curiosities/placementHandgun/PlacementPatterns.java +++ b/src/main/java/com/simibubi/create/modules/curiosities/placementHandgun/PlacementPatterns.java @@ -4,12 +4,12 @@ import com.simibubi.create.ScreenResources; public enum PlacementPatterns { - Solid(ScreenResources.ICON_PATTERN_SOLID), - Checkered(ScreenResources.ICON_PATTERN_CHECKERED), - InverseCheckered(ScreenResources.ICON_PATTERN_CHECKERED_INVERSED), - Chance25(ScreenResources.ICON_PATTERN_CHANCE_25), - Chance50(ScreenResources.ICON_PATTERN_CHANCE_50), - Chance75(ScreenResources.ICON_PATTERN_CHANCE_75); + Solid(ScreenResources.I_PATTERN_SOLID), + Checkered(ScreenResources.I_PATTERN_CHECKERED), + InverseCheckered(ScreenResources.I_PATTERN_CHECKERED_INVERSED), + Chance25(ScreenResources.I_PATTERN_CHANCE_25), + Chance50(ScreenResources.I_PATTERN_CHANCE_50), + Chance75(ScreenResources.I_PATTERN_CHANCE_75); public String translationKey; public ScreenResources icon; diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/LogisticalNetwork.java b/src/main/java/com/simibubi/create/modules/logistics/management/LogisticalNetwork.java index 7091c7d94..8e66ac355 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/LogisticalNetwork.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/LogisticalNetwork.java @@ -1,13 +1,16 @@ package com.simibubi.create.modules.logistics.management; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.PriorityQueue; +import java.util.function.Predicate; import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity; import com.simibubi.create.modules.logistics.management.base.LogisticalTask; import com.simibubi.create.modules.logistics.management.base.LogisticalTask.DepositTask; import com.simibubi.create.modules.logistics.management.base.LogisticalTask.SupplyTask; +import com.simibubi.create.modules.logistics.management.controller.StorageTileEntity; import com.simibubi.create.modules.logistics.management.controller.TransactionsTileEntity; import com.simibubi.create.modules.logistics.management.index.LogisticalIndexTileEntity; @@ -41,11 +44,15 @@ public class LogisticalNetwork { if (receivers.contains(te)) return; receivers.add(te); - indexers.forEach(LogisticalIndexTileEntity::syncReceivers); + reAdvertiseReceivers(); } participants++; } + public void reAdvertiseReceivers() { + indexers.forEach(LogisticalIndexTileEntity::syncReceivers); + } + public void removeController(LogisticalControllerTileEntity te) { if (te instanceof TransactionsTileEntity) if (!taskQueues.remove((TransactionsTileEntity) te)) @@ -59,7 +66,7 @@ public class LogisticalNetwork { if (te.isReceiver()) { if (!receivers.remove(te)) return; - indexers.forEach(LogisticalIndexTileEntity::syncReceivers); + reAdvertiseReceivers(); } participants--; } @@ -76,4 +83,50 @@ public class LogisticalNetwork { receivers.forEach(LogisticalControllerTileEntity::notifyTaskUpdate); } + public String getNextAvailableAddress(LogisticalControllerTileEntity te) { + Predicate isTaken = s -> false; + String prefix = ""; + + if (te instanceof TransactionsTileEntity) { + prefix = "Task Manager "; + isTaken = s -> isNameTaken(taskQueues, s); + } + + else if (te instanceof LogisticalIndexTileEntity) { + prefix = "Index "; + isTaken = s -> isNameTaken(indexers, s); + } + + else if (te instanceof StorageTileEntity) { + prefix = "Storage "; + isTaken = s -> isNameTaken(suppliers, s); + } + + else if (te.isSupplier()) { + prefix = "Supply "; + isTaken = s -> isNameTaken(suppliers, s); + } + + else if (te.isReceiver()) { + prefix = "Request "; + isTaken = s -> isNameTaken(receivers, s); + } + + int i = 0; + String name; + do { + name = prefix + (i == 0 ? "" : i); + i++; + } while (isTaken.test(name)); + + return name; + } + + private static boolean isNameTaken(Collection list, String name) { + for (T controller : list) + if (controller.address.equals(name)) + return true; + return false; + } + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/LogisticalNetworkHandler.java b/src/main/java/com/simibubi/create/modules/logistics/management/LogisticalNetworkHandler.java index 8a12becd0..c812c6a28 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/LogisticalNetworkHandler.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/LogisticalNetworkHandler.java @@ -25,26 +25,30 @@ public class LogisticalNetworkHandler { public LogisticalNetwork handleAdded(LogisticalControllerTileEntity te) { LogisticalNetwork networkByID = getNetworkByID(te.getWorld(), te.getNetworkId()); + if (te.address == null || te.address.isEmpty()) { + te.address = networkByID.getNextAvailableAddress(te); + te.sendData(); + } networkByID.addController(te); return networkByID; } - + public void handleRemoved(LogisticalControllerTileEntity te) { getNetworkByID(te.getWorld(), te.getNetworkId()).removeController(te); removeIfEmpty(te.getWorld(), te.getNetworkId()); } - + public LogisticalNetwork getNetworkByID(IWorld world, UUID id) { Map worldNets = networks.get(world); if (!worldNets.containsKey(id)) worldNets.put(id, new LogisticalNetwork()); return worldNets.get(id); } - + private void removeIfEmpty(IWorld world, UUID id) { Map worldNets = networks.get(world); if (worldNets.get(id).isEmpty()) worldNets.remove(id); } - + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalCasingTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalCasingTileEntity.java index d7613adb3..663872368 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalCasingTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalCasingTileEntity.java @@ -9,6 +9,7 @@ import java.util.stream.Collectors; import com.google.common.base.Predicates; import com.simibubi.create.AllTileEntities; import com.simibubi.create.foundation.block.SyncedTileEntity; +import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerTileEntity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerBlock.java b/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerBlock.java index fb2630a9c..bb58623b9 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerBlock.java @@ -11,11 +11,14 @@ import java.util.List; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; +import com.simibubi.create.Create; +import com.simibubi.create.foundation.block.IWithContainer; import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.IWithoutBlockItem; import com.simibubi.create.foundation.block.RenderUtilityBlock; import com.simibubi.create.modules.logistics.management.base.LogisticalCasingBlock.Part; import com.simibubi.create.modules.logistics.management.controller.CalculationTileEntity; +import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerTileEntity; import com.simibubi.create.modules.logistics.management.controller.RequestTileEntity; import com.simibubi.create.modules.logistics.management.controller.StorageTileEntity; import com.simibubi.create.modules.logistics.management.controller.SupplyTileEntity; @@ -27,10 +30,10 @@ import net.minecraft.block.Blocks; import net.minecraft.block.DirectionalBlock; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; import net.minecraft.state.EnumProperty; import net.minecraft.state.IProperty; import net.minecraft.state.StateContainer.Builder; @@ -46,6 +49,7 @@ import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkHooks; public class LogisticalControllerBlock extends DirectionalBlock implements IWithoutBlockItem, IWithTileEntity { @@ -127,21 +131,35 @@ public class LogisticalControllerBlock extends DirectionalBlock return isCasing; } + @Override + public String getTranslationKey() { + return "block." + Create.ID + ".logistical_controller"; + } + + public static String getControllerTypeTranslationKey(BlockState state) { + return "item." + Create.ID + ".logistical_controller_" + state.get(TYPE).name().toLowerCase(); + } + @Override public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { if (player.isSneaking() || !player.isAllowEdit()) return false; - ItemStack held = player.getHeldItem(handIn); - if (held.getItem() != Items.NAME_TAG) - return false; - if (!held.hasDisplayName()) + if (!state.hasTileEntity()) return false; - withTileEntityDo(worldIn, pos, te -> { - te.setName(held.getDisplayName().getUnformattedComponentText()); - }); + TileEntity te = worldIn.getTileEntity(pos); + if (!(te instanceof LogisticalInventoryControllerTileEntity)) + return false; + if (state.get(TYPE) == Type.CALCULATION) + return false; + if (AllItems.LOGISTICAL_DIAL.typeOf(player.getHeldItem(handIn))) + return false; + if (worldIn.isRemote) + return true; + IWithContainer cte = (IWithContainer) te; + NetworkHooks.openGui((ServerPlayerEntity) player, cte, cte::sendToContainer); return true; } diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerItem.java b/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerItem.java index 748e81ae0..9025ef0a5 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerItem.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerItem.java @@ -1,6 +1,7 @@ package com.simibubi.create.modules.logistics.management.base; import com.simibubi.create.AllBlocks; +import com.simibubi.create.Create; import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock.Type; import net.minecraft.item.BlockItem; @@ -23,6 +24,11 @@ public class LogisticalControllerItem extends BlockItem { items.add(new ItemStack(this)); } } + + @Override + public String getTranslationKey(ItemStack stack) { + return "item." + Create.ID + "." + getRegistryName().getPath(); + } public Type getType() { return type; diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerTileEntity.java index 7fcf580ca..d23812466 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalControllerTileEntity.java @@ -18,10 +18,11 @@ public abstract class LogisticalControllerTileEntity extends SyncedTileEntity implements Comparable, ITickableTileEntity { public static final int COOLDOWN = 20; + + public Priority priority = Priority.LOW; + public String address = ""; - protected Priority priority = Priority.LOW; protected LogisticalNetwork network; - protected String name = ""; protected UUID networkId; protected boolean initialize; protected boolean checkTasks; @@ -39,7 +40,7 @@ public abstract class LogisticalControllerTileEntity extends SyncedTileEntity initialize(); return; } - + if (taskCooldown > 0) taskCooldown--; } @@ -55,20 +56,12 @@ public abstract class LogisticalControllerTileEntity extends SyncedTileEntity handleRemoved(); super.remove(); } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } @Override public boolean hasFastRenderer() { return true; } - + public void notifyTaskUpdate() { checkTasks = true; } @@ -77,7 +70,8 @@ public abstract class LogisticalControllerTileEntity extends SyncedTileEntity public CompoundNBT write(CompoundNBT compound) { if (networkId != null) compound.putUniqueId("NetworkID", networkId); - compound.putString("Address", name); + compound.putString("Address", address); + compound.putInt("Priority", priority.ordinal()); return super.write(compound); } @@ -89,7 +83,8 @@ public abstract class LogisticalControllerTileEntity extends SyncedTileEntity public void read(CompoundNBT compound) { if (compound.contains("NetworkIDLeast")) networkId = compound.getUniqueId("NetworkID"); - name = compound.getString("Address"); + address = compound.getString("Address"); + priority = Priority.values()[compound.getInt("Priority")]; super.read(compound); } @@ -149,8 +144,12 @@ public abstract class LogisticalControllerTileEntity extends SyncedTileEntity return network; } + public Priority getPriority() { + return priority; + } + public static enum Priority { - LOWEST, LOW, MEDIUM, HIGH, HIGHEST; + HIGHEST, HIGH, LOWEST, LOW; } } diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/controller/CalculationTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/management/controller/CalculationTileEntity.java index 576bf50ce..89c2f27b0 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/controller/CalculationTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/controller/CalculationTileEntity.java @@ -1,7 +1,6 @@ package com.simibubi.create.modules.logistics.management.controller; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.modules.logistics.management.base.LogisticalInventoryControllerTileEntity; public class CalculationTileEntity extends LogisticalInventoryControllerTileEntity { diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalControllerConfigurationPacket.java b/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalControllerConfigurationPacket.java new file mode 100644 index 000000000..c75341a42 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalControllerConfigurationPacket.java @@ -0,0 +1,62 @@ +package com.simibubi.create.modules.logistics.management.controller; + +import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket; +import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity.Priority; +import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerTileEntity.ShippingInventory; + +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.BlockPos; + +public class LogisticalControllerConfigurationPacket + extends TileEntityConfigurationPacket { + + String address; + int filterAmount; + Priority priority; + boolean active; + + public LogisticalControllerConfigurationPacket(BlockPos pos, String address, int filterAmount, + Priority priority, boolean active) { + super(pos); + this.address = address; + this.filterAmount = filterAmount; + this.priority = priority; + this.active = active; + } + + public LogisticalControllerConfigurationPacket(PacketBuffer buffer) { + super(buffer); + } + + @Override + protected void writeSettings(PacketBuffer buffer) { + buffer.writeString(address, 2048); + buffer.writeInt(filterAmount); + buffer.writeInt(priority.ordinal()); + buffer.writeBoolean(active); + } + + @Override + protected void readSettings(PacketBuffer buffer) { + address = buffer.readString(2048); + filterAmount = buffer.readInt(); + priority = Priority.values()[buffer.readInt()]; + active = buffer.readBoolean(); + } + + @Override + protected void applySettings(LogisticalInventoryControllerTileEntity te) { + if (!address.isEmpty()) { + te.address = address; + if (te.getNetwork() != null) + te.getNetwork().reAdvertiseReceivers(); + } + te.priority = priority; + te.isActive = active; + te.shippingInventory.ifPresent(inv -> { + ShippingInventory sInv = (ShippingInventory) inv; + sInv.filterAmount = filterAmount; + }); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerContainer.java b/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerContainer.java new file mode 100644 index 000000000..e1bba4d6a --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerContainer.java @@ -0,0 +1,55 @@ +package com.simibubi.create.modules.logistics.management.controller; + +import com.simibubi.create.AllContainers; +import com.simibubi.create.foundation.block.AbstractTileEntityContainer; +import com.simibubi.create.foundation.type.CombinedCountedItemsList; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.ClickType; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.items.SlotItemHandler; + +public class LogisticalInventoryControllerContainer + extends AbstractTileEntityContainer { + + public CombinedCountedItemsList allItems = new CombinedCountedItemsList<>(); + + public LogisticalInventoryControllerContainer(int id, PlayerInventory inv, PacketBuffer extraData) { + super(AllContainers.LOGISTICAL_CONTROLLER, id, inv, extraData); + } + + public LogisticalInventoryControllerContainer(int id, PlayerInventory inv, + LogisticalInventoryControllerTileEntity te) { + super(AllContainers.LOGISTICAL_CONTROLLER, id, inv, te); + } + + public void init() { + addSlot(new SlotItemHandler(te.getInventory(), 0, 135, 32)); + addSlot(new SlotItemHandler(te.getInventory(), 1, 135 + 18, 32)); + addSlot(new SlotItemHandler(te.getInventory(), 2, 84, 29)); + addPlayerSlots(48, 118); + detectAndSendChanges(); + } + + @Override + public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, PlayerEntity player) { + if (slotId != 2) + return super.slotClick(slotId, dragType, clickTypeIn, player); + ItemStack item = player.inventory.getItemStack(); + ItemStack copy = item.copy(); + + if (copy.isEmpty()) { + te.getInventory().extractItem(2, 1, false); + return ItemStack.EMPTY; + } + + copy.setCount(1); + te.getInventory().extractItem(2, 1, false); + te.getInventory().insertItem(2, copy, false); + + return item; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerScreen.java b/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerScreen.java new file mode 100644 index 000000000..38644624c --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerScreen.java @@ -0,0 +1,252 @@ +package com.simibubi.create.modules.logistics.management.controller; + +import static com.simibubi.create.ScreenResources.I_PRIORITY_HIGH; +import static com.simibubi.create.ScreenResources.I_PRIORITY_LOW; +import static com.simibubi.create.ScreenResources.I_PRIORITY_VERY_HIGH; +import static com.simibubi.create.ScreenResources.I_PRIORITY_VERY_LOW; +import static com.simibubi.create.ScreenResources.LOGISTICAL_CONTROLLER; +import static com.simibubi.create.ScreenResources.LOGISTICAL_CONTROLLER_TRIM; +import static com.simibubi.create.ScreenResources.PLAYER_INVENTORY; +import static com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock.TYPE; +import static net.minecraft.state.properties.BlockStateProperties.FACING; + +import java.util.Arrays; +import java.util.List; + +import org.lwjgl.glfw.GLFW; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.AllPackets; +import com.simibubi.create.ScreenResources; +import com.simibubi.create.foundation.gui.AbstractSimiContainerScreen; +import com.simibubi.create.foundation.gui.ScreenElementRenderer; +import com.simibubi.create.foundation.gui.widgets.IconButton; +import com.simibubi.create.foundation.gui.widgets.Indicator; +import com.simibubi.create.foundation.gui.widgets.Indicator.State; +import com.simibubi.create.foundation.gui.widgets.ScrollInput; +import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock; +import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock.Type; +import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity.Priority; + +import net.minecraft.block.BlockState; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.InputMappings; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.Direction; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextFormatting; + +public class LogisticalInventoryControllerScreen + extends AbstractSimiContainerScreen { + + private BlockState controllerState; + private BlockState controllerLightState; + private ItemStack nameTagItem; + private ItemStack boxItem; + + private Type controllerType; + + private ScrollInput priorityInput; + private TextFieldWidget addressInput; + private IconButton passiveModeButton; + private IconButton activeModeButton; + private Indicator passiveModeIndicator; + private Indicator activeModeIndicator; + private IconButton confirmButton; + private ScrollInput filterAmountInput; + + private final List priorityIcons = Arrays.asList(I_PRIORITY_VERY_HIGH, I_PRIORITY_HIGH, + I_PRIORITY_LOW, I_PRIORITY_VERY_LOW); + private final List priorityOptions = Lang.translatedOptions("logistics.priority", "highest", "high", "low", + "lowest"); + + private String priority = Lang.translate("logistics.priority"); + private String requestedItemCount = Lang.translate("gui.requester.requestedItemCount"); + private String activeMode = Lang.translate("gui.logistical_controller.active_mode"); + private String passiveMode = Lang.translate("gui.logistical_controller.passive_mode"); + private String storagePassiveModeOnly = Lang.translate("gui.storage.passiveModeOnly"); + private String title; + + public LogisticalInventoryControllerScreen(LogisticalInventoryControllerContainer container, PlayerInventory inv, + ITextComponent title) { + super(container, inv, title); + this.title = I18n + .format(LogisticalControllerBlock.getControllerTypeTranslationKey(container.te.getBlockState())); + controllerState = container.te.getBlockState().with(BlockStateProperties.FACING, Direction.SOUTH); + controllerType = controllerState.get(LogisticalControllerBlock.TYPE); + controllerLightState = AllBlocks.LOGISTICAL_CONTROLLER_INDICATOR.get().getDefaultState() + .with(FACING, controllerState.get(FACING)).with(TYPE, controllerState.get(TYPE)); + nameTagItem = new ItemStack(Items.NAME_TAG); + boxItem = AllItems.CARDBOARD_BOX_1410.asStack(); + } + + @Override + protected void init() { + setWindowSize(256, 200); + super.init(); + widgets.clear(); + + int x = guiLeft; + int y = guiTop; + + addressInput = new TextFieldWidget(font, x + 29, y + 62, 116, 8, ""); + addressInput.setTextColor(0xFFFFFF); + addressInput.setDisabledTextColour(-1); + addressInput.setText(container.te.address); + addressInput.setEnableBackgroundDrawing(false); + addressInput.setMaxStringLength(256); + addressInput.func_212954_a(this::onAddressInputChanged); + addressInput.setFocused2(false); + + priorityInput = new SelectionScrollInput(x + 49, y + 31, 18, 18).forOptions(priorityOptions).titled(priority) + .setState(container.te.getPriority().ordinal()); + filterAmountInput = new ScrollInput(x + 85, y + 46, 15, 8).withRange(1, 1025).withShiftStep(64) + .titled(requestedItemCount).setState(container.te.getInventory().filterAmount); + + passiveModeButton = new IconButton(x + 8, y + 31, ScreenResources.I_PASSIVE); + passiveModeButton.setToolTip(passiveMode); + if (controllerType == Type.STORAGE) + passiveModeButton.getToolTip().add(TextFormatting.GOLD + storagePassiveModeOnly); + passiveModeIndicator = new Indicator(x + 8, y + 26, ""); + activeModeButton = new IconButton(x + 26, y + 31, ScreenResources.I_ACTIVE); + activeModeButton.setToolTip(activeMode); + activeModeIndicator = new Indicator(x + 26, y + 26, ""); + setPassiveMode(!container.te.isActive); + + confirmButton = new IconButton(x + 152, y + 57, ScreenResources.I_CONFIRM); + + widgets.addAll(Arrays.asList(priorityInput, addressInput, passiveModeButton, passiveModeIndicator, + activeModeButton, activeModeIndicator, confirmButton)); + if (controllerType == Type.REQUEST) + widgets.add(filterAmountInput); + } + + @Override + protected void renderWindow(int mouseX, int mouseY, float partialTicks) { + int x = guiLeft; + int y = guiTop; + + LOGISTICAL_CONTROLLER_TRIM.draw(this, x, y); + LOGISTICAL_CONTROLLER_TRIM.draw(this, x, y + 6 + LOGISTICAL_CONTROLLER.height); + + ColorHelper.glColor(container.te.getColor()); + LOGISTICAL_CONTROLLER.draw(this, x, y + 6); + ColorHelper.glResetColor(); + + ScreenResources.BIG_SLOT.draw(this, x + 79, y + 24); + ScreenResources.SHIPPING_SLOT.draw(this, x + 134, y + 28); + ScreenResources.RECEIVING_SLOT.draw(this, x + 134 + 18, y + 28); + PLAYER_INVENTORY.draw(this, x + (getXSize() - PLAYER_INVENTORY.width) / 2, y + 100); + + ScreenResources priorityIcon = priorityIcons.get(priorityInput.getState()); + ColorHelper.glColor(0); + priorityIcon.draw(this, x + 51, y + 33); + ColorHelper.glResetColor(); + priorityIcon.draw(this, x + 50, y + 32); + + if (controllerType == Type.REQUEST) { + ScreenResources.ITEM_COUNT_SCROLLAREA.draw(this, x + 81, y + 45); + GlStateManager.pushMatrix(); + double scale = getItemCountTextScale(); + String text = "" + filterAmountInput.getState(); + GlStateManager.translated(x + 91.5, y + 53, 0); + GlStateManager.scaled(scale, scale, 0); + int guiScaleFactor = (int) minecraft.mainWindow.getGuiScaleFactor(); + GlStateManager.translated((-font.getStringWidth(text)) / 2, + -font.FONT_HEIGHT + (guiScaleFactor > 1 ? 1 : 1.75f), 0); + font.drawStringWithShadow(text, 0, 0, 0xFFFFFF); + GlStateManager.popMatrix(); + } + + font.drawString(playerInventory.getDisplayName().getFormattedText(), x + 48, y + 106, 0x666666); + font.drawStringWithShadow(title, x + (LOGISTICAL_CONTROLLER.width - font.getStringWidth(title)) / 2, y + 9, + ColorHelper.mixColors(0xFFFFFF, container.te.getColor(), .25f)); + + ScreenElementRenderer.renderBlock(() -> { + transformRenderedBlocks(); + return controllerState; + }); + + ScreenElementRenderer.renderBlock(() -> { + transformRenderedBlocks(); + return controllerLightState; + }, container.te.getColor()); + + ColorHelper.glResetColor(); + RenderHelper.enableGUIStandardItemLighting(); + itemRenderer.renderItemIntoGUI(nameTagItem, x + 7, y + 57); + itemRenderer.renderItemIntoGUI(boxItem, x + 116, y + 32); + } + + public void onAddressInputChanged(String s) { + confirmButton.active = !s.isEmpty(); + } + + @Override + public boolean keyPressed(int code, int p_keyPressed_2_, int p_keyPressed_3_) { + InputMappings.Input mouseKey = InputMappings.getInputByCode(code, p_keyPressed_2_); + boolean closingScreen = this.minecraft.gameSettings.keyBindInventory.isActiveAndMatches(mouseKey); + boolean enter = code == GLFW.GLFW_KEY_ENTER; + + if (closingScreen && addressInput.isFocused()) + return true; + if (enter && addressInput.isFocused()) + addressInput.changeFocus(false); + + return super.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + if (confirmButton.active && confirmButton.isHovered()) + minecraft.displayGuiScreen(null); + if (activeModeButton.active && activeModeButton.isHovered()) + setPassiveMode(false); + if (passiveModeButton.active && passiveModeButton.isHovered()) + setPassiveMode(true); + + return super.mouseClicked(x, y, button); + } + + public void setPassiveMode(boolean passive) { + if (controllerType == Type.STORAGE) { + activeModeButton.active = passiveModeButton.active = false; + activeModeIndicator.state = State.OFF; + passiveModeIndicator.state = State.ON; + return; + } + + activeModeButton.active = passive; + passiveModeButton.active = !passive; + activeModeIndicator.state = passive ? State.OFF : State.ON; + passiveModeIndicator.state = !passive ? State.OFF : State.ON; + } + + @Override + public void removed() { + boolean active = !activeModeButton.active; + Priority priorityOut = Priority.values()[priorityInput.getState()]; + String text = addressInput.getText(); + AllPackets.channel.sendToServer(new LogisticalControllerConfigurationPacket(container.te.getPos(), text, + filterAmountInput.getState(), priorityOut, active)); + super.removed(); + } + + private void transformRenderedBlocks() { + GlStateManager.translated(guiLeft + 205, guiTop + 70, 0); + GlStateManager.rotatef(50, -.5f, 1, -.2f); + GlStateManager.rotatef(190, 0, 1, 0); + GlStateManager.scaled(1.25, 1.25, 1.25); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalInventoryControllerTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerTileEntity.java similarity index 88% rename from src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalInventoryControllerTileEntity.java rename to src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerTileEntity.java index 9a66b17c5..0b3839524 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/base/LogisticalInventoryControllerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/controller/LogisticalInventoryControllerTileEntity.java @@ -1,4 +1,4 @@ -package com.simibubi.create.modules.logistics.management.base; +package com.simibubi.create.modules.logistics.management.controller; import static net.minecraft.state.properties.BlockStateProperties.FACING; @@ -12,11 +12,16 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.Pair; +import com.simibubi.create.foundation.block.IWithContainer; import com.simibubi.create.foundation.type.CombinedCountedItemsList; import com.simibubi.create.foundation.type.CountedItemsList; import com.simibubi.create.foundation.type.CountedItemsList.ItemStackEntry; import com.simibubi.create.foundation.utility.ItemHelper; import com.simibubi.create.modules.logistics.item.CardboardBoxItem; +import com.simibubi.create.modules.logistics.management.base.LogisticalCasingTileEntity; +import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock; +import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity; +import com.simibubi.create.modules.logistics.management.base.LogisticalTask; import com.simibubi.create.modules.logistics.management.base.LogisticalTask.DepositTask; import com.simibubi.create.modules.logistics.management.base.LogisticalTask.SupplyTask; @@ -24,6 +29,7 @@ import net.minecraft.block.BlockState; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.Ingredient; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; @@ -34,7 +40,8 @@ import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemStackHandler; -public abstract class LogisticalInventoryControllerTileEntity extends LogisticalControllerTileEntity { +public abstract class LogisticalInventoryControllerTileEntity extends LogisticalControllerTileEntity + implements IWithContainer { protected Map observedInventories = new HashMap<>(); protected Map inventoryByHandler = new HashMap<>(); @@ -44,6 +51,8 @@ public abstract class LogisticalInventoryControllerTileEntity extends Logistical protected LazyOptional shippingInventory; protected boolean tryInsertBox; + public boolean isActive; + public LogisticalInventoryControllerTileEntity(TileEntityType tileEntityTypeIn) { super(tileEntityTypeIn); this.shippingInventory = LazyOptional.of(this::createInventory); @@ -56,6 +65,7 @@ public abstract class LogisticalInventoryControllerTileEntity extends Logistical ShippingInventory inv = (ShippingInventory) shippingInventory.orElse(null); inv.deserializeNBT(compound.getCompound("ShippingInventory")); } + isActive = compound.getBoolean("Active"); } public void inventoryChanged(BlockPos pos) { @@ -96,7 +106,7 @@ public abstract class LogisticalInventoryControllerTileEntity extends Logistical protected void notifyIndexers(CountedItemsList updates) { if (network == null) return; - network.indexers.forEach(indexer -> indexer.handleUpdatedController(getName(), updates)); + network.indexers.forEach(indexer -> indexer.handleUpdatedController(address, updates)); } @Override @@ -275,6 +285,7 @@ public abstract class LogisticalInventoryControllerTileEntity extends Logistical @Override public CompoundNBT write(CompoundNBT compound) { shippingInventory.ifPresent(inv -> compound.put("ShippingInventory", ((ShippingInventory) inv).serializeNBT())); + compound.putBoolean("Active", isActive); return super.write(compound); } @@ -324,25 +335,40 @@ public abstract class LogisticalInventoryControllerTileEntity extends Logistical } } + @Override + public IContainerFactory getContainerFactory() { + return LogisticalInventoryControllerContainer::new; + } + + @Override + public void sendToContainer(PacketBuffer buffer) { + IWithContainer.super.sendToContainer(buffer); + } + protected abstract ShippingInventory createInventory(); public class ShippingInventory extends ItemStackHandler { static final int SHIPPING = 0; static final int RECEIVING = 1; + static final int FILTER = 2; + int filterAmount = 0; + boolean ships; boolean receives; public ShippingInventory(boolean ships, boolean receives) { - super(2); + super(3); this.ships = ships; this.receives = receives; } @Override public boolean isItemValid(int slot, ItemStack stack) { + if (slot == FILTER) + return true; if (slot == RECEIVING && receives) - return stack.getItem() instanceof CardboardBoxItem && CardboardBoxItem.matchAddress(stack, name); + return stack.getItem() instanceof CardboardBoxItem && CardboardBoxItem.matchAddress(stack, address); return false; } @@ -357,6 +383,15 @@ public abstract class LogisticalInventoryControllerTileEntity extends Logistical return super.extractItem(slot, amount, simulate); } + @Override + public void setStackInSlot(int slot, ItemStack stack) { + if (slot == FILTER) { + stack = stack.copy(); + stack.setCount(1); + } + super.setStackInSlot(slot, stack); + } + public void createPackage(List contents, String address) { ItemStack box = CardboardBoxItem.containing(contents); CardboardBoxItem.addAddress(box, address); @@ -388,6 +423,7 @@ public abstract class LogisticalInventoryControllerTileEntity extends Logistical CompoundNBT tag = super.serializeNBT(); tag.putBoolean("Ships", ships); tag.putBoolean("Receives", receives); + tag.putInt("FilterAmount", filterAmount); return tag; } @@ -395,6 +431,7 @@ public abstract class LogisticalInventoryControllerTileEntity extends Logistical public void deserializeNBT(CompoundNBT nbt) { ships = nbt.getBoolean("Ships"); receives = nbt.getBoolean("Receives"); + filterAmount = nbt.getInt("FilterAmount"); super.deserializeNBT(nbt); } } diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/controller/RequestTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/management/controller/RequestTileEntity.java index 6270e04d8..bbc2e37d9 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/controller/RequestTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/controller/RequestTileEntity.java @@ -1,7 +1,6 @@ package com.simibubi.create.modules.logistics.management.controller; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.modules.logistics.management.base.LogisticalInventoryControllerTileEntity; public class RequestTileEntity extends LogisticalInventoryControllerTileEntity { diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/controller/StorageTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/management/controller/StorageTileEntity.java index 8f4b445e8..0146d0d04 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/controller/StorageTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/controller/StorageTileEntity.java @@ -1,7 +1,6 @@ package com.simibubi.create.modules.logistics.management.controller; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.modules.logistics.management.base.LogisticalInventoryControllerTileEntity; public class StorageTileEntity extends LogisticalInventoryControllerTileEntity { diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/controller/SupplyTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/management/controller/SupplyTileEntity.java index 3b69dda1c..480b08844 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/controller/SupplyTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/controller/SupplyTileEntity.java @@ -1,7 +1,6 @@ package com.simibubi.create.modules.logistics.management.controller; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.modules.logistics.management.base.LogisticalInventoryControllerTileEntity; public class SupplyTileEntity extends LogisticalInventoryControllerTileEntity { diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/index/LogisticalIndexScreen.java b/src/main/java/com/simibubi/create/modules/logistics/management/index/LogisticalIndexScreen.java index 0137bb0c0..1a1f89551 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/index/LogisticalIndexScreen.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/index/LogisticalIndexScreen.java @@ -2,7 +2,6 @@ package com.simibubi.create.modules.logistics.management.index; import static com.simibubi.create.ScreenResources.DISABLED_SLOT_FRAME; import static com.simibubi.create.ScreenResources.DISABLED_SLOT_INNER; -import static com.simibubi.create.ScreenResources.ICON_CONFIRM; import static com.simibubi.create.ScreenResources.INDEX_BOTTOM; import static com.simibubi.create.ScreenResources.INDEX_BOTTOM_TRIM; import static com.simibubi.create.ScreenResources.INDEX_MIDDLE; @@ -15,6 +14,7 @@ import static com.simibubi.create.ScreenResources.INDEX_TAB; import static com.simibubi.create.ScreenResources.INDEX_TAB_ACTIVE; import static com.simibubi.create.ScreenResources.INDEX_TOP; import static com.simibubi.create.ScreenResources.INDEX_TOP_TRIM; +import static com.simibubi.create.ScreenResources.I_CONFIRM; import static com.simibubi.create.ScreenResources.SLOT_FRAME; import static com.simibubi.create.ScreenResources.SLOT_INNER; @@ -24,8 +24,6 @@ import java.util.List; import java.util.UUID; import java.util.stream.Collectors; -import javax.annotation.Nullable; - import org.lwjgl.glfw.GLFW; import com.mojang.blaze3d.platform.GlStateManager; @@ -44,12 +42,8 @@ import com.simibubi.create.foundation.utility.Lang; import net.minecraft.block.Blocks; import net.minecraft.client.GameSettings; -import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.util.InputMappings; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; @@ -118,14 +112,14 @@ public class LogisticalIndexScreen extends AbstractSimiContainerScreen> 16 & 255, j >> 8 & 255, j & 255, - 255); - GlStateManager.enableBlend(); - GlStateManager.enableAlphaTest(); - GlStateManager.enableTexture(); - GlStateManager.enableLighting(); - GlStateManager.enableDepthTest(); - } - - if (stack.getCount() != 1 || text != null) { - String s = text == null ? String.valueOf(stack.getCount()) : text; - GlStateManager.disableLighting(); - GlStateManager.disableDepthTest(); - GlStateManager.disableBlend(); - GlStateManager.pushMatrix(); - - int guiScaleFactor = (int) minecraft.mainWindow.getGuiScaleFactor(); - GlStateManager.translated((float) (xPosition + 16.5f), (float) (yPosition + 16.5f), 0); - - double scale = 1; - switch (guiScaleFactor) { - case 1: - scale = 2060 / 2048d; - break; - case 2: - scale = .5; - break; - case 3: - scale = .675; - break; - case 4: - scale = .75; - break; - default: - scale = ((float) guiScaleFactor - 1) / guiScaleFactor; - } - - GlStateManager.scaled(scale, scale, 0); - GlStateManager.translated(-fr.getStringWidth(s) - (guiScaleFactor > 1 ? 0 : -.5f), - -font.FONT_HEIGHT + (guiScaleFactor > 1 ? 1 : 1.75f), 0); - fr.drawStringWithShadow(s, 0, 0, textColor); - - GlStateManager.popMatrix(); - GlStateManager.enableBlend(); - GlStateManager.enableLighting(); - GlStateManager.enableDepthTest(); - GlStateManager.enableBlend(); - } - } - } - - private void draw(BufferBuilder renderer, int x, int y, int width, int height, int red, int green, int blue, - int alpha) { - renderer.begin(7, DefaultVertexFormats.POSITION_COLOR); - renderer.pos((double) (x + 0), (double) (y + 0), 0.0D).color(red, green, blue, alpha).endVertex(); - renderer.pos((double) (x + 0), (double) (y + height), 0.0D).color(red, green, blue, alpha).endVertex(); - renderer.pos((double) (x + width), (double) (y + height), 0.0D).color(red, green, blue, alpha).endVertex(); - renderer.pos((double) (x + width), (double) (y + 0), 0.0D).color(red, green, blue, alpha).endVertex(); - Tessellator.getInstance().draw(); - } - } diff --git a/src/main/java/com/simibubi/create/modules/logistics/management/index/LogisticalIndexTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/management/index/LogisticalIndexTileEntity.java index 0c66c77d3..63dca8e9d 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/management/index/LogisticalIndexTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/management/index/LogisticalIndexTileEntity.java @@ -16,7 +16,7 @@ import com.simibubi.create.foundation.type.CountedItemsList; import com.simibubi.create.foundation.type.CountedItemsList.ItemStackEntry; import com.simibubi.create.modules.logistics.management.LogisticalNetwork; import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity; -import com.simibubi.create.modules.logistics.management.base.LogisticalInventoryControllerTileEntity; +import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerTileEntity; import com.simibubi.create.modules.logistics.management.index.IndexContainerUpdatePacket.Type; import net.minecraft.entity.player.PlayerEntity; @@ -91,7 +91,7 @@ public class LogisticalIndexTileEntity extends LogisticalControllerTileEntity im return; availableReceivers.clear(); for (LogisticalControllerTileEntity logisticalControllerTileEntity : network.receivers) - availableReceivers.add(logisticalControllerTileEntity.getName()); + availableReceivers.add(logisticalControllerTileEntity.address); sendData(); } @@ -165,7 +165,7 @@ public class LogisticalIndexTileEntity extends LogisticalControllerTileEntity im if (!(te instanceof LogisticalInventoryControllerTileEntity)) continue; CountedItemsList allItems = ((LogisticalInventoryControllerTileEntity) te).getAllItems(); - controllers.put(te.getName(), allItems); + controllers.put(te.address, allItems); } } 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 86accd556..17b63b6b0 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 @@ -72,9 +72,9 @@ public class SchematicTableScreen extends AbstractSimiContainerScreen(4); replaceLevelIndicators = new Vector<>(4); - List icons = ImmutableList.of(ScreenResources.ICON_DONT_REPLACE, - ScreenResources.ICON_REPLACE_SOLID, ScreenResources.ICON_REPLACE_ANY, - ScreenResources.ICON_REPLACE_EMPTY); + List icons = ImmutableList.of(ScreenResources.I_DONT_REPLACE, + ScreenResources.I_REPLACE_SOLID, ScreenResources.I_REPLACE_ANY, + ScreenResources.I_REPLACE_EMPTY); List toolTips = ImmutableList.of(Lang.translate("gui.schematicannon.option.dontReplaceSolid"), Lang.translate("gui.schematicannon.option.replaceWithSolid"), Lang.translate("gui.schematicannon.option.replaceWithAny"), @@ -102,12 +102,12 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen2w&n8IW+0mNaOjK}wn-B?c*J zq(M4feAl|`{sZ^7d-pkeo%1}uoVA{3pS8|Dks2=)$VnJT001CYQk2yK0MN}A1Q6lf zEQl|9+J7TAEd^)z#C})7RHGFfcGQG&C|YGB!3gF)=YUHHE|BW@cvA*48#Q zHnz65c6N65_Vykg9-f|_US3|_-rhbwKEA%b!NI{HAt9lmp<#a!9v%@9@h?V3Mn*+N zMMp=+#KgqL#>U0Pq0#90`1pi`gtu?szI*o$gTbVxroMmwJ}oURJv}`mBO^02GwTM~ zH#0l?U(CtL`S2IHd3kyH`S}I^Kk^F-Iy*c2`uh6&`v(RFuvqNi;NZ~E(D3l^$jHdp z*w~LBKgP$$CnhE)|6&S5Lc3w()KplN+)$Q>`DmzM^nktF+Box&rc4ZVu@7RWiz}V zq3}2my8dix(^{x}>Cg2wZ1x~yoAj-grSmIP(tK*OSAk!>-^$T*uWb~!?mBj(=a@8E z#H-oxVO>A~G33H7G>@tb0^Tl7d7O?)PW<98<+^$PjF+8w6Io0q1$!??2#H!yK;A)rtLZ3dQXy1W5O&a z_3m6Jv#z^SQB9zHRpcDWH}b8mj|(SI;*&@De=3pWPb@R*;#IqJWb@uXZpNfd zV7)pZjS?4&6<^dP=L08`xiOM5c{S^ySJsRoC3 z|BBl>Vx>nDRn)1;xoZ{&=E^7?=IHHORw>n|dcNGu2v2b(0*|XDdr?;qQhAWrDeSrw z#hKJtd5y&uPKUjl#jP^3^yj=#cY4pqYe6V0-y17sF+=2Mjd`d7%boxQn!afa_!J8Z z9n?aP)HsBSphR@`yXHFtLr&CT~K%o;ai{kWuKK z-$NV8#@Aj1EXonXMMLhNa%TK+BPz}k8)C0U%LW*)Ng$s5@!IA4Jxwhwt%m{GwrR++`OcFq9>;i>l@X$852W47KV->5~K5U z&S0>OmKZ#im403ZMi=17?{Ze#mdafkdiOSEy_G-s`XR=cfzA)i5@Pv)N|;?T!`P8x z^?YaDf`UbQqUkeJJUv-c(m5)ZLgNG>g?9>V#n|~A3PVYC$$~lFzV5BOY4HbP5vIkI zAQGmi5lkDv26ZdUo(*W=BB>%Yz+Ij}Vh*->q1~?5w$c2QabYFLks8G0*+1y3+E*Z$ zr)H}(a;oMT%bNgDiC^@dc3Wzbc=kg$4c$V+M8omSZDHP4-jI;+!y#eK)t2YQG> zDSLmKz!;c1xXz)GG7eugD177HAu*6Z4xem8Q>NIX@jxoZU4_hZ&9)IuP&VwgxDbIC z?kT4(dlpz2uDDM2TC28-_@W{5L{7n6mEZouEU~yy%2&K1mtbxeJn9?`2TJp}XVfAy zo?SMmBVc~w6qe`IWGD_}gNWyo#9&&9(DIByWHHnF?-@>l@Eb0zyd@}FERfwsy@T*E zCJvDg_dHR~9^F4_BD{B)ngZSr$`<@4i#QF8;mVy|eZcx!dbFHNp`GatoXD;c28U#* zf#@guVA-QnYfeRH=R1_QkECAtN3SLbKI!47Q=vz!d zpD6Tx#yH{rSuvc0qjsyqS=g|+8fUZ=!P~^Z zm$FZMk=o`nMKB*N)V$Z>*Tz9CypdfKHbVs)D|(LSE?Oouh6mL!Q%V1l)!M=|pGfo2 z`Ed71giHnT=t<^{AgP{X%3A98Ldu`PCr^gdto`o@Zn>b|F;fz5wfRfEu z7|bHzvE%adDxs_{hG~}t^IXiXDQU$4}CwbA+g-Y_Oeekmi2E=-HgJ4z=(T2ym_Or)|s#$n$T zzi@DdIa`lYx3$c)c@9~B2iz=pOJc8H7p5y%n#NgMUteF_#?$UZ68$8QBP~0s=K6DA zX`1%R^M_A0GN*0R;opwp2i%!AcOPUu4n|#D*-5CYW}D|dAmod2@&6&q%|l!(XeF@s zWT^ihO$I@^V!;|O@A@NY*{>rL$aEep?$WDE>Tt);=Zl3|obIRVi}{@5l0l04l!q?MP;^=>Duvzso(y78a!AqCa=3 zOo8U)1@wP}elzOZJLv0M%R-uu3MV1ed|L-X*&jm0gCh-=AA2P`!Dl;93lCwUcq z+cG0K29YaRSG7%*b4>fP;ajogbyc5>lWBZD0OTCveaj$ds~o^iYuW~;50rse8-`Ir zwTrCh)(YVRjolLW(U|uR{!3U@>G(o_SDPfa+{{#hVg4bWR&)9%pjFX%e^2DL32l3H zu1vC@;>Sw2c}Auluh&R!F%ePikNZlAHXKI}2_RFe;o-Esp(LIC4e@B7_gTns@erzI zgbe)Qb^BAL zbw_=xU$c$Sg*300GhL1JlWOz`p!0t^NY%Zumcpq;A9cN6KLLGtf7p6xHR+TXeC1v- zN7!On!DHS{Nq1^>ob0x%-285|xym(7V9b2r{>T;56v3#ub(>f0LkjY?mBfu!Ows>zSQBOm<~|Gylg_?O2v{ zz-?1VZSg8|WfR@gE;KWDfa_)TB6ARv5lpgkr1)HE3S$IH=1s|%qfUVRbVlU(W5W*N1z~;wEb_4scj*W#t0>z@^6J zu4-r&KCw-EaYkk378m*<^W4<Z60>d;=qn2n2%_#k2`{fZ= z&?OnQuoj!PiziLCK!ruoUe`ARD3W^jxE1~kI6ys679DE(DnRG(X-utk_9tVy<7d!q z)3sJO;=rK{U(PUiVWj}-@W_T*5j&h-8F+#B>q97}vpSV_SI8$0S8dL4_e_$FOgrHd zxc0aC;a;#Q7lj1m!Wg3G9aPdfpY&pJz=psfelSmffC#XSH$SHrH$RcSohkNG+|4yJ z(p^>f?x|r~p*@z*>>l_h66rRWb{62b3r{$?3x1)VR$%fjxpPmup{*>>{=Qae@Bk5$ zVAxqz@gD!1#j>rK)_K-x8nimgv)%bz{Od=Y>`=|yFVrQGzP|U~NC!M68dT~WOAKR; z`X0Nm>AqMYVx46h)z-oIs;k$N!%|LJlyg2SJ>CB>p-XnFIUuX+^4Ap)Z8Qt`>PSee z-KueyTHR#rv}AAT&H=w~sIdSoFZ$_X=z~6gsjo5S#r-<6GS4kGRo1ZwoKAK=CS)d! zL%#h3g&CPw=EFC7kUVh_9Ts9@{z*v|OC6wWX>D?UGJ!tn#WN8`Gg;c6gT7<`HR!F) z-JX-vLE0BB8%jFO(2v&`gUgx@PS7bjsW|H2Zp~&V@lufp*Y32`5Tms3P|rqhKwfuH zd3mfj-;MW+25(=0%>Vd;rQ6W`&E&oX1cK+hn8ml7$PSgjUua?(Z$7tHpF9|4&*t40 zlK1|lU3O|r3F%*E@#X|Yo~CGnUAL0sm0KhfB(E~u4PDoN#0R9HlHdKcgyoH_f4w1t z+h1cif>B|E>gt<)gfwOWm-*KzjlX+d>F6O*sQ!~kl^e?#?>(2GMdW=9N8IN_{;HV2 z9xCe^(g;e>OWG6BLC~lYfu%bi@`#k=-)p{KuPX}Y>6~H G=>GtZZJGE0 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/gui/icons.png b/src/main/resources/assets/create/textures/gui/icons.png index 79d3f93685339831abed998b955c6dfe8a65a2e3..e451bcdad08a8ecb742e3e915f20cea4cd9c8e60 100644 GIT binary patch delta 2267 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 diff --git a/src/main/resources/assets/create/textures/gui/placement_handgun.pdn b/src/main/resources/assets/create/textures/gui/placement_handgun.pdn deleted file mode 100644 index 2bd2649d55d6ec0deb4e4f273cf2f37bea5efb10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8649 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 Y