rendered paste bodyIndex: 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];