More accurate NPC hp overlay when max hp is known (#5528)

Closes #58
Closes #2509 

Co-authored-by: henke96 <henke96@bredband.net>
This commit is contained in:
Ron Young
2018-10-05 05:09:29 -05:00
committed by Tomas Slusny
parent 7c4e53d9ae
commit f5d8c26813

View File

@@ -61,7 +61,8 @@ class OpponentInfoOverlay extends Overlay
private final PanelComponent panelComponent = new PanelComponent();
private Integer lastMaxHealth;
private float lastRatio = 0;
private int lastRatio = 0;
private int lastHealthScale = 0;
private String opponentName;
private String opponentsOpponentName;
@@ -94,7 +95,8 @@ class OpponentInfoOverlay extends Overlay
if (opponent.getName() != null && opponent.getHealth() > 0)
{
lastRatio = (float) opponent.getHealthRatio() / (float) opponent.getHealth();
lastRatio = opponent.getHealthRatio();
lastHealthScale = opponent.getHealth();
opponentName = Text.removeTags(opponent.getName());
lastMaxHealth = null;
@@ -117,7 +119,7 @@ class OpponentInfoOverlay extends Overlay
final Actor opponentsOpponent = opponent.getInteracting();
if (opponentsOpponent != null
&& (opponentsOpponent != client.getLocalPlayer() || client.getVar(Varbits.MULTICOMBAT_AREA) == 1))
&& (opponentsOpponent != client.getLocalPlayer() || client.getVar(Varbits.MULTICOMBAT_AREA) == 1))
{
opponentsOpponentName = Text.removeTags(opponentsOpponent.getName());
}
@@ -144,7 +146,7 @@ class OpponentInfoOverlay extends Overlay
.build());
// Health bar
if (lastRatio >= 0)
if (lastRatio >= 0 && lastHealthScale > 0)
{
final ProgressBarComponent progressBarComponent = new ProgressBarComponent();
progressBarComponent.setBackgroundColor(HP_RED);
@@ -152,13 +154,46 @@ class OpponentInfoOverlay extends Overlay
if (lastMaxHealth != null && !opponentInfoConfig.showPercent())
{
// This is the reverse of the calculation of healthRatio done by the server
// which is: healthRatio = 1 + (healthScale - 1) * health / maxHealth (if health > 0, 0 otherwise)
// It's able to recover the exact health if maxHealth <= healthScale.
int health = 0;
if (lastRatio > 0)
{
int minHealth = 1;
int maxHealth;
if (lastHealthScale > 1)
{
if (lastRatio > 1)
{
// This doesn't apply if healthRatio = 1, because of the special case in the server calculation that
// health = 0 forces healthRatio = 0 instead of the expected healthRatio = 1
minHealth = (lastMaxHealth * (lastRatio - 1) + lastHealthScale - 2) / (lastHealthScale - 1);
}
maxHealth = (lastMaxHealth * lastRatio - 1) / (lastHealthScale - 1);
if (maxHealth > lastMaxHealth)
{
maxHealth = lastMaxHealth;
}
}
else
{
// If healthScale is 1, healthRatio will always be 1 unless health = 0
// so we know nothing about the upper limit except that it can't be higher than maxHealth
maxHealth = lastMaxHealth;
}
// Take the average of min and max possible healts
health = (minHealth + maxHealth + 1) / 2;
}
progressBarComponent.setLabelDisplayMode(ProgressBarComponent.LabelDisplayMode.FULL);
progressBarComponent.setMaximum(lastMaxHealth);
progressBarComponent.setValue(lastRatio * lastMaxHealth);
progressBarComponent.setValue(health);
}
else
{
progressBarComponent.setValue(lastRatio * 100d);
float floatRatio = (float) lastRatio / (float) lastHealthScale;
progressBarComponent.setValue(floatRatio * 100d);
}
panelComponent.getChildren().add(progressBarComponent);