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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user