diff --git a/src/main/java/gregtech/api/gui/GuiTextures.java b/src/main/java/gregtech/api/gui/GuiTextures.java index c1f1d68b1b..e6694a04ba 100644 --- a/src/main/java/gregtech/api/gui/GuiTextures.java +++ b/src/main/java/gregtech/api/gui/GuiTextures.java @@ -38,6 +38,7 @@ public class GuiTextures { public static final TextureArea BUTTON_ALLOW_IMPORT_EXPORT = TextureArea.fullImage("textures/gui/widget/button_allow_import_export.png"); public static final TextureArea BUTTON_CLEAR_GRID = TextureArea.fullImage("textures/gui/widget/button_clear_grid.png"); public static final TextureArea LOCK = TextureArea.fullImage("textures/gui/widget/lock.png"); + //INDICATORS & ICONS public static final TextureArea INDICATOR_NO_ENERGY = TextureArea.fullImage("textures/gui/base/indicator_no_energy.png"); public static final TextureArea TANK_ICON = TextureArea.fullImage("textures/gui/base/tank_icon.png"); @@ -125,5 +126,8 @@ public class GuiTextures { public static final TextureArea PROGRESS_BAR_SLICE = TextureArea.fullImage("textures/gui/progress_bar/progress_bar_slice.png"); public static final TextureArea PROGRESS_BAR_WIREMILL = TextureArea.fullImage("textures/gui/progress_bar/progress_bar_wiremill.png"); + //JEI + public static final TextureArea MULTIBLOCK_CATEGORY = TextureArea.fullImage("textures/gui/icon/coke_oven.png"); + public static final TextureArea INFO_ICON = TextureArea.fullImage("textures/gui/widget/information.png"); } diff --git a/src/main/java/gregtech/api/render/scene/WorldSceneRenderer.java b/src/main/java/gregtech/api/render/scene/WorldSceneRenderer.java index fc1e724579..be20fca570 100644 --- a/src/main/java/gregtech/api/render/scene/WorldSceneRenderer.java +++ b/src/main/java/gregtech/api/render/scene/WorldSceneRenderer.java @@ -182,7 +182,6 @@ private BlockPos handleMouseHit(Vec2f mousePosition) { //rewind buffer after read OBJECT_POS_BUFFER.rewind(); - //System.out.println(String.format("%f %f %f %f", pixelDepth, posX, posY, posZ)); //if we didn't hit anything, just return null //also return null if hit is too far from us if (posY < -100.0f) { @@ -211,7 +210,7 @@ public static Vec2f setupCamera(int x, int y, int width, int height, int skyColo Minecraft mc = Minecraft.getMinecraft(); ScaledResolution resolution = new ScaledResolution(mc); - GlStateManager.pushAttrib(); + GL11.glPushAttrib(GL11.GL_TRANSFORM_BIT); mc.entityRenderer.disableLightmap(); GlStateManager.disableLighting(); GlStateManager.enableDepth(); @@ -274,8 +273,12 @@ public static void resetCamera() { GlStateManager.matrixMode(GL11.GL_MODELVIEW); GlStateManager.popMatrix(); - //reset attributes - GlStateManager.popAttrib(); + //Re-enable disabled states + GlStateManager.disableBlend(); + GlStateManager.disableDepth(); + + //Reset Attributes + GL11.glPopAttrib(); } public class TrackedDummyWorld extends DummyWorld { diff --git a/src/main/java/gregtech/integration/jei/GTJeiPlugin.java b/src/main/java/gregtech/integration/jei/GTJeiPlugin.java index 6a496f43dd..e6f6b19906 100755 --- a/src/main/java/gregtech/integration/jei/GTJeiPlugin.java +++ b/src/main/java/gregtech/integration/jei/GTJeiPlugin.java @@ -25,6 +25,7 @@ import gregtech.common.items.MetaItems; import gregtech.common.metatileentities.MetaTileEntities; import gregtech.integration.jei.multiblock.MultiblockInfoCategory; +import gregtech.integration.jei.multiblock.MultiblockInfoPage; import gregtech.integration.jei.recipe.*; import gregtech.integration.jei.recipe.fuel.FuelRecipeMapCategory; import gregtech.integration.jei.recipe.fuel.GTFuelRecipeWrapper; @@ -197,5 +198,13 @@ public void register(IModRegistry registry) { registry.addIngredientInfo(machine.getStackForm(), VanillaTypes.ITEM, "gregtech.machine.fluid_canner.jei_description"); } + + //Multiblock info page registration + MultiblockInfoCategory.multiblockRecipes.values().forEach(v -> { + MultiblockInfoPage infoPage = v.getInfoPage(); + registry.addIngredientInfo(infoPage.getController().getStackForm(), + VanillaTypes.ITEM, + infoPage.getDescription()); + }); } } diff --git a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoCategory.java b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoCategory.java index f1d6f2bab1..7406953545 100644 --- a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoCategory.java +++ b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoCategory.java @@ -1,6 +1,7 @@ package gregtech.integration.jei.multiblock; import gregtech.api.GTValues; +import gregtech.api.gui.GuiTextures; import gregtech.common.metatileentities.MetaTileEntities; import gregtech.integration.jei.multiblock.infos.*; import mezz.jei.api.IJeiHelpers; @@ -12,7 +13,6 @@ import mezz.jei.api.recipe.IRecipeCategory; import mezz.jei.gui.recipes.RecipeLayout; import net.minecraft.client.resources.I18n; -import net.minecraft.util.ResourceLocation; import java.util.HashMap; import java.util.Map; @@ -26,8 +26,7 @@ public class MultiblockInfoCategory implements IRecipeCategory multiblockRecipes = new HashMap() {{ @@ -83,5 +82,4 @@ public IDrawable getIcon() { public void setRecipe(IRecipeLayout recipeLayout, MultiblockInfoRecipeWrapper recipeWrapper, IIngredients ingredients) { recipeWrapper.setRecipeLayout((RecipeLayout) recipeLayout, this.guiHelper); } - } diff --git a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoPage.java b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoPage.java index 109623beab..5f2a82bc12 100644 --- a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoPage.java +++ b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoPage.java @@ -1,8 +1,11 @@ package gregtech.integration.jei.multiblock; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import net.minecraft.client.resources.I18n; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; public abstract class MultiblockInfoPage { @@ -15,4 +18,12 @@ public abstract class MultiblockInfoPage { public float getDefaultZoom() { return 1.0f; } + + public List informationText() { + + return Stream.of("gregtech.multiblock.preview.tilt", "gregtech.multiblock.preview.zoom", + "gregtech.multiblock.preview.pan", "gregtech.multiblock.preview.move", "gregtech.multiblock.preview.reset") + .map(I18n::format) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java index cdd0c2a214..c6fefc01d6 100755 --- a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java +++ b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java @@ -22,7 +22,6 @@ import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.I18n; @@ -37,20 +36,28 @@ import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; +import net.minecraftforge.fml.client.config.GuiUtils; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import javax.vecmath.Vector3f; import java.util.*; import java.util.Map.Entry; -import java.util.stream.Collectors; public class MultiblockInfoRecipeWrapper implements IRecipeWrapper, SceneRenderCallback { private static final int MAX_PARTS = 20; + private static final int PARTS_HEIGHT = 36; + private final int SLOT_SIZE = 18; + private final int SLOTS_PER_ROW = 10; + private final int ICON_SIZE = 20; + private final int RIGHT_PADDING = 5; private static class MBPattern { final WorldSceneRenderer sceneRenderer; final List parts; + public MBPattern(final WorldSceneRenderer sceneRenderer, final List parts) { this.sceneRenderer = sceneRenderer; this.parts = parts; @@ -77,7 +84,9 @@ public MBPattern(final WorldSceneRenderer sceneRenderer, final List p private GuiButton buttonPreviousPattern; private GuiButton buttonNextPattern; private GuiButton nextLayerButton; + private IDrawable slot; + private IDrawable infoIcon; private ItemStack tooltipBlockStack; @@ -87,8 +96,8 @@ public MultiblockInfoRecipeWrapper(MultiblockInfoPage infoPage) { HashSet drops = new HashSet<>(); drops.add(new ItemStackKey(controllerStack)); this.patterns = infoPage.getMatchingShapes().stream() - .map(it -> initializePattern(it, drops)) - .toArray(MBPattern[]::new); + .map(it -> initializePattern(it, drops)) + .toArray(MBPattern[]::new); drops.forEach(it -> allItemStackInputs.add(it.getItemStack())); } @@ -98,33 +107,41 @@ public void getIngredients(IIngredients ingredients) { ingredients.setOutput(ItemStack.class, controllerStack); } + public MultiblockInfoPage getInfoPage() { + return infoPage; + } + public void setRecipeLayout(RecipeLayout layout, IGuiHelper guiHelper) { this.recipeLayout = layout; + + this.slot = guiHelper.drawableBuilder(GuiTextures.SLOT.imageLocation, 0, 0, SLOT_SIZE, SLOT_SIZE).setTextureSize(SLOT_SIZE, SLOT_SIZE).build(); + this.infoIcon = guiHelper.drawableBuilder(GuiTextures.INFO_ICON.imageLocation, 0, 0, ICON_SIZE, ICON_SIZE).setTextureSize(ICON_SIZE, ICON_SIZE).build(); + IDrawable border = layout.getRecipeCategory().getBackground(); + preparePlaceForParts(border.getHeight()); this.buttons.clear(); - this.nextLayerButton = new GuiButton(0, border.getWidth() - 25, 70, 20, 20, ""); - this.buttonPreviousPattern = new GuiButton(0, border.getWidth()-46, 90, 20, 20, "<"); - this.buttonNextPattern = new GuiButton(0, border.getWidth() - 25, 90, 20, 20, ">"); + this.nextLayerButton = new GuiButton(0, border.getWidth() - (ICON_SIZE + RIGHT_PADDING), 70, ICON_SIZE, ICON_SIZE, ""); + this.buttonPreviousPattern = new GuiButton(0, border.getWidth() - ((2 * ICON_SIZE) + RIGHT_PADDING + 1), 90, ICON_SIZE, ICON_SIZE, "<"); + this.buttonNextPattern = new GuiButton(0, border.getWidth() - (ICON_SIZE + RIGHT_PADDING), 90, ICON_SIZE, ICON_SIZE, ">"); this.buttons.put(nextLayerButton, this::toggleNextLayer); this.buttons.put(buttonPreviousPattern, () -> switchRenderPage(-1)); this.buttons.put(buttonNextPattern, () -> switchRenderPage(1)); + boolean isPagesDisabled = patterns.length == 1; this.buttonPreviousPattern.visible = !isPagesDisabled; this.buttonNextPattern.visible = !isPagesDisabled; this.buttonPreviousPattern.enabled = false; this.buttonNextPattern.enabled = patterns.length > 1; - IGuiItemStackGroup itemStackGroup = recipeLayout.getItemStacks(); - this.slot = guiHelper.createDrawable(GuiTextures.SLOT.imageLocation, 0, 0, 18, 18, 18, 18); - for (int i = 0; i < MAX_PARTS; ++i) - itemStackGroup.init(i, true, 18*i-180*(i/10), border.getHeight()-36+18*(i/10)); + this.panX = 0.0f; this.panY = 0.0f; this.zoom = infoPage.getDefaultZoom(); this.rotationYaw = -45.0f; this.rotationPitch = 0.0f; this.currentRendererPage = 0; + setNextLayer(-1); - updateParts(); + updateParts(); } public WorldSceneRenderer getCurrentRenderer() { @@ -162,6 +179,13 @@ private void switchRenderPage(int amount) { } } + private void preparePlaceForParts(int recipeHeight) { + IGuiItemStackGroup itemStackGroup = recipeLayout.getItemStacks(); + + for (int i = 0; i < MAX_PARTS; ++i) + itemStackGroup.init(i, true, SLOT_SIZE * i - (SLOT_SIZE * SLOTS_PER_ROW) * (i / SLOTS_PER_ROW), recipeHeight - PARTS_HEIGHT + SLOT_SIZE * (i / SLOTS_PER_ROW)); + } + private void updateParts() { IGuiItemStackGroup itemStackGroup = recipeLayout.getItemStacks(); List parts = this.patterns[currentRendererPage].parts; @@ -210,24 +234,32 @@ public void preRenderScene(WorldSceneRenderer renderer) { @Override public void drawInfo(Minecraft minecraft, int recipeWidth, int recipeHeight, int mouseX, int mouseY) { WorldSceneRenderer renderer = getCurrentRenderer(); - int scenePosY = 0; - //noinspection UnnecessaryLocalVariable,SuspiciousNameCombination - int sceneHeight = recipeHeight-36; - renderer.render(recipeLayout.getPosX(), recipeLayout.getPosY() + scenePosY, recipeWidth, sceneHeight, 0xC6C6C6); - drawText(minecraft, recipeWidth); + int sceneHeight = recipeHeight - PARTS_HEIGHT; + + renderer.render(recipeLayout.getPosX(), recipeLayout.getPosY(), recipeWidth, sceneHeight, 0xC6C6C6); + drawMultiblockName(recipeWidth); + + //reset colors (so any elements render after this point are not dark) + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + + this.infoIcon.draw(minecraft, recipeWidth - (ICON_SIZE + RIGHT_PADDING), 49); + for (int i = 0; i < MAX_PARTS; ++i) { - this.slot.draw(minecraft, 18*i-180*(i/10), recipeHeight-36+18*(i/10)); + this.slot.draw(minecraft, SLOT_SIZE * i - (SLOTS_PER_ROW * SLOT_SIZE) * (i / SLOTS_PER_ROW), sceneHeight + SLOT_SIZE * (i / SLOTS_PER_ROW)); } + // Hmmm, the buttons need to be last otherwise sometimes highlighting // the button by mousing over it, leaks into other gui elements? for (GuiButton button : buttons.keySet()) { button.drawButton(minecraft, mouseX, mouseY, 0.0f); } + drawHoveringInformationText(minecraft, infoPage.informationText(), mouseX, mouseY); + this.tooltipBlockStack = null; BlockPos pos = renderer.getLastHitBlock(); - boolean insideView = mouseX >= 0 && mouseY >= scenePosY && - mouseX < recipeWidth && mouseY < (scenePosY + sceneHeight); + boolean insideView = mouseX >= 0 && mouseY >= 0 && + mouseX < recipeWidth && mouseY < sceneHeight; boolean leftClickHeld = Mouse.isButtonDown(0); boolean rightClickHeld = Mouse.isButtonDown(1); boolean isHoldingShift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT); @@ -266,20 +298,26 @@ public void drawInfo(Minecraft minecraft, int recipeWidth, int recipeHeight, int this.lastMouseY = mouseY; } - private void drawText(Minecraft minecraft, int recipeWidth) { + @SideOnly(Side.CLIENT) + protected void drawHoveringInformationText(Minecraft minecraft, List tooltip, int mouseX, int mouseY) { + int minX = recipeLayout.getRecipeCategory().getBackground().getWidth(); + int[] yRange = new int[]{49, 69}; + int[] xRange = new int[]{minX - (ICON_SIZE + RIGHT_PADDING), minX - RIGHT_PADDING}; + //Only draw the hovering information tooltip above the information icon + if (isMouseWithinRange(yRange, xRange, mouseY, mouseX)) { + GuiUtils.drawHoveringText(tooltip, mouseX, mouseY, + 176, 176, -1, minecraft.fontRenderer); + } + } + + private boolean isMouseWithinRange(int[] yRange, int[] xRange, int mouseY, int mouseX) { + + return (yRange[0] < mouseY && mouseY < yRange[1] && xRange[0] < mouseX && mouseX < xRange[1]); + } + + private void drawMultiblockName(int recipeWidth) { String localizedName = I18n.format(infoPage.getController().getMetaFullName()); GTUtility.drawCenteredSizedText(recipeWidth / 2, 0, localizedName, 0x333333, 1.3); - FontRenderer fontRenderer = minecraft.fontRenderer; - List lines = Arrays.stream(infoPage.getDescription()) - .flatMap(s -> fontRenderer.listFormattedStringToWidth(s, recipeWidth).stream()) - .collect(Collectors.toList()); - for (int i = 0; i < lines.size(); i++) { - String lineText = lines.get(i); - int x = (recipeWidth - fontRenderer.getStringWidth(lineText)) / 2; - int y = 8 + i * fontRenderer.FONT_HEIGHT; - fontRenderer.drawString(lineText, x, y, 0x333333); - } - GlStateManager.color(1.0f, 1.0f, 1.0f); } @Override @@ -392,9 +430,9 @@ private MBPattern initializePattern(MultiblockShapeInfo shapeInfo, Set parts = new ArrayList(); + ArrayList parts = new ArrayList<>(); for (PartInfo partInfo : partInfos) { - parts.add(partInfo.getItemStack()); + parts.add(partInfo.getItemStack()); } return new MBPattern(worldSceneRenderer, parts); } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index a76b1021e7..84f3a6f39a 100755 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -2946,6 +2946,11 @@ gregtech.multiblock.invalid_structure.tooltip=This block is a controller of the gregtech.multiblock.validation_failed=Invalid amount of inputs/outputs. gregtech.multiblock.max_energy_per_tick=Max EU/t: %s (%s) gregtech.multiblock.generation_eu=Outputting: %s EU/t +gregtech.multiblock.preview.tilt=Shift+LMB to tilt +gregtech.multiblock.preview.zoom=Shift+RMB to zoom +gregtech.multiblock.preview.pan=LMB+Drag to pan +gregtech.multiblock.preview.move=RMB+Drag to move +gregtech.multiblock.preview.reset=Scroll Mousewheel to reset gregtech.multiblock.blast_furnace.max_temperature=Max Temperature: %sK gregtech.multiblock.multi_furnace.heating_coil_level=Heating Coil Level: %s diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/information.png b/src/main/resources/assets/gregtech/textures/gui/widget/information.png new file mode 100644 index 0000000000..01281dd53c Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/information.png differ