fix(Core/Spells): Implemented spell priorities. (#11278)

* fix(Core/Spells): Implemented spell priorities.

Fixes #11261

* Update.

* Update.

* Update.
This commit is contained in:
UltraNix
2022-04-16 15:28:24 +02:00
committed by GitHub
parent 13993a0b5b
commit 5a9bf21cd8
6 changed files with 83 additions and 21 deletions

View File

@@ -36,7 +36,9 @@
#include "PlayerSettings.h"
#include "PlayerTaxi.h"
#include "QuestDef.h"
#include "SpellAuras.h"
#include "SpellMgr.h"
#include "SpellInfo.h"
#include "TradeData.h"
#include "Unit.h"
#include "WorldSession.h"
@@ -2920,32 +2922,28 @@ template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& bas
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
return 0;
}
float totalmul = 1.0f;
int32 totalflat = 0;
// Drop charges for triggering spells instead of triggered ones
if (m_spellModTakingSpell)
spell = m_spellModTakingSpell;
for (auto mod : m_spellMods[op])
auto calculateSpellMod = [&](SpellModifier* mod)
{
// Charges can be set only for mods with auras
if (!mod->ownerAura)
ASSERT(mod->charges == 0);
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
continue;
// xinef: temporary pets cannot use charged mods of owner, needed for mirror image QQ they should use their own auras
if (temporaryPet && mod->charges != 0)
continue;
{
return;
}
if (mod->type == SPELLMOD_FLAT)
{
// xinef: do not allow to consume more than one 100% crit increasing spell
if (mod->op == SPELLMOD_CRITICAL_CHANCE && totalflat >= 100)
continue;
{
return;
}
totalflat += mod->value;
}
@@ -2953,32 +2951,88 @@ template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& bas
{
// skip percent mods for null basevalue (most important for spell mods with charges)
if (basevalue == T(0) || totalmul == 0.0f)
continue;
{
return;
}
// special case (skip > 10sec spell casts for instant cast setting)
if (mod->op == SPELLMOD_CASTING_TIME && basevalue >= T(10000) && mod->value <= -100)
continue;
{
return;
}
// xinef: special exception for surge of light, dont affect crit chance if previous mods were not applied
else if (mod->op == SPELLMOD_CRITICAL_CHANCE && spell && !HasSpellMod(mod, spell))
continue;
{
return;
}
// xinef: special case for backdraft gcd reduce with backlast time reduction, dont affect gcd if cast time was not applied
else if (mod->op == SPELLMOD_GLOBAL_COOLDOWN && spell && !HasSpellMod(mod, spell))
continue;
{
return;
}
// xinef: those two mods should be multiplicative (Glyph of Renew)
if (mod->op == SPELLMOD_DAMAGE || mod->op == SPELLMOD_DOT)
{
totalmul *= CalculatePct(1.0f, 100.0f + mod->value);
}
else
{
totalmul += CalculatePct(1.0f, mod->value);
}
}
DropModCharge(mod, spell);
};
// Drop charges for triggering spells instead of triggered ones
if (m_spellModTakingSpell)
{
spell = m_spellModTakingSpell;
}
SpellModifier* chargedMod = nullptr;
for (auto mod : m_spellMods[op])
{
// Charges can be set only for mods with auras
if (!mod->ownerAura)
{
ASSERT(!mod->charges);
}
if (!IsAffectedBySpellmod(spellInfo, mod, spell))
{
continue;
}
if (mod->ownerAura->IsUsingCharges())
{
if (!chargedMod || (chargedMod->ownerAura->GetSpellInfo()->SpellPriority < mod->ownerAura->GetSpellInfo()->SpellPriority))
{
chargedMod = mod;
}
continue;
}
calculateSpellMod(mod);
}
if (chargedMod)
{
calculateSpellMod(chargedMod);
}
float diff = 0.0f;
if (op == SPELLMOD_CASTING_TIME || op == SPELLMOD_DURATION)
{
diff = ((float)basevalue + totalflat) * (totalmul - 1.0f) + (float)totalflat;
}
else
{
diff = (float)basevalue * (totalmul - 1.0f) + (float)totalflat;
}
basevalue = T((float)basevalue + diff);
return T(diff);
}

View File

@@ -831,6 +831,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry)
SpellVisual = spellEntry->SpellVisual;
SpellIconID = spellEntry->SpellIconID;
ActiveIconID = spellEntry->ActiveIconID;
SpellPriority = spellEntry->SpellPriority;
SpellName = spellEntry->SpellName;
Rank = spellEntry->Rank;
MaxTargetLevel = spellEntry->MaxTargetLevel;

View File

@@ -377,6 +377,7 @@ public:
std::array<uint32, 2> SpellVisual;
uint32 SpellIconID;
uint32 ActiveIconID;
uint32 SpellPriority;
std::array<char const*, 16> SpellName;
std::array<char const*, 16> Rank;
uint32 MaxTargetLevel;

View File

@@ -244,7 +244,6 @@ void SpellMgr::LoadSpellInfoCorrections()
48108, // Hot Streak
51124, // Killing Machine
54741, // Firestarter
57761, // Fireball!
64823, // Item - Druid T8 Balance 4P Bonus
34477, // Misdirection
44401, // Missile Barrage
@@ -254,6 +253,13 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->ProcCharges = 1;
});
// Fireball
ApplySpellFix({ 57761 }, [](SpellInfo* spellInfo)
{
spellInfo->ProcCharges = 1;
spellInfo->SpellPriority = 50;
});
// Tidal Wave
ApplySpellFix({ 53390 }, [](SpellInfo* spellInfo)
{

View File

@@ -1637,7 +1637,7 @@ struct SpellEntry
std::array<uint32, 2> SpellVisual; // 131-132 m_spellVisualID
uint32 SpellIconID; // 133 m_spellIconID
uint32 ActiveIconID; // 134 m_activeIconID
//uint32 SpellPriority; // 135 not used
uint32 SpellPriority; // 135 not used
std::array<char const*, 16> SpellName; // 136-151 m_name_lang
//uint32 SpellNameFlag; // 152 not used
std::array<char const*, 16> Rank; // 153-168 m_nameSubtext_lang

View File

@@ -100,7 +100,7 @@ char constexpr SpellCastTimefmt[] = "nixx";
char constexpr SpellCategoryfmt[] = "ni";
char constexpr SpellDifficultyfmt[] = "niiii";
char constexpr SpellDurationfmt[] = "niii";
char constexpr SpellEntryfmt[] = "niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx";
char constexpr SpellEntryfmt[] = "niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiiissssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx";
char constexpr SpellFocusObjectfmt[] = "nxxxxxxxxxxxxxxxxx";
char constexpr SpellItemEnchantmentfmt[] = "niiiiiiixxxiiissssssssssssssssxiiiiiii";
char constexpr SpellItemEnchantmentConditionfmt[] = "nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";