diff options
Diffstat (limited to 'src/main/java/gregtech/api')
10 files changed, 397 insertions, 65 deletions
diff --git a/src/main/java/gregtech/api/gui/GT_GUIContainerMetaTile_Machine.java b/src/main/java/gregtech/api/gui/GT_GUIContainerMetaTile_Machine.java index 73da114b38..defa392b07 100644 --- a/src/main/java/gregtech/api/gui/GT_GUIContainerMetaTile_Machine.java +++ b/src/main/java/gregtech/api/gui/GT_GUIContainerMetaTile_Machine.java @@ -15,6 +15,7 @@ import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.MetaTileEntity; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.entity.RenderItem; +import gregtech.api.util.GT_TooltipDataCache; import net.minecraft.entity.player.InventoryPlayer; import java.util.List; @@ -29,9 +30,9 @@ import org.lwjgl.opengl.GL11; public class GT_GUIContainerMetaTile_Machine extends GT_GUIContainer implements GT_IToolTipRenderer, GT_ITabRenderer { public final GT_ContainerMetaTile_Machine mContainer; - - // IGuiScreen implementation + protected GT_GuiTooltipManager mTooltipManager = new GT_GuiTooltipManager(); + protected GT_TooltipDataCache mTooltipCache = new GT_TooltipDataCache(); // Cover Tabs support. Subclasses can override display position, style and visuals by overriding setupCoverTabs public GT_GuiCoverTabLine coverTabs; @@ -57,6 +58,11 @@ public class GT_GUIContainerMetaTile_Machine extends GT_GUIContainer implements ? (GT_Mod.gregtechproxy.mCoverTabsFlipped ? DisplayStyle.INVERSE : DisplayStyle.NORMAL) : DisplayStyle.NONE; setupCoverTabs(preferredDisplayStyle); + + // Only setup tooltips if they're currently enabled. + if (GT_Mod.gregtechproxy.mTooltipVerbosity > 0 || GT_Mod.gregtechproxy.mTooltipShiftVerbosity > 0) { + setupTooltips(); + } } public GT_GUIContainerMetaTile_Machine(InventoryPlayer aInventoryPlayer, IGregTechTileEntity aTileEntity, @@ -157,6 +163,14 @@ public class GT_GUIContainerMetaTile_Machine extends GT_GUIContainer implements return TAB_ICONSET; } + // Tooltips support + + /** + * Load data for and create appropriate tooltips for this machine. + * Only called when one of regular or shift tooltips are enabled. + */ + protected void setupTooltips() { } + // GT_IToolTipRenderer and GT_ITabRenderer implementations @Override public void drawHoveringText(List text, int x, int y, FontRenderer font) { diff --git a/src/main/java/gregtech/api/gui/GT_GUIContainer_BasicMachine.java b/src/main/java/gregtech/api/gui/GT_GUIContainer_BasicMachine.java index c13d151188..85c94cd723 100644 --- a/src/main/java/gregtech/api/gui/GT_GUIContainer_BasicMachine.java +++ b/src/main/java/gregtech/api/gui/GT_GUIContainer_BasicMachine.java @@ -5,19 +5,18 @@ import gregtech.api.gui.widgets.GT_GuiIcon; import gregtech.api.gui.widgets.GT_GuiTabLine.GT_GuiTabIconSet; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine_Bronze; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine_Steel; +import gregtech.api.gui.widgets.GT_GuiSlotTooltip; +import gregtech.api.gui.widgets.GT_GuiSmartTooltip; +import gregtech.api.gui.widgets.GT_GuiSmartTooltip.TooltipVisibilityProvider; import gregtech.api.net.GT_Packet_SetConfigurationCircuit; import gregtech.api.util.GT_Utility; +import gregtech.api.util.GT_Recipe.GT_Recipe_Map; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.StatCollector; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; +import java.awt.Rectangle; import static gregtech.api.enums.GT_Values.RES_PATH_GUI; @@ -26,16 +25,11 @@ import static gregtech.api.enums.GT_Values.RES_PATH_GUI; * <p/> * The GUI-Container I use for all my Basic Machines * <p/> - * As the NEI-RecipeTransferRect Handler can't handle one GUI-Class for all GUIs I needed to produce some dummy-classes which extend this class + * As the NEI-RecipeTransferRect Handler can't handle one GUI-Class for all GUIs I needed to produce some dummy-classes + * which extend this class */ public class GT_GUIContainer_BasicMachine extends GT_GUIContainerMetaTile_Machine { - - private static final List<String> GHOST_CIRCUIT_TOOLTIP = Arrays.asList( - "GT5U.machines.select_circuit.tooltip", - "GT5U.machines.select_circuit.tooltip.1", - "GT5U.machines.select_circuit.tooltip.2", - "GT5U.machines.select_circuit.tooltip.3" - ); + private static final int NEEDS_STEAM_VENTING = 64; private final static GT_GuiTabIconSet TAB_ICONSET_BRONZE = new GT_GuiTabIconSet( GT_GuiIcon.TAB_NORMAL_BRONZE, GT_GuiIcon.TAB_HIGHLIGHT_BRONZE, @@ -50,21 +44,101 @@ public class GT_GUIContainer_BasicMachine extends GT_GUIContainerMetaTile_Machin public final byte mProgressBarDirection, mProgressBarAmount; - public final boolean - mRenderAutoOutputSlots; - public GT_GUIContainer_BasicMachine(InventoryPlayer aInventoryPlayer, IGregTechTileEntity aTileEntity, String aName, String aTextureFile, String aNEI) { + // Tooltip localization keys + private static final String + GHOST_CIRCUIT_TOOLTIP = "GT5U.machines.select_circuit.tooltip", + BATTERY_SLOT_TOOLTIP = "GT5U.machines.battery_slot.tooltip", + BATTERY_SLOT_TOOLTIP_ALT = "GT5U.machines.battery_slot.tooltip.alternative", + UNUSED_SLOT_TOOLTIP = "GT5U.machines.unused_slot.tooltip", + SPECIAL_SLOT_TOOLTIP = "GT5U.machines.special_slot.tooltip", + FLUID_INPUT_TOOLTIP = "GT5U.machines.fluid_input_slot.tooltip", + FLUID_OUTPUT_TOOLTIP = "GT5U.machines.fluid_output_slot.tooltip", + STALLED_STUTTERING_TOOLTIP = "GT5U.machines.stalled_stuttering.tooltip", + STALLED_VENT_TOOLTIP = "GT5U.machines.stalled_vent.tooltip", + FLUID_TRANSFER_TOOLTIP = "GT5U.machines.fluid_transfer.tooltip", + ITEM_TRANSFER_TOOLTIP = "GT5U.machines.item_transfer.tooltip", + POWER_SOURCE_KEY = "GT5U.machines.powersource."; + + public GT_GUIContainer_BasicMachine(InventoryPlayer aInventoryPlayer, IGregTechTileEntity aTileEntity, String aName, + String aTextureFile, String aNEI) { this(aInventoryPlayer, aTileEntity, aName, aTextureFile, aNEI, (byte) 0, (byte) 1); } - public GT_GUIContainer_BasicMachine(InventoryPlayer aInventoryPlayer, IGregTechTileEntity aTileEntity, String aName, String aTextureFile, String aNEI, byte aProgressBarDirection, byte aProgressBarAmount) { - super(new GT_Container_BasicMachine(aInventoryPlayer, aTileEntity), RES_PATH_GUI + "basicmachines/" + aTextureFile); + public GT_GUIContainer_BasicMachine(InventoryPlayer aInventoryPlayer, IGregTechTileEntity aTileEntity, String aName, + String aTextureFile, String aNEI, byte aProgressBarDirection, byte aProgressBarAmount) { + super(new GT_Container_BasicMachine(aInventoryPlayer, aTileEntity), + RES_PATH_GUI + "basicmachines/" + aTextureFile); getContainer().setCircuitSlotClickCallback(this::openSelectCircuitDialog); mProgressBarDirection = aProgressBarDirection; mProgressBarAmount = (byte) Math.max(1, aProgressBarAmount); mName = aName; mNEI = aNEI; - mRenderAutoOutputSlots = !(aTileEntity.getMetaTileEntity() instanceof GT_MetaTileEntity_BasicMachine_Bronze); + } + + /** + * Load data for and create appropriate tooltips for this machine + */ + @Override + protected void setupTooltips() { + GT_MetaTileEntity_BasicMachine machine = getMachine(); + GT_Recipe_Map recipes = machine.getRecipeList(); + GT_Container_BasicMachine container = getContainer(); + Rectangle tProblemArea = new Rectangle(this.guiLeft + 79, this.guiTop + 44, 18, 18); + String batterySlotTooltipKey; + Object[] batterySlotTooltipArgs; + if (machine.allowSelectCircuit()) { + addToolTip(new GT_GuiSlotTooltip(container.slotCircuit, mTooltipCache.getData(GHOST_CIRCUIT_TOOLTIP))); + } + if (machine.isSteampowered()) { + batterySlotTooltipKey = UNUSED_SLOT_TOOLTIP; + batterySlotTooltipArgs = new String[0]; + addToolTip(new GT_GuiSmartTooltip(tProblemArea, new TooltipVisibilityProvider() { + public boolean shouldShowTooltip() { + return hasErrorCode(NEEDS_STEAM_VENTING); + } + }, mTooltipCache.getData(STALLED_VENT_TOOLTIP))); + } else { + String pTier1 = powerTierName(machine.mTier); + if (machine.mTier == GT_Values.VN.length - 1) { + batterySlotTooltipKey = BATTERY_SLOT_TOOLTIP_ALT; + batterySlotTooltipArgs = new String[] {pTier1}; + } else { + batterySlotTooltipKey = BATTERY_SLOT_TOOLTIP; + batterySlotTooltipArgs = new String[] {pTier1, powerTierName((byte) (machine.mTier + 1))}; + } + addToolTip(new GT_GuiSlotTooltip( container.slotFluidTransferToggle, + mTooltipCache.getData(FLUID_TRANSFER_TOOLTIP))); + addToolTip(new GT_GuiSlotTooltip( container.slotItemTransferToggle, + mTooltipCache.getData(ITEM_TRANSFER_TOOLTIP))); + } + if (recipes != null && recipes.hasFluidInputs()) { + addToolTip(new GT_GuiSlotTooltip(container.slotFluidInput, + mTooltipCache.getData(FLUID_INPUT_TOOLTIP, machine.getCapacity()))); + } + if (recipes != null && recipes.hasFluidOutputs()) { + addToolTip(new GT_GuiSlotTooltip(container.slotFluidOutput, + mTooltipCache.getData(FLUID_OUTPUT_TOOLTIP, machine.getCapacity()))); + } + addToolTip( new GT_GuiSlotTooltip(getContainer().slotBattery, + mTooltipCache.getData(batterySlotTooltipKey, batterySlotTooltipArgs))); + addToolTip(new GT_GuiSlotTooltip(container.slotSpecial, mTooltipCache.getData( + recipes != null && recipes.usesSpecialSlot() ? SPECIAL_SLOT_TOOLTIP : UNUSED_SLOT_TOOLTIP))); + addToolTip(new GT_GuiSmartTooltip(tProblemArea, new TooltipVisibilityProvider() { + public boolean shouldShowTooltip() { + return container.mStuttering && !hasErrorCode(NEEDS_STEAM_VENTING); + } + }, mTooltipCache.getData(STALLED_STUTTERING_TOOLTIP, StatCollector.translateToLocal( + POWER_SOURCE_KEY + (machine.isSteampowered() ? "steam" : "power"))))); + } + + /** + * Apply proper coloration to a machine's power tier short name + * @param machineTier + * @return colored power tier short name + */ + private String powerTierName(byte machineTier) { + return GT_Values.TIER_COLORS[machineTier] + GT_Values.VN[machineTier]; } private void openSelectCircuitDialog() { @@ -74,7 +148,8 @@ public class GT_GUIContainer_BasicMachine extends GT_GUIContainerMetaTile_Machin this, this::onCircuitSelected, getMachine().getConfigurationCircuits(), - GT_Utility.findMatchingStackInList(getMachine().getConfigurationCircuits(), getMachine().getStackInSlot(getMachine().getCircuitSlot())))); + GT_Utility.findMatchingStackInList(getMachine().getConfigurationCircuits(), + getMachine().getStackInSlot(getMachine().getCircuitSlot())))); } private void onCircuitSelected(ItemStack selected) { @@ -89,40 +164,16 @@ public class GT_GUIContainer_BasicMachine extends GT_GUIContainerMetaTile_Machin } @Override - public void drawScreen(int par1, int par2, float par3) { - super.drawScreen(par1, par2, par3); - if (mRenderAutoOutputSlots){ - drawTooltip(par1, par2); - } - } - - @Override - protected void drawGuiContainerForegroundLayer(int par1, int par2) { + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + super.drawGuiContainerForegroundLayer(mouseX, mouseY); fontRendererObj.drawString(mName, 8, 4, 4210752); } - private void drawTooltip(int x2, int y2) { - int xStart = (width - xSize) / 2; - int yStart = (height - ySize) / 2; - int x = x2 - xStart; - int y = y2 - yStart + 5; - if (y >= 67 && y <= 84) { - if (mRenderAutoOutputSlots && x >= 7 && x <= 24) { - drawHoveringText(Collections.singletonList("Fluid Auto-Output"), x2, y2, fontRendererObj); - } - if (mRenderAutoOutputSlots && x >= 25 && x <= 42) { - drawHoveringText(Collections.singletonList("Item Auto-Output"), x2, y2, fontRendererObj); - } - if (getMachine().allowSelectCircuit() && getMachine().getStackInSlot(getMachine().getCircuitSlot()) == null && x >= 153 && x <= 171) { - drawHoveringText(GHOST_CIRCUIT_TOOLTIP.stream().map(StatCollector::translateToLocal).collect(Collectors.toList()), x2, y2, fontRendererObj); - } - } - } - @Override protected void onMouseWheel(int mx, int my, int delta) { GT_Slot_Render slotCircuit = getContainer().slotCircuit; - if (slotCircuit != null && func_146978_c(slotCircuit.xDisplayPosition, slotCircuit.yDisplayPosition, 16, 16, mx, my)) { + if (slotCircuit != null && func_146978_c(slotCircuit.xDisplayPosition, + slotCircuit.yDisplayPosition, 16, 16, mx, my)) { // emulate click handleMouseClick(slotCircuit, -1, delta > 0 ? 1 : 0, 0); return; @@ -131,13 +182,13 @@ public class GT_GUIContainer_BasicMachine extends GT_GUIContainerMetaTile_Machin } @Override - protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { - super.drawGuiContainerBackgroundLayer(par1, par2, par3); + protected void drawGuiContainerBackgroundLayer(float parTicks, int mouseX, int mouseY) { + super.drawGuiContainerBackgroundLayer(parTicks, mouseX, mouseY); int x = (width - xSize) / 2; int y = (height - ySize) / 2; drawTexturedModalRect(x, y, 0, 0, xSize, ySize); if (mContainer != null) { - if (mRenderAutoOutputSlots){ + if (!getMachine().isSteampowered()) { if (getContainer().mFluidTransfer) drawTexturedModalRect(x + 7, y + 62, 176, 18, 18, 18); if (getContainer().mItemTransfer) @@ -147,7 +198,10 @@ public class GT_GUIContainer_BasicMachine extends GT_GUIContainerMetaTile_Machin drawTexturedModalRect(x + 79, y + 44, 176, 54, 18, 18); if (mContainer.mMaxProgressTime > 0) { - int tSize = mProgressBarDirection < 2 ? 20 : 18, tProgress = Math.max(1, Math.min(tSize * mProgressBarAmount, (mContainer.mProgressTime > 0 ? 1 : 0) + mContainer.mProgressTime * tSize * mProgressBarAmount / mContainer.mMaxProgressTime)) % (tSize + 1); + int tSize = mProgressBarDirection < 2 ? 20 : 18; + int tProgress = Math.max(1, Math.min(tSize * mProgressBarAmount, (mContainer.mProgressTime > 0 ? 1 : 0) + + mContainer.mProgressTime * tSize * mProgressBarAmount / mContainer.mMaxProgressTime)) + % (tSize + 1); switch (mProgressBarDirection) { // yes, my OCD was mad at me before I did the Tabs. case 0: @@ -192,6 +246,13 @@ public class GT_GUIContainer_BasicMachine extends GT_GUIContainerMetaTile_Machin return super.getTabBackground(); } + /** + * Whether the machine currently has this error code + */ + private boolean hasErrorCode(int errorCode) { + return (getContainer().mDisplayErrorCode & errorCode) != 0; + } + private GT_Container_BasicMachine getContainer() { return (GT_Container_BasicMachine) mContainer; } diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java new file mode 100644 index 0000000000..1fb25ecb1a --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java @@ -0,0 +1,22 @@ +package gregtech.api.gui.widgets; + +import java.awt.Rectangle; + +import gregtech.api.util.GT_TooltipDataCache.TooltipData; +import net.minecraft.inventory.Slot; + +public class GT_GuiSlotTooltip extends GT_GuiTooltip { + private final Slot slot; + + public GT_GuiSlotTooltip(Slot slot, TooltipData data) { + super(new Rectangle(slot.xDisplayPosition - 1, slot.yDisplayPosition - 1, 18, 18), data); + this.slot = slot; + } + + @Override + protected void onTick() { + super.onTick(); + // If disabled by super, stay disabled. + this.enabled = this.enabled && this.slot.getStack() == null; + } +} diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiSmartTooltip.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiSmartTooltip.java new file mode 100644 index 0000000000..d4f7df6d2c --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiSmartTooltip.java @@ -0,0 +1,25 @@ +package gregtech.api.gui.widgets; + +import java.awt.Rectangle; + +import gregtech.api.util.GT_TooltipDataCache.TooltipData; + +public class GT_GuiSmartTooltip extends GT_GuiTooltip{ + public interface TooltipVisibilityProvider { + boolean shouldShowTooltip(); + } + private final TooltipVisibilityProvider visibilityProvider; + + public GT_GuiSmartTooltip(Rectangle bounds, TooltipVisibilityProvider visibilityProvider, TooltipData data) { + super(bounds, data); + this.visibilityProvider = visibilityProvider; + } + + @Override + protected void onTick() { + super.onTick(); + // If disabled by super, stay disabled. + this.enabled = this.enabled && this.visibilityProvider.shouldShowTooltip(); + } + +} diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltip.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltip.java index 6b9e70a71b..815970c754 100644 --- a/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltip.java +++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltip.java @@ -1,38 +1,115 @@ package gregtech.api.gui.widgets; -import java.awt.*; +import java.awt.Rectangle; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import org.lwjgl.input.Keyboard; + +import gregtech.api.util.GT_TooltipDataCache.TooltipData; public class GT_GuiTooltip { protected Rectangle bounds; - private List<String> text; + protected TooltipData data; + private List<String> displayedText; public boolean enabled = true; + /** + * Used to create a tooltip that will appear over the specified bounds. + * This will initially be a "static" tooltip that doesn't respect verbosity levels or respond to the shift key. + * + * @param bounds + * @param text + */ public GT_GuiTooltip(Rectangle bounds, String... text) { this.bounds = bounds; setToolTipText(text); } + /** + * Used to create a tooltip that will appear over the specified bounds. + * This will initially be a "dynamic" tooltip that respects verbosity levels and responds to the shift key. + * + * @param bounds + * @param data + */ + public GT_GuiTooltip(Rectangle bounds, TooltipData data) { + this.bounds = bounds; + // Trust that the tooltips have already been formatted and colored, just make sure it has no nulls + this.data = sanitizeTooltipData(data); + } + + private TooltipData sanitizeTooltipData(TooltipData data) { + if (data.text == null){ + data.text = Arrays.asList(new String[0]); + } + if (data.shiftText == null){ + data.shiftText = Arrays.asList(new String[0]); + } + return data; + } + + /** + * Called before the tooltip manager checks whether this tooltip is enabled + */ + protected void onTick() { + // Switch which of our 2 stored texts we're displaying now. + this.displayedText = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) ? this.data.shiftText : this.data.text; + // If this text is empty, let's not display a tooltip at all. + this.enabled = this.displayedText.size() != 0; + } + + /** + * Called once this tooltip has been determined to be enabled + */ protected void updateText() { } + /** + * Used to set a "static" tooltip that doesn't respect verbosity levels or respond to the shift key + * + * @param text + */ public void setToolTipText(String... text) { + this.data = formatTooltip(text); + } + + /** + * Used to set a "dynamic" tooltip that respects verbosity levels and responds to the shift key + * + * @param text + */ + public void setToolTipText(TooltipData data) { + // Trust that the tooltips have already been formatted and colored, just make sure it has no nulls + this.data = sanitizeTooltipData(data); + } + + /** + * Apply tooltip colors in case the text doesn't contain them and return as tooltip data + * + * @param text + * @return colored tooltip lines as list + */ + protected TooltipData formatTooltip(String[] text) { + List<String> list; if (text != null) { - this.text = new ArrayList<>(text.length); + list = new ArrayList<>(text.length); for (int i = 0; i < text.length; i++) { if (i == 0) - this.text.add("\u00a7f" + text[i]); + list.add("\u00a7f" + text[i]); else - this.text.add("\u00a77" + text[i]); + list.add("\u00a77" + text[i]); } - } else - this.text = new ArrayList<>(); + } else { + list = Arrays.asList(new String[0]); + } + return new TooltipData(list, list) ; } + public List<String> getToolTipText() { - return text; + return this.displayedText; } public Rectangle getBounds() { diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltipManager.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltipManager.java index c098e4e2a7..e2ea65c482 100644 --- a/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltipManager.java +++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltipManager.java @@ -29,10 +29,11 @@ public class GT_GuiTooltipManager { } public final void onTick(GT_IToolTipRenderer render, int mouseX, int mouseY) { - if ((Math.abs(mouseX-lastMouseX) < 2 ) && (Math.abs(mouseY-lastMouseY) < 2 )) + if ((Math.abs(mouseX-lastMouseX) < 2 ) && (Math.abs(mouseY-lastMouseY) < 2 )) { mouseStopped = Math.min(mouseStopped+1, 50); - else + } else { mouseStopped = 0; + } lastMouseX = mouseX; lastMouseY = mouseY; @@ -40,6 +41,8 @@ public class GT_GuiTooltipManager { mouseX -= render.getGuiLeft(); mouseY -= render.getGuiTop(); for (GT_GuiTooltip tip : tips) { + // Give the tooltip the opportunity to decide whether they should be enabled + tip.onTick(); if (tip.enabled && (!tip.isDelayed() || mouseStopped > DELAY) && tip.getBounds().contains(mouseX, mouseY)) { tip.updateText(); drawTooltip(tip, mouseX, mouseY, render); diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java index feca23949a..5cd01376cd 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine.java @@ -587,6 +587,12 @@ public abstract class GT_MetaTileEntity_BasicMachine extends GT_MetaTileEntity_B } } } + // Only using mNeedsSteamVenting right now and assigning it to 64 to space in the range for more single block + // machine problems. + // Value | Class | Field + // 1 | GT_MetaTileEntity_BasicMachine | mStuttering + // 64 | GT_MetaTileEntity_BasicMachine_Bronze | mNeedsSteamVenting + aBaseMetaTileEntity.setErrorDisplayID((aBaseMetaTileEntity.getErrorDisplayID() & ~127));// | (mStuttering ? 1 : 0)); } protected void doDisplayThings() { diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Bronze.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Bronze.java index d573c6bfd1..204156f3ab 100644 --- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Bronze.java +++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_BasicMachine_Bronze.java @@ -3,6 +3,7 @@ package gregtech.api.metatileentity.implementations; import gregtech.api.GregTech_API; import gregtech.api.enums.Dyes; import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.objects.GT_ItemStack; import gregtech.api.render.TextureFactory; import gregtech.api.util.GT_Log; @@ -38,6 +39,7 @@ public abstract class GT_MetaTileEntity_BasicMachine_Bronze extends GT_MetaTileE return new GT_MetaTileEntity_BasicMachine_Bronze(mTier, mDescription, mTextures); } */ + private static final int NEEDS_STEAM_VENTING = 64; public boolean mNeedsSteamVenting = false; public GT_MetaTileEntity_BasicMachine_Bronze(int aID, String aName, String aNameRegional, String aDescription, int aInputSlotCount, int aOutputSlotCount, boolean aBricked) { @@ -151,6 +153,13 @@ public abstract class GT_MetaTileEntity_BasicMachine_Bronze extends GT_MetaTileE } @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + super.onPostTick(aBaseMetaTileEntity, aTick); + // Super already zeroed out setErrorDisplayID, add additional error codes here. + aBaseMetaTileEntity.setErrorDisplayID(aBaseMetaTileEntity.getErrorDisplayID() | (mNeedsSteamVenting ? 64 : 0)); + } + + @Override public void endProcess() { if (isSteampowered()) mNeedsSteamVenting = true; } diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java index aa16340f68..3b143bab4c 100644 --- a/src/main/java/gregtech/api/util/GT_Recipe.java +++ b/src/main/java/gregtech/api/util/GT_Recipe.java @@ -850,6 +850,11 @@ public class GT_Recipe implements Comparable<GT_Recipe> { private boolean mHasFluidOutputs = false; /** + * Whether this recipe map contains special slot inputs. + */ + private boolean mUsesSpecialSlot = false; + + /** * Initialises a new type of Recipe Handler. * * @param aRecipeList a List you specify as Recipe List. Usually just an ArrayList with a pre-initialised Size. @@ -955,6 +960,9 @@ public class GT_Recipe implements Comparable<GT_Recipe> { if (aRecipe.mFluidOutputs.length != 0) { this.mHasFluidOutputs = true; } + if (aRecipe.mSpecialItems != null) { + this.mUsesSpecialSlot = true; + } return addToItemMap(aRecipe); } @@ -1100,6 +1108,13 @@ public class GT_Recipe implements Comparable<GT_Recipe> { public boolean hasFluidInputs() { return mRecipeFluidNameMap.size() != 0; } + + /** + * Whether this recipe map contains special slot inputs. + */ + public boolean usesSpecialSlot() { + return mUsesSpecialSlot; + } } // ----------------------------------------------------------------------------------------------------------------- diff --git a/src/main/java/gregtech/api/util/GT_TooltipDataCache.java b/src/main/java/gregtech/api/util/GT_TooltipDataCache.java new file mode 100644 index 0000000000..7844bb04fd --- /dev/null +++ b/src/main/java/gregtech/api/util/GT_TooltipDataCache.java @@ -0,0 +1,100 @@ +package gregtech.api.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import gregtech.GT_Mod; +import net.minecraft.util.StatCollector; + +public class GT_TooltipDataCache { + + public static class TooltipData { + public List<String> text; + public List<String> shiftText; + + public TooltipData(List<String> text, List<String> shiftText) { + this.text = text; + this.shiftText = shiftText; + } + } + private final Map<String, TooltipData> fetchedTooltipData = new HashMap<>(); + + /** + * Returns tooltip data respecting the user's configured verbosity levels, applying any formatting arguments. + * + * @param key the key to lookup + * @param args arguments for string formatting (prefer using positional arguments) + * @return The tooltip data the user asked for + */ + public TooltipData getData(String key, Object... args) { + TooltipData tooltipData = fetchedTooltipData.get(key); + if (tooltipData == null) { + tooltipData = getUncachedTooltipData(key, args); + fetchedTooltipData.put(key, tooltipData); + } + return tooltipData; + } + + /** + * Builds tooltip data respecting the user's configured verbosity levels, applying any formatting arguments. + * + * @param key the key to lookup + * @param args arguments for string formatting (prefer using positional arguments) + * @return The tooltip data the user asked for + */ + private TooltipData getUncachedTooltipData(String key, Object... args) { + List<String> lines = getAllLines(key, args); + int normalLines = lines.size(); + if (Math.max(GT_Mod.gregtechproxy.mTooltipVerbosity, GT_Mod.gregtechproxy.mTooltipShiftVerbosity) >= 3) { + lines.addAll(getAllLines(key + ".extended", args)); // Are extended lines enabled? If so add them to the lines + } + if (lines.size() == 0) { + lines.add(key); // Fallback in case no lines could be found at all + } + return new TooltipData( + lines.subList(0, getVerbosityIndex(GT_Mod.gregtechproxy.mTooltipVerbosity, normalLines, lines.size())), + lines.subList(0, getVerbosityIndex(GT_Mod.gregtechproxy.mTooltipShiftVerbosity, normalLines, lines.size()))); + } + + /** + * Gets all the lines for the given key and every other subsequent consecutive key with a .n suffix, n in {1,2,3...} + * + * @param key the key to lookup + * @param args arguments for string formatting (prefer using positional arguments) + * @return The lines for the key and all of it's subkeys + */ + private List<String> getAllLines(String key, Object... args) { + List<String> lines = new ArrayList<String>(); + String keyToLookup = key; + int i = 1; // First loop has no .number postfix + while (StatCollector.canTranslate(keyToLookup)) { + lines.add(StatCollector.translateToLocalFormatted(keyToLookup, args)); + keyToLookup = key + "." + i++; + } + return lines; + } + + /** + * Determines how many lines from a tooltip to include from the full line list to respect a given verbosity level. + * + * @param tooltipVerbosity the verbosity level we're applying + * @param defaultIndex return if tooltipVerbosity is 2 + * @param maxIndex return if tooltipVerbosity is greater than 2 + * @return verbosity appropriate index + */ + private static int getVerbosityIndex(int tooltipVerbosity, int defaultIndex, int maxIndex) { + int index; + if (tooltipVerbosity < 1) { + index = 0; + } else if (tooltipVerbosity == 1) { + index = 1; + } else if (tooltipVerbosity == 2) { + index = defaultIndex; + } else { + index = maxIndex; + } + return index; + } +} |