diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/DataStores/DBCStructure.h | 2 | ||||
| -rw-r--r-- | src/server/game/DataStores/DBCfmt.h | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 117 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 1 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.h | 1 |
6 files changed, 33 insertions, 91 deletions
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index b0bea8ca81c..8c84e4596cf 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1404,7 +1404,7 @@ struct SpellEntry uint32 SpellVisual[2]; // 131-132 m_spellVisualID uint32 SpellIconID; // 133 m_spellIconID uint32 activeIconID; // 134 m_activeIconID - //uint32 spellPriority; // 135 not used + uint32 SpellPriority; // 135 m_spellPriority char* SpellName[16]; // 136-151 m_name_lang //uint32 SpellNameFlag; // 152 not used char* Rank[16]; // 153-168 m_nameSubtext_lang diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index dd74cffb51e..6651270848b 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -113,7 +113,7 @@ char const SpellDifficultyfmt[] = "niiii"; const std::string CustomSpellDifficultyfmt = "ppppp"; const std::string CustomSpellDifficultyIndex = "id"; char const SpellDurationfmt[] = "niii"; -char const SpellEntryfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx"; +char const SpellEntryfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiiissssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx"; const std::string CustomSpellEntryfmt = "papppppppppppapapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppaaappppppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaaaaaa"; const std::string CustomSpellEntryIndex = "Id"; char const SpellFocusObjectfmt[] = "nxxxxxxxxxxxxxxxxx"; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 266259b8257..6874c6a1f77 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -20869,6 +20869,10 @@ bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod if (mod->op == SPELLMOD_DURATION && spellInfo->GetDuration() == -1) return false; + // mod crit to spells that can't crit + if (mod->op == SPELLMOD_CRITICAL_CHANCE && !spellInfo->HasAttribute(SPELL_ATTR0_CU_CAN_CRIT)) + return false; + return spellInfo->IsAffectedBySpellMod(mod); } @@ -20882,103 +20886,48 @@ void Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* s float totalmul = 1.0f; int32 totalflat = 0; - // Drop charges for triggering spells instead of triggered ones - if (m_spellModTakingSpell) - spell = m_spellModTakingSpell; - - switch (op) + auto calculateSpellMod = [&](SpellModifier* mod) { - // special case, if a mod makes spell instant, only consume that mod - case SPELLMOD_CASTING_TIME: - { - SpellModifier* modInstantSpell = nullptr; - for (SpellModifier* mod : m_spellMods[op]) - { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) - continue; - - if (mod->type == SPELLMOD_PCT && basevalue < T(10000) && mod->value <= -100) - { - modInstantSpell = mod; - break; - } - } - - if (modInstantSpell) - { - Player::ApplyModToSpell(modInstantSpell, spell); - basevalue = T(0); - return; - } - break; - } - // special case if two mods apply 100% critical chance, only consume one - case SPELLMOD_CRITICAL_CHANCE: - { - SpellModifier* modCritical = nullptr; - for (SpellModifier* mod : m_spellMods[op]) - { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) - continue; - - if (mod->type == SPELLMOD_FLAT && mod->value >= 100) - { - modCritical = mod; - break; - } - } - - if (modCritical) - { - Player::ApplyModToSpell(modCritical, spell); - basevalue = T(100); - return; - } - break; - } - default: - break; - } - - for (SpellModifier* mod : m_spellMods[op]) - { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) - continue; - switch (mod->type) { case SPELLMOD_FLAT: totalflat += mod->value; break; case SPELLMOD_PCT: - { - // skip percent mods with null basevalue (most important for spell mods with charges) - if (basevalue == T(0)) - continue; - // special case (skip > 10sec spell casts for instant cast setting) if (op == SPELLMOD_CASTING_TIME && mod->value <= -100 && basevalue >= T(10000)) - continue; - else if (!Player::HasSpellModApplied(mod, spell)) - { - // special case for Surge of Light, don't apply critical chance reduction if other mods not applied (ie procs while casting another spell) - // (Surge of Light is the only PCT_MOD on critical chance) - if (op == SPELLMOD_CRITICAL_CHANCE) - continue; - // special case for Backdraft, dont' apply GCD reduction if cast time reduction wasn't applied (ie when Backlash is consumed first) - // (Backdraft is the only PCT_MOD on global cooldown) - else if (op == SPELLMOD_GLOBAL_COOLDOWN) - continue; - } + return; totalmul += CalculatePct(1.0f, mod->value); break; - } } Player::ApplyModToSpell(mod, spell); + }; + + // Drop charges for triggering spells instead of triggered ones + if (m_spellModTakingSpell) + spell = m_spellModTakingSpell; + + SpellModifier* chargedMod = nullptr; + for (SpellModifier* mod : m_spellMods[op]) + { + if (!IsAffectedBySpellmod(spellInfo, mod, spell)) + continue; + + if (mod->ownerAura->IsUsingCharges()) + { + if (!chargedMod || (chargedMod->ownerAura->GetSpellInfo()->Priority < mod->ownerAura->GetSpellInfo()->Priority)) + chargedMod = mod; + continue; + } + + calculateSpellMod(mod); } + if (chargedMod) + calculateSpellMod(chargedMod); + basevalue = T(float(basevalue + totalflat) * totalmul); } @@ -21023,14 +20972,6 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply) m_spellMods[mod->op].erase(mod); } -bool Player::HasSpellModApplied(SpellModifier* mod, Spell* spell) -{ - if (!spell) - return false; - - return spell->m_appliedMods.count(mod->ownerAura) != 0; -} - void Player::ApplyModToSpell(SpellModifier* mod, Spell* spell) { if (!spell) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index fd9c4230ca9..e828bdb5488 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1454,7 +1454,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> template <class T> void ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* spell = nullptr) const; static void ApplyModToSpell(SpellModifier* mod, Spell* spell); - static bool HasSpellModApplied(SpellModifier* mod, Spell* spell); void SetSpellModTakingSpell(Spell* spell, bool apply); void RemoveArenaSpellCooldowns(bool removeActivePetCooldowns = false); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 873bfbefdcf..88958e97fd3 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -841,6 +841,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry) SpellIconID = spellEntry->SpellIconID; ActiveIconID = spellEntry->activeIconID; + Priority = spellEntry->SpellPriority; for (uint8 i = 0; i < 16; ++i) SpellName[i] = spellEntry->SpellName[i]; diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index e117319a7f1..5670a9052a2 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -386,6 +386,7 @@ class TC_GAME_API SpellInfo uint32 SpellVisual[2]; uint32 SpellIconID; uint32 ActiveIconID; + uint32 Priority; char* SpellName[16]; char* Rank[16]; uint32 MaxTargetLevel; |
