fix(Core/Spells): Implemented spell priorities. (#11278)
* fix(Core/Spells): Implemented spell priorities. Fixes #11261 * Update. * Update. * Update.
This commit is contained in:
@@ -36,7 +36,9 @@
|
|||||||
#include "PlayerSettings.h"
|
#include "PlayerSettings.h"
|
||||||
#include "PlayerTaxi.h"
|
#include "PlayerTaxi.h"
|
||||||
#include "QuestDef.h"
|
#include "QuestDef.h"
|
||||||
|
#include "SpellAuras.h"
|
||||||
#include "SpellMgr.h"
|
#include "SpellMgr.h"
|
||||||
|
#include "SpellInfo.h"
|
||||||
#include "TradeData.h"
|
#include "TradeData.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
#include "WorldSession.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);
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||||
if (!spellInfo)
|
if (!spellInfo)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
float totalmul = 1.0f;
|
float totalmul = 1.0f;
|
||||||
int32 totalflat = 0;
|
int32 totalflat = 0;
|
||||||
|
|
||||||
// Drop charges for triggering spells instead of triggered ones
|
auto calculateSpellMod = [&](SpellModifier* mod)
|
||||||
if (m_spellModTakingSpell)
|
|
||||||
spell = m_spellModTakingSpell;
|
|
||||||
|
|
||||||
for (auto mod : m_spellMods[op])
|
|
||||||
{
|
{
|
||||||
// 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
|
// 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)
|
if (temporaryPet && mod->charges != 0)
|
||||||
continue;
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mod->type == SPELLMOD_FLAT)
|
if (mod->type == SPELLMOD_FLAT)
|
||||||
{
|
{
|
||||||
// xinef: do not allow to consume more than one 100% crit increasing spell
|
// xinef: do not allow to consume more than one 100% crit increasing spell
|
||||||
if (mod->op == SPELLMOD_CRITICAL_CHANCE && totalflat >= 100)
|
if (mod->op == SPELLMOD_CRITICAL_CHANCE && totalflat >= 100)
|
||||||
continue;
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
totalflat += mod->value;
|
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)
|
// skip percent mods for null basevalue (most important for spell mods with charges)
|
||||||
if (basevalue == T(0) || totalmul == 0.0f)
|
if (basevalue == T(0) || totalmul == 0.0f)
|
||||||
continue;
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// special case (skip > 10sec spell casts for instant cast setting)
|
// special case (skip > 10sec spell casts for instant cast setting)
|
||||||
if (mod->op == SPELLMOD_CASTING_TIME && basevalue >= T(10000) && mod->value <= -100)
|
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
|
// 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))
|
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
|
// 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))
|
else if (mod->op == SPELLMOD_GLOBAL_COOLDOWN && spell && !HasSpellMod(mod, spell))
|
||||||
continue;
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// xinef: those two mods should be multiplicative (Glyph of Renew)
|
// xinef: those two mods should be multiplicative (Glyph of Renew)
|
||||||
if (mod->op == SPELLMOD_DAMAGE || mod->op == SPELLMOD_DOT)
|
if (mod->op == SPELLMOD_DAMAGE || mod->op == SPELLMOD_DOT)
|
||||||
|
{
|
||||||
totalmul *= CalculatePct(1.0f, 100.0f + mod->value);
|
totalmul *= CalculatePct(1.0f, 100.0f + mod->value);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
totalmul += CalculatePct(1.0f, mod->value);
|
totalmul += CalculatePct(1.0f, mod->value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DropModCharge(mod, spell);
|
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;
|
float diff = 0.0f;
|
||||||
if (op == SPELLMOD_CASTING_TIME || op == SPELLMOD_DURATION)
|
if (op == SPELLMOD_CASTING_TIME || op == SPELLMOD_DURATION)
|
||||||
|
{
|
||||||
diff = ((float)basevalue + totalflat) * (totalmul - 1.0f) + (float)totalflat;
|
diff = ((float)basevalue + totalflat) * (totalmul - 1.0f) + (float)totalflat;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
diff = (float)basevalue * (totalmul - 1.0f) + (float)totalflat;
|
diff = (float)basevalue * (totalmul - 1.0f) + (float)totalflat;
|
||||||
|
}
|
||||||
|
|
||||||
basevalue = T((float)basevalue + diff);
|
basevalue = T((float)basevalue + diff);
|
||||||
return T(diff);
|
return T(diff);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -831,6 +831,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry)
|
|||||||
SpellVisual = spellEntry->SpellVisual;
|
SpellVisual = spellEntry->SpellVisual;
|
||||||
SpellIconID = spellEntry->SpellIconID;
|
SpellIconID = spellEntry->SpellIconID;
|
||||||
ActiveIconID = spellEntry->ActiveIconID;
|
ActiveIconID = spellEntry->ActiveIconID;
|
||||||
|
SpellPriority = spellEntry->SpellPriority;
|
||||||
SpellName = spellEntry->SpellName;
|
SpellName = spellEntry->SpellName;
|
||||||
Rank = spellEntry->Rank;
|
Rank = spellEntry->Rank;
|
||||||
MaxTargetLevel = spellEntry->MaxTargetLevel;
|
MaxTargetLevel = spellEntry->MaxTargetLevel;
|
||||||
|
|||||||
@@ -377,6 +377,7 @@ public:
|
|||||||
std::array<uint32, 2> SpellVisual;
|
std::array<uint32, 2> SpellVisual;
|
||||||
uint32 SpellIconID;
|
uint32 SpellIconID;
|
||||||
uint32 ActiveIconID;
|
uint32 ActiveIconID;
|
||||||
|
uint32 SpellPriority;
|
||||||
std::array<char const*, 16> SpellName;
|
std::array<char const*, 16> SpellName;
|
||||||
std::array<char const*, 16> Rank;
|
std::array<char const*, 16> Rank;
|
||||||
uint32 MaxTargetLevel;
|
uint32 MaxTargetLevel;
|
||||||
|
|||||||
@@ -244,7 +244,6 @@ void SpellMgr::LoadSpellInfoCorrections()
|
|||||||
48108, // Hot Streak
|
48108, // Hot Streak
|
||||||
51124, // Killing Machine
|
51124, // Killing Machine
|
||||||
54741, // Firestarter
|
54741, // Firestarter
|
||||||
57761, // Fireball!
|
|
||||||
64823, // Item - Druid T8 Balance 4P Bonus
|
64823, // Item - Druid T8 Balance 4P Bonus
|
||||||
34477, // Misdirection
|
34477, // Misdirection
|
||||||
44401, // Missile Barrage
|
44401, // Missile Barrage
|
||||||
@@ -254,6 +253,13 @@ void SpellMgr::LoadSpellInfoCorrections()
|
|||||||
spellInfo->ProcCharges = 1;
|
spellInfo->ProcCharges = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fireball
|
||||||
|
ApplySpellFix({ 57761 }, [](SpellInfo* spellInfo)
|
||||||
|
{
|
||||||
|
spellInfo->ProcCharges = 1;
|
||||||
|
spellInfo->SpellPriority = 50;
|
||||||
|
});
|
||||||
|
|
||||||
// Tidal Wave
|
// Tidal Wave
|
||||||
ApplySpellFix({ 53390 }, [](SpellInfo* spellInfo)
|
ApplySpellFix({ 53390 }, [](SpellInfo* spellInfo)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1637,7 +1637,7 @@ struct SpellEntry
|
|||||||
std::array<uint32, 2> SpellVisual; // 131-132 m_spellVisualID
|
std::array<uint32, 2> SpellVisual; // 131-132 m_spellVisualID
|
||||||
uint32 SpellIconID; // 133 m_spellIconID
|
uint32 SpellIconID; // 133 m_spellIconID
|
||||||
uint32 ActiveIconID; // 134 m_activeIconID
|
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
|
std::array<char const*, 16> SpellName; // 136-151 m_name_lang
|
||||||
//uint32 SpellNameFlag; // 152 not used
|
//uint32 SpellNameFlag; // 152 not used
|
||||||
std::array<char const*, 16> Rank; // 153-168 m_nameSubtext_lang
|
std::array<char const*, 16> Rank; // 153-168 m_nameSubtext_lang
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ char constexpr SpellCastTimefmt[] = "nixx";
|
|||||||
char constexpr SpellCategoryfmt[] = "ni";
|
char constexpr SpellCategoryfmt[] = "ni";
|
||||||
char constexpr SpellDifficultyfmt[] = "niiii";
|
char constexpr SpellDifficultyfmt[] = "niiii";
|
||||||
char constexpr SpellDurationfmt[] = "niii";
|
char constexpr SpellDurationfmt[] = "niii";
|
||||||
char constexpr SpellEntryfmt[] = "niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx";
|
char constexpr SpellEntryfmt[] = "niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiiissssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx";
|
||||||
char constexpr SpellFocusObjectfmt[] = "nxxxxxxxxxxxxxxxxx";
|
char constexpr SpellFocusObjectfmt[] = "nxxxxxxxxxxxxxxxxx";
|
||||||
char constexpr SpellItemEnchantmentfmt[] = "niiiiiiixxxiiissssssssssssssssxiiiiiii";
|
char constexpr SpellItemEnchantmentfmt[] = "niiiiiiixxxiiissssssssssssssssxiiiiiii";
|
||||||
char constexpr SpellItemEnchantmentConditionfmt[] = "nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
|
char constexpr SpellItemEnchantmentConditionfmt[] = "nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
|
||||||
|
|||||||
Reference in New Issue
Block a user