diff --git a/effects/src/main/java/sunsetsatellite/catalyst/effects/api/effect/render/heartContainer/HeartContainer.java b/effects/src/main/java/sunsetsatellite/catalyst/effects/api/effect/render/heartContainer/HeartContainer.java index 838d5cc..0f223f2 100644 --- a/effects/src/main/java/sunsetsatellite/catalyst/effects/api/effect/render/heartContainer/HeartContainer.java +++ b/effects/src/main/java/sunsetsatellite/catalyst/effects/api/effect/render/heartContainer/HeartContainer.java @@ -2,81 +2,81 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.gui.hud.HudIngame; +import net.minecraft.client.gui.Gui; import net.minecraft.client.render.texture.stitcher.TextureRegistry; import net.minecraft.core.entity.player.Player; @Environment(EnvType.CLIENT) public class HeartContainer { - public enum HeartGlyphVariant { - NONE(""), - HARDCORE("hardcore"), - PREVIEW("preview"), - OVERHEAL("overheal"); - - private final String name; - - HeartGlyphVariant(String colorName) { - this.name = colorName; - } - - public String getName() { - return name; - } - } - - public enum HeartGlyphType { - FULL("full"), - HALF("half"), - HALF_RIGHT("half_right"), - CONTAINER("container"); - - private final String name; - - HeartGlyphType(String colorName) { - this.name = colorName; - } - - public String getName() { - return name; - } - } - - protected final Player player; - - public HeartContainer(Player player) { - this.player = player; - } - - public String getBasePath() { - return "minecraft:gui/hud/heart/"; - } - - public String getPathForGlyph(HeartGlyphVariant glyphVariant, HeartGlyphType glyphType) { - if (glyphType == HeartGlyphType.CONTAINER) { - return getBasePath() + glyphType.name + (isHeartFlashing() ? "_blinking" : ""); - } - - String prefix = (glyphVariant != HeartGlyphVariant.NONE ? glyphVariant.name + "_" : ""); - return getBasePath() + prefix + glyphType.name + (isHeartFlashing() ? "_blinking" : ""); - } - - public void drawHeart(HeartGlyphVariant variant, HeartGlyphType glyphType, int x, int y, HudIngame hud) { - hud.drawGuiIcon(x, y, 9, 9, TextureRegistry.getTexture(getPathForGlyph(variant, glyphType))); - } - - public boolean isHeartFlashing() { - boolean heartsFlash = player.heartsFlashTime / 3 % 2 == 1; - if (player.heartsFlashTime < 10) { - heartsFlash = false; - } - - return heartsFlash; - } - - public boolean shouldShake() { - return player.getHealth() < 4 || isHeartFlashing(); - } + public enum HeartGlyphVariant { + NONE(""), + HARDCORE("hardcore"), + PREVIEW("preview"), + OVERHEAL("overheal"); + + private final String name; + + HeartGlyphVariant(String colorName) { + this.name = colorName; + } + + public String getName() { + return name; + } + } + + public enum HeartGlyphType { + FULL("full"), + HALF("half"), + HALF_RIGHT("half_right"), + CONTAINER("container"); + + private final String name; + + HeartGlyphType(String colorName) { + this.name = colorName; + } + + public String getName() { + return name; + } + } + + protected final Player player; + + public HeartContainer(Player player) { + this.player = player; + } + + public String getBasePath() { + return "minecraft:gui/hud/heart/"; + } + + public String getPathForGlyph(HeartGlyphVariant glyphVariant, HeartGlyphType glyphType) { + if (glyphType == HeartGlyphType.CONTAINER) { + return getBasePath() + glyphType.name + (isHeartFlashing() ? "_blinking" : ""); + } + + String prefix = (glyphVariant != HeartGlyphVariant.NONE ? glyphVariant.name + "_" : ""); + return getBasePath() + prefix + glyphType.name + (isHeartFlashing() ? "_blinking" : ""); + } + + public void drawHeart(HeartGlyphVariant variant, HeartGlyphType glyphType, int x, int y, Gui hud) { + hud.drawGuiIcon(x, y, 9, 9, TextureRegistry.getTexture(getPathForGlyph(variant, glyphType))); + } + + public boolean isHeartFlashing() { + boolean heartsFlash = player.heartsFlashTime / 3 % 2 == 1; + if (player.heartsFlashTime < 10) { + heartsFlash = false; + } + + return heartsFlash; + } + + public boolean shouldShake() { + return player.getHealth() < 4 || isHeartFlashing(); + } } diff --git a/effects/src/main/java/sunsetsatellite/catalyst/effects/mixin/HudComponentHealthBarMixin.java b/effects/src/main/java/sunsetsatellite/catalyst/effects/mixin/HudComponentHealthBarMixin.java index 672f253..89c36cd 100644 --- a/effects/src/main/java/sunsetsatellite/catalyst/effects/mixin/HudComponentHealthBarMixin.java +++ b/effects/src/main/java/sunsetsatellite/catalyst/effects/mixin/HudComponentHealthBarMixin.java @@ -1,6 +1,7 @@ package sunsetsatellite.catalyst.effects.mixin; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.hud.HudIngame; import net.minecraft.client.gui.hud.component.ComponentAnchor; import net.minecraft.client.gui.hud.component.HudComponentHealthBar; @@ -22,8 +23,8 @@ import sunsetsatellite.catalyst.effects.api.effect.render.EffectRenderer; import sunsetsatellite.catalyst.effects.api.effect.render.EffectRendererDispatcher; import sunsetsatellite.catalyst.effects.api.effect.render.EffectRendererManager; -import sunsetsatellite.catalyst.effects.api.effect.render.heartContainer.IHasCustomHeartContainer; import sunsetsatellite.catalyst.effects.api.effect.render.heartContainer.HeartContainer; +import sunsetsatellite.catalyst.effects.api.effect.render.heartContainer.IHasCustomHeartContainer; import sunsetsatellite.catalyst.effects.helper.HealthHelper; import sunsetsatellite.catalyst.effects.interfaces.mixins.IKeybinds; @@ -35,11 +36,6 @@ public abstract class HudComponentHealthBarMixin extends HudComponentMovable { @Unique Random random = new Random(); - @Unique - int iconWidth = 9; - @Unique - int iconHeight = 9; - @Unique int spacing = 1; @@ -49,15 +45,18 @@ public HudComponentHealthBarMixin(String key, int xSize, int ySize, Layout layou @Unique int getRows(Player player) { - return (int) Math.ceil((double) player.getMaxHealth() / 20); + return (int) Math.ceil(player.getMaxHealth() / 20.0); } @Override public int getYSize(Minecraft mc) { + if (mc.thePlayer == null) return super.getYSize(mc); + EffectExtraHealthDisplayStyle extraHealthDisplay = ((IKeybinds) mc.gameSettings).getExtraHealthDisplayStyle().value; if (extraHealthDisplay == EffectExtraHealthDisplayStyle.EXTRA_BARS) { - return iconHeight * getRows(mc.thePlayer) + spacing; + int rows = getRows(mc.thePlayer); + return 10 * rows; } return super.getYSize(mc); @@ -65,19 +64,20 @@ public int getYSize(Minecraft mc) { @Override public int getAnchorY(ComponentAnchor anchor) { - return (int) (anchor.yPosition * (float) this.getYSize(Minecraft.getMinecraft())); + return (int) (anchor.yPosition * this.getYSize(Minecraft.getMinecraft())); } @Inject(method = "render", at = @At("HEAD"), cancellable = true) public void render(Minecraft mc, HudIngame hud, int xSizeScreen, int ySizeScreen, float partialTick, CallbackInfo ci) { Player player = mc.thePlayer; + if (player == null) return; EffectStack stack = EffectRendererManager.resolveDominantHeartContainer(((IHasEffects) player).getContainer()); if (stack == null && getRows(player) == 1) return; - HeartContainer heartContainer = null; ci.cancel(); + HeartContainer heartContainer = null; if (stack != null) { EffectRenderer renderer = EffectRendererDispatcher.getRendererFor(stack.getEffect()); @@ -92,71 +92,60 @@ public void render(Minecraft mc, HudIngame hud, int xSizeScreen, int ySizeScreen int y = this.getLayout().getComponentY(mc, this, ySizeScreen); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GL11.glDisable(3042); + GL11.glDisable(GL11.GL_BLEND); - this.random.setSeed((long) hud.updateCounter * 312871L); + this.random.setSeed(hud.updateCounter * 312871L); - EffectExtraHealthDisplayStyle extraHealthDisplay = ((IKeybinds) mc.gameSettings).getExtraHealthDisplayStyle().value; + EffectExtraHealthDisplayStyle style = ((IKeybinds) mc.gameSettings).getExtraHealthDisplayStyle().value; - if (extraHealthDisplay == EffectExtraHealthDisplayStyle.EXTRA_BARS || getRows(player) == 1) { + if (style == EffectExtraHealthDisplayStyle.EXTRA_BARS || getRows(player) == 1) { drawExtraBars(mc, hud, player, heartContainer, x, y); - } - - else if (extraHealthDisplay == EffectExtraHealthDisplayStyle.MULTIPLIER) { + } else if (style == EffectExtraHealthDisplayStyle.MULTIPLIER) { drawNumberBar(mc, hud, player, heartContainer, x, y); } } @Unique - private void drawNumberBar(Minecraft mc, HudIngame hud, Player player, HeartContainer heartContainer, int x, int y) { + private void drawNumberBar(Minecraft mc, Gui hud, Player player, HeartContainer heartContainer, int x, int y) { float playerHealthPercent = (float) player.getHealth() / HealthHelper.getMaxHealth(player); int extraHearts = HealthHelper.getMaxHealth(player) / 2; final int heartsToRender = 8; - drawRow( - mc, hud, player, - heartContainer, - heartsToRender, - (int) (playerHealthPercent * (heartsToRender * 2)), - x, y - ); + drawRow(mc, hud, player, heartContainer, heartsToRender, (int) (playerHealthPercent * (heartsToRender * 2)), x, y); - hud.drawString( - mc.font, + hud.drawString(mc.font, String.format("+%s", extraHearts), - x + 3 * spacing + (heartsToRender - 1) * iconWidth, + x + 3 * spacing + (heartsToRender - 1) * 8, y + (heartContainer.shouldShake() ? this.random.nextInt(2) : 0), DyeColor.WHITE.color.value ); } @Unique - public void drawExtraBars(Minecraft mc, HudIngame hud, Player player, HeartContainer heartContainer, int x, int y) { - int health = player.getHealth(); - - GL11.glTranslated(0, 0, 0.01 * getRows(player)); - for (int barCount = 0; barCount < getRows(player); barCount++) { - int totalHealth = HealthHelper.getMaxHealth(player); + public void drawExtraBars(Minecraft mc, Gui hud, Player player, HeartContainer heartContainer, int x, int y) { + int totalHealth = HealthHelper.getMaxHealth(player); + int rows = getRows(player); - int healthInRow = Math.min(totalHealth - barCount * 20, 20); + for (int row = 0; row < rows; row++) { + int healthInRow = Math.min(totalHealth - row * 20, 20); int heartsToRender = (healthInRow + 1) / 2; if (heartsToRender == 0) continue; - int healthInCurrentRow = health - barCount * 20; - GL11.glTranslated(0, 0, -0.01 * barCount); + int healthInCurrentRow = Math.max(0, player.getHealth() - row * 20); + + int rowY = y + this.getYSize(mc) - 10 - (row * 10); - int rowY = y - (iconHeight * barCount) + this.getYSize(mc) - iconHeight - spacing; drawRow(mc, hud, player, heartContainer, heartsToRender, healthInCurrentRow, x, rowY); } } @Unique - public void drawRow(Minecraft mc, HudIngame hud, Player player, HeartContainer heartContainer, int heartsToRender, int healthInCurrentRow, int x, int y) { + public void drawRow(Minecraft mc, Gui hud, Player player, HeartContainer heartContainer, int heartsToRender, int healthInCurrentRow, int x, int y) { HeartContainer.HeartGlyphVariant glyphVariant = player.getGamemode() == Gamemode.hardcore ? HeartContainer.HeartGlyphVariant.HARDCORE : HeartContainer.HeartGlyphVariant.NONE; - for (int i = 0; i < heartsToRender; ++i) { + for (int i = 0; i < heartsToRender; i++) { int xHeart = x + i * 8; int yHeart = y; @@ -168,29 +157,88 @@ public void drawRow(Minecraft mc, HudIngame hud, Player player, HeartContainer h heartContainer.drawHeart(glyphVariant, HeartContainer.HeartGlyphType.CONTAINER, xHeart, yHeart, hud); - if (currentHeart < healthInCurrentRow) + if (currentHeart < healthInCurrentRow) { heartContainer.drawHeart(glyphVariant, HeartContainer.HeartGlyphType.FULL, xHeart, yHeart, hud); + } - if (currentHeart == healthInCurrentRow) + if (currentHeart == healthInCurrentRow) { heartContainer.drawHeart(glyphVariant, HeartContainer.HeartGlyphType.HALF, xHeart, yHeart, hud); + } if (player.inventory.getCurrentItem() != null && player.inventory.getCurrentItem().getItem() instanceof ItemFood - && mc.gameSettings.foodHealthRegenOverlay.value - ) { + && Boolean.TRUE.equals(mc.gameSettings.foodHealthRegenOverlay.value)) { + int healing = ((ItemFood) player.inventory.getCurrentItem().getItem()).getHealAmount(); - if (currentHeart < healthInCurrentRow) continue; + if (currentHeart >= healthInCurrentRow) { + if (currentHeart == healthInCurrentRow) { + heartContainer.drawHeart(HeartContainer.HeartGlyphVariant.PREVIEW, HeartContainer.HeartGlyphType.HALF_RIGHT, xHeart, yHeart, hud); + } else if (currentHeart < healthInCurrentRow + healing) { + heartContainer.drawHeart(HeartContainer.HeartGlyphVariant.PREVIEW, HeartContainer.HeartGlyphType.FULL, xHeart, yHeart, hud); + } else if (currentHeart == healthInCurrentRow + healing) { + heartContainer.drawHeart(HeartContainer.HeartGlyphVariant.PREVIEW, HeartContainer.HeartGlyphType.HALF, xHeart, yHeart, hud); + } + } + } + } + } + + @Inject(method = "renderPreview", at = @At("HEAD"), cancellable = true) + public void renderPreview(Minecraft mc, Gui gui, Layout layout, int xSizeScreen, int ySizeScreen, CallbackInfo ci) { + Player player = mc.thePlayer; + if (player == null) return; - if (currentHeart == healthInCurrentRow) - heartContainer.drawHeart(HeartContainer.HeartGlyphVariant.PREVIEW, HeartContainer.HeartGlyphType.HALF_RIGHT, xHeart, yHeart, hud); + EffectStack stack = EffectRendererManager.resolveDominantHeartContainer(((IHasEffects) player).getContainer()); + if (stack == null && getRows(player) == 1) return; - else if (currentHeart < healthInCurrentRow + healing) - heartContainer.drawHeart(HeartContainer.HeartGlyphVariant.PREVIEW, HeartContainer.HeartGlyphType.FULL, xHeart, yHeart, hud); + ci.cancel(); - else if (currentHeart == healthInCurrentRow + healing) - heartContainer.drawHeart(HeartContainer.HeartGlyphVariant.PREVIEW, HeartContainer.HeartGlyphType.HALF, xHeart, yHeart, hud); + int x = layout.getComponentX(mc, this, xSizeScreen); + int y = layout.getComponentY(mc, this, ySizeScreen); + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(GL11.GL_BLEND); + + final int previewHealth = 21; + final int rows = 2; + final int previewYSize = 10 * rows; + + for (int row = 0; row < rows; row++) { + int healthInRow = 20; + int heartsToRender = (healthInRow + 1) / 2; + + int healthInCurrentRow = Math.max(0, previewHealth - row * 20); + int rowY = y + previewYSize - 10 - (row * 10); + + Player previewPlayer = mc.thePlayer; + HeartContainer previewHeartContainer = new HeartContainer(previewPlayer); + + drawRowPreview(gui, previewPlayer, previewHeartContainer, heartsToRender, healthInCurrentRow, x, rowY); + } + } + + @Unique + private void drawRowPreview(Gui gui, Player player, HeartContainer heartContainer, int heartsToRender, int healthInCurrentRow, int x, int y) { + HeartContainer.HeartGlyphVariant glyphVariant = player.getGamemode() == Gamemode.hardcore + ? HeartContainer.HeartGlyphVariant.HARDCORE + : HeartContainer.HeartGlyphVariant.NONE; + + for (int i = 0; i < heartsToRender; i++) { + int xHeart = x + i * 8; + + int currentHeart = i * 2 + 1; + + heartContainer.drawHeart(glyphVariant, HeartContainer.HeartGlyphType.CONTAINER, xHeart, y, gui); + + if (currentHeart < healthInCurrentRow) { + heartContainer.drawHeart(glyphVariant, HeartContainer.HeartGlyphType.FULL, xHeart, y, gui); + } + + if (currentHeart == healthInCurrentRow) { + heartContainer.drawHeart(glyphVariant, HeartContainer.HeartGlyphType.HALF, xHeart, y, gui); } } } + }