diff options
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r-- | src/game/Player.cpp | 376 |
1 files changed, 219 insertions, 157 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 03078a35b3e..1f94d5a78fd 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -65,6 +65,7 @@ #include "GameEventMgr.h" #include "AchievementMgr.h" #include "SpellAuras.h" +#include "SpellAuraEffects.h" #include <cmath> @@ -945,7 +946,7 @@ int32 Player::getMaxTimer(MirrorTimerType timer) if (!isAlive() || HasAuraType(SPELL_AURA_WATER_BREATHING) || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING)) return DISABLED_MIRROR_TIMER; int32 UnderWaterTime = 3*MINUTE*IN_MILISECONDS; - AuraEffectList const& mModWaterBreathing = GetAurasByType(SPELL_AURA_MOD_WATER_BREATHING); + AuraEffectList const& mModWaterBreathing = GetAuraEffectsByType(SPELL_AURA_MOD_WATER_BREATHING); for (AuraEffectList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i) UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetAmount()) / 100.0f); return UnderWaterTime; @@ -2022,14 +2023,12 @@ void Player::RegenerateAll() HasAuraType(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT) || IsPolymorphed() ) { RegenerateHealth(); - if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) - { - Regenerate(POWER_RAGE); - if (getClass() == CLASS_DEATH_KNIGHT) - Regenerate(POWER_RUNIC_POWER); - } } + Regenerate(POWER_RAGE); + if (getClass() == CLASS_DEATH_KNIGHT) + Regenerate(POWER_RUNIC_POWER); + if(getClass() == CLASS_DEATH_KNIGHT) Regenerate(POWER_RUNE); @@ -2051,18 +2050,6 @@ void Player::Regenerate(Powers power) return; uint32 curValue = GetPower(power); - switch (power) - { - case POWER_RAGE: - case POWER_RUNIC_POWER: - if (curValue == 0) - return; - break; - default: - if (curValue == maxValue) - return; - break; - } // TODO: possible use of miscvalueb instead of amount if (HasAuraTypeWithValue(SPELL_AURA_PREVENT_REGENERATE_POWER, power)) @@ -2077,22 +2064,28 @@ void Player::Regenerate(Powers power) bool recentCast = IsUnderLastManaUseEffect(); float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA); if (recentCast) // Trinity Updates Mana in intervals of 2s, which is correct - addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer; + addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer; else - addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer; + addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer; } break; case POWER_RAGE: // Regenerate rage { - float RageDecreaseRate = sWorld.getRate(RATE_POWER_RAGE_LOSS); - addvalue = 20 * RageDecreaseRate; // 2 rage by tick (= 2 seconds => 1 rage/sec) + if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) + { + float RageDecreaseRate = sWorld.getRate(RATE_POWER_RAGE_LOSS); + addvalue += -20 * RageDecreaseRate; // 2 rage by tick (= 2 seconds => 1 rage/sec) + } } break; case POWER_ENERGY: // Regenerate energy (rogue) - addvalue = 0.01f * m_regenTimer; + addvalue += 0.01f * m_regenTimer; break; case POWER_RUNIC_POWER: { - float RunicPowerDecreaseRate = sWorld.getRate(RATE_POWER_RUNICPOWER_LOSS); - addvalue = 30 * RunicPowerDecreaseRate; // 3 RunicPower by tick + if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) + { + float RunicPowerDecreaseRate = sWorld.getRate(RATE_POWER_RUNICPOWER_LOSS); + addvalue += -30 * RunicPowerDecreaseRate; // 3 RunicPower by tick + } } break; case POWER_RUNE: case POWER_FOCUS: @@ -2102,44 +2095,58 @@ void Player::Regenerate(Powers power) } // Mana regen calculated in Player::UpdateManaRegen() - // Exist only for POWER_MANA, POWER_ENERGY, POWER_FOCUS auras if (power != POWER_MANA) { - AuraEffectList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT); + AuraEffectList const& ModPowerRegenPCTAuras = GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT); for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i) if ((*i)->GetMiscValue() == power) addvalue *= ((*i)->GetAmount() + 100) / 100.0f; + + // Butchery requires combat for this effect + if (power != POWER_RUNIC_POWER || isInCombat()) + addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * ((power != POWER_ENERGY) ? m_regenTimerCount : m_regenTimer) / (5 * IN_MILISECONDS); } + if (addvalue < 0.0f) + { + if (curValue == 0) + return; + } + else if (addvalue > 0.0f) + { + if (curValue == maxValue) + return; + } + else + return; + addvalue += m_powerFraction[power]; - uint32 integerValue = uint32(addvalue); + uint32 integerValue = uint32(abs(addvalue)); - switch (power) + if (addvalue < 0.0f) { - case POWER_RAGE: - case POWER_RUNIC_POWER: - if(curValue > integerValue) - { - curValue -= integerValue; - m_powerFraction[power] = addvalue - integerValue; - } - else - { - curValue = 0; - m_powerFraction[power] = 0; - } - break; - default: - curValue += integerValue; + if(curValue > integerValue) + { + curValue -= integerValue; + m_powerFraction[power] = addvalue + integerValue; + } + else + { + curValue = 0; + m_powerFraction[power] = 0; + } + } + else + { + curValue += integerValue; - if (curValue > maxValue) - { - curValue = maxValue; - m_powerFraction[power] = 0; - } - else - m_powerFraction[power] = addvalue - integerValue; - break; + if (curValue > maxValue) + { + curValue = maxValue; + m_powerFraction[power] = 0; + } + else + m_powerFraction[power] = addvalue - integerValue; } if(m_regenTimerCount >= 2000) SetPower(power, curValue); @@ -2168,9 +2175,11 @@ void Player::RegenerateHealth() addvalue = OCTRegenHPPerSpirit()* HealthIncreaseRate; if (!isInCombat()) { - AuraEffectList const& mModHealthRegenPct = GetAurasByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT); + AuraEffectList const& mModHealthRegenPct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT); for (AuraEffectList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i) addvalue *= (100.0f + (*i)->GetAmount()) / 100.0f; + + addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * 2 * IN_MILISECONDS / (5 * IN_MILISECONDS); } else if (HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT)) addvalue *= GetTotalAuraModifier(SPELL_AURA_MOD_REGEN_DURING_COMBAT) / 100.0f; @@ -2330,7 +2339,7 @@ void Player::SetGameMaster(bool on) else { // restore phase - AuraEffectList const& phases = GetAurasByType(SPELL_AURA_PHASE); + AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE); SetPhaseMask(!phases.empty() ? phases.front()->GetMiscValue() : PHASEMASK_NORMAL,false); m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON; @@ -4454,9 +4463,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) { int32 delta = (int32(getLevel()) - startLevel + 1)*MINUTE; - if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS, GetGUID())) + if(Aura * aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS, GetGUID())) { - Aur->SetAuraDuration(delta*IN_MILISECONDS); + aur->SetDuration(delta*IN_MILISECONDS); } } } @@ -5194,10 +5203,10 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply) int32 amount = uint32(m_baseRatingValue[cr]); // Apply bonus from SPELL_AURA_MOD_RATING_FROM_STAT // stat used stored in miscValueB for this aura - AuraEffectList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT); + AuraEffectList const& modRatingFromStat = GetAuraEffectsByType(SPELL_AURA_MOD_RATING_FROM_STAT); for (AuraEffectList::const_iterator i = modRatingFromStat.begin(); i != modRatingFromStat.end(); ++i) if ((*i)->GetMiscValue() & (1<<cr)) - amount += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetAmount() / 100.0f); + amount += int32(GetStat(Stats((*i)->GetMiscValueB())) * (*i)->GetAmount() / 100.0f); if (amount < 0) amount = 0; SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, uint32(amount)); @@ -5723,16 +5732,16 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal) SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0); // temporary bonuses - AuraEffectList const& mModSkill = GetAurasByType(SPELL_AURA_MOD_SKILL); + AuraEffectList const& mModSkill = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL); for (AuraEffectList::const_iterator j = mModSkill.begin(); j != mModSkill.end(); ++j) if ((*j)->GetMiscValue() == int32(id)) - (*j)->ApplyModifier(true); + (*j)->HandleEffect(this, 0, true); // permanent bonuses - AuraEffectList const& mModSkillTalent = GetAurasByType(SPELL_AURA_MOD_SKILL_TALENT); + AuraEffectList const& mModSkillTalent = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_TALENT); for (AuraEffectList::const_iterator j = mModSkillTalent.begin(); j != mModSkillTalent.end(); ++j) if ((*j)->GetMiscValue() == int32(id)) - (*j)->ApplyModifier(true); + (*j)->HandleEffect(this, 0, true); // Learn all spells for skill learnSkillRewardedSpells(id, currVal); @@ -6826,19 +6835,21 @@ void Player::DuelComplete(DuelCompleteType type) duel->initiator->RemoveGameObject(obj,true); /* remove auras */ - AuraMap &itsAuras = duel->opponent->GetAuras(); - for (AuraMap::iterator i = itsAuras.begin(); i != itsAuras.end();) + AuraApplicationMap &itsAuras = duel->opponent->GetAppliedAuras(); + for (AuraApplicationMap::iterator i = itsAuras.begin(); i != itsAuras.end();) { - if (!i->second->IsPositive() && i->second->GetCasterGUID() == GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime) + Aura const * aura = i->second->GetBase(); + if (!i->second->IsPositive() && aura->GetCasterGUID() == GetGUID() && aura->GetApplyTime() >= duel->startTime) duel->opponent->RemoveAura(i); else ++i; } - AuraMap &myAuras = GetAuras(); - for (AuraMap::iterator i = myAuras.begin(); i != myAuras.end();) + AuraApplicationMap &myAuras = GetAppliedAuras(); + for (AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();) { - if (!i->second->IsPositive() && i->second->GetCasterGUID() == duel->opponent->GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime) + Aura const * aura = i->second->GetBase(); + if (!i->second->IsPositive() && aura->GetCasterGUID() == duel->opponent->GetGUID() && aura->GetApplyTime() >= duel->startTime) RemoveAura(i); else ++i; @@ -7215,20 +7226,20 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl void Player::_ApplyWeaponDependentAuraMods(Item *item,WeaponAttackType attackType,bool apply) { - AuraEffectList const& auraCritList = GetAurasByType(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); + AuraEffectList const& auraCritList = GetAuraEffectsByType(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); for (AuraEffectList::const_iterator itr = auraCritList.begin(); itr!=auraCritList.end(); ++itr) _ApplyWeaponDependentAuraCritMod(item,attackType,*itr,apply); - AuraEffectList const& auraDamageFlatList = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE); + AuraEffectList const& auraDamageFlatList = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE); for (AuraEffectList::const_iterator itr = auraDamageFlatList.begin(); itr!=auraDamageFlatList.end(); ++itr) _ApplyWeaponDependentAuraDamageMod(item,attackType,*itr,apply); - AuraEffectList const& auraDamagePCTList = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + AuraEffectList const& auraDamagePCTList = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); for (AuraEffectList::const_iterator itr = auraDamagePCTList.begin(); itr!=auraDamagePCTList.end(); ++itr) _ApplyWeaponDependentAuraDamageMod(item,attackType,*itr,apply); } -void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, AuraEffect* aura, bool apply) +void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, AuraEffect const* aura, bool apply) { // generic not weapon specific case processes in aura code if (aura->GetSpellProto()->EquippedItemClass == -1) @@ -7247,7 +7258,7 @@ void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attac HandleBaseModValue(mod, FLAT_MOD, float (aura->GetAmount()), apply); } -void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, AuraEffect* aura, bool apply) +void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, AuraEffect const* aura, bool apply) { //don't apply mod if item is broken if (item->IsBroken()) @@ -7271,7 +7282,7 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType att } UnitModifierType unitModType = TOTAL_VALUE; - switch (aura->GetAuraName()) + switch (aura->GetAuraType()) { case SPELL_AURA_MOD_DAMAGE_DONE: unitModType = TOTAL_VALUE; break; case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: unitModType = TOTAL_PCT; break; @@ -7322,9 +7333,9 @@ void Player::ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply if (form_change) // check aura active state from other form { - AuraMap const& auras = GetAuras(); - for (AuraMap::const_iterator itr = auras.lower_bound(spellInfo->Id); itr != auras.upper_bound(spellInfo->Id); ++itr) - if (!item || itr->second->GetCastItemGUID()==item->GetGUID()) + AuraApplicationMap const& auras = GetAppliedAuras(); + for (AuraApplicationMap::const_iterator itr = auras.lower_bound(spellInfo->Id); itr != auras.upper_bound(spellInfo->Id); ++itr) + if (!item || itr->second->GetBase()->GetCastItemGUID() == item->GetGUID()) return; } @@ -13851,7 +13862,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver uint32 XP = q_status.m_rewarded ? 0 : uint32(pQuest->XPValue( this )*sWorld.getRate(RATE_XP_QUEST)); // handle SPELL_AURA_MOD_XP_QUEST_PCT auras - Unit::AuraEffectList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_QUEST_PCT); + Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT); for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i) XP = uint32(XP*(1.0f + (*i)->GetAmount() / 100.0f)); @@ -16007,24 +16018,29 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) { sLog.outDebug("Loading auras for player %u",GetGUIDLow()); - //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_mask,stackcount,amount0,amount1,amount2,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow()); + //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow()); if (result) { do { int32 damage[3]; + int32 baseDamage[3]; Field *fields = result->Fetch(); uint64 caster_guid = fields[0].GetUInt64(); uint32 spellid = fields[1].GetUInt32(); uint8 effmask = fields[2].GetUInt8(); - uint8 stackcount = fields[3].GetUInt8(); - damage[0] = fields[4].GetInt32(); - damage[1] = fields[5].GetInt32(); - damage[2] = fields[6].GetInt32(); - int32 maxduration = fields[7].GetInt32(); - int32 remaintime = fields[8].GetInt32(); - uint8 remaincharges = fields[9].GetUInt8(); + uint8 recalculatemask = fields[3].GetUInt8(); + uint8 stackcount = fields[4].GetUInt8(); + damage[0] = fields[5].GetInt32(); + damage[1] = fields[6].GetInt32(); + damage[2] = fields[7].GetInt32(); + baseDamage[0] = fields[8].GetInt32(); + baseDamage[1] = fields[9].GetInt32(); + baseDamage[2] = fields[10].GetInt32(); + int32 maxduration = fields[11].GetInt32(); + int32 remaintime = fields[12].GetInt32(); + uint8 remaincharges = fields[13].GetUInt8(); SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid); if (!spellproto) @@ -16051,15 +16067,17 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) else remaincharges = 0; - Aura* aura = new Aura(spellproto, effmask, this, this, this); - aura->SetLoadedState(caster_guid,maxduration,remaintime,remaincharges, stackcount, &damage[0]); - if (!aura->CanBeSaved()) + if (Aura * aura = Aura::TryCreate(spellproto, effmask, this, NULL, &baseDamage[0], NULL, caster_guid)) { - delete aura; - continue; + if (!aura->CanBeSaved()) + { + aura->Remove(); + continue; + } + aura->SetLoadedState(maxduration,remaintime,remaincharges,stackcount,recalculatemask,&damage[0]); + aura->ApplyForTargets(); + sLog.outDetail("Added aura spellid %u, effectmask %u", spellproto->Id, effmask); } - AddAura(aura); - sLog.outDetail("Added aura spellid %u, effectmask %u", spellproto->Id, effmask); } while (result->NextRow()); @@ -17170,26 +17188,39 @@ void Player::_SaveAuras() { CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow()); - AuraMap const& auras = GetAuras(); - for (AuraMap::const_iterator itr = auras.begin(); itr !=auras.end() ; ++itr) + for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end() ; ++itr) { if (!itr->second->CanBeSaved()) continue; - int32 amounts[MAX_SPELL_EFFECTS]; + Aura * aura = itr->second; + + int32 damage[MAX_SPELL_EFFECTS]; + int32 baseDamage[MAX_SPELL_EFFECTS]; + uint8 effMask = 0; + uint8 recalculateMask = 0; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { - if (AuraEffect * partAura = itr->second->GetPartAura(i)) - amounts[i] = partAura->GetAmount(); + if (aura->GetEffect(i)) + { + baseDamage[i] = aura->GetEffect(i)->GetBaseAmount(); + damage[i] = aura->GetEffect(i)->GetAmount(); + effMask |= (1<<i); + if (aura->GetEffect(i)->CanBeRecalculated()) + recalculateMask |= (1<<i); + } else - amounts[i] = 0; + { + baseDamage[i] = NULL; + damage[i] = NULL; + } } - CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_mask,stackcount,amount0,amount1,amount2,maxduration,remaintime,remaincharges) " - "VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%u')", - GetGUIDLow(), itr->second->GetCasterGUID(), itr->second->GetId(), itr->second->GetEffectMask(), - itr->second->GetStackAmount(), amounts[0], amounts[1], amounts[2], - itr->second->GetAuraMaxDuration(),itr->second->GetAuraDuration(),itr->second->GetAuraCharges()); + CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges) " + "VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')", + GetGUIDLow(), itr->second->GetCasterGUID(), itr->second->GetId(), effMask, recalculateMask, + itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2], + itr->second->GetMaxDuration(), itr->second->GetDuration(),itr->second->GetCharges()); } } @@ -18204,6 +18235,7 @@ bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mo void Player::AddSpellMod(SpellModifier* mod, bool apply) { + sLog.outDebug("Player::AddSpellMod %d", mod->spellId); uint16 Opcode = (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER; int i = 0; @@ -18236,7 +18268,9 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply) else { m_spellMods[mod->op].remove(mod); - delete mod; + // mods bound to aura will be removed in AuraEffect::~AuraEffect + if (!mod->ownerAura) + delete mod; } } @@ -18253,7 +18287,7 @@ void Player::RestoreSpellMods(Spell * spell) SpellModifier *mod = *itr; // spellmods without aura set cannot be charged - if (!mod->ownerAura || !mod->ownerAura->GetAuraCharges()) + if (!mod->ownerAura || !mod->ownerAura->GetCharges()) continue; // check if mod affected this spell @@ -18271,12 +18305,12 @@ void Player::RestoreSpellMods(Spell * spell) mod->charges++; // Do not set more spellmods than avalible - if (mod->ownerAura->GetAuraCharges() < mod->charges) - mod->charges = mod->ownerAura->GetAuraCharges(); + if (mod->ownerAura->GetCharges() < mod->charges) + mod->charges = mod->ownerAura->GetCharges(); // Skip this check for now - aura charges may change due to various reason // TODO: trac these changes correctly - //assert (mod->ownerAura->GetAuraCharges() <= mod->charges); + //assert (mod->ownerAura->GetCharges() <= mod->charges); } } } @@ -18287,27 +18321,28 @@ void Player::RemoveSpellMods(Spell * spell) return; std::set <Aura *> checkedSpells; - AuraEffectList const & auraList = GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE); + AuraEffectList const & auraList = GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE); for (AuraEffectList::const_iterator itr = auraList.begin(); itr != auraList.end();) { - AuraEffect * aur = *itr; + AuraEffect * aurEff = *itr; + Aura * aura = aurEff->GetBase(); ++itr; - if (!aur->GetParentAura()->GetAuraCharges()) + if (!aura->GetCharges()) continue; - SpellEntry const * spellInfo = aur->GetSpellProto(); + SpellEntry const * spellInfo = aura->GetSpellProto(); if (spellInfo->SpellFamilyName != spell->m_spellInfo->SpellFamilyName || - checkedSpells.find(aur->GetParentAura()) != checkedSpells.end()) + checkedSpells.find(aura) != checkedSpells.end()) continue; - if (spell->m_spellInfo->SpellFamilyFlags & spellInfo->EffectSpellClassMask[aur->GetEffIndex()] + if (spell->m_spellInfo->SpellFamilyFlags & spellInfo->EffectSpellClassMask[aurEff->GetEffIndex()] // this is for fingers of frost, look at spell::finish part, a charge will be taken by the triggering spell - && aur->GetParentAura()->GetAuraDuration() != aur->GetParentAura()->GetAuraMaxDuration()) + && aura->GetDuration() != aura->GetMaxDuration()) { - checkedSpells.insert(aur->GetParentAura()); - spell->m_appliedMods.erase(aur->GetParentAura()); - if (aur->GetParentAura()->DropAuraCharge()) + checkedSpells.insert(aura); + spell->m_appliedMods.erase(aura); + if (aura->DropCharge()) itr = auraList.begin(); } } @@ -18323,7 +18358,7 @@ void Player::RemoveSpellMods(Spell * spell) ++itr; // spellmods without aura set cannot be charged - if (!mod->ownerAura || !mod->ownerAura->GetAuraCharges()) + if (!mod->ownerAura || !mod->ownerAura->GetCharges()) continue; // check if mod affected this spell @@ -18334,7 +18369,7 @@ void Player::RemoveSpellMods(Spell * spell) // remove from list spell->m_appliedMods.erase(iterMod); - if (mod->ownerAura->DropAuraCharge()) + if (mod->ownerAura->DropCharge()) itr = m_spellMods[i].begin(); } } @@ -19565,7 +19600,7 @@ void Player::SetBattleGroundEntryPoint() // Mount spell id storing if (IsMounted()) { - AuraEffectList const& auras = GetAurasByType(SPELL_AURA_MOUNTED); + AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_MOUNTED); if (!auras.empty()) m_bgData.mountSpell = (*auras.begin())->GetId(); } @@ -20181,15 +20216,15 @@ void Player::SendInitialPacketsAfterAddToMap() }; for (AuraType const* itr = &auratypes[0]; itr && itr[0] != SPELL_AURA_NONE; ++itr) { - Unit::AuraEffectList const& auraList = GetAurasByType(*itr); + Unit::AuraEffectList const& auraList = GetAuraEffectsByType(*itr); if(!auraList.empty()) - auraList.front()->ApplyModifier(true,true); + auraList.front()->HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true); } if(HasAuraType(SPELL_AURA_MOD_STUN)) SetMovement(MOVE_ROOT); - // manual send package (have code in ApplyModifier(true,true); that don't must be re-applied. + // manual send package (have code in HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true); that don't must be re-applied. if(HasAuraType(SPELL_AURA_MOD_ROOT)) { WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10); @@ -20489,29 +20524,28 @@ void Player::SendAurasForTarget(Unit *target) Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras(); for (Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr) { - Aura * aura=itr->second; - data << uint8(aura->GetAuraSlot()); + AuraApplication * auraApp = itr->second; + Aura * aura = auraApp->GetBase(); + data << uint8(auraApp->GetSlot()); data << uint32(aura->GetId()); // flags - data << aura->m_auraFlags; + uint32 flags = auraApp->GetFlags(); + if (aura->GetMaxDuration() > 0) + flags |= AFLAG_DURATION; + data << uint8(flags); // level - data << aura->m_auraLevel; + data << uint8(aura->GetCasterLevel()); // charges - data << uint8(aura->GetStackAmount()>1 ? aura->GetStackAmount() : aura->GetAuraCharges()); + data << uint8(aura->GetStackAmount() > 1 ? aura->GetStackAmount() : (aura->GetCharges()) ? aura->GetCharges() : 1); - if(!(aura->m_auraFlags & AFLAG_CASTER)) - { - if (Unit * caster = aura->GetCaster()) - data.append(caster->GetPackGUID()); - else - data << uint8(0); - } + if(!(flags & AFLAG_CASTER)) + data.appendPackGUID(aura->GetCasterGUID()); - if(aura->m_auraFlags & AFLAG_DURATION) // include aura duration + if(flags & AFLAG_DURATION) // include aura duration { - data << uint32(aura->GetAuraMaxDuration()); - data << uint32(aura->GetAuraDuration()); + data << uint32(aura->GetMaxDuration()); + data << uint32(aura->GetDuration()); } } @@ -20847,14 +20881,13 @@ bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const void Player::RemoveItemDependentAurasAndCasts( Item * pItem ) { - AuraMap& auras = GetAuras(); - for (AuraMap::iterator itr = auras.begin(); itr != auras.end();) + for (AuraMap::iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end();) { - Aura* aura = itr->second; + Aura * aura = itr->second; // skip passive (passive item dependent spells work in another way) and not self applied auras SpellEntry const* spellInfo = aura->GetSpellProto(); - if(aura->IsPassive() || aura->GetCasterGUID()!=GetGUID()) + if(aura->IsPassive() || aura->GetCasterGUID() != GetGUID()) { ++itr; continue; @@ -20868,7 +20901,7 @@ void Player::RemoveItemDependentAurasAndCasts( Item * pItem ) } // no alt item, remove aura, restart check - RemoveAura(itr); + RemoveOwnedAura(itr); } // currently casted spells can be dependent from item @@ -20883,7 +20916,7 @@ uint32 Player::GetResurrectionSpellId() // search priceless resurrection possibilities uint32 prio = 0; uint32 spell_id = 0; - AuraEffectList const& dummyAuras = GetAurasByType(SPELL_AURA_DUMMY); + AuraEffectList const& dummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY); for (AuraEffectList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) { // Soulstone Resurrection // prio: 3 (max, non death persistent) @@ -20997,7 +21030,7 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim) uint32 itr_xp = (member_with_max_level == not_gray_member_with_max_level) ? uint32(xp*rate) : uint32((xp*rate/2)+1); // handle SPELL_AURA_MOD_XP_PCT auras - Unit::AuraEffectList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_PCT); + Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT); for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i) itr_xp = uint32(itr_xp*(1.0f + (*i)->GetAmount() / 100.0f)); @@ -21031,7 +21064,7 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim) RewardReputation(pVictim,1); // handle SPELL_AURA_MOD_XP_PCT auras - Unit::AuraEffectList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_PCT); + Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT); for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i) xp = uint32(xp*(1.0f + (*i)->GetAmount() / 100.0f)); @@ -21158,11 +21191,11 @@ void Player::UpdateZoneDependentAuras( uint32 newZone ) void Player::UpdateAreaDependentAuras( uint32 newArea ) { // remove auras from spells with area limitations - for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();) + for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();) { // use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date if(spellmgr.GetSpellAllowedInLocationError(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea,this) != SPELL_CAST_OK) - RemoveAura(iter); + RemoveOwnedAura(iter); else ++iter; } @@ -21575,7 +21608,7 @@ void Player::InitGlyphsForLevel() bool Player::isTotalImmune() { - AuraEffectList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY); + AuraEffectList const& immune = GetAuraEffectsByType(SPELL_AURA_SCHOOL_IMMUNITY); uint32 immuneMask = 0; for (AuraEffectList::const_iterator itr = immune.begin(); itr != immune.end(); ++itr) @@ -21626,7 +21659,7 @@ void Player::SetTitle(CharTitlesEntry const* title, bool lost) /*-----------------------TRINITY--------------------------*/ bool Player::isTotalImmunity() { - AuraEffectList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY); + AuraEffectList const& immune = GetAuraEffectsByType(SPELL_AURA_SCHOOL_IMMUNITY); for (AuraEffectList::const_iterator itr = immune.begin(); itr != immune.end(); ++itr) { @@ -21656,9 +21689,9 @@ void Player::UpdateCharmedAI() //kill self if charm aura has infinite duration if(charmer->IsInEvadeMode()) { - AuraEffectList const& auras = GetAurasByType(SPELL_AURA_MOD_CHARM); + AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_MOD_CHARM); for (AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) - if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->IsPermanent()) + if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetBase()->IsPermanent()) { charmer->DealDamage(this, GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); return; @@ -21680,6 +21713,34 @@ void Player::UpdateCharmedAI() } } +void Player::RemoveRunesByAuraEffect(AuraEffect const * aura) +{ + for(uint8 i = 0; i < MAX_RUNES; ++i) + { + if (m_runes->runes[i].ConvertAura == aura) + { + ConvertRune(i, GetBaseRune(i)); + SetRuneConvertAura(i, NULL); + } + } +} + +void Player::RestoreBaseRune(uint8 index) +{ + AuraEffect const * aura = m_runes->runes[index].ConvertAura; + ConvertRune(index, GetBaseRune(index)); + SetRuneConvertAura(index, NULL); + // Don't drop passive talents providing rune convertion + if (!aura || aura->GetAuraType() != SPELL_AURA_CONVERT_RUNE) + return; + for(uint8 i = 0; i < MAX_RUNES; ++i) + { + if (aura == m_runes->runes[i].ConvertAura) + return; + } + aura->GetBase()->Remove(); +} + void Player::ConvertRune(uint8 index, RuneType newType) { SetCurrentRune(index, newType); @@ -21732,6 +21793,7 @@ void Player::InitRunes() SetBaseRune(i, runeSlotTypes[i]); // init base types SetCurrentRune(i, runeSlotTypes[i]); // init current types SetRuneCooldown(i, 0); // reset cooldowns + SetRuneConvertAura(i, NULL); m_runes->SetRuneState(i); } @@ -21915,7 +21977,7 @@ uint32 Player::GetPhaseMaskForSpawn() const phase = GetPhaseMask(); else { - AuraEffectList const& phases = GetAurasByType(SPELL_AURA_PHASE); + AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE); if (!phases.empty()) phase = phases.front()->GetMiscValue(); } @@ -22034,7 +22096,7 @@ void Player::HandleFall(MovementInfo const& movementInfo) DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall); } } - RemoveAura(44795); // No fly zone - Parachute + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // No fly zone - Parachute } void Player::UpdateAchievementCriteria( AchievementCriteriaTypes type, uint32 miscvalue1/*=0*/, uint32 miscvalue2/*=0*/, Unit *unit/*=NULL*/, uint32 time/*=0*/ ) |