[10156] Add shared object for auras of same spell and move spell proc code to its own file, also spread procs by auras and effect indexes.

This commit is contained in:
Laise 2010-07-07 19:07:53 +03:00
parent abe6776358
commit a32b3063a2
32 changed files with 7507 additions and 6076 deletions

View file

@ -598,7 +598,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx)
if (needConsume)
for (uint32 i = 0; i < doses; ++i)
unitTarget->RemoveSingleSpellAurasByCasterSpell(spellId, m_caster->GetGUID());
unitTarget->RemoveSingleAuraHolderFromStack(spellId, m_caster->GetGUID());
damage *= doses;
damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * doses);
@ -2460,12 +2460,11 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx)
else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000010))
{
uint32 count = 0;
Unit::AuraMap const& auras = unitTarget->GetAuras();
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
{
if (itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE &&
itr->second->GetCasterGUID() == m_caster->GetGUID() &&
IsSpellLastAuraEffect(itr->second->GetSpellProto(), itr->second->GetEffIndex()))
itr->second->GetCasterGUID() == m_caster->GetGUID())
{
++count;
// max. 15%
@ -2635,8 +2634,8 @@ void Spell::EffectTriggerSpell(SpellEffectIndex effIndex)
// Cloak of Shadows
case 35729:
{
Unit::AuraMap& Auras = unitTarget->GetAuras();
for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter)
Unit::SpellAuraHolderMap& Auras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter)
{
// Remove all harmful spells on you except positive/passive/physical auras
if (!iter->second->IsPositive() &&
@ -2972,16 +2971,16 @@ void Spell::EffectApplyAura(SpellEffectIndex eff_idx)
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[eff_idx]);
Aura* Aur = CreateAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], unitTarget, caster, m_CastItem);
Aura* Aur = CreateAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], spellAuraHolder, unitTarget, caster, m_CastItem);
// Now Reduce spell duration using data received at spell hit
int32 duration = Aur->GetAuraMaxDuration();
int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup,m_spellInfo);
unitTarget->ApplyDiminishingToDuration(m_diminishGroup, duration, m_caster, m_diminishLevel,limitduration);
Aur->setDiminishGroup(m_diminishGroup);
spellAuraHolder->setDiminishGroup(m_diminishGroup);
// if Aura removed and deleted, do not continue.
if(duration== 0 && !(Aur->IsPermanent()))
if(duration== 0 && !(spellAuraHolder->IsPermanent()))
{
delete Aur;
return;
@ -2993,7 +2992,7 @@ void Spell::EffectApplyAura(SpellEffectIndex eff_idx)
Aur->SetAuraDuration(duration);
}
unitTarget->AddAura(Aur);
spellAuraHolder->AddAura(Aur, eff_idx);
}
void Spell::EffectUnlearnSpecialization(SpellEffectIndex eff_idx)
@ -3200,7 +3199,7 @@ void Spell::EffectHeal(SpellEffectIndex /*eff_idx*/)
if (riptide)
{
addhealth += addhealth/4;
unitTarget->RemoveAura(riptide);
unitTarget->RemoveAurasDueToSpell(riptide->GetId());
}
}
}
@ -3506,8 +3505,8 @@ void Spell::EffectEnergize(SpellEffectIndex eff_idx)
{
// find elixirs on target
uint32 elixir_mask = 0;
Unit::AuraMap& Auras = unitTarget->GetAuras();
for(Unit::AuraMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
Unit::SpellAuraHolderMap& Auras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
{
uint32 spell_id = itr->second->GetId();
if(uint32 mask = sSpellMgr.GetSpellElixirMask(spell_id))
@ -3801,8 +3800,8 @@ void Spell::EffectApplyAreaAura(SpellEffectIndex eff_idx)
if (!unitTarget->isAlive())
return;
AreaAura* Aur = new AreaAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], unitTarget, m_caster, m_CastItem);
unitTarget->AddAura(Aur);
AreaAura* Aur = new AreaAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], spellAuraHolder, unitTarget, m_caster, m_CastItem);
spellAuraHolder->AddAura(Aur, eff_idx);
}
void Spell::EffectSummonType(SpellEffectIndex eff_idx)
@ -4044,33 +4043,31 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx)
return;
// Fill possible dispell list
std::vector <Aura *> dispel_list;
std::list <std::pair<SpellAuraHolder* ,uint32>> dispel_list;
// Create dispel mask by dispel type
uint32 dispel_type = m_spellInfo->EffectMiscValue[eff_idx];
uint32 dispelMask = GetDispellMask( DispelType(dispel_type) );
Unit::AuraMap const& auras = unitTarget->GetAuras();
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
Aura *aur = (*itr).second;
if (aur && (1<<aur->GetSpellProto()->Dispel) & dispelMask)
SpellAuraHolder *holder = itr->second;
if ((1<<holder->GetSpellProto()->Dispel) & dispelMask)
{
if(aur->GetSpellProto()->Dispel == DISPEL_MAGIC)
if(holder->GetSpellProto()->Dispel == DISPEL_MAGIC)
{
bool positive = true;
if (!aur->IsPositive())
if (!holder->IsPositive())
positive = false;
else
positive = (aur->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_NEGATIVE)==0;
positive = (holder->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_NEGATIVE)==0;
// do not remove positive auras if friendly target
// negative auras if non-friendly target
if (positive == unitTarget->IsFriendlyTo(m_caster))
continue;
}
// Add aura to dispel list (all stack cases)
for(int k = 0; k < aur->GetStackAmount(); ++k)
dispel_list.push_back(aur);
dispel_list.push_back(std::pair<SpellAuraHolder* ,uint32>(holder, holder->GetStackAmount()));
}
}
// Ok if exist some buffs for dispel try dispel it
@ -4087,20 +4084,23 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx)
for (int32 count=0; count < damage && !dispel_list.empty(); ++count)
{
// Random select buff for dispel
std::vector<Aura*>::iterator dispel_itr = dispel_list.begin();
std::list<std::pair<SpellAuraHolder* ,uint32>>::iterator dispel_itr = dispel_list.begin();
std::advance(dispel_itr,urand(0, dispel_list.size()-1));
Aura *aur = *dispel_itr;
SpellAuraHolder *holder = dispel_itr->first;
// remove entry from dispel_list
dispel_list.erase(dispel_itr);
dispel_itr->second -= 1;
SpellEntry const* spellInfo = aur->GetSpellProto();
// remove entry from dispel_list if nothing left in stack
if (dispel_itr->second == 0)
dispel_list.erase(dispel_itr);
SpellEntry const* spellInfo = holder->GetSpellProto();
// Base dispel chance
// TODO: possible chance depend from spell level??
int32 miss_chance = 0;
// Apply dispel mod from aura caster
if (Unit *caster = aur->GetCaster())
if (Unit *caster = holder->GetCaster())
{
if ( Player* modOwner = caster->GetSpellModOwner() )
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_DISPEL_CHANCE, miss_chance, this);
@ -4109,7 +4109,7 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx)
if (roll_chance_i(miss_chance))
fail_list.push_back(spellInfo->Id);
else
success_list.push_back(std::pair<uint32,uint64>(aur->GetId(),aur->GetCasterGUID()));
success_list.push_back(std::pair<uint32,uint64>(holder->GetId(),holder->GetCasterGUID()));
}
// Send success log and really remove auras
if (!success_list.empty())
@ -4126,7 +4126,7 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx)
SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first);
data << uint32(spellInfo->Id); // Spell Id
data << uint8(0); // 0 - dispeled !=0 cleansed
unitTarget->RemoveSingleAuraDueToSpellByDispel(spellInfo->Id, j->second, m_caster);
unitTarget->RemoveSingleAuraHolderDueToSpellByDispel(spellInfo->Id, j->second, m_caster);
}
m_caster->SendMessageToSet(&data, true);
@ -5002,16 +5002,16 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx)
{
uint32 stack = 0;
// Need refresh all Sunder Armor auras from this caster
Unit::AuraMap& suAuras = unitTarget->GetAuras();
Unit::SpellAuraHolderMap& suAuras = unitTarget->GetSpellAuraHolderMap();
SpellEntry const *spellInfo;
for(Unit::AuraMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr)
for(Unit::SpellAuraHolderMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr)
{
spellInfo = (*itr).second->GetSpellProto();
if( spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR &&
(spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) &&
(*itr).second->GetCasterGUID() == m_caster->GetGUID())
{
(*itr).second->RefreshAura();
(*itr).second->RefreshHolder();
stack = (*itr).second->GetStackAmount();
break;
}
@ -5037,8 +5037,8 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx)
// full aura scan
else
{
Unit::AuraMap const& auras = unitTarget->GetAuras();
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
{
if(itr->second->GetSpellProto()->Dispel == DISPEL_POISON)
{
@ -5125,12 +5125,11 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx)
m_spellInfo->SpellIconID == 1736)
{
uint32 count = 0;
Unit::AuraMap const& auras = unitTarget->GetAuras();
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
{
if(itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE &&
itr->second->GetCasterGUID() == m_caster->GetGUID() &&
IsSpellLastAuraEffect(itr->second->GetSpellProto(), itr->second->GetEffIndex()))
itr->second->GetCasterGUID() == m_caster->GetGUID())
++count;
}
@ -5435,7 +5434,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
return;
}
case 24590: // Brittle Armor - need remove one 24575 Brittle Armor aura
unitTarget->RemoveSingleSpellAurasFromStack(24575);
unitTarget->RemoveSingleAuraHolderFromStack(24575);
return;
case 26275: // PX-238 Winter Wondervolt TRAP
{
@ -5454,7 +5453,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
return;
}
case 26465: // Mercurial Shield - need remove one 26464 Mercurial Shield aura
unitTarget->RemoveSingleSpellAurasFromStack(26464);
unitTarget->RemoveSingleAuraHolderFromStack(26464);
return;
case 25140: // Orb teleport spells
case 25143:
@ -6188,22 +6187,22 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
case 47422: // Everlasting Affliction
{
// Need refresh caster corruption auras on target
Unit::AuraMap& suAuras = unitTarget->GetAuras();
for(Unit::AuraMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr)
Unit::SpellAuraHolderMap& suAuras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr)
{
SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
if(spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
(spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000002)) &&
(*itr).second->GetCasterGUID() == m_caster->GetGUID())
(*itr).second->RefreshAura();
(*itr).second->RefreshHolder();
}
return;
}
case 63521: // Guarded by The Light (Paladin spell with SPELLFAMILY_WARLOCK)
{
// Divine Plea, refresh on target (3 aura slots)
if (Aura* aura = unitTarget->GetAura(54428, EFFECT_INDEX_0))
aura->RefreshAura();
if (SpellAuraHolder* holder = unitTarget->GetSpellAuraHolder(54428))
holder->RefreshHolder();
return;
}
@ -6220,15 +6219,15 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
return;
// Refresh Shadow Word: Pain on target
Unit::AuraMap& auras = unitTarget->GetAuras();
for(Unit::AuraMap::iterator itr = auras.begin(); itr != auras.end(); ++itr)
Unit::SpellAuraHolderMap& auras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
if (spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST &&
(spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000008000)) &&
(*itr).second->GetCasterGUID() == m_caster->GetGUID())
{
(*itr).second->RefreshAura();
(*itr).second->RefreshHolder();
return;
}
}
@ -6251,23 +6250,28 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
uint32 spellId = 0;
int32 basePoint = 0;
Unit* target = unitTarget;
Unit::AuraMap& Auras = unitTarget->GetAuras();
for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
Unit::SpellAuraHolderMap& Auras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
{
Aura *aura = (*i).second;
if (aura->GetCasterGUID() != m_caster->GetGUID())
SpellAuraHolder *holder = i->second;
if (holder->GetCasterGUID() != m_caster->GetGUID())
continue;
// Search only Serpent Sting, Viper Sting, Scorpid Sting auras
uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags;
uint64 familyFlag = holder->GetSpellProto()->SpellFamilyFlags;
if (!(familyFlag & UI64LIT(0x000000800000C000)))
continue;
// Refresh aura duration
aura->RefreshAura();
holder->RefreshHolder();
Aura *aura = holder->GetAuraByEffectIndex(EFFECT_INDEX_0);
if (!aura)
continue;
// Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
if ((familyFlag & UI64LIT(0x0000000000004000)) && aura->GetEffIndex() == EFFECT_INDEX_0)
if ((familyFlag & UI64LIT(0x0000000000004000)))
{
// m_amount already include RAP bonus
basePoint = aura->GetModifier()->m_amount * aura->GetAuraMaxTicks() * 40 / 100;
@ -6275,7 +6279,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
}
// Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
if ((familyFlag & UI64LIT(0x0000008000000000)) && aura->GetEffIndex() == EFFECT_INDEX_0)
if ((familyFlag & UI64LIT(0x0000008000000000)))
{
uint32 target_max_mana = unitTarget->GetMaxPower(POWER_MANA);
if (!target_max_mana)
@ -7317,13 +7321,13 @@ void Spell::EffectDispelMechanic(SpellEffectIndex eff_idx)
uint32 mechanic = m_spellInfo->EffectMiscValue[eff_idx];
Unit::AuraMap& Auras = unitTarget->GetAuras();
for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
Unit::SpellAuraHolderMap& Auras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next)
{
next = iter;
++next;
SpellEntry const *spell = sSpellStore.LookupEntry(iter->second->GetSpellProto()->Id);
if(spell->Mechanic == mechanic || spell->EffectMechanic[iter->second->GetEffIndex()] == mechanic)
if(spell->Mechanic == mechanic || iter->second->HasAuraAndMechanicEffect(mechanic))
{
unitTarget->RemoveAurasDueToSpell(spell->Id);
if(Auras.empty())
@ -7661,19 +7665,19 @@ void Spell::EffectStealBeneficialBuff(SpellEffectIndex eff_idx)
if(!unitTarget || unitTarget==m_caster) // can't steal from self
return;
std::vector <Aura *> steal_list;
std::vector <SpellAuraHolder *> steal_list;
// Create dispel mask by dispel type
uint32 dispelMask = GetDispellMask( DispelType(m_spellInfo->EffectMiscValue[eff_idx]) );
Unit::AuraMap const& auras = unitTarget->GetAuras();
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap();
for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
Aura *aur = (*itr).second;
if (aur && (1<<aur->GetSpellProto()->Dispel) & dispelMask)
SpellAuraHolder *holder = itr->second;
if (holder && (1<<holder->GetSpellProto()->Dispel) & dispelMask)
{
// Need check for passive? this
if (aur->IsPositive() && !aur->IsPassive() && !(aur->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE))
steal_list.push_back(aur);
if (holder->IsPositive() && !holder->IsPassive() && !(holder->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE))
steal_list.push_back(holder);
}
}
// Ok if exist some buffs for dispel try dispel it
@ -7685,16 +7689,16 @@ void Spell::EffectStealBeneficialBuff(SpellEffectIndex eff_idx)
for (int32 count=0; count < damage && list_size > 0; ++count)
{
// Random select buff for dispel
Aura *aur = steal_list[urand(0, list_size-1)];
SpellAuraHolder *holder = steal_list[urand(0, list_size-1)];
// Not use chance for steal
// TODO possible need do it
success_list.push_back( std::pair<uint32,uint64>(aur->GetId(),aur->GetCasterGUID()));
success_list.push_back( std::pair<uint32,uint64>(holder->GetId(),holder->GetCasterGUID()));
// Remove buff from list for prevent doubles
for (std::vector<Aura *>::iterator j = steal_list.begin(); j != steal_list.end(); )
for (std::vector<SpellAuraHolder *>::iterator j = steal_list.begin(); j != steal_list.end(); )
{
Aura *stealed = *j;
if (stealed->GetId() == aur->GetId() && stealed->GetCasterGUID() == aur->GetCasterGUID())
SpellAuraHolder *stealed = *j;
if (stealed->GetId() == holder->GetId() && stealed->GetCasterGUID() == holder->GetCasterGUID())
{
j = steal_list.erase(j);
--list_size;