All pastes #912594 Raw Edit

Someone

public text v1 · immutable
·published 2008-02-21 14:14 UTC
rendered paste body
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp	(revision 5266)
+++ src/game/Player.cpp	(working copy)
@@ -56,6 +56,7 @@
 #include "ArenaTeam.h"
 #include "Chat.h"
 #include "Database/DatabaseImpl.h"
+#include "Spell.h"
 
 #include <cmath>
 
@@ -14746,13 +14747,22 @@
     return total;
 }
 
-bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod)
+bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell)
 {
     if (!mod || !spellInfo)
         return false;
 
-    if ((mod->charges == -1) && (mod->lastAffected != spellInfo->Id))
-        return false;
+    if(mod->charges == -1 && mod->lastAffected )            // marked as expired but locked until spell casting finish
+    {
+        // prevent apply to any spell expect spell that trigger expire
+        if(spell)
+        {
+            if(mod->lastAffected != spell)
+                return false;
+        }
+        else if(mod->lastAffected != FindCurrentSpellBySpellId(spellInfo->Id))
+            return false;
+    }
 
     return spellmgr.IsAffectedBySpell(spellInfo,mod->spellId,mod->effectId,mod->mask);
 }
@@ -14791,24 +14801,26 @@
     }
 }
 
-void Player::RemoveSpellMods(uint32 spellId)
+void Player::RemoveSpellMods(Spell const* spell)
 {
-    if(!spellId || (m_SpellModRemoveCount == 0))
+    if(!spell || (m_SpellModRemoveCount == 0))
         return;
 
     for(int i=0;i<MAX_SPELLMOD;++i)
-        for (SpellModList::iterator itr = m_spellMods[i].begin(), next; itr != m_spellMods[i].end(); itr = next)
     {
-        next = itr;
-        next++;
-        SpellModifier *mod = *itr;
-        if (mod && mod->charges == -1 && mod->lastAffected == spellId)
+        for (SpellModList::iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end();)
         {
-            RemoveAurasDueToSpell(mod->spellId);
-            if (m_spellMods[i].empty())
-                break;
-            else
-                next = m_spellMods[i].begin();
+            SpellModifier *mod = *itr;
+            ++itr;
+
+            if (mod && mod->charges == -1 && (mod->lastAffected == spell || mod->lastAffected==NULL))
+            {
+                RemoveAurasDueToSpell(mod->spellId);
+                if (m_spellMods[i].empty())
+                    break;
+                else
+                    itr = m_spellMods[i].begin();
+            }
         }
     }
 }
Index: src/game/Player.h
===================================================================
--- src/game/Player.h	(revision 5266)
+++ src/game/Player.h	(working copy)
@@ -80,7 +80,7 @@
     uint64 mask;
     uint32 spellId;
     uint32 effectId;
-    uint32 lastAffected;
+    Spell const* lastAffected;
 };
 
 typedef HM_NAMESPACE::hash_map<uint16, PlayerSpell*> PlayerSpellMap;
@@ -1332,9 +1332,9 @@
         void AddSpellMod(SpellModifier* mod, bool apply);
         int32 GetTotalFlatMods(uint32 spellId, uint8 op);
         int32 GetTotalPctMods(uint32 spellId, uint8 op);
