diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 147 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 42 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 2 |
3 files changed, 108 insertions, 83 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index dbe61592ec1..e03e856e156 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -21199,13 +21199,25 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply) { WorldPackets::Spells::SpellModifierData modData; - for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr) - if ((*itr)->type == mod->type && (*itr)->mask & _mask) - modData.ModifierValue += (*itr)->value; + if (mod->type == SPELLMOD_FLAT) + { + for (SpellModList::iterator itr = m_spellMods[mod->op][SPELLMOD_FLAT].begin(); itr != m_spellMods[mod->op][SPELLMOD_FLAT].end(); ++itr) + if (*itr != mod && (*itr)->mask & _mask) + modData.ModifierValue += (*itr)->value; + + if (apply) + modData.ModifierValue += mod->value; + } + else + { + modData.ModifierValue = 1.0f; + for (SpellModList::iterator itr = m_spellMods[mod->op][SPELLMOD_PCT].begin(); itr != m_spellMods[mod->op][SPELLMOD_PCT].end(); ++itr) + if (*itr != mod && (*itr)->mask & _mask) + modData.ModifierValue *= CalculatePct(1.0f, (*itr)->value); - modData.ModifierValue += apply ? mod->value : -(mod->value); - if (mod->type == SPELLMOD_PCT) - modData.ModifierValue = 1.0f + (modData.ModifierValue * 0.01f); + if (apply) + modData.ModifierValue *= CalculatePct(1.0f, mod->value); + } modData.ClassIndex = eff; @@ -21217,10 +21229,10 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply) } if (apply) - m_spellMods[mod->op].push_back(mod); + m_spellMods[mod->op][mod->type].push_back(mod); else { - m_spellMods[mod->op].remove(mod); + m_spellMods[mod->op][mod->type].remove(mod); // mods bound to aura will be removed in AuraEffect::~AuraEffect if (!mod->ownerAura) delete mod; @@ -21237,49 +21249,52 @@ void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId, Aura* aura) for (uint8 i=0; i<MAX_SPELLMOD; ++i) { - for (SpellModList::iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end(); ++itr) + for (uint8 j = 0; j < SPELLMOD_END; ++j) { - SpellModifier* mod = *itr; + for (SpellModList::iterator itr = m_spellMods[i][j].begin(); itr != m_spellMods[i][j].end(); ++itr) + { + SpellModifier* mod = *itr; - // Spellmods without aura set cannot be charged - if (!mod->ownerAura || !mod->ownerAura->IsUsingCharges()) - continue; + // Spellmods without aura set cannot be charged + if (!mod->ownerAura || !mod->ownerAura->IsUsingCharges()) + continue; - // Restore only specific owner aura mods - if (ownerAuraId && (ownerAuraId != mod->ownerAura->GetSpellInfo()->Id)) - continue; + // Restore only specific owner aura mods + if (ownerAuraId && (ownerAuraId != mod->ownerAura->GetSpellInfo()->Id)) + continue; - if (aura && mod->ownerAura != aura) - continue; + if (aura && mod->ownerAura != aura) + continue; - // Check if mod affected this spell - // First, check if the mod aura applied at least one spellmod to this spell - Spell::UsedSpellMods::iterator iterMod = spell->m_appliedMods.find(mod->ownerAura); - if (iterMod == spell->m_appliedMods.end()) - continue; - // Second, check if the current mod is one of those applied by the mod aura - if (!(mod->mask & spell->m_spellInfo->SpellFamilyFlags)) - continue; + // Check if mod affected this spell + // First, check if the mod aura applied at least one spellmod to this spell + Spell::UsedSpellMods::iterator iterMod = spell->m_appliedMods.find(mod->ownerAura); + if (iterMod == spell->m_appliedMods.end()) + continue; + // Second, check if the current mod is one of those applied by the mod aura + if (!(mod->mask & spell->m_spellInfo->SpellFamilyFlags)) + continue; - // remove from list - This will be done after all mods have been gone through - // to ensure we iterate over all mods of an aura before removing said aura - // from applied mods (Else, an aura with two mods on the current spell would - // only see the first of its modifier restored) - aurasQueue.push_back(mod->ownerAura); + // remove from list - This will be done after all mods have been gone through + // to ensure we iterate over all mods of an aura before removing said aura + // from applied mods (Else, an aura with two mods on the current spell would + // only see the first of its modifier restored) + aurasQueue.push_back(mod->ownerAura); - // add mod charges back to mod - if (mod->charges == -1) - mod->charges = 1; - else - mod->charges++; + // add mod charges back to mod + if (mod->charges == -1) + mod->charges = 1; + else + mod->charges++; - // Do not set more spellmods than available - if (mod->ownerAura->GetCharges() < mod->charges) - mod->charges = mod->ownerAura->GetCharges(); + // Do not set more spellmods than available + 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 track these changes correctly - //ASSERT (mod->ownerAura->GetCharges() <= mod->charges); + // Skip this check for now - aura charges may change due to various reason + /// @todo track these changes correctly + //ASSERT (mod->ownerAura->GetCharges() <= mod->charges); + } } } @@ -21306,27 +21321,30 @@ void Player::RemoveSpellMods(Spell* spell) if (spell->m_appliedMods.empty()) return; - for (uint8 i=0; i<MAX_SPELLMOD; ++i) + for (uint8 i = 0; i < MAX_SPELLMOD; ++i) { - for (SpellModList::const_iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end();) + for (uint8 j = 0; j < SPELLMOD_END; ++j) { - SpellModifier* mod = *itr; - ++itr; + for (SpellModList::const_iterator itr = m_spellMods[i][j].begin(); itr != m_spellMods[i][j].end();) + { + SpellModifier* mod = *itr; + ++itr; - // spellmods without aura set cannot be charged - if (!mod->ownerAura || !mod->ownerAura->IsUsingCharges()) - continue; + // spellmods without aura set cannot be charged + if (!mod->ownerAura || !mod->ownerAura->IsUsingCharges()) + continue; - // check if mod affected this spell - Spell::UsedSpellMods::iterator iterMod = spell->m_appliedMods.find(mod->ownerAura); - if (iterMod == spell->m_appliedMods.end()) - continue; + // check if mod affected this spell + Spell::UsedSpellMods::iterator iterMod = spell->m_appliedMods.find(mod->ownerAura); + if (iterMod == spell->m_appliedMods.end()) + continue; - // remove from list - spell->m_appliedMods.erase(iterMod); + // remove from list + spell->m_appliedMods.erase(iterMod); - if (mod->ownerAura->DropCharge(AURA_REMOVE_BY_EXPIRE)) - itr = m_spellMods[i].begin(); + if (mod->ownerAura->DropCharge(AURA_REMOVE_BY_EXPIRE)) + itr = m_spellMods[i][j].begin(); + } } } } @@ -21379,16 +21397,13 @@ void Player::SendSpellModifiers() const pctMod.ModifierData[j].ClassIndex = j; pctMod.ModifierData[j].ModifierValue = 1.0f; - for (SpellModifier* mod : m_spellMods[i]) - { + for (SpellModifier* mod : m_spellMods[i][SPELLMOD_FLAT]) if (mod->mask & mask) - { - if (mod->type == SPELLMOD_FLAT) - flatMod.ModifierData[j].ModifierValue += mod->value; - else - pctMod.ModifierData[j].ModifierValue *= 1.0f + (mod->value * 0.01f); - } - } + flatMod.ModifierData[j].ModifierValue += mod->value; + + for (SpellModifier* mod : m_spellMods[i][SPELLMOD_PCT]) + if (mod->mask & mask) + pctMod.ModifierData[j].ModifierValue *= 1.0f + CalculatePct(1.0f, mod->value); } flatMod.ModifierData.erase(std::remove_if(flatMod.ModifierData.begin(), flatMod.ModifierData.end(), [](WorldPackets::Spells::SpellModifierData const& mod) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index c33ec0d2d4d..3c2248058b5 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -74,8 +74,9 @@ enum SkillFieldOffset // Note: SPELLMOD_* values is aura types in fact enum SpellModType { - SPELLMOD_FLAT = 107, // SPELL_AURA_ADD_FLAT_MODIFIER - SPELLMOD_PCT = 108 // SPELL_AURA_ADD_PCT_MODIFIER + SPELLMOD_FLAT = 0, // SPELL_AURA_ADD_FLAT_MODIFIER + SPELLMOD_PCT = 1, // SPELL_AURA_ADD_PCT_MODIFIER + SPELLMOD_END }; // 2^n values, Player::m_isunderwater is a bitmask. These are Trinity internal values, they are never send to any client @@ -2681,7 +2682,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> uint32 m_baseHealthRegen; int32 m_spellPenetrationItemMod; - SpellModList m_spellMods[MAX_SPELLMOD]; + SpellModList m_spellMods[MAX_SPELLMOD][SPELLMOD_END]; EnchantDurationList m_enchantDuration; ItemDurationList m_itemDuration; @@ -2864,7 +2865,7 @@ void Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* s if (m_spellModTakingSpell) spell = m_spellModTakingSpell; - for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr) + for (SpellModList::iterator itr = m_spellMods[op][SPELLMOD_FLAT].begin(); itr != m_spellMods[op][SPELLMOD_FLAT].end(); ++itr) { SpellModifier* mod = *itr; @@ -2875,21 +2876,30 @@ void Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* s if (!IsAffectedBySpellmod(spellInfo, mod, spell)) continue; - if (mod->type == SPELLMOD_FLAT) - totalflat += mod->value; - else if (mod->type == SPELLMOD_PCT) - { - // skip percent mods for null basevalue (most important for spell mods with charges) - if (basevalue == T(0)) - continue; + totalflat += mod->value; + DropModCharge(mod, spell); + } - // special case (skip > 10sec spell casts for instant cast setting) - if (mod->op == SPELLMOD_CASTING_TIME && basevalue >= T(10000) && mod->value <= -100) - continue; + for (SpellModList::iterator itr = m_spellMods[op][SPELLMOD_PCT].begin(); itr != m_spellMods[op][SPELLMOD_PCT].end(); ++itr) + { + SpellModifier* mod = *itr; - totalmul += CalculatePct(1.0f, mod->value); - } + // Charges can be set only for mods with auras + if (!mod->ownerAura) + ASSERT(mod->charges == 0); + + if (!IsAffectedBySpellmod(spellInfo, mod, spell)) + continue; + + // skip percent mods for null basevalue (most important for spell mods with charges) + if (basevalue + totalflat == T(0)) + continue; + + // special case (skip > 10sec spell casts for instant cast setting) + if (mod->op == SPELLMOD_CASTING_TIME && basevalue >= T(10000) && mod->value <= -100) + continue; + totalmul *= 1.0f + CalculatePct(1.0f, mod->value); DropModCharge(mod, spell); } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 96bf92a5cf8..395b732f6a7 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -809,7 +809,7 @@ void AuraEffect::CalculateSpellMod() m_spellmod = new SpellModifier(GetBase()); m_spellmod->op = SpellModOp(GetMiscValue()); - m_spellmod->type = SpellModType(uint32(GetAuraType())); // SpellModType value == spell aura types + m_spellmod->type = GetAuraType() == SPELL_AURA_ADD_PCT_MODIFIER ? SPELLMOD_PCT : SPELLMOD_FLAT; m_spellmod->spellId = GetId(); m_spellmod->mask = GetSpellEffectInfo()->SpellClassMask; m_spellmod->charges = GetBase()->GetCharges(); |
