Core/Spells:

* renamed SPELL_ATTR3_CANT_TRIGGER_PROC to SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS and expanded its implementation
* renamed SPELL_ATTR3_NO_INITIAL_AGGRO to SPELL_ATTR3_CANT_TRIGGER_TARGET_PROCS and implement the attribute
* expanded implementation SPELL_ATTR2_NO_INITIAL_THREAT to cover all remaining spots
This commit is contained in:
Ovahlord committed 2021-03-30 17:50:27 +02:00
1 parent e93a66d287
commit 77158594ff
7 files changed
+124 -67

No files matched your search

+1 -1
View File
@@ -308,7 +308,7 @@ void ThreatManager::AddThreat(Unit* target, float amount, SpellInfo const* spell
{
if (spell->HasAttribute(SPELL_ATTR1_NO_THREAT))
return;
if (!_owner->IsEngaged() && spell->HasAttribute(SPELL_ATTR3_NO_INITIAL_AGGRO))
if (!_owner->IsEngaged() && spell->HasAttribute(SPELL_ATTR2_NO_INITIAL_THREAT))
return;
}
@@ -477,8 +477,8 @@ enum SpellAttr3
SPELL_ATTR3_DONT_DISPLAY_CHANNEL_BAR = 0x00002000, // 13 Clientside attribute - will not display channeling bar
SPELL_ATTR3_IS_HONORLESS_TARGET = 0x00004000, // 14 "Honorless Target" only this spells have this flag
SPELL_ATTR3_UNK15 = 0x00008000, // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag
SPELL_ATTR3_CANT_TRIGGER_PROC = 0x00010000, // 16 confirmed with many patchnotes
SPELL_ATTR3_NO_INITIAL_AGGRO = 0x00020000, // 17 Soothe Animal, 39758, Mind Soothe
SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS = 0x00010000, // 16 Suppress Caster Procs
SPELL_ATTR3_CANT_TRIGGER_TARGET_PROCS = 0x00020000, // 17 Suppress Target Procs
SPELL_ATTR3_IGNORE_HIT_RESULT = 0x00040000, // 18 Spell should always hit its target
SPELL_ATTR3_DISABLE_PROC = 0x00080000, // 19 during aura proc no spells can trigger (20178, 20375)
SPELL_ATTR3_DEATH_PERSISTENT = 0x00100000, // 20 Death persistent spells
@@ -5760,8 +5760,12 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
caster->DealDamageMods(target, damage, &absorb);
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 procAttacker = 0, procVictim = 0;
if (!m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS))
procAttacker = PROC_FLAG_DONE_PERIODIC;
if (!m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_TARGET_PROCS))
procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 hitMask = damageInfo.GetHitMask();
if (damage)
{
@@ -5850,13 +5854,19 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
damage = damageInfo.GetDamage();
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 procAttacker = 0, procVictim = 0;
if (!m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS))
procAttacker = PROC_FLAG_DONE_PERIODIC;
if (!m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_TARGET_PROCS))
procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 hitMask = damageInfo.GetHitMask();
if (damage)
{
hitMask |= crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL;
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
if (!m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_TARGET_PROCS))
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
}
int32 new_damage = caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false);
@@ -6020,8 +6030,12 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
if (GetAuraType() == SPELL_AURA_OBS_MOD_HEALTH)
return;
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 procAttacker = 0, procVictim = 0;
if (!m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS))
procAttacker = PROC_FLAG_DONE_PERIODIC;
if (!m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_TARGET_PROCS))
procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 hitMask = crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL;
// ignore item heals
if (!haveCastItem)
@@ -6192,8 +6206,12 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
caster->SendSpellNonMeleeDamageLog(&damageInfo);
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 procAttacker = 0, procVictim = 0;
if (!m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS))
procAttacker = PROC_FLAG_DONE_PERIODIC;
if (!m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_TARGET_PROCS))
procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 hitMask = createProcHitMask(&damageInfo, SPELL_MISS_NONE);
uint32 spellTypeMask = PROC_SPELL_TYPE_NO_DMG_HEAL;
if (damageInfo.damage)
+82 -37
View File
@@ -2139,6 +2139,12 @@ void Spell::prepareDataForTriggerSystem()
m_procAttacker = PROC_FLAG_DONE_PERIODIC;
m_procVictim = PROC_FLAG_TAKEN_PERIODIC;
}
// Some spells may not trigger any procs at all.
if (m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS))
m_procAttacker = 0;
if (m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS))
m_procVictim = 0;
}
void Spell::CleanupTargetList()
@@ -2521,7 +2527,31 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
// Spells with this flag cannot trigger if effect is cast on self
bool const canEffectTrigger = !m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_PROC) && unitTarget->CanProc() && (CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE || missInfo == SPELL_MISS_IMMUNE2);
bool const canTriggerCasterProcs = [&]()
{
if (m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS))
return false;
if (!unitTarget->CanProc())
return false;
if (!(CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE || missInfo == SPELL_MISS_IMMUNE2))
return false;
return true;
}();
bool const canTriggerTargetProcs = [&]()
{
if (m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_TARGET_PROCS))
return false;
if (!caster->CanProc())
return false;
return true;
}();
Unit* spellHitTarget = nullptr;
if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
@@ -2559,7 +2589,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
m_needComboPoints = false;
// Trigger info was not filled in Spell::prepareDataForTriggerSystem - we do it now
if (canEffectTrigger && !procAttacker && !procVictim)
if ((canTriggerCasterProcs || canTriggerTargetProcs) && !procAttacker && !procVictim)
{
bool positive = true;
if (m_damage > 0)
@@ -2580,34 +2610,49 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
}
}
switch (m_spellInfo->DmgClass)
if (canTriggerCasterProcs)
{
case SPELL_DAMAGE_CLASS_MAGIC:
if (positive)
{
procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS;
procVictim |= PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS;
}
else
{
procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG;
procVictim |= PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG;
}
break;
case SPELL_DAMAGE_CLASS_NONE:
if (positive)
{
procAttacker |= PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS;
procVictim |= PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS;
}
else
{
procAttacker |= PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG;
procVictim |= PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG;
}
break;
switch (m_spellInfo->DmgClass)
{
case SPELL_DAMAGE_CLASS_MAGIC:
if (positive)
procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS;
else
procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG;
break;
case SPELL_DAMAGE_CLASS_NONE:
if (positive)
procAttacker |= PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS;
else
procAttacker |= PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG;
break;
default:
break;
}
}
if (canTriggerTargetProcs)
{
switch (m_spellInfo->DmgClass)
{
case SPELL_DAMAGE_CLASS_MAGIC:
if (positive)
procVictim |= PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS;
else
procVictim |= PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG;
break;
case SPELL_DAMAGE_CLASS_NONE:
if (positive)
procVictim |= PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS;
else
procVictim |= PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG;
break;
default:
break;
}
}
}
CallScriptOnHitHandlers();
// All calculated do it!
@@ -2630,7 +2675,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
m_healing = healInfo.GetEffectiveHeal();
// Do triggers for unit
if (canEffectTrigger)
if (canTriggerCasterProcs || canTriggerTargetProcs)
caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_HIT, hitMask, this, nullptr, &healInfo);
}
// Do damage and triggers
@@ -2676,7 +2721,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
}
// Do triggers for unit
if (canEffectTrigger)
if (canTriggerCasterProcs || canTriggerTargetProcs)
{
DamageInfo spellDamageInfo(damageInfo, SPELL_DIRECT_DAMAGE, m_attackType, hitMask);
caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, hitMask, this, &spellDamageInfo, nullptr);
@@ -2698,7 +2743,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
hitMask |= createProcHitMask(&damageInfo, missInfo);
// Do triggers for unit
if (canEffectTrigger)
if (canTriggerCasterProcs || canTriggerTargetProcs)
{
DamageInfo spellNoDamageInfo(damageInfo, NODAMAGE, m_attackType, hitMask);
caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_NO_DMG_HEAL, PROC_SPELL_PHASE_HIT, hitMask, this, &spellNoDamageInfo, nullptr);
@@ -2723,7 +2768,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
if (missInfo != SPELL_MISS_EVADE && spellHitTarget && !m_caster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)))
{
if (Unit* unitCaster = m_caster->ToUnit())
unitCaster->AtTargetAttacked(unit, m_spellInfo->HasInitialAggro() && !unitCaster->IsIgnoringCombat());
unitCaster->AtTargetAttacked(unit, m_spellInfo->CausesInitialThreat() && !unitCaster->IsIgnoringCombat());
if (!unit->IsStandState())
unit->SetStandState(UNIT_STAND_STATE_STAND);
@@ -2820,7 +2865,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
}
}
if (m_originalCaster && unit->IsInCombat() && m_spellInfo->HasInitialAggro())
if (m_originalCaster && unit->IsInCombat() && m_spellInfo->CausesInitialThreat())
{
if (m_originalCaster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) // only do explicit combat forwarding for PvP enabled units
m_originalCaster->GetCombatManager().InheritCombatStatesFrom(unit); // for creature v creature combat, the threat forward does it for us
@@ -3645,7 +3690,7 @@ void Spell::_cast(bool skipCheck)
// Handle procs on cast
uint32 procAttacker = m_procAttacker;
if (!procAttacker)
if (!procAttacker && !m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS))
{
if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)
procAttacker = m_spellInfo->IsPositive() ? PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG;
@@ -3855,7 +3900,7 @@ void Spell::_handle_finish_phase()
return;
uint32 procAttacker = m_procAttacker;
if (!procAttacker)
if (!procAttacker && !m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS))
{
if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)
procAttacker = m_spellInfo->IsPositive() ? PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG;
@@ -5291,7 +5336,7 @@ void Spell::HandleThreatSpells()
if (m_UniqueTargetInfo.empty())
return;
if (!m_spellInfo->HasInitialAggro())
if (!m_spellInfo->CausesInitialThreat())
return;
float threat = 0.0f;
@@ -5302,7 +5347,7 @@ void Spell::HandleThreatSpells()
threat += threatEntry->flatMod;
}
else if (!m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NO_INITIAL_THREAT) && !m_spellInfo->HasAttribute(SPELL_ATTR2_NO_INITIAL_THREAT))
else if (!m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NO_INITIAL_THREAT))
threat += m_spellInfo->SpellLevel;
// past this point only multiplicative effects occur
@@ -7727,7 +7772,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
if (m_originalCaster && targetInfo.missCondition != SPELL_MISS_EVADE
&& !m_originalCaster->IsFriendlyTo(unit)
&& (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL))
&& (m_spellInfo->HasInitialAggro() || unit->IsEngaged())
&& (m_spellInfo->CausesInitialThreat() || unit->IsEngaged())
&& !m_originalCaster->IsIgnoringCombat())
m_originalCaster->SetInCombatWith(unit);
+2 -2
View File
@@ -1479,9 +1479,9 @@ bool SpellInfo::IsAutoRepeatRangedSpell() const
return HasAttribute(SPELL_ATTR2_AUTOREPEAT_FLAG);
}
bool SpellInfo::HasInitialAggro() const
bool SpellInfo::CausesInitialThreat() const
{
return !(HasAttribute(SPELL_ATTR1_NO_THREAT) || HasAttribute(SPELL_ATTR3_NO_INITIAL_AGGRO));
return !(HasAttribute(SPELL_ATTR1_NO_THREAT) || HasAttribute(SPELL_ATTR2_NO_INITIAL_THREAT));
}
WeaponAttackType SpellInfo::GetAttackType() const
+1 -1
View File
@@ -528,7 +528,7 @@ class TC_GAME_API SpellInfo
bool IsBreakingStealth() const;
bool IsRangedWeaponSpell() const;
bool IsAutoRepeatRangedSpell() const;
bool HasInitialAggro() const;
bool CausesInitialThreat() const;
WeaponAttackType GetAttackType() const;
+9 -15
View File
@@ -3247,7 +3247,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// Vampiric Embrace
ApplySpellFix({ 15290 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
spellInfo->AttributesEx3 |= SPELL_ATTR2_NO_INITIAL_THREAT;
});
// Vampiric Touch (dispel effect)
@@ -3763,12 +3763,6 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
});
// Lock Players and Tap Chest
ApplySpellFix({ 72347 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 &= ~SPELL_ATTR3_NO_INITIAL_AGGRO;
});
// Lock and Load (Rank 1)
ApplySpellFix({ 56342 }, [](SpellInfo* spellInfo)
{
@@ -4578,7 +4572,7 @@ void SpellMgr::LoadSpellInfoCorrections()
ApplySpellFix({ 76194, 91042 }, [](SpellInfo* spellInfo)
{
spellInfo->MaxAffectedTargets = 1;
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
spellInfo->AttributesEx3 |= SPELL_ATTR2_NO_INITIAL_THREAT;
});
// Shadow Gale
@@ -4683,7 +4677,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// Destruction Protocoll
ApplySpellFix({ 77437 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
spellInfo->AttributesEx3 |= SPELL_ATTR2_NO_INITIAL_THREAT;
});
// Crumbling Ruin
@@ -4774,7 +4768,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// Feral Charge (Cat Form
ApplySpellFix({ 49376 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 &= ~SPELL_ATTR3_CANT_TRIGGER_PROC;
spellInfo->AttributesEx3 &= ~SPELL_ATTR3_CANT_TRIGGER_CASTER_PROCS;
});
//
@@ -4981,7 +4975,7 @@ void SpellMgr::LoadSpellInfoCorrections()
97352
}, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
spellInfo->AttributesEx3 |= SPELL_ATTR2_NO_INITIAL_THREAT;
});
// Poison Bolt Volley
@@ -5165,7 +5159,7 @@ void SpellMgr::LoadSpellInfoCorrections()
93299
}, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
spellInfo->AttributesEx3 |= SPELL_ATTR2_NO_INITIAL_THREAT;
});
// Lightning Clouds
@@ -5243,7 +5237,7 @@ void SpellMgr::LoadSpellInfoCorrections()
106464 // Enter the Dream
}, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
spellInfo->AttributesEx3 |= SPELL_ATTR2_NO_INITIAL_THREAT;
});
// Root
@@ -5532,7 +5526,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// Debilitating Slime
ApplySpellFix({ 77615 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
spellInfo->AttributesEx3 |= SPELL_ATTR2_NO_INITIAL_THREAT;
});
// Dragon Orb
@@ -5642,7 +5636,7 @@ void SpellMgr::LoadSpellInfoCorrections()
91884
}, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
spellInfo->AttributesEx3 |= SPELL_ATTR2_NO_INITIAL_THREAT;
spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_4_YARDS);
});