summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/net/minecraft/server/EntityLiving.java24
-rw-r--r--src/main/java/net/minecraft/server/EntityPlayer.java10
-rw-r--r--src/main/java/net/minecraft/server/EntityTrackerEntry.java10
-rw-r--r--src/main/java/net/minecraft/server/FoodMetaData.java2
-rw-r--r--src/main/java/net/minecraft/server/ItemFood.java2
-rw-r--r--src/main/java/net/minecraft/server/PlayerList.java2
-rw-r--r--src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java67
7 files changed, 106 insertions, 11 deletions
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 45b1410e..c7012c51 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -82,7 +82,8 @@ public abstract class EntityLiving extends Entity {
public EntityLiving(World world) {
super(world);
this.ay();
- this.setHealth(this.getMaxHealth());
+ // CraftBukkit - setHealth(getMaxHealth()) -> current - inlined to skip the instanceof check for EntityPlayers
+ this.datawatcher.watch(6, (float) this.getAttributeInstance(GenericAttributes.a).getValue());
this.m = true;
this.aM = (float) (Math.random() + 1.0D) * 0.01F;
this.setPosition(this.locX, this.locY, this.locZ);
@@ -583,10 +584,31 @@ public abstract class EntityLiving extends Entity {
}
public final float getHealth() {
+ // CraftBukkit start - Scaled Health
+ if (this instanceof EntityPlayer) {
+ return (float) ((EntityPlayer) this).getBukkitEntity().getHealth();
+ }
+ // CraftBukkit end
return this.datawatcher.getFloat(6);
}
public void setHealth(float f) {
+ // CraftBukkit start - Scaled Health
+ if (this instanceof EntityPlayer) {
+ org.bukkit.craftbukkit.entity.CraftPlayer player = ((EntityPlayer) this).getBukkitEntity();
+ // Squeeze
+ if (f < 0.0F) {
+ player.setRealHealth(0.0D);
+ } else if (f > player.getMaxHealth()) {
+ player.setRealHealth(player.getMaxHealth());
+ } else {
+ player.setRealHealth(f);
+ }
+
+ this.datawatcher.watch(6, Float.valueOf(player.getScaledHealth()));
+ return;
+ }
+ // CraftBukkit end
this.datawatcher.watch(6, Float.valueOf(MathHelper.a(f, 0.0F, this.getMaxHealth())));
}
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 955b75c3..58e52179 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -51,6 +51,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public int newLevel = 0;
public int newTotalExp = 0;
public boolean keepLevel = false;
+ public double maxHealthCache;
// CraftBukkit end
public EntityPlayer(MinecraftServer minecraftserver, World world, String s, PlayerInteractManager playerinteractmanager) {
@@ -84,6 +85,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
this.displayName = this.name;
this.listName = this.name;
// this.canPickUpLoot = true; TODO
+ this.maxHealthCache = this.getMaxHealth();
// CraftBukkit end
}
@@ -234,7 +236,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
if (this.getHealth() != this.bP || this.bQ != this.foodData.a() || this.foodData.e() == 0.0F != this.bR) {
// CraftBukkit - Optionally scale health
- this.playerConnection.sendPacket(new Packet8UpdateHealth(getBukkitEntity().getScaledHealth(), this.foodData.a(), this.foodData.e()));
+ this.playerConnection.sendPacket(new Packet8UpdateHealth(this.getBukkitEntity().getScaledHealth(), this.foodData.a(), this.foodData.e()));
this.bP = this.getHealth();
this.bQ = this.foodData.a();
this.bR = this.foodData.e() == 0.0F;
@@ -246,6 +248,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
this.world.getServer().getScoreboardManager().updateAllScoresForList(IScoreboardCriteria.f, this.getLocalizedName(), com.google.common.collect.ImmutableList.of(this));
}
+ // CraftBukkit start - Force max health updates
+ if (this.maxHealthCache != this.getMaxHealth()) {
+ this.getBukkitEntity().updateScaledHealth();
+ }
+ // CraftBukkit end
+
if (this.expTotal != this.lastSentExp) {
this.lastSentExp = this.expTotal;
this.playerConnection.sendPacket(new Packet43SetExperience(this.exp, this.expTotal, this.expLevel));
diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java
index 673c2042..e05296c7 100644
--- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java
+++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java
@@ -250,6 +250,11 @@ public class EntityTrackerEntry {
Set set = attributemapserver.b();
if (!set.isEmpty()) {
+ // CraftBukkit start - Send scaled max health
+ if (this.tracker instanceof EntityPlayer) {
+ ((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(set, false);
+ }
+ // CraftBukkit end
this.broadcastIncludingSelf(new Packet44UpdateAttributes(this.tracker.id, set));
}
@@ -321,6 +326,11 @@ public class EntityTrackerEntry {
AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).aW();
Collection collection = attributemapserver.c();
+ // CraftBukkit start - If sending own attributes send scaled health instead of current maximum health
+ if (this.tracker.id == entityplayer.id) {
+ ((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(collection, false);
+ }
+ // CraftBukkit end
if (!collection.isEmpty()) {
entityplayer.playerConnection.sendPacket(new Packet44UpdateAttributes(this.tracker.id, collection));
}
diff --git a/src/main/java/net/minecraft/server/FoodMetaData.java b/src/main/java/net/minecraft/server/FoodMetaData.java
index 6e5bf831..37349f5c 100644
--- a/src/main/java/net/minecraft/server/FoodMetaData.java
+++ b/src/main/java/net/minecraft/server/FoodMetaData.java
@@ -39,7 +39,7 @@ public class FoodMetaData {
this.foodLevel = event.getFoodLevel();
}
- ((EntityPlayer) entityhuman).playerConnection.sendPacket(new Packet8UpdateHealth(entityhuman.getHealth(), this.foodLevel, this.saturationLevel));
+ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new Packet8UpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), this.foodLevel, this.saturationLevel));
// CraftBukkit end
}
}
diff --git a/src/main/java/net/minecraft/server/ItemFood.java b/src/main/java/net/minecraft/server/ItemFood.java
index c0274094..78bbb59b 100644
--- a/src/main/java/net/minecraft/server/ItemFood.java
+++ b/src/main/java/net/minecraft/server/ItemFood.java
@@ -36,7 +36,7 @@ public class ItemFood extends Item {
entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, this.getSaturationModifier());
}
- ((EntityPlayer) entityhuman).playerConnection.sendPacket(new Packet8UpdateHealth(entityhuman.getHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel));
+ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new Packet8UpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel));
// CraftBukkit end
world.makeSound(entityhuman, "random.burp", 0.5F, world.random.nextFloat() * 0.1F + 0.9F);
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index f24ba954..0f17c90c 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -981,7 +981,7 @@ public abstract class PlayerList {
public void updateClient(EntityPlayer entityplayer) {
entityplayer.updateInventory(entityplayer.defaultContainer);
- entityplayer.triggerHealthUpdate();
+ entityplayer.getBukkitEntity().updateScaledHealth(); // CraftBukkit - Update scaled health on respawn and worldchange
entityplayer.playerConnection.sendPacket(new Packet16BlockItemSwitch(entityplayer.inventory.itemInHandIndex));
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 977adff6..fd738566 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -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)));
}
}