refactor(Core/Combat): Port TrinityCore heap-based threat system (#24715)
Co-authored-by: blinkysc <blinkysc@users.noreply.github.com> Co-authored-by: Treeston <treeston.mmoc@gmail.com> Co-authored-by: killerwife <killerwife@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2652,7 +2652,7 @@ void Spell::EffectDispel(SpellEffIndex effIndex)
|
||||
|
||||
// put in combat
|
||||
if (unitTarget->IsFriendlyTo(m_caster))
|
||||
unitTarget->getHostileRefMgr().threatAssist(m_caster, 0.0f, m_spellInfo);
|
||||
unitTarget->GetThreatMgr().ForwardThreatForAssistingMe(m_caster, 0.0f, m_spellInfo);
|
||||
|
||||
if (success_list.empty())
|
||||
return;
|
||||
@@ -3299,33 +3299,25 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/)
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
// xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
|
||||
// xinef: Hand of Reckoning, cast before checking canhavethreatlist. fixes damage against pets
|
||||
if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
|
||||
{
|
||||
m_caster->CastSpell(unitTarget, 67485, true);
|
||||
unitTarget->CombatStart(m_caster);
|
||||
}
|
||||
|
||||
// this effect use before aura Taunt apply for prevent taunt already attacking target
|
||||
// for spell as marked "non effective at already attacking target"
|
||||
if (!unitTarget->CanHaveThreatList() || (unitTarget->GetVictim() == m_caster && !m_spellInfo->HasAura(SPELL_AURA_MOD_TAUNT)))
|
||||
if (!unitTarget->CanHaveThreatList())
|
||||
{
|
||||
SendCastResult(SPELL_FAILED_DONT_REPORT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!unitTarget->GetThreatMgr().GetOnlineContainer().empty())
|
||||
ThreatManager& mgr = unitTarget->GetThreatMgr();
|
||||
if (mgr.GetCurrentVictim() == m_caster)
|
||||
{
|
||||
// Also use this effect to set the taunter's threat to the taunted creature's highest value
|
||||
float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
|
||||
float topThreat = unitTarget->GetThreatMgr().GetOnlineContainer().getMostHated()->GetThreat();
|
||||
if (topThreat > myThreat)
|
||||
unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
|
||||
|
||||
//Set aggro victim to caster
|
||||
if (HostileReference* forcedVictim = unitTarget->GetThreatMgr().GetOnlineContainer().getReferenceByTarget(m_caster))
|
||||
unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
|
||||
SendCastResult(SPELL_FAILED_DONT_REPORT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mgr.IsThreatListEmpty())
|
||||
mgr.MatchUnitThreatToHighestThreat(m_caster);
|
||||
}
|
||||
|
||||
void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
|
||||
@@ -3677,7 +3669,8 @@ void Spell::EffectThreat(SpellEffIndex /*effIndex*/)
|
||||
if (!unitTarget->CanHaveThreatList() || m_caster->IsFriendlyTo(unitTarget))
|
||||
return;
|
||||
|
||||
unitTarget->AddThreat(m_caster, float(damage));
|
||||
// SPELL_EFFECT_THREAT adds flat threat that should not be modified by threat reduction
|
||||
unitTarget->GetThreatMgr().AddThreat(m_caster, float(damage), m_spellInfo, true);
|
||||
}
|
||||
|
||||
void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/)
|
||||
@@ -4002,24 +3995,18 @@ void Spell::EffectSanctuary(SpellEffIndex /*effIndex*/)
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
if (unitTarget->GetInstanceScript() && unitTarget->GetInstanceScript()->IsEncounterInProgress())
|
||||
unitTarget->GetThreatMgr().EvaluateSuppressed();
|
||||
|
||||
if (unitTarget->IsPlayer() && !unitTarget->GetMap()->IsDungeon())
|
||||
{
|
||||
unitTarget->getHostileRefMgr().UpdateVisibility(true);
|
||||
// Xinef: replaced with CombatStop(false)
|
||||
unitTarget->AttackStop();
|
||||
unitTarget->RemoveAllAttackers();
|
||||
|
||||
// Night Elf: Shadowmeld only resets threat temporarily
|
||||
if (m_spellInfo->Id != 59646)
|
||||
unitTarget->getHostileRefMgr().addThreatPercent(-100);
|
||||
|
||||
if (unitTarget->IsPlayer())
|
||||
unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
|
||||
// stop all pve combat for players outside dungeons, suppress pvp combat
|
||||
unitTarget->CombatStop(false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
|
||||
unitTarget->CombatStop(true);
|
||||
// in dungeons (or for nonplayers), reset this unit on all enemies' threat lists
|
||||
for (auto const& pair : unitTarget->GetThreatMgr().GetThreatenedByMeList())
|
||||
pair.second->ScaleThreat(0.0f);
|
||||
}
|
||||
|
||||
UnitList targets;
|
||||
@@ -5185,7 +5172,7 @@ void Spell::EffectDispelMechanic(SpellEffIndex effIndex)
|
||||
|
||||
// put in combat
|
||||
if (unitTarget->IsFriendlyTo(m_caster))
|
||||
unitTarget->getHostileRefMgr().threatAssist(m_caster, 0.0f, m_spellInfo);
|
||||
unitTarget->GetThreatMgr().ForwardThreatForAssistingMe(m_caster, 0.0f, m_spellInfo);
|
||||
}
|
||||
|
||||
void Spell::EffectResurrectPet(SpellEffIndex /*effIndex*/)
|
||||
@@ -5903,7 +5890,7 @@ void Spell::EffectRedirectThreat(SpellEffIndex /*effIndex*/)
|
||||
return;
|
||||
|
||||
if (unitTarget)
|
||||
m_caster->SetRedirectThreat(unitTarget->GetGUID(), uint32(damage));
|
||||
m_caster->GetThreatMgr().RegisterRedirectThreat(m_spellInfo->Id, unitTarget->GetGUID(), uint32(damage));
|
||||
}
|
||||
|
||||
void Spell::EffectGameObjectDamage(SpellEffIndex /*effIndex*/)
|
||||
|
||||
Reference in New Issue
Block a user