mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
[11023] Implement support for threat multiplier and AP based threat bonus for spells.
* Higher ranks are now automatically filled when not listed in spell_threat * Added some loading checks to detect inconsistent data Signed-off-by: Lynx3d <lynx3d@some-imaginary-isp.org>
This commit is contained in:
parent
77d8b41cc4
commit
d35be7f4c1
12 changed files with 238 additions and 177 deletions
238
sql/mangos.sql
238
sql/mangos.sql
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
||||||
`version` varchar(120) default NULL,
|
`version` varchar(120) default NULL,
|
||||||
`creature_ai_version` varchar(120) default NULL,
|
`creature_ai_version` varchar(120) default NULL,
|
||||||
`cache_id` int(10) default '0',
|
`cache_id` int(10) default '0',
|
||||||
`required_11018_01_mangos_command` bit(1) default NULL
|
`required_11023_01_mangos_spell_threat` bit(1) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
@ -17629,6 +17629,8 @@ DROP TABLE IF EXISTS `spell_threat`;
|
||||||
CREATE TABLE `spell_threat` (
|
CREATE TABLE `spell_threat` (
|
||||||
`entry` mediumint(8) unsigned NOT NULL,
|
`entry` mediumint(8) unsigned NOT NULL,
|
||||||
`Threat` smallint(6) NOT NULL,
|
`Threat` smallint(6) NOT NULL,
|
||||||
|
`multiplier` float NOT NULL default '1' COMMENT 'threat multiplier for damage/healing',
|
||||||
|
`ap_bonus` float NOT NULL default '0' COMMENT 'additional threat bonus from attack power',
|
||||||
PRIMARY KEY (`entry`)
|
PRIMARY KEY (`entry`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED;
|
||||||
|
|
||||||
|
|
@ -17639,123 +17641,123 @@ CREATE TABLE `spell_threat` (
|
||||||
LOCK TABLES `spell_threat` WRITE;
|
LOCK TABLES `spell_threat` WRITE;
|
||||||
/*!40000 ALTER TABLE `spell_threat` DISABLE KEYS */;
|
/*!40000 ALTER TABLE `spell_threat` DISABLE KEYS */;
|
||||||
INSERT INTO `spell_threat` VALUES
|
INSERT INTO `spell_threat` VALUES
|
||||||
(72,293),
|
( 72, 293, 1, 0),
|
||||||
(78,20),
|
( 78, 20, 1, 0),
|
||||||
(99,42),
|
( 99, 42, 1, 0),
|
||||||
(284,39),
|
( 284, 39, 1, 0),
|
||||||
(285,59),
|
( 285, 59, 1, 0),
|
||||||
(469,40),
|
( 469, 40, 1, 0),
|
||||||
(676,104),
|
( 676, 104, 1, 0),
|
||||||
(770,108),
|
( 770, 108, 1, 0),
|
||||||
(845,10),
|
( 845, 10, 1, 0),
|
||||||
(1160,16),
|
( 1160, 16, 1, 0),
|
||||||
(1608,78),
|
( 1608, 78, 1, 0),
|
||||||
(1672,180),
|
( 1672, 180, 1, 0),
|
||||||
(1715,61),
|
( 1715, 61, 1, 0),
|
||||||
(1735,42),
|
( 1735, 42, 1, 0),
|
||||||
(2048,70),
|
( 2048, 70, 1, 0),
|
||||||
(2139,300),
|
( 2139, 300, 1, 0),
|
||||||
(5242,26),
|
( 5242, 26, 1, 0),
|
||||||
(6190,26),
|
( 6190, 26, 1, 0),
|
||||||
(6192,32),
|
( 6192, 32, 1, 0),
|
||||||
(6343,17),
|
( 6343, 17, 1, 0),
|
||||||
(6572,155),
|
( 6572, 155, 1, 0),
|
||||||
(6673,18),
|
( 6673, 18, 1, 0),
|
||||||
(6574,195),
|
( 6574, 195, 1, 0),
|
||||||
(6807,322),
|
( 6807, 322, 1, 0),
|
||||||
(6808,322),
|
( 6808, 322, 1, 0),
|
||||||
(6809,322),
|
( 6809, 322, 1, 0),
|
||||||
(7369,40),
|
( 7369, 40, 1, 0),
|
||||||
(7372,101),
|
( 7372, 101, 1, 0),
|
||||||
(7373,141),
|
( 7373, 141, 1, 0),
|
||||||
(7379,235),
|
( 7379, 235, 1, 0),
|
||||||
(7386,100),
|
( 7386, 100, 1, 0),
|
||||||
(8198,40),
|
( 8198, 40, 1, 0),
|
||||||
(8204,64),
|
( 8204, 64, 1, 0),
|
||||||
(8205,96),
|
( 8205, 96, 1, 0),
|
||||||
(8972,322),
|
( 8972, 322, 1, 0),
|
||||||
(9490,42),
|
( 9490, 42, 1, 0),
|
||||||
(9745,322),
|
( 9745, 322, 1, 0),
|
||||||
(9747,42),
|
( 9747, 42, 1, 0),
|
||||||
(9880,322),
|
( 9880, 322, 1, 0),
|
||||||
(9881,322),
|
( 9881, 322, 1, 0),
|
||||||
(9898,42),
|
( 9898, 42, 1, 0),
|
||||||
(11549,40),
|
(11549, 40, 1, 0),
|
||||||
(11550,48),
|
(11550, 48, 1, 0),
|
||||||
(11551,56),
|
(11551, 56, 1, 0),
|
||||||
(11554,30),
|
(11554, 30, 1, 0),
|
||||||
(11555,37),
|
(11555, 37, 1, 0),
|
||||||
(11556,43),
|
(11556, 43, 1, 0),
|
||||||
(11564,98),
|
(11564, 98, 1, 0),
|
||||||
(11565,118),
|
(11565, 118, 1, 0),
|
||||||
(11566,137),
|
(11566, 137, 1, 0),
|
||||||
(11567,145),
|
(11567, 145, 1, 0),
|
||||||
(11580,143),
|
(11580, 143, 1, 0),
|
||||||
(11581,180),
|
(11581, 180, 1, 0),
|
||||||
(11600,275),
|
(11600, 275, 1, 0),
|
||||||
(11601,315),
|
(11601, 315, 1, 0),
|
||||||
(11608,60),
|
(11608, 60, 1, 0),
|
||||||
(11609,70),
|
(11609, 70, 1, 0),
|
||||||
(11775,395),
|
(11775, 395, 1, 0),
|
||||||
(14921,415),
|
(14921, 415, 1, 0),
|
||||||
(16857,108),
|
(16857, 108, 1, 0),
|
||||||
(17735,200),
|
(17735, 200, 1, 0),
|
||||||
(17750,300),
|
(17750, 300, 1, 0),
|
||||||
(17751,450),
|
(17751, 450, 1, 0),
|
||||||
(17752,600),
|
(17752, 600, 1, 0),
|
||||||
(20569,100),
|
(20569, 100, 1, 0),
|
||||||
(20736,100),
|
(20736, 100, 1, 0),
|
||||||
(20925,20),
|
(20925, 20, 1, 0),
|
||||||
(20927,30),
|
(20927, 30, 1, 0),
|
||||||
(20928,40),
|
(20928, 40, 1, 0),
|
||||||
(23922,160),
|
(23922, 160, 1, 0),
|
||||||
(23923,190),
|
(23923, 190, 1, 0),
|
||||||
(23924,220),
|
(23924, 220, 1, 0),
|
||||||
(23925,250),
|
(23925, 250, 1, 0),
|
||||||
(24394,580),
|
(24394, 580, 1, 0),
|
||||||
(24583,5),
|
(24583, 5, 1, 0),
|
||||||
(25202,50),
|
(25202, 50, 1, 0),
|
||||||
(25203,55),
|
(25203, 55, 1, 0),
|
||||||
(25231,130),
|
(25231, 130, 1, 0),
|
||||||
(25258,286),
|
(25258, 286, 1, 0),
|
||||||
(25264,215),
|
(25264, 215, 1, 0),
|
||||||
(25269,400),
|
(25269, 400, 1, 0),
|
||||||
(25286,175),
|
(25286, 175, 1, 0),
|
||||||
(25288,355),
|
(25288, 355, 1, 0),
|
||||||
(25289,62),
|
(25289, 62, 1, 0),
|
||||||
(26996,322),
|
(26996, 322, 1, 0),
|
||||||
(26998,42),
|
(26998, 42, 1, 0),
|
||||||
(27179,54),
|
(27179, 54, 1, 0),
|
||||||
(29704,230),
|
(29704, 230, 1, 0),
|
||||||
(29707,196),
|
(29707, 196, 1, 0),
|
||||||
(30324,220),
|
(30324, 220, 1, 0),
|
||||||
(30356,323),
|
(30356, 323, 1, 0),
|
||||||
(30357,483),
|
(30357, 483, 1, 0),
|
||||||
(33745,285),
|
(33745, 285, 1, 0),
|
||||||
(33878,129),
|
(33878, 129, 1, 0),
|
||||||
(33986,180),
|
(33986, 180, 1, 0),
|
||||||
(33987,232),
|
(33987, 232, 1, 0),
|
||||||
(47436,78),
|
(47436, 78, 1, 0),
|
||||||
(47437,63),
|
(47437, 63, 1, 0),
|
||||||
(47439,60),
|
(47439, 60, 1, 0),
|
||||||
(47440,80),
|
(47440, 80, 1, 0),
|
||||||
(47449,236),
|
(47449, 236, 1, 0),
|
||||||
(47450,259),
|
(47450, 259, 1, 0),
|
||||||
(47487,520),
|
(47487, 520, 1, 0),
|
||||||
(47488,770),
|
(47488, 770, 1, 0),
|
||||||
(47497,101),
|
(47497, 101, 1, 0),
|
||||||
(47498,101),
|
(47498, 101, 1, 0),
|
||||||
(47501,235),
|
(47501, 235, 1, 0),
|
||||||
(47502,260),
|
(47502, 260, 1, 0),
|
||||||
(47519,180),
|
(47519, 180, 1, 0),
|
||||||
(47520,225),
|
(47520, 225, 1, 0),
|
||||||
(48479,322),
|
(48479, 322, 1, 0),
|
||||||
(48480,322),
|
(48480, 322, 1, 0),
|
||||||
(48559,42),
|
(48559, 42, 1, 0),
|
||||||
(48560,42),
|
(48560, 42, 1, 0),
|
||||||
(48567,285),
|
(48567, 285, 1, 0),
|
||||||
(48568,285),
|
(48568, 285, 1, 0),
|
||||||
(57823,500);
|
(57823, 500, 1, 0);
|
||||||
/*!40000 ALTER TABLE `spell_threat` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `spell_threat` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
|
|
||||||
5
sql/updates/11023_01_mangos_spell_threat.sql
Normal file
5
sql/updates/11023_01_mangos_spell_threat.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_11018_01_mangos_command required_11023_01_mangos_spell_threat bit;
|
||||||
|
|
||||||
|
ALTER TABLE spell_threat ADD COLUMN multiplier FLOAT NOT NULL DEFAULT 1.0 COMMENT 'threat multiplier for damage/healing' AFTER Threat;
|
||||||
|
|
||||||
|
ALTER TABLE spell_threat ADD COLUMN ap_bonus FLOAT NOT NULL DEFAULT 0.0 COMMENT 'additional threat bonus from attack power' AFTER multiplier;
|
||||||
|
|
@ -153,6 +153,7 @@ pkgdata_DATA = \
|
||||||
10998_01_mangos_spell_proc_event.sql \
|
10998_01_mangos_spell_proc_event.sql \
|
||||||
11002_01_mangos_spell_proc_event.sql \
|
11002_01_mangos_spell_proc_event.sql \
|
||||||
11018_01_mangos_command.sql \
|
11018_01_mangos_command.sql \
|
||||||
|
11023_01_mangos_spell_threat.sql \
|
||||||
README
|
README
|
||||||
|
|
||||||
## Additional files to include when running 'make dist'
|
## Additional files to include when running 'make dist'
|
||||||
|
|
@ -286,4 +287,5 @@ EXTRA_DIST = \
|
||||||
10998_01_mangos_spell_proc_event.sql \
|
10998_01_mangos_spell_proc_event.sql \
|
||||||
11002_01_mangos_spell_proc_event.sql \
|
11002_01_mangos_spell_proc_event.sql \
|
||||||
11018_01_mangos_command.sql \
|
11018_01_mangos_command.sql \
|
||||||
|
11023_01_mangos_spell_threat.sql \
|
||||||
README
|
README
|
||||||
|
|
|
||||||
|
|
@ -1023,7 +1023,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
||||||
int32 gain = caster->DealHeal(unitTarget, addhealth, m_spellInfo, crit, absorb);
|
int32 gain = caster->DealHeal(unitTarget, addhealth, m_spellInfo, crit, absorb);
|
||||||
|
|
||||||
if (real_caster)
|
if (real_caster)
|
||||||
unitTarget->getHostileRefManager().threatAssist(real_caster, float(gain) * 0.5f, m_spellInfo);
|
unitTarget->getHostileRefManager().threatAssist(real_caster, float(gain) * 0.5f * sSpellMgr.GetSpellThreatMultiplier(m_spellInfo), m_spellInfo);
|
||||||
}
|
}
|
||||||
// Do damage and triggers
|
// Do damage and triggers
|
||||||
else if (m_damage)
|
else if (m_damage)
|
||||||
|
|
@ -4225,14 +4225,18 @@ void Spell::HandleThreatSpells(uint32 spellId)
|
||||||
if(!m_targets.getUnitTarget()->CanHaveThreatList())
|
if(!m_targets.getUnitTarget()->CanHaveThreatList())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint16 threat = sSpellMgr.GetSpellThreat(spellId);
|
SpellThreatEntry const* threatEntry = sSpellMgr.GetSpellThreatEntry(spellId);
|
||||||
|
|
||||||
if(!threat)
|
if(!threatEntry || (!threatEntry->threat && threatEntry->ap_bonus == 0.0f))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_targets.getUnitTarget()->AddThreat(m_caster, float(threat), false, GetSpellSchoolMask(m_spellInfo), m_spellInfo);
|
float threat = threatEntry->threat;
|
||||||
|
if (threatEntry->ap_bonus != 0.0f)
|
||||||
|
threat += threatEntry->ap_bonus * m_caster->GetTotalAttackPowerValue(GetWeaponAttackType(m_spellInfo));
|
||||||
|
|
||||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u, rank %u, added an additional %i threat", spellId, sSpellMgr.GetSpellRank(spellId), threat);
|
m_targets.getUnitTarget()->AddThreat(m_caster, threat, false, GetSpellSchoolMask(m_spellInfo), m_spellInfo);
|
||||||
|
|
||||||
|
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u, rank %u, added an additional %f threat", spellId, sSpellMgr.GetSpellRank(spellId), threat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,SpellEffectIndex i, float DamageMultiplier)
|
void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,SpellEffectIndex i, float DamageMultiplier)
|
||||||
|
|
|
||||||
|
|
@ -6879,7 +6879,7 @@ void Aura::PeriodicTick()
|
||||||
pCaster->CalculateHealAbsorb(heal, &absorbHeal);
|
pCaster->CalculateHealAbsorb(heal, &absorbHeal);
|
||||||
|
|
||||||
int32 gain = pCaster->DealHeal(pCaster, heal - absorbHeal, spellProto, false, absorbHeal);
|
int32 gain = pCaster->DealHeal(pCaster, heal - absorbHeal, spellProto, false, absorbHeal);
|
||||||
pCaster->getHostileRefManager().threatAssist(pCaster, gain * 0.5f, spellProto);
|
pCaster->getHostileRefManager().threatAssist(pCaster, gain * 0.5f * sSpellMgr.GetSpellThreatMultiplier(spellProto), spellProto);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_PERIODIC_HEAL:
|
case SPELL_AURA_PERIODIC_HEAL:
|
||||||
|
|
@ -6951,7 +6951,7 @@ void Aura::PeriodicTick()
|
||||||
if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )
|
if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )
|
||||||
bg->UpdatePlayerScore(((Player*)pCaster), SCORE_HEALING_DONE, gain);
|
bg->UpdatePlayerScore(((Player*)pCaster), SCORE_HEALING_DONE, gain);
|
||||||
|
|
||||||
target->getHostileRefManager().threatAssist(pCaster, float(gain) * 0.5f, spellProto);
|
target->getHostileRefManager().threatAssist(pCaster, float(gain) * 0.5f * sSpellMgr.GetSpellThreatMultiplier(spellProto), spellProto);
|
||||||
|
|
||||||
// heal for caster damage
|
// heal for caster damage
|
||||||
if(target != pCaster && spellProto->SpellVisual[0] == 163)
|
if(target != pCaster && spellProto->SpellVisual[0] == 163)
|
||||||
|
|
@ -7091,7 +7091,7 @@ void Aura::PeriodicTick()
|
||||||
int32 gain = target->ModifyPower(power,pdamage);
|
int32 gain = target->ModifyPower(power,pdamage);
|
||||||
|
|
||||||
if(Unit* pCaster = GetCaster())
|
if(Unit* pCaster = GetCaster())
|
||||||
target->getHostileRefManager().threatAssist(pCaster, float(gain) * 0.5f, spellProto);
|
target->getHostileRefManager().threatAssist(pCaster, float(gain) * 0.5f * sSpellMgr.GetSpellThreatMultiplier(spellProto), spellProto);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_OBS_MOD_MANA:
|
case SPELL_AURA_OBS_MOD_MANA:
|
||||||
|
|
@ -7117,7 +7117,7 @@ void Aura::PeriodicTick()
|
||||||
int32 gain = target->ModifyPower(POWER_MANA, pdamage);
|
int32 gain = target->ModifyPower(POWER_MANA, pdamage);
|
||||||
|
|
||||||
if(Unit* pCaster = GetCaster())
|
if(Unit* pCaster = GetCaster())
|
||||||
target->getHostileRefManager().threatAssist(pCaster, float(gain) * 0.5f, spellProto);
|
target->getHostileRefManager().threatAssist(pCaster, float(gain) * 0.5f * sSpellMgr.GetSpellThreatMultiplier(spellProto), spellProto);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_POWER_BURN_MANA:
|
case SPELL_AURA_POWER_BURN_MANA:
|
||||||
|
|
@ -7179,7 +7179,7 @@ void Aura::PeriodicTick()
|
||||||
|
|
||||||
int32 gain = target->ModifyHealth(m_modifier.m_amount);
|
int32 gain = target->ModifyHealth(m_modifier.m_amount);
|
||||||
if (Unit *caster = GetCaster())
|
if (Unit *caster = GetCaster())
|
||||||
target->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto);
|
target->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f * sSpellMgr.GetSpellThreatMultiplier(spellProto), spellProto);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_MOD_POWER_REGEN:
|
case SPELL_AURA_MOD_POWER_REGEN:
|
||||||
|
|
|
||||||
|
|
@ -3538,7 +3538,7 @@ void Spell::EffectHealPct(SpellEffectIndex /*eff_idx*/)
|
||||||
unitTarget->CalculateHealAbsorb(addhealth, &absorb);
|
unitTarget->CalculateHealAbsorb(addhealth, &absorb);
|
||||||
|
|
||||||
int32 gain = caster->DealHeal(unitTarget, addhealth - absorb, m_spellInfo, false, absorb);
|
int32 gain = caster->DealHeal(unitTarget, addhealth - absorb, m_spellInfo, false, absorb);
|
||||||
unitTarget->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
|
unitTarget->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f * sSpellMgr.GetSpellThreatMultiplier(m_spellInfo), m_spellInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1636,26 +1636,77 @@ void SpellMgr::LoadSpellElixirs()
|
||||||
sLog.outString( ">> Loaded %u spell elixir definitions", count );
|
sLog.outString( ">> Loaded %u spell elixir definitions", count );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DoSpellThreat
|
||||||
|
{
|
||||||
|
DoSpellThreat(SpellThreatMap& _threatMap) : threatMap(_threatMap), count(0) {}
|
||||||
|
void operator() (uint32 spell_id)
|
||||||
|
{
|
||||||
|
SpellThreatEntry const &ste = state->second;
|
||||||
|
// add ranks only for not filled data (spells adding flat threat are usually different for ranks)
|
||||||
|
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_bonus == r_ste.ap_bonus)
|
||||||
|
sLog.outErrorDb("Spell %u listed in `spell_threat` as custom rank has same data as Rank 1, so redundant", spell_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const char* TableName() { return "spell_threat"; }
|
||||||
|
bool IsValidCustomRank(SpellThreatEntry const &ste, uint32 entry, uint32 first_id)
|
||||||
|
{
|
||||||
|
if (!ste.threat)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("Spell %u listed in `spell_threat` is not first rank (%u) in chain and has no threat", entry, first_id);
|
||||||
|
// prevent loading unexpected data
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void AddEntry(SpellThreatEntry const &ste, SpellEntry const *spell)
|
||||||
|
{
|
||||||
|
threatMap[spell->Id] = ste;
|
||||||
|
|
||||||
|
// flat threat bonus and attack power bonus currently only work properly when all
|
||||||
|
// effects have same targets, otherwise, we'd need to seperate it by effect index
|
||||||
|
if (ste.threat || ste.ap_bonus != 0.f)
|
||||||
|
{
|
||||||
|
const uint32 *targetA = spell->EffectImplicitTargetA;
|
||||||
|
const uint32 *targetB = spell->EffectImplicitTargetB;
|
||||||
|
if ((targetA[EFFECT_INDEX_1] && targetA[EFFECT_INDEX_1] != targetA[EFFECT_INDEX_0]) ||
|
||||||
|
(targetA[EFFECT_INDEX_2] && targetA[EFFECT_INDEX_2] != targetA[EFFECT_INDEX_0]))
|
||||||
|
sLog.outErrorDb("Spell %u listed in `spell_threat` has effects with different targets, threat may be assigned incorrectly", spell->Id);
|
||||||
|
}
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
bool HasEntry(uint32 spellId) { return threatMap.count(spellId) > 0; }
|
||||||
|
bool SetStateToEntry(uint32 spellId) { return (state = threatMap.find(spellId)) != threatMap.end(); }
|
||||||
|
|
||||||
|
SpellThreatMap& threatMap;
|
||||||
|
SpellThreatMap::const_iterator state;
|
||||||
|
uint32 count;
|
||||||
|
};
|
||||||
|
|
||||||
void SpellMgr::LoadSpellThreats()
|
void SpellMgr::LoadSpellThreats()
|
||||||
{
|
{
|
||||||
mSpellThreatMap.clear(); // need for reload case
|
mSpellThreatMap.clear(); // need for reload case
|
||||||
|
|
||||||
uint32 count = 0;
|
// 0 1 2 3
|
||||||
|
QueryResult *result = WorldDatabase.Query("SELECT entry, Threat, multiplier, ap_bonus FROM spell_threat");
|
||||||
// 0 1
|
|
||||||
QueryResult *result = WorldDatabase.Query("SELECT entry, Threat FROM spell_threat");
|
|
||||||
if( !result )
|
if( !result )
|
||||||
{
|
{
|
||||||
|
|
||||||
barGoLink bar( 1 );
|
barGoLink bar( 1 );
|
||||||
|
|
||||||
bar.step();
|
bar.step();
|
||||||
|
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
sLog.outString( ">> Loaded %u aggro generating spells", count );
|
sLog.outString( ">> No spell threat entries loaded.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpellRankHelper<SpellThreatEntry, DoSpellThreat, SpellThreatMap> rankHelper(*this, mSpellThreatMap);
|
||||||
|
|
||||||
barGoLink bar( (int)result->GetRowCount() );
|
barGoLink bar( (int)result->GetRowCount() );
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|
@ -1665,23 +1716,22 @@ void SpellMgr::LoadSpellThreats()
|
||||||
bar.step();
|
bar.step();
|
||||||
|
|
||||||
uint32 entry = fields[0].GetUInt32();
|
uint32 entry = fields[0].GetUInt32();
|
||||||
uint16 Threat = fields[1].GetUInt16();
|
|
||||||
|
|
||||||
if (!sSpellStore.LookupEntry(entry))
|
SpellThreatEntry ste;
|
||||||
{
|
ste.threat = fields[1].GetUInt16();
|
||||||
sLog.outErrorDb("Spell %u listed in `spell_threat` does not exist", entry);
|
ste.multiplier = fields[2].GetFloat();
|
||||||
continue;
|
ste.ap_bonus = fields[3].GetFloat();
|
||||||
}
|
|
||||||
|
|
||||||
mSpellThreatMap[entry] = Threat;
|
rankHelper.RecordRank(ste, entry);
|
||||||
|
|
||||||
++count;
|
|
||||||
} while( result->NextRow() );
|
} while( result->NextRow() );
|
||||||
|
|
||||||
|
rankHelper.FillHigherRanks();
|
||||||
|
|
||||||
delete result;
|
delete result;
|
||||||
|
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
sLog.outString( ">> Loaded %u aggro generating spells", count );
|
sLog.outString( ">> Loaded %u spell threat entries", rankHelper.worker.count );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpellMgr::IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellId_2) const
|
bool SpellMgr::IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellId_2) const
|
||||||
|
|
|
||||||
|
|
@ -622,9 +622,16 @@ typedef UNORDERED_MAP<uint32, SpellBonusEntry> SpellBonusMap;
|
||||||
#define ELIXIR_SHATTRATH_MASK 0x08
|
#define ELIXIR_SHATTRATH_MASK 0x08
|
||||||
#define ELIXIR_WELL_FED 0x10 // Some foods have SPELLFAMILY_POTION
|
#define ELIXIR_WELL_FED 0x10 // Some foods have SPELLFAMILY_POTION
|
||||||
|
|
||||||
|
struct SpellThreatEntry
|
||||||
|
{
|
||||||
|
uint16 threat;
|
||||||
|
float multiplier;
|
||||||
|
float ap_bonus;
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::map<uint32, uint8> SpellElixirMap;
|
typedef std::map<uint32, uint8> SpellElixirMap;
|
||||||
typedef std::map<uint32, float> SpellProcItemEnchantMap;
|
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)
|
// Spell script target related declarations (accessed using SpellMgr functions)
|
||||||
enum SpellTargetType
|
enum SpellTargetType
|
||||||
|
|
@ -846,13 +853,24 @@ class SpellMgr
|
||||||
return SPELL_NORMAL;
|
return SPELL_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 GetSpellThreat(uint32 spellid) const
|
SpellThreatEntry const* GetSpellThreatEntry(uint32 spellid) const
|
||||||
{
|
{
|
||||||
SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellid);
|
SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellid);
|
||||||
if(itr==mSpellThreatMap.end())
|
if (itr != mSpellThreatMap.end())
|
||||||
return 0;
|
return &itr->second;
|
||||||
|
|
||||||
return itr->second;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetSpellThreatMultiplier(SpellEntry const *spellInfo) const
|
||||||
|
{
|
||||||
|
if (!spellInfo)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (SpellThreatEntry const *entry = GetSpellThreatEntry(spellInfo->Id))
|
||||||
|
return entry->multiplier;
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spell proc events
|
// Spell proc events
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,7 @@ void Unit::Update( uint32 update_diff, uint32 p_time )
|
||||||
{
|
{
|
||||||
if(!IsInWorld())
|
if(!IsInWorld())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*if(p_time > m_AurasCheck)
|
/*if(p_time > m_AurasCheck)
|
||||||
{
|
{
|
||||||
m_AurasCheck = 2000;
|
m_AurasCheck = 2000;
|
||||||
|
|
@ -953,10 +953,8 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
||||||
}
|
}
|
||||||
if (pVictim->GetTypeId() != TYPEID_PLAYER)
|
if (pVictim->GetTypeId() != TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
if(spellProto && IsDamageToThreatSpell(spellProto))
|
float threat = damage * sSpellMgr.GetSpellThreatMultiplier(spellProto);
|
||||||
pVictim->AddThreat(this, float(damage*2), (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto);
|
pVictim->AddThreat(this, threat, (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto);
|
||||||
else
|
|
||||||
pVictim->AddThreat(this, float(damage), (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto);
|
|
||||||
}
|
}
|
||||||
else // victim is a player
|
else // victim is a player
|
||||||
{
|
{
|
||||||
|
|
@ -7185,22 +7183,6 @@ bool Unit::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex i
|
||||||
return false;
|
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,
|
* Calculates caster part of melee damage bonuses,
|
||||||
* also includes different bonuses dependent from target auras
|
* also includes different bonuses dependent from target auras
|
||||||
|
|
|
||||||
|
|
@ -1450,8 +1450,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, 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);
|
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 DeMorph();
|
||||||
|
|
||||||
void SendAttackStateUpdate(CalcDamageInfo *damageInfo);
|
void SendAttackStateUpdate(CalcDamageInfo *damageInfo);
|
||||||
|
|
@ -2151,4 +2149,4 @@ inline void Unit::SendMonsterMoveByPath(Path<Elem,Node> const& path, uint32 star
|
||||||
SendMessageToSet(&data, true);
|
SendMessageToSet(&data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "11022"
|
#define REVISION_NR "11023"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef __REVISION_SQL_H__
|
#ifndef __REVISION_SQL_H__
|
||||||
#define __REVISION_SQL_H__
|
#define __REVISION_SQL_H__
|
||||||
#define REVISION_DB_CHARACTERS "required_10973_01_characters_game_event_status"
|
#define REVISION_DB_CHARACTERS "required_10973_01_characters_game_event_status"
|
||||||
#define REVISION_DB_MANGOS "required_11018_01_mangos_command"
|
#define REVISION_DB_MANGOS "required_11023_01_mangos_spell_threat"
|
||||||
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
||||||
#endif // __REVISION_SQL_H__
|
#endif // __REVISION_SQL_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue