summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Entities/Entity.cpp10
-rw-r--r--src/Entities/Entity.h12
-rw-r--r--src/Entities/Minecart.cpp2
-rw-r--r--src/Protocol/Protocol_1_8.cpp2
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp2
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.cpp23
6 files changed, 35 insertions, 16 deletions
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 90aefd082..11405d2fd 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -528,9 +528,9 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
Player->GetStatManager().AddValue(statDamageDealt, static_cast<StatValue>(floor(a_TDI.FinalDamage * 10 + 0.5)));
}
- m_Health -= static_cast<short>(a_TDI.FinalDamage);
+ m_Health -= static_cast<float>(a_TDI.FinalDamage);
- m_Health = std::max(m_Health, 0);
+ m_Health = std::max(m_Health, 0.0f);
// Add knockback:
if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != nullptr))
@@ -810,9 +810,9 @@ void cEntity::Heal(int a_HitPoints)
-void cEntity::SetHealth(int a_Health)
+void cEntity::SetHealth(float a_Health)
{
- m_Health = Clamp(a_Health, 0, m_MaxHealth);
+ m_Health = Clamp(a_Health, 0.0f, m_MaxHealth);
}
@@ -1782,7 +1782,7 @@ void cEntity::OnFinishedBurning(void)
-void cEntity::SetMaxHealth(int a_MaxHealth)
+void cEntity::SetMaxHealth(float a_MaxHealth)
{
m_MaxHealth = a_MaxHealth;
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 4174160bf..fae296ab4 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -368,10 +368,10 @@ public:
virtual void Heal(int a_HitPoints);
/** Returns the health of this entity */
- int GetHealth(void) const { return m_Health; }
+ float GetHealth(void) const { return m_Health; }
/** Sets the health of this entity; doesn't broadcast any hurt animation */
- void SetHealth(int a_Health);
+ void SetHealth(float a_Health);
// tolua_end
@@ -403,9 +403,9 @@ public:
// tolua_begin
/** Sets the maximum value for the health */
- void SetMaxHealth(int a_MaxHealth);
+ void SetMaxHealth(float a_MaxHealth);
- int GetMaxHealth(void) const { return m_MaxHealth; }
+ float GetMaxHealth(void) const { return m_MaxHealth; }
/** Sets whether the entity is fireproof */
void SetIsFireproof(bool a_IsFireproof);
@@ -556,8 +556,8 @@ protected:
Note that the UniqueID is not persisted through storage. */
UInt32 m_UniqueID;
- int m_Health;
- int m_MaxHealth;
+ float m_Health;
+ float m_MaxHealth;
/** The entity to which this entity is attached (vehicle), nullptr if none */
cEntity * m_AttachedTo;
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp
index 7c5ca49ce..4de53d716 100644
--- a/src/Entities/Minecart.cpp
+++ b/src/Entities/Minecart.cpp
@@ -1035,7 +1035,7 @@ bool cMinecart::DoTakeDamage(TakeDamageInfo & TDI)
if ((TDI.Attacker != nullptr) && TDI.Attacker->IsPlayer() && static_cast<cPlayer *>(TDI.Attacker)->IsGameModeCreative())
{
Destroy();
- TDI.FinalDamage = GetMaxHealth(); // Instant hit for creative
+ TDI.FinalDamage = static_cast<int>(GetMaxHealth()); // Instant hit for creative
SetInvulnerableTicks(0);
return super::DoTakeDamage(TDI); // No drops for creative
}
diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp
index e7f197d3d..ec5a9440b 100644
--- a/src/Protocol/Protocol_1_8.cpp
+++ b/src/Protocol/Protocol_1_8.cpp
@@ -3310,7 +3310,7 @@ void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a
Health: 1 | 3 - (1 - 3) = 5
*/
auto & Minecart = reinterpret_cast<const cMinecart &>(a_Entity);
- a_Pkt.WriteBEInt32((((a_Entity.GetMaxHealth() / 2) - (a_Entity.GetHealth() - (a_Entity.GetMaxHealth() / 2))) * Minecart.LastDamage()) * 4);
+ a_Pkt.WriteBEInt32(static_cast<Int32>((((a_Entity.GetMaxHealth() / 2) - (a_Entity.GetHealth() - (a_Entity.GetMaxHealth() / 2))) * Minecart.LastDamage()) * 4));
a_Pkt.WriteBEUInt8(0x52);
a_Pkt.WriteBEInt32(1); // Shaking direction, doesn't seem to affect anything
a_Pkt.WriteBEUInt8(0x73);
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 12f767abf..78573572d 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -431,7 +431,7 @@ void cNBTChunkSerializer::AddBasicEntity(cEntity * a_Entity, const AString & a_C
m_Writer.AddDouble("", a_Entity->GetYaw());
m_Writer.AddDouble("", a_Entity->GetPitch());
m_Writer.EndList();
- m_Writer.AddShort("Health", static_cast<Int16>(a_Entity->GetHealth()));
+ m_Writer.AddFloat("Health", a_Entity->GetHealth());
}
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index b47d3eddd..35fdaa8d8 100755
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -3154,9 +3154,28 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N
a_Entity.SetYaw(Rotation[0]);
a_Entity.SetRoll(Rotation[1]);
- // Load health:
+ // Depending on the Minecraft version, the entity's health is
+ // stored either as a float Health tag (HealF prior to 1.9) or
+ // as a short Health tag. The float tags should be preferred.
int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
- a_Entity.SetHealth(Health > 0 ? a_NBT.GetShort(Health) : a_Entity.GetMaxHealth());
+ int HealF = a_NBT.FindChildByName(a_TagIdx, "HealF");
+
+ if (Health > 0 && a_NBT.GetType(Health) == TAG_Float)
+ {
+ a_Entity.SetHealth(a_NBT.GetFloat(Health));
+ }
+ else if (HealF > 0)
+ {
+ a_Entity.SetHealth(a_NBT.GetFloat(HealF));
+ }
+ else if (Health > 0)
+ {
+ a_Entity.SetHealth(static_cast<float>(a_NBT.GetShort(Health)));
+ }
+ else
+ {
+ a_Entity.SetHealth(a_Entity.GetMaxHealth());
+ }
return true;
}