-        bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod);
-        template <class T> T ApplySpellMod(uint32 spellId, uint8 op, T &basevalue);
-        void RemoveSpellMods(uint32 spellId);
+        bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL);
+        template <class T> T ApplySpellMod(uint32 spellId, uint8 op, T &basevalue, Spell const* spell = NULL);
+        void RemoveSpellMods(Spell const* spell);
 
         bool HasSpellCooldown(uint32 spell_id) const
         {
@@ -2079,7 +2079,7 @@
 void RemoveItemsSetItem(Player*player,ItemPrototype const *proto);
 
 // "the bodies of template functions must be made available in a header file"
-template <class T> T Player::ApplySpellMod(uint32 spellId, uint8 op, T &basevalue)
+template <class T> T Player::ApplySpellMod(uint32 spellId, uint8 op, T &basevalue, Spell const* spell)
 {
     SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
     if (!spellInfo) return 0;
@@ -2089,7 +2089,7 @@
     {
         SpellModifier *mod = *itr;
 
-        if(!IsAffectedBySpellmod(spellInfo,mod))
+        if(!IsAffectedBySpellmod(spellInfo,mod,spell))
             continue;
         if (mod->type == SPELLMOD_FLAT)
             totalflat += mod->value;
@@ -2101,7 +2101,9 @@
             if (mod->charges == 0)
             {
                 mod->charges = -1;
-                mod->lastAffected = spellId;
+                mod->lastAffected = spell;
+                if(!mod->lastAffected)
+                    mod->lastAffected = FindCurrentSpellBySpellId(spellId);
                 m_SpellModRemoveCount++;
             }
         }
Index: src/game/Spell.cpp
===================================================================
--- src/game/Spell.cpp	(revision 5266)
+++ src/game/Spell.cpp	(working copy)
@@ -298,7 +298,7 @@
     casttime = GetCastTime(sCastTimesStore.LookupEntry(m_spellInfo->CastingTimeIndex));
 
     if(Player* modOwner = m_caster->GetSpellModOwner())
-        modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_CASTING_TIME, casttime);
+        modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_CASTING_TIME, casttime,this);
 
     casttime = int32(casttime*m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
 
@@ -719,7 +719,7 @@
                 float multiplier = m_spellInfo->DmgMultiplier[effectNumber];
                 // Apply multiplier mods
                 if(Player* modOwner = m_originalCaster->GetSpellModOwner())
-                    modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier);
+                    modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier,this);
                 m_damageMultipliers[effectNumber] *= multiplier;
             }
         }
@@ -835,7 +835,7 @@
 
     if(m_originalCaster)
         if(Player* modOwner = m_originalCaster->GetSpellModOwner())
-            modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius);
+            modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius,this);
 
     uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets;
     switch(cur)
@@ -1565,7 +1565,7 @@
         return;
     }
 
-    if(m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.getUnitTarget())
+    if(m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.getUnitTarget() && m_targets.getUnitTarget() != m_caster)
         m_caster->SetInFront(m_targets.getUnitTarget());
 
     castResult = CheckMana( &mana);
@@ -1795,7 +1795,7 @@
 
     //remove spell mods
     if (m_caster->GetTypeId() == TYPEID_PLAYER)
-        ((Player*)m_caster)->RemoveSpellMods(m_spellInfo->Id);
+        ((Player*)m_caster)->RemoveSpellMods(this);
 }
 
 void Spell::SendSpellCooldown()
@@ -1847,10 +1847,10 @@
 
     // Now we have cooldown data (if found any), time to apply mods
     if(rec > 0)
-        _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, rec);
+        _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, rec, this);
 
     if(catrec > 0)
-        _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, catrec);
+        _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, catrec, this);
 
     // replace negative cooldowns by 0
     if (rec < 0) rec = 0;
@@ -3513,7 +3513,7 @@
     float min_range = GetMinRange(srange);
 
     if(Player* modOwner = m_caster->GetSpellModOwner())
-        modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range);
+        modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
 
     Unit *target = m_targets.getUnitTarget();
 
@@ -3585,7 +3585,7 @@
     manaCost+= m_caster->GetInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+m_spellInfo->School);
 
     if(Player* modOwner = m_caster->GetSpellModOwner())
-        modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, manaCost);
+        modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, manaCost, this);
 
     manaCost*= (1.0f+m_caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+m_spellInfo->School));
     if (manaCost < 0)
@@ -3913,7 +3913,7 @@
 
     //check resist chance
     int32 resistChance = 100;                               //must be initialized to 100 for percent modifiers
-    ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance);
+    ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance, this);
     resistChance += m_caster->GetTotalAuraModifier(SPELL_AURA_RESIST_PUSHBACK) - 100;
     if (roll_chance_f(resistChance))
         return;
