diff --git a/README.md b/README.md index ba538b9f..987b942b 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,8 @@ This mod also has a flexible API that other mods can use to add more information * showProbeNoteGUI (Default: true) If players can open the Note UI with the Note * probeNoteBlock (Default: minecraft:log) The block to use as the example in the probe config UI * showBreakProgressText (Default: true) Show the text in the progress bar - * probeProgressColor, probeProgressAltColor, and probeProgressBorderColor Config the color of the progress bar + * probeProgressColor, probeProgressAltColor, probeProgressBackgroundColor, and probeProgressBorderColor Config the color of the progress bar + * probeProgressGradient (Default: false) Use a gradient instead of alternating colors in solid blocks * Replaced the hardcoded strings with language-translatable versions * Updated ru_ru.lang (By: @bigenergy) * New en_ud.lang diff --git a/src/main/java/mcjty/theoneprobe/apiimpl/client/ElementProgressGradientRender.java b/src/main/java/mcjty/theoneprobe/apiimpl/client/ElementProgressGradientRender.java new file mode 100644 index 00000000..074ca762 --- /dev/null +++ b/src/main/java/mcjty/theoneprobe/apiimpl/client/ElementProgressGradientRender.java @@ -0,0 +1,112 @@ +package mcjty.theoneprobe.apiimpl.client; + +import mcjty.theoneprobe.api.IProgressStyle; +import mcjty.theoneprobe.apiimpl.elements.ElementProgress; +import mcjty.theoneprobe.rendering.RenderHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class ElementProgressGradientRender { + + private static final ResourceLocation ICONS = new ResourceLocation("textures/gui/icons.png"); + + public static void render(IProgressStyle style, long current, long max, int x, int y, int w, int h) { + if (style.isLifeBar()) { + renderLifeBar(current, x, y, w, h); + } else if (style.isArmorBar()) { + renderArmorBar(current, x, y, w, h); + } else { + RenderHelper.drawThickBeveledBox(x, y, x + w, y + h, 1, style.getBorderColor(), style.getBorderColor(), style.getBackgroundColor()); + if (current > 0 && max > 0) { + // Determine the progress bar width, but limit it to the size of the element (minus 2). + int dx = (int) Math.min((current * (w - 2) / max), w - 2); + + if (dx > 0) { + drawGradientBar(x + 1, y + 1, x + dx + 1, y + h - 1, style.getAlternatefilledColor(), style.getFilledColor()); + } + } + } + + if (style.isShowText()) { + RenderHelper.renderText(Minecraft.getMinecraft(), x + 3, y + 2, style.getPrefix() + ElementProgress.format(current, style.getNumberFormat(), style.getSuffix())); + } + } + + private static void drawGradientBar(int startX, int startY, int endX, int endY, int startColor, int endColor) { + // Save the current OpenGL state + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.shadeModel(7425); // GL_SMOOTH + + // Start drawing a quad + net.minecraft.client.renderer.Tessellator tessellator = net.minecraft.client.renderer.Tessellator.getInstance(); + net.minecraft.client.renderer.BufferBuilder buffer = tessellator.getBuffer(); + buffer.begin(7, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_COLOR); // GL_QUADS + + // Convert colors to RGBA components + float startAlpha = (startColor >> 24 & 255) / 255.0F; + float startRed = (startColor >> 16 & 255) / 255.0F; + float startGreen = (startColor >> 8 & 255) / 255.0F; + float startBlue = (startColor & 255) / 255.0F; + + float endAlpha = (endColor >> 24 & 255) / 255.0F; + float endRed = (endColor >> 16 & 255) / 255.0F; + float endGreen = (endColor >> 8 & 255) / 255.0F; + float endBlue = (endColor & 255) / 255.0F; + + // Define the gradient vertices + buffer.pos(startX, endY, 0).color(startRed, startGreen, startBlue, startAlpha).endVertex(); + buffer.pos(endX, endY, 0).color(endRed, endGreen, endBlue, endAlpha).endVertex(); + buffer.pos(endX, startY, 0).color(endRed, endGreen, endBlue, endAlpha).endVertex(); + buffer.pos(startX, startY, 0).color(startRed, startGreen, startBlue, startAlpha).endVertex(); + + // Finish rendering + tessellator.draw(); + + // Restore the OpenGL state + GlStateManager.shadeModel(7424); // GL_FLAT + GlStateManager.disableBlend(); + GlStateManager.enableTexture2D(); + } + + private static void renderLifeBar(long current, int x, int y, int w, int h) { + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + Minecraft.getMinecraft().getTextureManager().bindTexture(ICONS); + if (current * 4 >= w) { + // Shortened view + RenderHelper.drawTexturedModalRect(x, y, 52, 0, 9, 9); + RenderHelper.renderText(Minecraft.getMinecraft(), x + 12, y, TextFormatting.WHITE + String.valueOf((current / 2))); + } else { + for (int i = 0; i < current / 2; i++) { + RenderHelper.drawTexturedModalRect(x, y, 52, 0, 9, 9); + x += 8; + } + if (current % 2 != 0) { + RenderHelper.drawTexturedModalRect(x, y, 61, 0, 9, 9); + } + } + } + + private static void renderArmorBar(long current, int x, int y, int w, int h) { + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + Minecraft.getMinecraft().getTextureManager().bindTexture(ICONS); + if (current * 4 >= w) { + // Shortened view + RenderHelper.drawTexturedModalRect(x, y, 43, 9, 9, 9); + RenderHelper.renderText(Minecraft.getMinecraft(), x + 12, y, TextFormatting.WHITE + String.valueOf((current / 2))); + } else { + for (int i = 0; i < current / 2; i++) { + RenderHelper.drawTexturedModalRect(x, y, 43, 9, 9, 9); + x += 8; + } + if (current % 2 != 0) { + RenderHelper.drawTexturedModalRect(x, y, 25, 9, 9, 9); + } + } + } +} diff --git a/src/main/java/mcjty/theoneprobe/apiimpl/elements/ElementProgress.java b/src/main/java/mcjty/theoneprobe/apiimpl/elements/ElementProgress.java index 11dd3a21..7836cf90 100644 --- a/src/main/java/mcjty/theoneprobe/apiimpl/elements/ElementProgress.java +++ b/src/main/java/mcjty/theoneprobe/apiimpl/elements/ElementProgress.java @@ -5,6 +5,7 @@ import mcjty.theoneprobe.api.IProgressStyle; import mcjty.theoneprobe.api.NumberFormat; import mcjty.theoneprobe.apiimpl.TheOneProbeImp; +import mcjty.theoneprobe.apiimpl.client.ElementProgressGradientRender; import mcjty.theoneprobe.apiimpl.client.ElementProgressRender; import mcjty.theoneprobe.apiimpl.styles.ProgressStyle; import mcjty.theoneprobe.network.NetworkTools; @@ -18,11 +19,17 @@ public class ElementProgress implements IElement { private final long current; private final long max; private final IProgressStyle style; + private final boolean doGradient; public ElementProgress(long current, long max, IProgressStyle style) { + this(current, max, style, false); // Default doGradient to false + } + + public ElementProgress(long current, long max, IProgressStyle style, boolean doGradient) { this.current = current; this.max = max; this.style = style; + this.doGradient = doGradient; } public ElementProgress(ByteBuf buf) { @@ -41,6 +48,7 @@ public ElementProgress(ByteBuf buf) { .numberFormat(NumberFormat.values()[buf.readByte()]) .lifeBar(buf.readBoolean()) .armorBar(buf.readBoolean()); + doGradient = buf.readBoolean(); // Deserialize doGradient } private static final DecimalFormat dfCommas = new DecimalFormat("###,###"); @@ -83,7 +91,12 @@ public static String format(long in, NumberFormat style, String suffix) { @Override @SideOnly(Side.CLIENT) public void render(int x, int y) { - ElementProgressRender.render(style, current, max, x, y, getWidth(), getHeight()); + if(doGradient){ + ElementProgressGradientRender.render(style, current, max, x, y, getWidth(), getHeight()); + } + else{ + ElementProgressRender.render(style, current, max, x, y, getWidth(), getHeight()); + } } @Override @@ -119,6 +132,7 @@ public void toBytes(ByteBuf buf) { buf.writeByte(style.getNumberFormat().ordinal()); buf.writeBoolean(style.isLifeBar()); buf.writeBoolean(style.isArmorBar()); + buf.writeBoolean(doGradient); } @Override diff --git a/src/main/java/mcjty/theoneprobe/config/ConfigSetup.java b/src/main/java/mcjty/theoneprobe/config/ConfigSetup.java index efbd6f56..f7d201b8 100644 --- a/src/main/java/mcjty/theoneprobe/config/ConfigSetup.java +++ b/src/main/java/mcjty/theoneprobe/config/ConfigSetup.java @@ -91,6 +91,8 @@ public class ConfigSetup { public static int probeProgressColor = 0xff990000; public static int probeProgressAltColor = 0xff550000; public static int probeProgressBorderColor = 0; + public static int probeProgressBackgroundColor = 0xff000000; + public static boolean probeProgressGradient = false; private static int boxBorderColor = 0xff999999; private static int boxFillColor = 0x55006699; @@ -246,6 +248,8 @@ public static void setupStyleConfig(Configuration cfg) { probeProgressColor = parseColor(cfg.getString("probeProgressColor", CATEGORY_CLIENT, Integer.toHexString(probeProgressColor), "Color of the progress bar (0 to disable)")); probeProgressAltColor = parseColor(cfg.getString("probeProgressAltColor", CATEGORY_CLIENT, Integer.toHexString(probeProgressAltColor), "Alt color of the progress bar (0 to disable)")); probeProgressBorderColor = parseColor(cfg.getString("probeProgressBorderColor", CATEGORY_CLIENT, Integer.toHexString(probeProgressBorderColor), "Color of the border of the progress bar (0 to disable)")); + probeProgressBackgroundColor = parseColor(cfg.getString("probeProgressBackgroundColor", CATEGORY_CLIENT, Integer.toHexString(probeProgressBackgroundColor), "Color of the background of the progress bar (0 to disable)")); + probeProgressGradient = cfg.getBoolean("probeProgressGradient", CATEGORY_CLIENT, probeProgressGradient, "Use a gradient instead of alternating colors in solid blocks"); chestContentsBorderColor = parseColor(cfg.getString("chestContentsBorderColor", CATEGORY_CLIENT, Integer.toHexString(chestContentsBorderColor), "Color of the border of the chest contents box (0 to disable)")); showBreakProgress = cfg.getInt("showBreakProgress", CATEGORY_CLIENT, showBreakProgress, 0, 2, "0 means don't show break progress, 1 is show as bar, 2 is show as text"); harvestStyleVanilla = cfg.getBoolean("harvestStyleVanilla", CATEGORY_CLIENT, harvestStyleVanilla, "true means shows harvestability with vanilla style icons"); diff --git a/src/main/java/mcjty/theoneprobe/gui/GuiConfig.java b/src/main/java/mcjty/theoneprobe/gui/GuiConfig.java index 2aabd78a..df79587f 100644 --- a/src/main/java/mcjty/theoneprobe/gui/GuiConfig.java +++ b/src/main/java/mcjty/theoneprobe/gui/GuiConfig.java @@ -218,8 +218,8 @@ private void renderElements(ProbeInfo probeInfo, IOverlayStyle style) { y += guiTop; double factor = (ConfigSetup.tooltipScale - 1) * 1.4 + 1; - x *= factor; - y *= factor; + x *= (int) factor; + y *= (int) factor; if (thick > 0) { int x2 = x + w - 1; diff --git a/src/main/java/mcjty/theoneprobe/playerdata/PropertiesDispatcher.java b/src/main/java/mcjty/theoneprobe/playerdata/PropertiesDispatcher.java index 8c0a75a4..af8bf32b 100644 --- a/src/main/java/mcjty/theoneprobe/playerdata/PropertiesDispatcher.java +++ b/src/main/java/mcjty/theoneprobe/playerdata/PropertiesDispatcher.java @@ -8,7 +8,7 @@ public class PropertiesDispatcher implements ICapabilityProvider, INBTSerializable { - private PlayerGotNote playerGotNote = new PlayerGotNote(); + private final PlayerGotNote playerGotNote = new PlayerGotNote(); @Override public boolean hasCapability(Capability capability, EnumFacing facing) { diff --git a/src/main/java/mcjty/theoneprobe/rendering/OverlayRenderer.java b/src/main/java/mcjty/theoneprobe/rendering/OverlayRenderer.java index 43cd1d22..49d2c7e5 100644 --- a/src/main/java/mcjty/theoneprobe/rendering/OverlayRenderer.java +++ b/src/main/java/mcjty/theoneprobe/rendering/OverlayRenderer.java @@ -207,7 +207,6 @@ private static void renderHUDEntity(ProbeMode mode, RayTraceResult mouseOver, do } } - UUID uuid = entity.getPersistentID(); EntityPlayerSP player = Minecraft.getMinecraft().player; long time = System.currentTimeMillis(); @@ -235,19 +234,18 @@ private static void renderHUDBlock(ProbeMode mode, RayTraceResult mouseOver, dou if (ConfigSetup.showBreakProgress > 0) { float damage = Minecraft.getMinecraft().playerController.curBlockDamageMP; if (damage > 0) { - boolean showText = ConfigSetup.showBreakProgressText; damageElement = ConfigSetup.showBreakProgress == 2 - ? new ElementText("" + TextFormatting.RED + I18n.format("theoneprobe.probe.progress_indicator") + " " + (int) (damage * 100) + "%") + ? new ElementText(TextFormatting.RED + I18n.format("theoneprobe.probe.progress_indicator") + " " + (int) (damage * 100) + "%") : new ElementProgress((long) (damage * 100), 100, new ProgressStyle() - .prefix(showText - ? I18n.format("theoneprobe.probe.progress_indicator") + " " - : " ") // If showText is false, skip the prefix + .prefix(I18n.format("theoneprobe.probe.progress_indicator") + " ") .suffix("%") .width(85) + .showText(ConfigSetup.showBreakProgressText) + .backgroundColor(ConfigSetup.probeProgressBackgroundColor) .borderColor(ConfigSetup.probeProgressBorderColor) .filledColor(ConfigSetup.probeProgressColor) - .alternateFilledColor(ConfigSetup.probeProgressAltColor)); + .alternateFilledColor(ConfigSetup.probeProgressAltColor), ConfigSetup.probeProgressGradient); } }