From 7670c8c95899c8fe9bca5b8e08ebdaeae02cfe45 Mon Sep 17 00:00:00 2001 From: Provismet <17149901+Provismet@users.noreply.github.com> Date: Mon, 26 Feb 2024 05:08:37 +0000 Subject: [PATCH 1/4] Make text particles resize smoothly. --- .../provismet/provihealth/particle/TextParticle.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/provismet/provihealth/particle/TextParticle.java b/src/main/java/com/provismet/provihealth/particle/TextParticle.java index a0ac839..3264a1a 100644 --- a/src/main/java/com/provismet/provihealth/particle/TextParticle.java +++ b/src/main/java/com/provismet/provihealth/particle/TextParticle.java @@ -12,6 +12,7 @@ import net.minecraft.client.particle.SpriteProvider; import net.minecraft.client.render.LightmapTextureManager; import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; public class TextParticle extends SpriteBillboardParticle { @@ -20,6 +21,8 @@ public class TextParticle extends SpriteBillboardParticle { private final float maxScale; private final int textColour; + private float prevScale; + @SuppressWarnings("resource") protected TextParticle (ClientWorld clientWorld, double x, double y, double z, TextParticleEffect particleEffect) { super(clientWorld, x, y, z); @@ -28,6 +31,7 @@ protected TextParticle (ClientWorld clientWorld, double x, double y, double z, T this.green = particleEffect.getColour().y(); this.blue = particleEffect.getColour().z(); this.scale = 0f; + this.prevScale = 0f; this.alpha = particleEffect.alpha; this.textColour = particleEffect.textColour; this.text = particleEffect.text; @@ -75,6 +79,7 @@ protected TextParticle (ClientWorld clientWorld, double x, double y, double z, T @Override public void tick () { super.tick(); + this.prevScale = this.scale; if (this.age > this.maxAge / 2) this.scale -= this.maxScale / (this.maxAge / 2f); else if (this.scale < this.maxScale) this.scale += this.maxScale / 5f; @@ -110,6 +115,11 @@ public int getColour () { return this.textColour; } + @Override + public float getSize (float tickDelta) { + return MathHelper.lerp(tickDelta, this.prevScale, this.scale); + } + public Vec3d getPos () { return new Vec3d(this.x, this.y, this.z); } From 2d41067d7099dae5ab75438b5f781b933f01764b Mon Sep 17 00:00:00 2001 From: Provismet <17149901+Provismet@users.noreply.github.com> Date: Mon, 26 Feb 2024 05:13:45 +0000 Subject: [PATCH 2/4] Fix paperdoll compatibility issue #18 --- .../compat/ProviHealthConfigScreen.java | 7 ++ .../provismet/provihealth/config/Options.java | 17 ++++ .../provihealth/hud/TargetHealthBar.java | 97 +++++++++++-------- .../assets/provihealth/lang/en_us.json | 5 + 4 files changed, 88 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/provismet/provihealth/compat/ProviHealthConfigScreen.java b/src/main/java/com/provismet/provihealth/compat/ProviHealthConfigScreen.java index dacc09b..0ff7bc7 100644 --- a/src/main/java/com/provismet/provihealth/compat/ProviHealthConfigScreen.java +++ b/src/main/java/com/provismet/provihealth/compat/ProviHealthConfigScreen.java @@ -2,6 +2,7 @@ import com.provismet.provihealth.config.Options; import com.provismet.provihealth.config.Options.DamageParticleType; +import com.provismet.provihealth.config.Options.HUDPortraitCompatMode; import com.provismet.provihealth.config.Options.HUDPosition; import com.provismet.provihealth.config.Options.HUDType; import com.provismet.provihealth.config.Options.SeeThroughText; @@ -365,6 +366,12 @@ public static Screen build (Screen parent) { .build() ); + compatibility.addEntry(entryBuilder.startEnumSelector(Text.translatable("entry.provihealth.compatHud"), HUDPortraitCompatMode.class, Options.HUDCompat) + .setDefaultValue(HUDPortraitCompatMode.STANDARD) + .setSaveConsumer(newValue -> Options.HUDCompat = newValue) + .build() + ); + builder.setSavingRunnable(Options::save); return builder.build(); } diff --git a/src/main/java/com/provismet/provihealth/config/Options.java b/src/main/java/com/provismet/provihealth/config/Options.java index aa8774c..4d8ad43 100644 --- a/src/main/java/com/provismet/provihealth/config/Options.java +++ b/src/main/java/com/provismet/provihealth/config/Options.java @@ -89,6 +89,7 @@ public class Options { public static SeeThroughText seeThroughTextType = SeeThroughText.STANDARD; public static boolean compatInWorld = false; public static boolean compatInHUD = false; + public static HUDPortraitCompatMode HUDCompat = HUDPortraitCompatMode.STANDARD; @SuppressWarnings("resource") public static boolean shouldRenderHealthFor (LivingEntity livingEntity) { @@ -181,6 +182,7 @@ public static void save () { .append("maxParticleDistance", maxParticleDistance).newLine() .append("topLayerTextType", seeThroughTextType.name()).newLine() .append("compatWorldBar", compatInWorld).newLine() + .append("compatHudPaperdoll", HUDCompat.name()).newLine() .createArray("healthBlacklist", blacklist).newLine() .createArray("hudBlacklist", blacklistHUD).newLine(false) .closeObject() @@ -392,6 +394,10 @@ public static void load () { compatInWorld = parser.nextBoolean(); break; + case "compatHudPaperdoll": + HUDCompat = HUDPortraitCompatMode.valueOf(parser.nextString()); + break; + case "healthBlacklist": ArrayList tempBlacklist = new ArrayList<>(); parser.beginArray(); @@ -514,4 +520,15 @@ public String toString () { return "enum.provihealth.seethroughtext." + super.toString().toLowerCase(); } } + + public static enum HUDPortraitCompatMode { + STANDARD, + COMPAT, + NONE; + + @Override + public String toString () { + return "enum.provihealth.hudportraitcompatmode." + super.toString().toLowerCase(); + } + } } diff --git a/src/main/java/com/provismet/provihealth/hud/TargetHealthBar.java b/src/main/java/com/provismet/provihealth/hud/TargetHealthBar.java index 7979ab1..7d87b7a 100644 --- a/src/main/java/com/provismet/provihealth/hud/TargetHealthBar.java +++ b/src/main/java/com/provismet/provihealth/hud/TargetHealthBar.java @@ -8,6 +8,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.provismet.provihealth.ProviHealthClient; import com.provismet.provihealth.config.Options; +import com.provismet.provihealth.config.Options.HUDPortraitCompatMode; import com.provismet.provihealth.config.Options.HUDPosition; import com.provismet.provihealth.config.Options.HUDType; import com.provismet.provihealth.util.Visibility; @@ -172,45 +173,65 @@ public void onHudRender (DrawContext drawContext, float tickDelta) { } // Render Paper Doll - float prevTargetHeadYaw = this.target.getHeadYaw(); - float prevPrevTargetHeadYaw = this.target.prevHeadYaw; - float prevTargetBodyYaw = this.target.getBodyYaw(); - float prevPrevTargetBodyYaw = this.target.prevBodyYaw; - float prevTargetYaw = this.target.getYaw(); - - float headBodyYawDifference = this.target.getHeadYaw() - this.target.getBodyYaw(); - - this.target.setYaw(Options.hudPosition.portraitYAW); - this.target.setBodyYaw(this.target.getYaw()); - this.target.prevBodyYaw = this.target.getYaw(); - this.target.setHeadYaw(this.target.getYaw() + headBodyYawDifference); - this.target.prevHeadYaw = this.target.getYaw() + headBodyYawDifference; - - float renderHeight; - if (this.target.getEyeHeight(EntityPose.STANDING) >= this.target.getHeight() * 0.6) { - renderHeight = this.target.getEyeHeight(this.target.getPose()) + 0.5f; - if (renderHeight < 1f) renderHeight = 1f; + if (Options.HUDCompat == HUDPortraitCompatMode.STANDARD) { + float prevTargetHeadYaw = this.target.headYaw; + float prevPrevTargetHeadYaw = this.target.prevHeadYaw; + float prevTargetBodyYaw = this.target.bodyYaw; + float prevPrevTargetBodyYaw = this.target.prevBodyYaw; + + this.target.bodyYaw = Options.hudPosition.portraitYAW; + this.target.prevBodyYaw = Options.hudPosition.portraitYAW; + this.target.headYaw = Options.hudPosition.portraitYAW; + this.target.prevHeadYaw = Options.hudPosition.portraitYAW; + + float renderHeight; + if (this.target.getEyeHeight(EntityPose.STANDING) >= this.target.getHeight() * 0.6) { + renderHeight = this.target.getEyeHeight(this.target.getPose()) + 0.5f; + if (renderHeight < 1f) renderHeight = 1f; + } + else renderHeight = this.target.getEyeHeight(this.target.getPose()) + 0.8f; + + drawContext.enableScissor(OFFSET_X, OFFSET_Y, OFFSET_X + FRAME_LENGTH, OFFSET_Y + FRAME_LENGTH); + EntityHealthBar.enabled = false; + disabledLabels = true; + this.drawEntity(drawContext, 24 + OFFSET_X, OFFSET_Y, 30, + new Vector3f(0f, renderHeight, 0f), + (new Quaternionf()).rotateZ(3.1415927f), + null, + this.target + ); + EntityHealthBar.enabled = true; + disabledLabels = false; + drawContext.disableScissor(); + + this.target.headYaw = prevTargetHeadYaw; + this.target.prevHeadYaw = prevPrevTargetHeadYaw; + this.target.bodyYaw = prevTargetBodyYaw; + this.target.prevBodyYaw = prevPrevTargetBodyYaw; + } + else if (Options.HUDCompat == HUDPortraitCompatMode.COMPAT) { + float yawOffset = -(Options.hudPosition.portraitYAW - this.target.getBodyYaw()) / MathHelper.DEGREES_PER_RADIAN; + + float renderHeight; + if (this.target.getEyeHeight(EntityPose.STANDING) >= this.target.getHeight() * 0.6) { + renderHeight = this.target.getEyeHeight(this.target.getPose()) + 0.5f; + if (renderHeight < 1f) renderHeight = 1f; + } + else renderHeight = this.target.getEyeHeight(this.target.getPose()) + 0.8f; + + drawContext.enableScissor(OFFSET_X, OFFSET_Y, OFFSET_X + FRAME_LENGTH, OFFSET_Y + FRAME_LENGTH); + EntityHealthBar.enabled = false; + disabledLabels = true; + this.drawEntity(drawContext, 24 + OFFSET_X, OFFSET_Y, 30, + new Vector3f(0f, renderHeight, 0f), + (new Quaternionf()).rotateZ(3.1415927f).rotateY(yawOffset), + null, + this.target + ); + EntityHealthBar.enabled = true; + disabledLabels = false; + drawContext.disableScissor(); } - else renderHeight = this.target.getEyeHeight(this.target.getPose()) + 0.8f; - - drawContext.enableScissor(OFFSET_X, OFFSET_Y, OFFSET_X + FRAME_LENGTH, OFFSET_Y + FRAME_LENGTH); - EntityHealthBar.enabled = false; - disabledLabels = true; - this.drawEntity(drawContext, 24 + OFFSET_X, OFFSET_Y, 30, - new Vector3f(0f, renderHeight, 0f), - (new Quaternionf()).rotateZ(3.1415927f), - null, - this.target - ); - EntityHealthBar.enabled = true; - disabledLabels = false; - drawContext.disableScissor(); - - this.target.setHeadYaw(prevTargetHeadYaw); - this.target.prevHeadYaw = prevPrevTargetHeadYaw; - this.target.setBodyYaw(prevTargetBodyYaw); - this.target.prevBodyYaw = prevPrevTargetBodyYaw; - this.target.setYaw(prevTargetYaw); } } } diff --git a/src/main/resources/assets/provihealth/lang/en_us.json b/src/main/resources/assets/provihealth/lang/en_us.json index 76a378b..adeeef0 100644 --- a/src/main/resources/assets/provihealth/lang/en_us.json +++ b/src/main/resources/assets/provihealth/lang/en_us.json @@ -48,6 +48,7 @@ "entry.provihealth.worldOffsetY": "Health Bar Offset Y", "entry.provihealth.damageAlpha": "Damage Particle Alpha", "entry.provihealth.healingAlpha": "Healing Particle Alpha", + "entry.provihealth.compatHud": "HUD Paperdoll Render Mode", "enum.provihealth.full": "Full", "enum.provihealth.portrait_only": "Portrait Only", @@ -68,6 +69,10 @@ "enum.provihealth.seethroughtext.none": "Normal Text/Shadows", "enum.provihealth.seethroughtext.full": "SeeThrough Text/Shadows", + "enum.provihealth.hudportraitcompatmode.standard": "Standard", + "enum.provihealth.hudportraitcompatmode.compat": "Compatibility", + "enum.provihealth.hudportraitcompatmode.none": "None", + "tooltip.provihealth.hudDuration": "How many ticks the HUD display will linger for when not targeting a mob.", "tooltip.provihealth.targetOverride": "Always render health bar when targeting a mob of this type.", "tooltip.provihealth.glide": "Determines how quickly the health bar will slide from its old value to new values.\nWarning: Very low values will prevent the health bar visual from catching up with the true value.", From 47e7c188ed71c57758a81fe90edd2e8c56d7b8cd Mon Sep 17 00:00:00 2001 From: Provismet <17149901+Provismet@users.noreply.github.com> Date: Mon, 26 Feb 2024 05:13:54 +0000 Subject: [PATCH 3/4] Bump version number. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 688d965..2f1fb7b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ yarn_mappings=1.20.2+build.1 loader_version=0.15.6 # Mod Properties -mod_version=1.2.3 +mod_version=1.2.4 maven_group=com.provismet archives_base_name=provihealth From 268b784398a04d00110c83c2ff052473500850ed Mon Sep 17 00:00:00 2001 From: Provismet <17149901+Provismet@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:51:39 +0000 Subject: [PATCH 4/4] Fix mount health bar weirdness. The in-world mount health bar was compressing weirdly. The numbers have been adjusted so this works now. --- .../provismet/provihealth/world/EntityHealthBar.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/provismet/provihealth/world/EntityHealthBar.java b/src/main/java/com/provismet/provihealth/world/EntityHealthBar.java index 4420cd5..41584a9 100644 --- a/src/main/java/com/provismet/provihealth/world/EntityHealthBar.java +++ b/src/main/java/com/provismet/provihealth/world/EntityHealthBar.java @@ -35,7 +35,6 @@ public class EntityHealthBar { private static final Identifier BARS = ProviHealthClient.identifier("textures/gui/healthbars/in_world.png"); private static final Identifier COMPAT_BARS = ProviHealthClient.identifier("textures/gui/healthbars/in_world_coloured.png"); private static final float TEXTURE_SIZE = 64; - private static final float MOUNT_BAR_PIXEL_LENGTH = 58; public static boolean enabled = true; @@ -163,15 +162,17 @@ private static Text getName (LivingEntity entity) { } private static void renderBar (Matrix4f model, VertexConsumer vertexConsumer, int index, float percentage, boolean isMount) { + if (isMount) percentage = MathHelper.lerp(percentage, 3f / TEXTURE_SIZE, 61f / TEXTURE_SIZE); + // All U and V values are a percentage. - final float MIN_U = isMount ? 3f / TEXTURE_SIZE : 0f; // Leftmost pixel + final float MIN_U = 0f; // Leftmost pixel final float MIN_V = ((index * 12f) / TEXTURE_SIZE) + (isMount ? 7f / TEXTURE_SIZE : 0f); // Topmost pixel - final float MAX_U = percentage * (isMount ? 61f / TEXTURE_SIZE : 1f); // Leftmost pixel + final float MAX_U = percentage; // Rightmost pixel final float MAX_V = MIN_V + (isMount ? 5f : 7f) / TEXTURE_SIZE; // Bottommost pixel // X and Y are block coordinates relative to the matrix shenanigans. - final float MIN_X = isMount ? 0.5f * (MOUNT_BAR_PIXEL_LENGTH / TEXTURE_SIZE) : 0.5f; // Pushes the bar half a block to the left, centering it. - final float MAX_X = MIN_X - percentage * (isMount ? MOUNT_BAR_PIXEL_LENGTH / TEXTURE_SIZE : 1f); + final float MIN_X = 0.5f; // Pushes the bar half a block to the left, centering it. + final float MAX_X = MIN_X - percentage; final float MIN_Y = 0f; final float MAX_Y = -1f * ((isMount ? 5f : 7f) / TEXTURE_SIZE); // Mount bar is 5 pixels tall, Health bar is 7 pixels tall.