Commit
This is the first stage of the ongoing aura rewrite task. The changelog: Revamp of positive/negatve effects handling: * Introducing neutral target modes category: positive/negative sign depends on caster's and target's relations. * Existing target modes are now split into 3 categories: friendly, hostile, neutral. * Positive/negative effect detection revamped and cleaned up to use the new target mode logic. A few bugs may appear due to neutral targets behaviour, report them asap for hotfix. * Small improvement for aura cancel handler. Changes to proc/trigger system: * Additional target triggers now use target mode sign check to not proc hostile procs on friendly targets (SP's Shadow Weaving). * Spell proc now has a basic check for target mode relation between the target and the caster to not cast hostile procs on friendly targets, unless reflected (To be improved in the future). Misc changes: * Friendly Fire spells (such as Gruul's Shatter) should no longer put friendly players in PvP combat with each other. Changes to spell hit detection system: * Failed hostile spell hits now put caster in combat with creatures. * Failed hostile spell hits now put caster in PvP combat with players. * Fixes Polymorph and several other spells not initiating combat: SPELL_ATTR_STOP_ATTACK_TARGET does not prevent aggro.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1041,28 +1041,34 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) | |
|
||
if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target | ||
DoSpellHitOnUnit(unit, mask); | ||
else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit) | ||
else if (missInfo != SPELL_MISS_EVADE) | ||
{ | ||
if (target->reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him | ||
if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit) | ||
{ | ||
DoSpellHitOnUnit(m_caster, mask); | ||
unitTarget = m_caster; | ||
if (target->reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him | ||
{ | ||
DoSpellHitOnUnit(m_caster, mask); | ||
unitTarget = m_caster; | ||
} | ||
} | ||
} | ||
else if (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_RESIST) | ||
{ | ||
|
||
// Failed hostile spell hits count as attack made against target (if detected) | ||
if (real_caster && real_caster != unit) | ||
{ | ||
// can cause back attack (if detected) | ||
if (!m_spellInfo->HasAttribute(SPELL_ATTR_EX3_NO_INITIAL_AGGRO) && !IsPositiveSpell(m_spellInfo->Id) && | ||
m_caster->isVisibleForOrDetect(unit, unit, false)) | ||
if (!m_spellInfo->HasAttribute(SPELL_ATTR_EX3_NO_INITIAL_AGGRO) && | ||
!m_spellInfo->HasAttribute(SPELL_ATTR_EX_NO_THREAT) && | ||
!IsPositiveSpell(m_spellInfo->Id, real_caster, unit) && | ||
m_caster->isVisibleForOrDetect(unit, unit, false)) | ||
{ | ||
if (!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI()) | ||
((Creature*)unit)->AI()->AttackedBy(real_caster); | ||
|
||
unit->AddThreat(real_caster); | ||
unit->SetInCombatWith(real_caster); | ||
real_caster->SetInCombatWith(unit); | ||
|
||
if (Player* attackedPlayer = unit->GetCharmerOrOwnerPlayerOrPlayerItself()) | ||
real_caster->SetContestedPvP(attackedPlayer); | ||
} | ||
} | ||
} | ||
|
@@ -1249,9 +1255,11 @@ void Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask) | |
if (!m_spellInfo->HasAttribute(SPELL_ATTR_EX_NOT_BREAK_STEALTH)) | ||
unit->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); | ||
|
||
// can cause back attack (if detected), stealth removed at Spell::cast if spell break it | ||
if (!m_spellInfo->HasAttribute(SPELL_ATTR_EX3_NO_INITIAL_AGGRO) && !IsPositiveSpell(m_spellInfo->Id) && | ||
m_caster->isVisibleForOrDetect(unit, unit, false)) | ||
// Hostile spell hits count as attack made against target (if detected), stealth removed at Spell::cast if spell break it | ||
if (!m_spellInfo->HasAttribute(SPELL_ATTR_EX3_NO_INITIAL_AGGRO) && | ||
!m_spellInfo->HasAttribute(SPELL_ATTR_EX_NO_THREAT) && | ||
!IsPositiveSpell(m_spellInfo->Id, realCaster, unit) && | ||
m_caster->isVisibleForOrDetect(unit, unit, false)) | ||
{ | ||
// use speedup check to avoid re-remove after above lines | ||
if (m_spellInfo->HasAttribute(SPELL_ATTR_EX_NOT_BREAK_STEALTH)) | ||
|
@@ -1265,23 +1273,20 @@ void Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask) | |
|
||
unit->AddThreat(realCaster); | ||
|
||
if (!m_spellInfo->HasAttribute(SPELL_ATTR_STOP_ATTACK_TARGET)) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
Warlockbugs
Author
Member
|
||
{ | ||
if (!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI()) | ||
unit->AttackedBy(realCaster); | ||
if (!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI()) | ||
unit->AttackedBy(realCaster); | ||
|
||
unit->SetInCombatWith(realCaster); | ||
realCaster->SetInCombatWith(unit); | ||
unit->SetInCombatWith(realCaster); | ||
realCaster->SetInCombatWith(unit); | ||
|
||
if (Player* attackedPlayer = unit->GetCharmerOrOwnerPlayerOrPlayerItself()) | ||
realCaster->SetContestedPvP(attackedPlayer); | ||
} | ||
if (Player* attackedPlayer = unit->GetCharmerOrOwnerPlayerOrPlayerItself()) | ||
realCaster->SetContestedPvP(attackedPlayer); | ||
} | ||
} | ||
else | ||
{ | ||
// for delayed spells ignore negative spells (after duel end) for friendly targets | ||
if (speed > 0.0f && !IsPositiveSpell(m_spellInfo->Id)) | ||
if (speed > 0.0f && !IsPositiveSpell(m_spellInfo->Id, realCaster, unit)) | ||
{ | ||
realCaster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE); | ||
ResetEffectDamageAndHeal(); | ||
|
@@ -3788,11 +3793,15 @@ void Spell::finish(bool ok) | |
{ | ||
SpellEntry const* auraSpellInfo = (*i)->GetSpellProto(); | ||
SpellEffectIndex auraSpellIdx = (*i)->GetEffIndex(); | ||
const uint32 procid = auraSpellInfo->EffectTriggerSpell[auraSpellIdx]; | ||
// Quick target mode check for procs and triggers (do not cast at friendly targets stuff against hostiles only) | ||
if (IsPositiveSpellTargetMode(m_spellInfo, m_caster, unit) != IsPositiveSpellTargetMode(procid, m_caster, unit)) | ||
continue; | ||
// Calculate chance at that moment (can be depend for example from combo points) | ||
int32 auraBasePoints = (*i)->GetBasePoints(); | ||
int32 chance = m_caster->CalculateSpellDamage(unit, auraSpellInfo, auraSpellIdx, &auraBasePoints); | ||
if (roll_chance_i(chance)) | ||
m_caster->CastSpell(unit, auraSpellInfo->EffectTriggerSpell[auraSpellIdx], true, nullptr, (*i)); | ||
m_caster->CastSpell(unit, procid, true, nullptr, (*i)); | ||
} | ||
} | ||
} | ||
|
@@ -5143,7 +5152,7 @@ SpellCastResult Spell::CheckCast(bool strict) | |
if (!explicit_target_mode && m_caster->GetTypeId() == TYPEID_UNIT && m_caster->GetCharmerOrOwnerGuid()) | ||
{ | ||
// check correctness positive/negative cast target (pet cast real check and cheating check) | ||
if (IsPositiveSpell(m_spellInfo->Id)) | ||
if (IsPositiveSpell(m_spellInfo->Id, m_caster, target)) | ||
{ | ||
if (!target_hostile_checked) | ||
{ | ||
|
@@ -5168,7 +5177,7 @@ SpellCastResult Spell::CheckCast(bool strict) | |
} | ||
} | ||
|
||
if (IsPositiveSpell(m_spellInfo->Id)) | ||
if (IsPositiveSpell(m_spellInfo->Id, m_caster, target)) | ||
if (target->IsImmuneToSpell(m_spellInfo, target == m_caster) && !target->hasUnitState(UNIT_STAT_ISOLATED)) | ||
return SPELL_FAILED_TARGET_AURASTATE; | ||
|
||
|
@@ -6244,7 +6253,7 @@ SpellCastResult Spell::CheckPetCast(Unit* target) | |
if (!_target->isTargetableForAttack()) | ||
return SPELL_FAILED_BAD_TARGETS; // guessed error | ||
|
||
if (IsPositiveSpell(m_spellInfo->Id)) | ||
if (IsPositiveSpell(m_spellInfo->Id, m_caster, _target)) | ||
{ | ||
if (m_caster->IsHostileTo(_target)) | ||
return SPELL_FAILED_BAD_TARGETS; | ||
|
@@ -7312,7 +7321,7 @@ bool Spell::CheckTarget(Unit* target, SpellEffectIndex eff) | |
if (((Player*)target)->GetVisibility() == VISIBILITY_OFF) | ||
return false; | ||
|
||
if (((Player*)target)->isGameMaster() && !IsPositiveSpell(m_spellInfo->Id)) | ||
if (((Player*)target)->isGameMaster() && !IsPositiveSpell(m_spellInfo->Id, m_caster, target)) | ||
return false; | ||
} | ||
|
||
|
1 comment
on commit 21f2f00
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Looks very good and clean.
Can't wait to play around with this when I have the chance.
@Warlockbugs this is needed, i recently introduced this to avoid creature start the combat before receiving possess aura. Possess still work but you the creature start chase a millisecond before aura apply. And we can see it in some case.
But now i face similar problem while iam working on charm aura. If you cast 13180 it fail because creature already in combat. Its probably due to this. I wonder now if all the code are in the good place, it maybe should not be here at all or placed after applying the aura.