package mcjty.rftools.blocks.crafter; import mcjty.lib.base.StyleConfig; import mcjty.lib.container.GenericGuiContainer; import mcjty.lib.gui.RenderHelper; import mcjty.lib.gui.Window; import mcjty.lib.gui.events.ButtonEvent; import mcjty.lib.gui.events.ChoiceEvent; import mcjty.lib.gui.events.DefaultSelectionEvent; import mcjty.lib.gui.layout.HorizontalAlignment; import mcjty.lib.gui.layout.HorizontalLayout; import mcjty.lib.gui.layout.PositionalLayout; import mcjty.lib.gui.widgets.*; import mcjty.lib.gui.widgets.Button; import mcjty.lib.gui.widgets.Label; import mcjty.lib.gui.widgets.Panel; import mcjty.lib.network.Argument; import mcjty.rftools.BlockInfo; import mcjty.rftools.RFTools; import mcjty.rftools.blocks.RedstoneMode; import mcjty.rftools.network.RFToolsMessages; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.util.ForgeDirection; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import java.awt.*; public class GuiCrafter extends GenericGuiContainer<CrafterBaseTE> { public static final int CRAFTER_WIDTH = 256; public static final int CRAFTER_HEIGHT = 224; private EnergyBar energyBar; private WidgetList recipeList; private ChoiceLabel keepItem; private ChoiceLabel internalRecipe; private Button applyButton; private ImageChoiceLabel redstoneMode; private ImageChoiceLabel speedMode; private Button rememberButton; private Button forgetButton; private static final ResourceLocation iconLocation = new ResourceLocation(RFTools.MODID, "textures/gui/crafter.png"); private static final ResourceLocation iconGuiElements = new ResourceLocation(RFTools.MODID, "textures/gui/guielements.png"); public GuiCrafter(CrafterBaseTE crafterBlockTileEntity, CrafterContainer container) { super(RFTools.instance, RFToolsMessages.INSTANCE, crafterBlockTileEntity, container, RFTools.GUI_MANUAL_MAIN, "crafter"); crafterBlockTileEntity.setCurrentRF(crafterBlockTileEntity.getEnergyStored(ForgeDirection.DOWN)); xSize = CRAFTER_WIDTH; ySize = CRAFTER_HEIGHT; } @Override public void initGui() { super.initGui(); int maxEnergyStored = tileEntity.getMaxEnergyStored(ForgeDirection.DOWN); energyBar = new EnergyBar(mc, this).setVertical().setMaxValue(maxEnergyStored).setLayoutHint(new PositionalLayout.PositionalHint(12, 141, 10, 76)).setShowText(false); energyBar.setValue(tileEntity.getCurrentRF()); initKeepMode(); initInternalRecipe(); Slider listSlider = initRecipeList(); applyButton = new Button(mc, this). setText("Apply"). setTooltips("Press to apply the", "recipe to the crafter"). addButtonEvent(new ButtonEvent() { @Override public void buttonClicked(Widget parent) { applyRecipe(); } }). setEnabled(false). setLayoutHint(new PositionalLayout.PositionalHint(212, 65, 34, 16)); rememberButton = new Button(mc, this) .setText("R") .setTooltips("Remember the current items", "in the internal and", "external buffers") .addButtonEvent(new ButtonEvent() { @Override public void buttonClicked(Widget widget) { rememberItems(); } }) .setLayoutHint(new PositionalLayout.PositionalHint(148, 70, 18, 16)); forgetButton = new Button(mc, this) .setText("F") .setTooltips("Forget the remembered layout") .addButtonEvent(new ButtonEvent() { @Override public void buttonClicked(Widget widget) { forgetItems(); } }) .setLayoutHint(new PositionalLayout.PositionalHint(168, 70, 18, 16)); initRedstoneMode(); initSpeedMode(); Widget toplevel = new Panel(mc, this).setBackground(iconLocation).setLayout(new PositionalLayout()).addChild(energyBar).addChild(keepItem).addChild(internalRecipe). addChild(recipeList).addChild(listSlider).addChild(applyButton).addChild(redstoneMode).addChild(speedMode).addChild(rememberButton).addChild(forgetButton); toplevel.setBounds(new Rectangle(guiLeft, guiTop, xSize, ySize)); selectRecipe(); sendChangeToServer(-1, null, null, false, false); window = new Window(this, toplevel); tileEntity.requestRfFromServer(RFToolsMessages.INSTANCE); } private Slider initRecipeList() { recipeList = new WidgetList(mc, this). addSelectionEvent(new DefaultSelectionEvent() { @Override public void select(Widget parent, int index) { selectRecipe(); } }). setLayoutHint(new PositionalLayout.PositionalHint(10, 7, 126, 80)); populateList(); return new Slider(mc, this).setVertical().setScrollable(recipeList).setLayoutHint(new PositionalLayout.PositionalHint(137, 7, 10, 80)); } private void initInternalRecipe() { internalRecipe = new ChoiceLabel(mc, this). addChoices("Ext", "Int"). setTooltips("'Int' will put result of", "crafting operation in", "inventory instead of", "output buffer"). addChoiceEvent(new ChoiceEvent() { @Override public void choiceChanged(Widget parent, String newChoice) { updateRecipe(); } }). setEnabled(false). setLayoutHint(new PositionalLayout.PositionalHint(148, 24, 41, 14)); } private void initKeepMode() { keepItem = new ChoiceLabel(mc, this). addChoices("All", "Keep"). setTooltips("'Keep' will keep one", "item in every inventory", "slot"). addChoiceEvent(new ChoiceEvent() { @Override public void choiceChanged(Widget parent, String newChoice) { updateRecipe(); } }). setEnabled(false). setLayoutHint(new PositionalLayout.PositionalHint(148, 7, 41, 14)); } private void initSpeedMode() { speedMode = new ImageChoiceLabel(mc, this). addChoiceEvent(new ChoiceEvent() { @Override public void choiceChanged(Widget parent, String newChoice) { changeSpeedMode(); } }). addChoice("Slow", "Speed mode:\nSlow", iconGuiElements, 48, 0). addChoice("Fast", "Speed mode:\nFast", iconGuiElements, 64, 0); speedMode.setLayoutHint(new PositionalLayout.PositionalHint(49, 186, 16, 16)); speedMode.setCurrentChoice(tileEntity.getSpeedMode()); } private void initRedstoneMode() { redstoneMode = new ImageChoiceLabel(mc, this). addChoiceEvent(new ChoiceEvent() { @Override public void choiceChanged(Widget parent, String newChoice) { changeRedstoneMode(); } }). addChoice(RedstoneMode.REDSTONE_IGNORED.getDescription(), "Redstone mode:\nIgnored", iconGuiElements, 0, 0). addChoice(RedstoneMode.REDSTONE_OFFREQUIRED.getDescription(), "Redstone mode:\nOff to activate", iconGuiElements, 16, 0). addChoice(RedstoneMode.REDSTONE_ONREQUIRED.getDescription(), "Redstone mode:\nOn to activate", iconGuiElements, 32, 0); redstoneMode.setLayoutHint(new PositionalLayout.PositionalHint(31, 186, 16, 16)); redstoneMode.setCurrentChoice(tileEntity.getRedstoneMode().ordinal()); } private void changeRedstoneMode() { tileEntity.setRedstoneMode(RedstoneMode.values()[redstoneMode.getCurrentChoiceIndex()]); sendChangeToServer(); } private void changeSpeedMode() { tileEntity.setSpeedMode(speedMode.getCurrentChoiceIndex()); sendChangeToServer(); } private void rememberItems() { sendServerCommand(RFToolsMessages.INSTANCE, CrafterBaseTE.CMD_REMEMBER); } private void forgetItems() { sendServerCommand(RFToolsMessages.INSTANCE, CrafterBaseTE.CMD_FORGET); } private void sendChangeToServer() { sendServerCommand(RFToolsMessages.INSTANCE, CrafterBaseTE.CMD_MODE, new Argument("rs", RedstoneMode.values()[redstoneMode.getCurrentChoiceIndex()].getDescription()), new Argument("speed", speedMode.getCurrentChoiceIndex())); } private void populateList() { recipeList.removeChildren(); for (int i = 0 ; i < tileEntity.getSupportedRecipes() ; i++) { CraftingRecipe recipe = tileEntity.getRecipe(i); ItemStack stack = recipe.getResult(); addRecipeLine(stack); } } private void addRecipeLine(Object craftingResult) { String readableName = BlockInfo.getReadableName(craftingResult, 0); int color = StyleConfig.colorTextInListNormal; if (craftingResult == null) { readableName = "<no recipe>"; color = 0xFF505050; } Panel panel = new Panel(mc, this).setLayout(new HorizontalLayout()). addChild(new BlockRender(mc, this).setRenderItem(craftingResult)). addChild(new Label(mc, this).setColor(color).setHorizontalAlignment(HorizontalAlignment.ALIGH_LEFT).setDynamic(true).setText(readableName)); recipeList.addChild(panel); } private void selectRecipe() { int selected = recipeList.getSelected(); if (selected == -1) { for (int i = 0 ; i < 10 ; i++) { inventorySlots.getSlot(i).putStack(null); } keepItem.setChoice("All"); internalRecipe.setChoice("Ext"); keepItem.setEnabled(false); internalRecipe.setEnabled(false); applyButton.setEnabled(false); return; } CraftingRecipe craftingRecipe = tileEntity.getRecipe(selected); InventoryCrafting inv = craftingRecipe.getInventory(); for (int i = 0 ; i < 9 ; i++) { inventorySlots.getSlot(i).putStack(inv.getStackInSlot(i)); } inventorySlots.getSlot(9).putStack(craftingRecipe.getResult()); keepItem.setChoice(craftingRecipe.isKeepOne() ? "Keep" : "All"); internalRecipe.setChoice(craftingRecipe.isCraftInternal() ? "Int" : "Ext"); keepItem.setEnabled(true); internalRecipe.setEnabled(true); applyButton.setEnabled(true); } private void testRecipe() { int selected = recipeList.getSelected(); if (selected == -1) { return; } InventoryCrafting inv = new InventoryCrafting(new Container() { @Override public boolean canInteractWith(EntityPlayer var1) { return false; } }, 3, 3); for (int i = 0 ; i < 9 ; i++) { inv.setInventorySlotContents(i, inventorySlots.getSlot(i).getStack()); } // Compare current contents to avoid unneeded slot update. IRecipe recipe = CraftingRecipe.findRecipe(mc.theWorld, inv); ItemStack newResult; if (recipe == null) { newResult = null; } else { newResult = recipe.getCraftingResult(inv); } inventorySlots.getSlot(9).putStack(newResult); } private void applyRecipe() { int selected = recipeList.getSelected(); if (selected == -1) { return; } CraftingRecipe craftingRecipe = tileEntity.getRecipe(selected); InventoryCrafting inv = craftingRecipe.getInventory(); for (int i = 0 ; i < 9 ; i++) { ItemStack oldStack = inv.getStackInSlot(i); ItemStack newStack = inventorySlots.getSlot(i).getStack(); if (!itemStacksEqual(oldStack, newStack)) { inv.setInventorySlotContents(i, newStack); } } // Compare current contents to avoid unneeded slot update. IRecipe recipe = CraftingRecipe.findRecipe(mc.theWorld, inv); ItemStack newResult; if (recipe == null) { newResult = null; } else { newResult = recipe.getCraftingResult(inv); } ItemStack oldResult = inventorySlots.getSlot(9).getStack(); if (!itemStacksEqual(oldResult, newResult)) { inventorySlots.getSlot(9).putStack(newResult); } craftingRecipe.setResult(newResult); updateRecipe(); populateList(); } private void updateRecipe() { int selected = recipeList.getSelected(); if (selected == -1) { return; } CraftingRecipe craftingRecipe = tileEntity.getRecipe(selected); boolean keepOne = "Keep".equals(keepItem.getCurrentChoice()); boolean craftInternal = "Int".equals(internalRecipe.getCurrentChoice()); craftingRecipe.setKeepOne(keepOne); craftingRecipe.setCraftInternal(craftInternal); sendChangeToServer(selected, craftingRecipe.getInventory(), craftingRecipe.getResult(), keepOne, craftInternal); } private boolean itemStacksEqual(ItemStack matches, ItemStack oldStack) { if (matches == null) { return oldStack == null; } else { return oldStack != null && matches.isItemEqual(oldStack); } } private void sendChangeToServer(int index, InventoryCrafting inv, ItemStack result, boolean keepOne, boolean craftInternal) { RFToolsMessages.INSTANCE.sendToServer(new PacketCrafter(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord, index, inv, result, keepOne, craftInternal)); } /** * Draws the screen and all the components in it. */ @Override public void drawScreen(int par1, int par2, float par3) { super.drawScreen(par1, par2, par3); testRecipe(); } @Override protected void drawGuiContainerBackgroundLayer(float v, int x, int y) { drawWindow(); int currentRF = tileEntity.getCurrentRF(); energyBar.setValue(currentRF); tileEntity.requestRfFromServer(RFToolsMessages.INSTANCE); // Draw the ghost slots here drawGhostSlots(); } private void drawGhostSlots() { GL11.glPushMatrix(); GL11.glTranslatef((float)guiLeft, (float)guiTop, 0.0F); GL11.glColor4f(1.0F, 0.0F, 0.0F, 1.0F); GL11.glEnable(GL12.GL_RESCALE_NORMAL); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) (short) 240 / 1.0F, (float) (short) 240 / 1.0F); ItemStack[] ghostSlots = tileEntity.getGhostSlots(); zLevel = 100.0F; itemRender.zLevel = 100.0F; GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_LIGHTING); for (int i = 0 ; i < ghostSlots.length ; i++) { ItemStack stack = ghostSlots[i]; if (stack != null) { int slotIdx; if (i < CrafterContainer.BUFFER_SIZE) { slotIdx = i + CrafterContainer.SLOT_BUFFER; } else { slotIdx = i + CrafterContainer.SLOT_BUFFEROUT - CrafterContainer.BUFFER_SIZE; } Slot slot = inventorySlots.getSlot(slotIdx); if (!slot.getHasStack()) { itemRender.renderItemAndEffectIntoGUI(this.fontRendererObj, this.mc.getTextureManager(), stack, slot.xDisplayPosition, slot.yDisplayPosition); GL11.glDisable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_BLEND); GL11.glDisable(GL11.GL_DEPTH_TEST); this.mc.getTextureManager().bindTexture(iconGuiElements); RenderHelper.drawTexturedModalRect(slot.xDisplayPosition, slot.yDisplayPosition, 14 * 16, 3 * 16, 16, 16); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_LIGHTING); } } } itemRender.zLevel = 0.0F; zLevel = 0.0F; GL11.glPopMatrix(); } }