Jump to content

[Patch] Fear


Auntie Mangos

Recommended Posts

  • 38 years later...

There are two problems with Fear and Confusions: if one fear effect ends and there is another one ( typicaly Death Coil followed by Fear ) target is no longer feared, even it still has fear aura.

Second problem is, when target is killed while feared, it's corpse will move ( because alive check is still true at time of removing )

diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index b4741b4..41caa26 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -3097,7 +3097,13 @@ void Aura::HandleModConfuse(bool apply, bool Real)
    if(!Real)
        return;

-    m_target->SetConfused(apply, GetCasterGUID(), GetId());
+    // check if there are no other confuse auras
+    Unit::AuraList const& confuseAuras = m_target->GetAurasByType(SPELL_AURA_MOD_CONFUSE);
+    if(!apply && !confuseAuras.empty())
+        return;
+
+
+    m_target->SetConfused(apply, GetCasterGUID(), GetId(), m_removeMode==AURA_REMOVE_BY_DEATH);
}

void Aura::HandleModFear(bool apply, bool Real)
@@ -3105,7 +3111,12 @@ void Aura::HandleModFear(bool apply, bool Real)
    if (!Real)
        return;

-    m_target->SetFeared(apply, GetCasterGUID(), GetId());
+    // check if there are no other fear auras
+    Unit::AuraList const& fearAuras = m_target->GetAurasByType(SPELL_AURA_MOD_FEAR);
+    if(!apply && !fearAuras.empty())
+        return;
+
+    m_target->SetFeared(apply, GetCasterGUID(), GetId(), m_removeMode==AURA_REMOVE_BY_DEATH);
}

void Aura::HandleFeignDeath(bool apply, bool Real)
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index cfd5fa9..49b88eb 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -10290,7 +10290,7 @@ void Unit::StopMoving()
    SendMessageToSet(&data,false);
}

-void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)
+void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID, bool death)
{
    if( apply )
    {
@@ -10312,7 +10312,7 @@ void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)

        GetMotionMaster()->MovementExpired(false);

-        if( GetTypeId() != TYPEID_PLAYER && isAlive() )
+        if( GetTypeId() != TYPEID_PLAYER && !death )
        {
            // restore appropriate movement generator
            if(getVictim())
@@ -10331,7 +10331,7 @@ void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)
        ((Player*)this)->SetClientControl(this, !apply);
}

-void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)
+void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID, bool death)
{
    if( apply )
    {
@@ -10347,7 +10347,7 @@ void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)

        GetMotionMaster()->MovementExpired(false);

-        if (GetTypeId() == TYPEID_UNIT)
+        if (GetTypeId() == TYPEID_UNIT && !death)
        {
            // if in combat restore movement generator
            if(getVictim())
diff --git a/src/game/Unit.h b/src/game/Unit.h
index a81308c..2cde239 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1234,8 +1234,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
        uint32 GetUnitMovementFlags() const { return m_unit_movement_flags; }
        void SetUnitMovementFlags(uint32 f) { m_unit_movement_flags = f; }

-        void SetFeared(bool apply, uint64 casterGUID = 0, uint32 spellID = 0);
-        void SetConfused(bool apply, uint64 casterGUID = 0, uint32 spellID = 0);
+        void SetFeared(bool apply, uint64 casterGUID = 0, uint32 spellID = 0, bool death = false);
+        void SetConfused(bool apply, uint64 casterGUID = 0, uint32 spellID = 0, bool death = false);

        void AddComboPointHolder(uint32 lowguid) { m_ComboPointHolders.insert(lowguid); }
        void RemoveComboPointHolder(uint32 lowguid) { m_ComboPointHolders.erase(lowguid); }

Link to comment
Share on other sites

May be the second problem is caused by possibly wrong check in TMG?

template<class T>
bool
TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
{
   if(!i_target.isValid())
       return false;

   if( !&owner || !owner.isAlive())
       return true;

The first problem solution is wrong I guess because this two effects using two different generators. They are pushed into stack and active is always the upper one. So the point of problem is else where.

If you apply fear and after it death coil. It push on stack FleeMG and than ConfuseMG. If fear is done before Death Coil

   else
   {
       RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);

       GetMotionMaster()->MovementExpired(false);

and this will expire wrong MovementGenerator. Because the confused one is on the top and than

           if(getVictim())
               GetMotionMaster()->MoveChase(getVictim());

we will immediately mutate into chase so the ConfusedMG is still the second on stack. When Death coil is done TargetMovementGenerator is expired and FearMG appear on stack but UNIT STATE is not set eny more so we will mutate into Chase again. At this point it is totaly messed up :) So I think correct solution sould be on aura remove always correctly remove certain MG where ever it is in stack.

But may be my calculations are wong :) I am almost two days without sleep ...

Link to comment
Share on other sites

  • 3 weeks later...

So it must search and remove first found _related_ movement generator and restart top generator if top change?

Main problem in req. work in different way for different movmeent generator types: for basic movment generators, combat movments and temporary effects (last stackable). Maybe we need have slot for single basic movement generator. Slot for single combas chase generator and std::stack for other with removeing expired generators not only from top but from middle of stack... or one stack but proper work with different generators types.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use