mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-07 19:12:22 +01:00
Add API to control scaled health. Adds BUKKIT-4590
This commit implements the ability to set the scale of hearts that the client renders. When the Packet44UpdateAttributes packet is sent, the max health attribute is replaced with a scaled version, to preserve the scaled health illusion clientside. In order to accurately display the scaled health for players, a true health is stored within CraftPlayer, and the datawatcher now stores the scaled health. The getHealth() method for players still returns their true health. Changed setHealth() within EntityLiving to appropriately handle health for instances of EntityPlayer. Inlined a call to setHealth(getMaxHealth()) within the EntityLiving constructor to work around CraftEntity instantiation. Additionally fixes the health values sent when eating food within FoodMetaData and ItemFood, which previously sent the unscaled health; this commit alters them to send the properly scaled health. Additionally fixes BUKKIT-4535, BUKKIT-4536, and BUKKIT-4127 By: T00thpick1 <t00thpick1dirko@gmail.com>
This commit is contained in:
parent
701de44fd3
commit
4af51c2ffb
1 changed files with 61 additions and 6 deletions
|
@ -7,6 +7,7 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
@ -61,7 +62,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||
private final Set<String> channels = new HashSet<String>();
|
||||
private final Map<String, Player> hiddenPlayers = new MapMaker().softValues().makeMap();
|
||||
private int hash = 0;
|
||||
private boolean scaledHealth;
|
||||
private double health = 20;
|
||||
private boolean scaledHealth = false;
|
||||
private double healthScale = 20;
|
||||
|
||||
public CraftPlayer(CraftServer server, EntityPlayer entity) {
|
||||
super(server, entity);
|
||||
|
@ -973,6 +976,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||
@Override
|
||||
public void setMaxHealth(double amount) {
|
||||
super.setMaxHealth(amount);
|
||||
this.health = Math.min(this.health, health);
|
||||
getHandle().triggerHealthUpdate();
|
||||
}
|
||||
|
||||
|
@ -999,15 +1003,66 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||
this.server.getScoreboardManager().setPlayerBoard(this, scoreboard);
|
||||
}
|
||||
|
||||
public void setHealthScale(double value) {
|
||||
Validate.isTrue((float) value > 0F, "Must be greater than 0");
|
||||
healthScale = value;
|
||||
scaledHealth = true;
|
||||
updateScaledHealth();
|
||||
}
|
||||
|
||||
public double getHealthScale() {
|
||||
return healthScale;
|
||||
}
|
||||
|
||||
public void setHealthScaled(boolean scale) {
|
||||
if (scaledHealth != (scaledHealth = scale)) {
|
||||
updateScaledHealth();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHealthScaled() {
|
||||
return scaledHealth;
|
||||
}
|
||||
|
||||
public float getScaledHealth() {
|
||||
return (float) (this.scaledHealth ? getHealth() / getMaxHealth() * 20.0D : getHealth());
|
||||
return (float) (isHealthScaled() ? getHealth() * getHealthScale() / getMaxHealth() : getHealth());
|
||||
}
|
||||
|
||||
public void setScaleHealth(boolean scale) {
|
||||
this.scaledHealth = scale;
|
||||
@Override
|
||||
public double getHealth() {
|
||||
return health;
|
||||
}
|
||||
|
||||
public boolean isScaledHealth() {
|
||||
return this.scaledHealth;
|
||||
public void setRealHealth(double health) {
|
||||
this.health = health;
|
||||
}
|
||||
|
||||
public void updateScaledHealth() {
|
||||
AttributeMapServer attributemapserver = (AttributeMapServer) getHandle().aW();
|
||||
Set set = attributemapserver.b();
|
||||
|
||||
injectScaledMaxHealth(set, true);
|
||||
|
||||
getHandle().getDataWatcher().watch(6, (float) getScaledHealth());
|
||||
getHandle().playerConnection.sendPacket(new Packet8UpdateHealth(getScaledHealth(), getHandle().getFoodData().a(), getHandle().getFoodData().e()));
|
||||
getHandle().playerConnection.sendPacket(new Packet44UpdateAttributes(getHandle().id, set));
|
||||
|
||||
set.clear();
|
||||
getHandle().maxHealthCache = getMaxHealth();
|
||||
}
|
||||
|
||||
public void injectScaledMaxHealth(Collection collection, boolean force) {
|
||||
if (!scaledHealth && !force) {
|
||||
return;
|
||||
}
|
||||
for (Object genericInstance : collection) {
|
||||
IAttribute attribute = ((AttributeInstance) genericInstance).a();
|
||||
if (attribute.a().equals("generic.maxHealth")) {
|
||||
collection.remove(genericInstance);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
collection.add(new AttributeModifiable(getHandle().aW(), (new AttributeRanged("generic.maxHealth", scaledHealth ? healthScale : getMaxHealth(), 0.0D, Float.MAX_VALUE)).a("Max Health").a(true)));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue