-
-
Save x3n/763765 to your computer and use it in GitHub Desktop.
threat_multiplier.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp | |
index 38674a2..397e37f 100644 | |
--- a/src/game/Spell.cpp | |
+++ b/src/game/Spell.cpp | |
@@ -4218,14 +4218,14 @@ void Spell::HandleThreatSpells(uint32 spellId) | |
if(!m_targets.getUnitTarget()->CanHaveThreatList()) | |
return; | |
- uint16 threat = sSpellMgr.GetSpellThreat(spellId); | |
+ SpellThreatEntry const* threatEntry = sSpellMgr.GetSpellThreatEntry(spellId); | |
- if(!threat) | |
+ if(!threatEntry || !threatEntry->threat) | |
return; | |
- m_targets.getUnitTarget()->AddThreat(m_caster, float(threat), false, GetSpellSchoolMask(m_spellInfo), m_spellInfo); | |
+ m_targets.getUnitTarget()->AddThreat(m_caster, float(threatEntry->threat), false, GetSpellSchoolMask(m_spellInfo), m_spellInfo); | |
- DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u, rank %u, added an additional %i threat", spellId, sSpellMgr.GetSpellRank(spellId), threat); | |
+ DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u, rank %u, added an additional %i threat", spellId, sSpellMgr.GetSpellRank(spellId), threatEntry->threat); | |
} | |
void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,SpellEffectIndex i, float DamageMultiplier) | |
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp | |
index c2d6351..ff4f10b 100644 | |
--- a/src/game/SpellMgr.cpp | |
+++ b/src/game/SpellMgr.cpp | |
@@ -1606,14 +1606,39 @@ void SpellMgr::LoadSpellElixirs() | |
sLog.outString( ">> Loaded %u spell elixir definitions", count ); | |
} | |
+struct DoSpellThreat | |
+{ | |
+ DoSpellThreat(SpellThreatMap& _threatMap, SpellThreatEntry const& _ste) : threatMap(_threatMap), ste(_ste) {} | |
+ void operator() (uint32 spell_id) | |
+ { | |
+ // add ranks only for not filled data (spells adding flat threat are usually different for ranks for example) | |
+ SpellThreatMap::const_iterator spellItr = threatMap.find(spell_id); | |
+ if (spellItr == threatMap.end()) | |
+ threatMap[spell_id] = ste; | |
+ | |
+ // just assert that entry is not redundant | |
+ else | |
+ { | |
+ SpellThreatEntry const& r_ste = spellItr->second; | |
+ if (ste.threat == r_ste.threat && ste.multiplier == r_ste.multiplier && ste.ap_multiplier == r_ste.ap_multiplier) | |
+ sLog.outErrorDb("Spell %u listed in `spell_threat` as custom rank has same data as Rank 1, so redundant", spell_id); | |
+ } | |
+ } | |
+ | |
+ SpellThreatMap& threatMap; | |
+ SpellThreatEntry const& ste; | |
+}; | |
+ | |
+ | |
void SpellMgr::LoadSpellThreats() | |
{ | |
mSpellThreatMap.clear(); // need for reload case | |
uint32 count = 0; | |
+ uint32 customRank = 0; | |
- // 0 1 | |
- QueryResult *result = WorldDatabase.Query("SELECT entry, Threat FROM spell_threat"); | |
+ // 0 1 2 3 | |
+ QueryResult *result = WorldDatabase.Query("SELECT entry, Threat, Multiplier, AP_Multiplier FROM spell_threat"); | |
if( !result ) | |
{ | |
@@ -1626,6 +1651,9 @@ void SpellMgr::LoadSpellThreats() | |
return; | |
} | |
+ std::set<uint32> firstRankSpells; | |
+ std::set<uint32> firstRankSpellsWithCustomRanks; | |
+ | |
barGoLink bar( (int)result->GetRowCount() ); | |
do | |
@@ -1635,7 +1663,6 @@ void SpellMgr::LoadSpellThreats() | |
bar.step(); | |
uint32 entry = fields[0].GetUInt32(); | |
- uint16 Threat = fields[1].GetUInt16(); | |
if (!sSpellStore.LookupEntry(entry)) | |
{ | |
@@ -1643,11 +1670,58 @@ void SpellMgr::LoadSpellThreats() | |
continue; | |
} | |
- mSpellThreatMap[entry] = Threat; | |
+ SpellThreatEntry ste; | |
+ ste.threat = fields[1].GetUInt16(); | |
+ ste.multiplier = fields[2].GetFloat(); | |
+ ste.ap_multiplier = fields[3].GetFloat(); | |
+ | |
+ mSpellThreatMap[entry] = ste; | |
+ | |
+ | |
+ uint32 first_id = GetFirstSpellInChain(entry); | |
+ | |
+ // by default, spell ranks are expected to have same data | |
+ if(first_id) | |
+ { | |
+ firstRankSpells.insert(first_id); | |
+ | |
+ if(first_id != entry) | |
+ { | |
+ // let have independent data in table for spells with flat threat bonus | |
+ if(!ste.threat) | |
+ { | |
+ sLog.outErrorDb("Spell %u listed in `spell_threat` is not first rank (%u) in chain", entry, first_id); | |
+ // prevent loading since it won't have an effect anyway | |
+ continue; | |
+ } | |
+ // for later check that first rank also added | |
+ else | |
+ { | |
+ firstRankSpellsWithCustomRanks.insert(first_id); | |
+ ++customRank; | |
+ } | |
+ } | |
+ } | |
++count; | |
} while( result->NextRow() ); | |
+ // check that first rank added for custom ranks | |
+ for (std::set<uint32>::const_iterator itr = firstRankSpellsWithCustomRanks.begin(); itr != firstRankSpellsWithCustomRanks.end(); ++itr) | |
+ if (mSpellThreatMap.find(*itr) == mSpellThreatMap.end()) | |
+ sLog.outErrorDb("Spell %u must be listed in `spell_threat` as first rank for listed custom ranks of spell but not found!", *itr); | |
+ | |
+ // fill absent non first ranks data base at first rank data | |
+ for(std::set<uint32>::const_iterator itr = firstRankSpells.begin(); itr != firstRankSpells.end(); ++itr) | |
+ { | |
+ SpellThreatMap::const_iterator speItr = mSpellThreatMap.find(*itr); | |
+ if (speItr != mSpellThreatMap.end()) | |
+ { | |
+ DoSpellThreat worker(mSpellThreatMap, speItr->second); | |
+ doForHighRanks(speItr->first, worker); | |
+ } | |
+ } | |
+ | |
delete result; | |
sLog.outString(); | |
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h | |
index 40e45a5..d22bec9 100644 | |
--- a/src/game/SpellMgr.h | |
+++ b/src/game/SpellMgr.h | |
@@ -612,9 +612,16 @@ typedef UNORDERED_MAP<uint32, SpellBonusEntry> SpellBonusMap; | |
#define ELIXIR_SHATTRATH_MASK 0x08 | |
#define ELIXIR_WELL_FED 0x10 // Some foods have SPELLFAMILY_POTION | |
+struct SpellThreatEntry | |
+{ | |
+ uint16 threat; | |
+ float multiplier; | |
+ float ap_multiplier; | |
+}; | |
+ | |
typedef std::map<uint32, uint8> SpellElixirMap; | |
typedef std::map<uint32, float> SpellProcItemEnchantMap; | |
-typedef std::map<uint32, uint16> SpellThreatMap; | |
+typedef std::map<uint32, SpellThreatEntry> SpellThreatMap; | |
// Spell script target related declarations (accessed using SpellMgr functions) | |
enum SpellTargetType | |
@@ -836,13 +843,13 @@ class SpellMgr | |
return SPELL_NORMAL; | |
} | |
- uint16 GetSpellThreat(uint32 spellid) const | |
+ SpellThreatEntry const* GetSpellThreatEntry(uint32 spellid) const | |
{ | |
SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellid); | |
- if(itr==mSpellThreatMap.end()) | |
- return 0; | |
+ if (itr != mSpellThreatMap.end()) | |
+ return &itr->second; | |
- return itr->second; | |
+ return NULL; | |
} | |
// Spell proc events | |
diff --git a/src/game/ThreatManager.cpp b/src/game/ThreatManager.cpp | |
index d814552..e17dbba 100644 | |
--- a/src/game/ThreatManager.cpp | |
+++ b/src/game/ThreatManager.cpp | |
@@ -24,6 +24,7 @@ | |
#include "Player.h" | |
#include "ObjectAccessor.h" | |
#include "UnitEvents.h" | |
+#include "SpellMgr.h" | |
//============================================================== | |
//================= ThreatCalcHelper =========================== | |
@@ -38,11 +39,21 @@ float ThreatCalcHelper::calcThreat(Unit* pHatedUnit, Unit* /*pHatingUnit*/, floa | |
if (pThreatSpell) | |
{ | |
+ SpellThreatEntry const* threatEntry = sSpellMgr.GetSpellThreatEntry(pThreatSpell->Id); | |
+ | |
if (Player* modOwner = pHatedUnit->GetSpellModOwner()) | |
+ { | |
modOwner->ApplySpellMod(pThreatSpell->Id, SPELLMOD_THREAT, pThreat); | |
- if(crit) | |
+ if(threatEntry && threatEntry->ap_multiplier) | |
+ pThreat += modOwner->CalculateDamage(BASE_ATTACK, false) * threatEntry->ap_multiplier; | |
+ } | |
+ | |
+ if (crit) | |
pThreat *= pHatedUnit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRITICAL_THREAT,schoolMask); | |
+ | |
+ if (threatEntry) | |
+ pThreat *= threatEntry->multiplier; | |
} | |
float threat = pHatedUnit->ApplyTotalThreatModifier(pThreat, schoolMask); | |
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp | |
index 8051720..dde1861 100644 | |
--- a/src/game/Unit.cpp | |
+++ b/src/game/Unit.cpp | |
@@ -950,10 +950,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa | |
} | |
if (pVictim->GetTypeId() != TYPEID_PLAYER) | |
{ | |
- if(spellProto && IsDamageToThreatSpell(spellProto)) | |
- pVictim->AddThreat(this, float(damage*2), (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto); | |
- else | |
- pVictim->AddThreat(this, float(damage), (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto); | |
+ pVictim->AddThreat(this, float(damage), (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto); | |
} | |
else // victim is a player | |
{ | |
@@ -7176,22 +7173,6 @@ bool Unit::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex i | |
return false; | |
} | |
-bool Unit::IsDamageToThreatSpell(SpellEntry const * spellInfo) const | |
-{ | |
- if (!spellInfo) | |
- return false; | |
- | |
- uint32 family = spellInfo->SpellFamilyName; | |
- uint64 flags = spellInfo->SpellFamilyFlags; | |
- | |
- if ((family == 5 && flags == 256) || //Searing Pain | |
- (family == 6 && flags == 8192) || //Mind Blast | |
- (family == 11 && flags == 1048576)) //Earth Shock | |
- return true; | |
- | |
- return false; | |
-} | |
- | |
/** | |
* Calculates caster part of melee damage bonuses, | |
* also includes different bonuses dependent from target auras | |
diff --git a/src/game/Unit.h b/src/game/Unit.h | |
index 35e1726..f3901fe 100644 | |
--- a/src/game/Unit.h | |
+++ b/src/game/Unit.h | |
@@ -1464,8 +1464,6 @@ class MANGOS_DLL_SPEC Unit : public WorldObject | |
void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem = NULL, Aura* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid(), SpellEntry const* triggeredBy = NULL); | |
void CastSpell(float x, float y, float z, SpellEntry const *spellInfo, bool triggered, Item *castItem = NULL, Aura* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid(), SpellEntry const* triggeredBy = NULL); | |
- bool IsDamageToThreatSpell(SpellEntry const * spellInfo) const; | |
- | |
void DeMorph(); | |
void SendAttackStateUpdate(CalcDamageInfo *damageInfo); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ALTER TABLE spell_threat ADD COLUMN Multiplier FLOAT NOT NULL DEFAULT 1.0 AFTER Threat; | |
ALTER TABLE spell_threat ADD COLUMN AP_Multiplier FLOAT NOT NULL DEFAULT 0.0 AFTER Multiplier; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
added queries