@@ -3937,7 +3937,7 @@
 
     //check resist chance
     int32 resistChance = 100;                               //must be initialized to 100 for percent modifiers
-    ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance);
+    ((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance, this);
     resistChance += m_caster->GetTotalAuraModifier(SPELL_AURA_RESIST_PUSHBACK) - 100;
     if (roll_chance_f(resistChance))
         return;
Index: src/game/SpellAuras.cpp
===================================================================
--- src/game/SpellAuras.cpp	(revision 5266)
+++ src/game/SpellAuras.cpp	(working copy)
@@ -1001,7 +1001,7 @@
         mod->type = SpellModType(m_modifier.m_auraname);    // SpellModType value == spell aura types
         mod->spellId = m_spellId;
         mod->effectId = m_effIndex;
-        mod->lastAffected = 0;
+        mod->lastAffected = NULL;
 
         SpellAffection const *spellAffect = spellmgr.GetSpellAffection(m_spellId, m_effIndex);
 
@@ -1194,7 +1194,7 @@
             mod->type = SPELLMOD_PCT;
             mod->spellId = m_spellId;
             mod->effectId = m_effIndex;
-            mod->lastAffected = 0;
+            mod->lastAffected = NULL;
             mod->mask = 0x00008000 | 0x00001000;
             mod->charges = 0;
 
@@ -1216,7 +1216,7 @@
             mod->type = SPELLMOD_FLAT;
             mod->spellId = m_spellId;
             mod->effectId = m_effIndex;
-            mod->lastAffected = 0;
+            mod->lastAffected = NULL;
             mod->mask = 0x4000000000000LL;
             mod->charges = 0;
 
Index: src/game/SpellEffects.cpp
===================================================================
--- src/game/SpellEffects.cpp	(revision 5266)
+++ src/game/SpellEffects.cpp	(working copy)
@@ -625,7 +625,7 @@
                     mod->type = SPELLMOD_PCT;
                     mod->spellId = 0;
                     mod->effectId = 0;
-                    mod->lastAffected = 0;
+                    mod->lastAffected = NULL;
                     mod->mask = 0x20800000000LL;
                     mod->charges = 0;
 
@@ -716,7 +716,7 @@
                 float cost = m_currentBasePoints[0]+1;
 
                 if(Player* modOwner = m_caster->GetSpellModOwner())
-                    modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, cost);
+                    modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, cost,this);
 
                 uint32 dmg = m_caster->SpellDamageBonus(m_caster, m_spellInfo,uint32(cost > 0 ? cost : 0), SPELL_DIRECT_DAMAGE);
 
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp	(revision 5266)
+++ src/game/Unit.cpp	(working copy)
@@ -3359,6 +3359,14 @@
     }
 }
 
+Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const
+{
+    for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
+        if(m_currentSpells[i] && m_currentSpells[i]->m_spellInfo->Id==spell_id)
+            return m_currentSpells[i];
+    return NULL;
+}
+
 bool Unit::isInFront(Unit const* target, float radius) const
 {
     return IsWithinDistInMap(target, radius) && HasInArc( M_PI, target );
@@ -5045,7 +5053,7 @@
                 mod->type = SPELLMOD_PCT;
                 mod->spellId = 0;
                 mod->effectId = 0;
-                mod->lastAffected = 0;
+                mod->lastAffected = NULL;
                 mod->mask = 0x0000000000000003LL;
                 mod->charges = 0;
                 ((Player*)this)->AddSpellMod(mod, true);
Index: src/game/Unit.h
===================================================================
--- src/game/Unit.h	(revision 5266)
+++ src/game/Unit.h	(working copy)
@@ -857,7 +857,10 @@
         // delayed+channeled spells are always interrupted
         void InterruptNonMeleeSpells(bool withDelayed);
 
+        Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;
+
         Spell* m_currentSpells[CURRENT_MAX_SPELL];
+
         uint32 m_addDmgOnce;
         uint64 m_TotemSlot[4];
         uint64 m_ObjectSlot[4];