diff options
| -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; | 
