From 59e906ec6caac03a705d194705cc2859c5797632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Imrich?= Date: Fri, 22 Jan 2021 10:05:18 +0100 Subject: [PATCH] Implementation of totem of undying behaviour (#5111) * notchian totem of undying * ... * .... * Update src/Entities/Pawn.cpp Co-authored-by: Alexander Harkness * DeductTotem func * fixed build errors * Added myself to CONTRIBUTORS * Small changes Co-authored-by: Peter Co-authored-by: Alexander Harkness Co-authored-by: Tiger Wang --- CONTRIBUTORS | 1 + src/Entities/Entity.h | 2 ++ src/Entities/Pawn.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++ src/Entities/Pawn.h | 5 +++++ 4 files changed, 57 insertions(+) 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(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> tEffectMap; tEffectMap m_EntityEffects; @@ -83,4 +84,8 @@ private: /** A list of all monsters that are targeting this pawn. */ std::vector 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