From 44a9955fa559a671f7444f96c4acd5f7974a1fd3 Mon Sep 17 00:00:00 2001 From: wbc3467-spec Date: Thu, 4 Dec 2025 09:28:27 +0000 Subject: [PATCH 1/3] Fixed entity reloading error, issues/82, by changing the primiry var of barStatus to entity id instead of entity reference --- .../torocraft/torohealth/bars/BarState.java | 147 ++++++++++-------- .../torocraft/torohealth/bars/BarStates.java | 2 +- 2 files changed, 85 insertions(+), 64 deletions(-) diff --git a/src/main/java/net/torocraft/torohealth/bars/BarState.java b/src/main/java/net/torocraft/torohealth/bars/BarState.java index d706697c..b9c264e7 100644 --- a/src/main/java/net/torocraft/torohealth/bars/BarState.java +++ b/src/main/java/net/torocraft/torohealth/bars/BarState.java @@ -1,85 +1,106 @@ package net.torocraft.torohealth.bars; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.Entity; import net.minecraft.util.math.MathHelper; +import net.minecraft.client.MinecraftClient; import net.torocraft.torohealth.ToroHealth; public class BarState { - public final LivingEntity entity; - - public float health; - public float previousHealth; - public float previousHealthDisplay; - public float previousHealthDelay; - public int lastDmg; - public int lastDmgCumulative; - public float lastHealth; - public float lastDmgDelay; - private float animationSpeed = 0; + public final Integer entityID; + + public float health; + public float previousHealthDisplay; + public float previousHealthDelay; + public int lastDmg; + public int lastDmgCumulative; + public float lastHealth; + public float lastDmgDelay; + private float animationSpeed; + + private static final float HEALTH_INDICATOR_DELAY = 10; + + + + public BarState(Integer id) { + MinecraftClient client = MinecraftClient.getInstance(); + Entity entity = client.world != null ? client.world.getEntityById(id) : null; + if (entity instanceof LivingEntity living) { + this.entityID = id; + health = Math.min(living.getHealth(), living.getMaxHealth()); + previousHealthDisplay = health; + lastDmg = 0; + lastDmgCumulative = 0; + lastHealth = health; + lastDmgDelay = 0; + animationSpeed = 0; + } else { + this.entityID = null; // will be ignored + } + } - private static final float HEALTH_INDICATOR_DELAY = 10; + public void tick() { + MinecraftClient client = MinecraftClient.getInstance(); + LivingEntity entity = (LivingEntity) client.world.getEntityById(entityID); - public BarState(LivingEntity entity) { - this.entity = entity; - } + if (entity != null){ + health = Math.min(entity.getHealth(), entity.getMaxHealth()); + incrementTimers(); - public void tick() { - health = Math.min(entity.getHealth(), entity.getMaxHealth()); - incrementTimers(); + if (lastHealth < 0.1) { + reset(); - if (lastHealth < 0.1) { - reset(); + } else if (lastHealth != health) { + handleHealthChange(); - } else if (lastHealth != health) { - handleHealthChange(); + } else if (lastDmgDelay == 0.0F) { + reset(); + } - } else if (lastDmgDelay == 0.0F) { - reset(); + updateAnimations(); + } } - updateAnimations(); - } - - private void reset() { - lastHealth = health; - lastDmg = 0; - lastDmgCumulative = 0; - } - - private void incrementTimers() { - if (this.lastDmgDelay > 0) { - this.lastDmgDelay--; + private void reset() { + lastHealth = health; + lastDmg = 0; + lastDmgCumulative = 0; } - if (this.previousHealthDelay > 0) { - this.previousHealthDelay--; - } - } - - private void handleHealthChange() { - lastDmg = MathHelper.ceil(lastHealth) - MathHelper.ceil(health); - lastDmgCumulative += lastDmg; - lastDmgDelay = HEALTH_INDICATOR_DELAY * 2; - lastHealth = health; - if (ToroHealth.CONFIG.particle.show) { - BarStates.PARTICLES.add(new BarParticle(entity, lastDmg)); + private void incrementTimers() { + if (this.lastDmgDelay > 0) { + this.lastDmgDelay--; + } + if (this.previousHealthDelay > 0) { + this.previousHealthDelay--; + } } - } - - private void updateAnimations() { - if (previousHealthDelay > 0) { - float diff = previousHealthDisplay - health; - if (diff > 0) { - animationSpeed = diff / 10f; - } - } else if (previousHealthDelay < 1 && previousHealthDisplay > health) { - previousHealthDisplay -= animationSpeed; - } else { - previousHealthDisplay = health; - previousHealth = health; - previousHealthDelay = HEALTH_INDICATOR_DELAY; + + private void handleHealthChange() { + lastDmg = MathHelper.ceil(lastHealth) - MathHelper.ceil(health); + lastDmgCumulative += lastDmg; + + lastDmgDelay = HEALTH_INDICATOR_DELAY * 2; + lastHealth = health; + if (ToroHealth.CONFIG.particle.show) { + MinecraftClient client = MinecraftClient.getInstance(); + LivingEntity entity = (LivingEntity) client.world.getEntityById(entityID); + BarStates.PARTICLES.add(new BarParticle(entity, lastDmg)); + } } - } + private void updateAnimations() { + if (previousHealthDelay > 0) { + float diff = previousHealthDisplay - health; + if (diff > 0) { + animationSpeed = diff / 10f; + } + } else if (previousHealthDelay < 1 && previousHealthDisplay > health) { + previousHealthDisplay -= animationSpeed; + } else { + previousHealthDisplay = health; + previousHealthDelay = HEALTH_INDICATOR_DELAY; + } + } } diff --git a/src/main/java/net/torocraft/torohealth/bars/BarStates.java b/src/main/java/net/torocraft/torohealth/bars/BarStates.java index 77a62b6a..476da9af 100644 --- a/src/main/java/net/torocraft/torohealth/bars/BarStates.java +++ b/src/main/java/net/torocraft/torohealth/bars/BarStates.java @@ -18,7 +18,7 @@ public static BarState getState(LivingEntity entity) { int id = entity.getId(); BarState state = STATES.get(id); if (state == null) { - state = new BarState(entity); + state = new BarState(id); STATES.put(id, state); } return state; From e55bbfa484e0dce14130c9fbc4547069f6192b15 Mon Sep 17 00:00:00 2001 From: wbc3467-spec Date: Sun, 7 Dec 2025 11:36:14 +0000 Subject: [PATCH 2/3] BugFix: solved the crash caused by ticking null Barstate - added safer method to add new BarStates - added simple exception handler --- .../torocraft/torohealth/bars/BarState.java | 35 ++++++++++++------- .../torocraft/torohealth/bars/BarStates.java | 3 +- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/main/java/net/torocraft/torohealth/bars/BarState.java b/src/main/java/net/torocraft/torohealth/bars/BarState.java index b9c264e7..29b136f3 100644 --- a/src/main/java/net/torocraft/torohealth/bars/BarState.java +++ b/src/main/java/net/torocraft/torohealth/bars/BarState.java @@ -22,26 +22,32 @@ public class BarState { private static final float HEALTH_INDICATOR_DELAY = 10; + private BarState(Integer id, float health){ + this.entityID = id; + this.health = health; + this.previousHealthDisplay = health; + this.lastDmg = 0; + this.lastDmgCumulative = 0; + this.lastHealth = health; + this.lastDmgDelay = 0; + this.animationSpeed = 0; + } - public BarState(Integer id) { + public static BarState create(Integer id){ MinecraftClient client = MinecraftClient.getInstance(); - Entity entity = client.world != null ? client.world.getEntityById(id) : null; + assert client.world != null; + Entity entity = client.world.getEntityById(id); if (entity instanceof LivingEntity living) { - this.entityID = id; - health = Math.min(living.getHealth(), living.getMaxHealth()); - previousHealthDisplay = health; - lastDmg = 0; - lastDmgCumulative = 0; - lastHealth = health; - lastDmgDelay = 0; - animationSpeed = 0; - } else { - this.entityID = null; // will be ignored + float currentHealth = Math.min(living.getHealth(), living.getMaxHealth()); + return new BarState(id, currentHealth); } + return null; } + public void tick() { MinecraftClient client = MinecraftClient.getInstance(); + assert client.world != null; LivingEntity entity = (LivingEntity) client.world.getEntityById(entityID); if (entity != null){ @@ -85,8 +91,11 @@ private void handleHealthChange() { lastHealth = health; if (ToroHealth.CONFIG.particle.show) { MinecraftClient client = MinecraftClient.getInstance(); + assert client.world != null; LivingEntity entity = (LivingEntity) client.world.getEntityById(entityID); - BarStates.PARTICLES.add(new BarParticle(entity, lastDmg)); + if (entity != null) { + BarStates.PARTICLES.add(new BarParticle(entity, lastDmg)); + } } } diff --git a/src/main/java/net/torocraft/torohealth/bars/BarStates.java b/src/main/java/net/torocraft/torohealth/bars/BarStates.java index 476da9af..f549dae7 100644 --- a/src/main/java/net/torocraft/torohealth/bars/BarStates.java +++ b/src/main/java/net/torocraft/torohealth/bars/BarStates.java @@ -18,7 +18,7 @@ public static BarState getState(LivingEntity entity) { int id = entity.getId(); BarState state = STATES.get(id); if (state == null) { - state = new BarState(id); + state = BarState.create(id); STATES.put(id, state); } return state; @@ -49,6 +49,7 @@ private static boolean stateExpired(Map.Entry entry) { } MinecraftClient minecraft = MinecraftClient.getInstance(); + assert minecraft.world != null; Entity entity = minecraft.world.getEntityById(entry.getKey()); if (!(entity instanceof LivingEntity)) { From 9cc7317e37c5bc93b4ad08aeeb6883757dbd2285 Mon Sep 17 00:00:00 2001 From: wbc3467-spec Date: Sun, 7 Dec 2025 20:03:53 +0000 Subject: [PATCH 3/3] Bugfix: fixed crash caused by returning null state --- src/main/java/net/torocraft/torohealth/bars/BarStates.java | 4 +++- .../java/net/torocraft/torohealth/bars/HealthBarRenderer.java | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/torocraft/torohealth/bars/BarStates.java b/src/main/java/net/torocraft/torohealth/bars/BarStates.java index f549dae7..2be28a66 100644 --- a/src/main/java/net/torocraft/torohealth/bars/BarStates.java +++ b/src/main/java/net/torocraft/torohealth/bars/BarStates.java @@ -19,7 +19,9 @@ public static BarState getState(LivingEntity entity) { BarState state = STATES.get(id); if (state == null) { state = BarState.create(id); - STATES.put(id, state); + if (state != null) { + STATES.put(id, state); + } } return state; } diff --git a/src/main/java/net/torocraft/torohealth/bars/HealthBarRenderer.java b/src/main/java/net/torocraft/torohealth/bars/HealthBarRenderer.java index 10ec0cac..94782c03 100644 --- a/src/main/java/net/torocraft/torohealth/bars/HealthBarRenderer.java +++ b/src/main/java/net/torocraft/torohealth/bars/HealthBarRenderer.java @@ -135,6 +135,9 @@ public static void render(MatrixStack matrix, LivingEntity entity, double x, dou : ToroHealth.CONFIG.bar.foeColorSecondary; BarState state = BarStates.getState(entity); + if (state == null) { + return; + } float percent = Math.min(1, Math.min(state.health, entity.getMaxHealth()) / entity.getMaxHealth()); float percent2 = Math.min(state.previousHealthDisplay, entity.getMaxHealth()) / entity.getMaxHealth();