summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS1
-rw-r--r--src/Entities/Entity.h2
-rw-r--r--src/Entities/Pawn.cpp49
-rw-r--r--src/Entities/Pawn.h5
4 files changed, 57 insertions, 0 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index e2179adb9..f5ee91b89 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -17,6 +17,7 @@ Bond_009
changyongGuo
Cocosushi6
derouinw
+dImrich (Damian Imrich)
Diusrex
Duralex
Earboxer (Zach DeCook)
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index cbefc764c..143993dad 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -146,6 +146,8 @@ public:
esFireworkExploding = 17,
// Passive mob is in "love mode"
esMobInLove = 18,
+ // Plays totem of undying animation and sound
+ esTotemOfUndying = 35,
} ;
static const int FIRE_TICKS_PER_DAMAGE = 10; ///< Ticks to wait between damaging an entity when it stands in fire
diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp
index 35efe05ce..6f33a5eca 100644
--- a/src/Entities/Pawn.cpp
+++ b/src/Entities/Pawn.cpp
@@ -111,6 +111,20 @@ void cPawn::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
void cPawn::KilledBy(TakeDamageInfo & a_TDI)
{
ClearEntityEffects();
+
+ // Is death eligible for totem reanimation?
+ if (DeductTotem(a_TDI.DamageType))
+ {
+ m_World->BroadcastEntityStatus(*this, esTotemOfUndying);
+
+ AddEntityEffect(cEntityEffect::effAbsorption, 100, 1);
+ AddEntityEffect(cEntityEffect::effRegeneration, 900, 1);
+ AddEntityEffect(cEntityEffect::effFireResistance, 800, 0);
+
+ m_Health = 1;
+ return;
+ }
+
Super::KilledBy(a_TDI);
}
@@ -490,3 +504,38 @@ void cPawn::ResetPosition(Vector3d a_NewPosition)
Super::ResetPosition(a_NewPosition);
m_LastGroundHeight = GetPosY();
}
+
+
+
+
+
+bool cPawn::DeductTotem(const eDamageType a_DamageType)
+{
+ if ((a_DamageType == dtAdmin) || (a_DamageType == dtInVoid))
+ {
+ // Beyond saving:
+ return false;
+ }
+
+ if (!IsPlayer())
+ {
+ // TODO: implement when mobs will be able to pick up items based on CanPickUpLoot attribute:
+ return false;
+ }
+
+ // If the player is holding a totem of undying in their off-hand or
+ // main-hand slot and receives otherwise fatal damage, the totem saves the player from death.
+
+ auto & inv = static_cast<cPlayer *>(this)->GetInventory();
+ if (inv.GetEquippedItem().m_ItemType == E_ITEM_TOTEM_OF_UNDYING)
+ {
+ inv.SetEquippedItem({});
+ return true;
+ }
+ if (inv.GetShieldSlot().m_ItemType == E_ITEM_TOTEM_OF_UNDYING)
+ {
+ inv.SetShieldSlot({});
+ return true;
+ }
+ return false;
+}
diff --git a/src/Entities/Pawn.h b/src/Entities/Pawn.h
index 1a9285b77..ab8d66a58 100644
--- a/src/Entities/Pawn.h
+++ b/src/Entities/Pawn.h
@@ -71,6 +71,7 @@ public:
cEntityEffect * GetEntityEffect(cEntityEffect::eType a_EffectType) const;
protected:
+
typedef std::map<cEntityEffect::eType, std::unique_ptr<cEntityEffect>> tEffectMap;
tEffectMap m_EntityEffects;
@@ -83,4 +84,8 @@ private:
/** A list of all monsters that are targeting this pawn. */
std::vector<cMonster*> m_TargetingMe;
+
+ /** Attempt to activate a Totem of Undying.
+ If activation for the given type of damage was successful, consumes the totem and returns true. */
+ bool DeductTotem(eDamageType a_DamageType);
} ; // tolua_export