From 0c32277139a173c31043706d72e1cfe8830aaade Mon Sep 17 00:00:00 2001 From: Shauren Date: Mon, 4 Mar 2024 16:14:23 +0100 Subject: Core/Auras: Feign death will no longer cause creatures immune to it to drop combat (and then reenter it because the unit feigning death is considered valid) --- src/server/game/Entities/Creature/Creature.cpp | 3 ++- src/server/game/Entities/Creature/Creature.h | 5 ++-- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 30 +++++++++++++++-------- 3 files changed, 25 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index a71b84bd9ab..8041ce56691 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -567,6 +567,7 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/) // TODO: migrate these in DB _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_2_ALLOW_MOUNTED_COMBAT, (GetCreatureDifficulty()->TypeFlags & CREATURE_TYPE_FLAG_ALLOW_MOUNTED_COMBAT) != 0); + SetIgnoreFeignDeath((creatureInfo->flags_extra & CREATURE_FLAG_EXTRA_IGNORE_FEIGN_DEATH) != 0); SetInteractionAllowedInCombat((GetCreatureDifficulty()->TypeFlags & CREATURE_TYPE_FLAG_ALLOW_INTERACTION_WHILE_IN_COMBAT) != 0); SetTreatAsRaidUnit((GetCreatureDifficulty()->TypeFlags & CREATURE_TYPE_FLAG_TREAT_AS_RAID_UNIT) != 0); @@ -2641,7 +2642,7 @@ bool Creature::_IsTargetAcceptable(Unit const* target) const if (target->HasUnitState(UNIT_STATE_DIED)) { // some creatures can detect fake death - if (CanIgnoreFeignDeath() && target->HasUnitFlag2(UNIT_FLAG2_FEIGN_DEATH)) + if (IsIgnoringFeignDeath() && target->HasUnitFlag2(UNIT_FLAG2_FEIGN_DEATH)) return true; else return false; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 237b5f45310..839abfdd725 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -319,9 +319,10 @@ class TC_GAME_API Creature : public Unit, public GridObject, public Ma bool HasSearchedAssistance() const { return m_AlreadySearchedAssistance; } bool CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction = true) const; bool _IsTargetAcceptable(Unit const* target) const; - bool CanIgnoreFeignDeath() const { return (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_IGNORE_FEIGN_DEATH) != 0; } + bool IsIgnoringFeignDeath() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_2_IGNORE_FEIGN_DEATH); } + void SetIgnoreFeignDeath(bool ignoreFeignDeath) { _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_2_IGNORE_FEIGN_DEATH, ignoreFeignDeath); } bool IsIgnoringSanctuarySpellEffect() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_2_IGNORE_SANCTUARY); } - void SetIngoreSanctuarySpellEffect(bool ignoreSanctuary) { _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_2_IGNORE_SANCTUARY, ignoreSanctuary); } + void SetIgnoreSanctuarySpellEffect(bool ignoreSanctuary) { _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_2_IGNORE_SANCTUARY, ignoreSanctuary); } void RemoveCorpse(bool setSpawnTime = true, bool destroyForNearbyPlayers = true); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index c9ceb470b9d..65894bf3ec7 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2209,27 +2209,37 @@ void AuraEffect::HandleFeignDeath(AuraApplication const* aurApp, uint8 mode, boo if (apply) { - UnitList targets; + auto isAffectedByFeignDeath = [](Unit const* attacker) + { + Creature const* attackerCreature = attacker->ToCreature(); + return !attackerCreature || !attackerCreature->IsIgnoringFeignDeath(); + }; + + std::vector targets; Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(target, target, target->GetMap()->GetVisibilityRange()); - Trinity::UnitListSearcher searcher(target, targets, u_check); + Trinity::UnitListSearcher searcher(target, targets, u_check); Cell::VisitAllObjects(target, searcher, target->GetMap()->GetVisibilityRange()); - for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter) + for (Unit* unit : targets) { - if (!(*iter)->HasUnitState(UNIT_STATE_CASTING)) + if (!unit->HasUnitState(UNIT_STATE_CASTING)) + continue; + + if (!isAffectedByFeignDeath(unit)) continue; for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) { - if ((*iter)->GetCurrentSpell(i) - && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == target->GetGUID()) + if (unit->GetCurrentSpell(i) + && unit->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == target->GetGUID()) { - (*iter)->InterruptSpell(CurrentSpellTypes(i), false); + unit->InterruptSpell(CurrentSpellTypes(i), false); } } } - for (auto& pair : target->GetThreatManager().GetThreatenedByMeList()) - pair.second->ScaleThreat(0.0f); + for (auto const& [guid, ref] : target->GetThreatManager().GetThreatenedByMeList()) + if (isAffectedByFeignDeath(ref->GetOwner())) + ref->ScaleThreat(0.0f); if (target->GetMap()->IsDungeon()) // feign death does not remove combat in dungeons { @@ -2238,7 +2248,7 @@ void AuraEffect::HandleFeignDeath(AuraApplication const* aurApp, uint8 mode, boo targetPlayer->SendAttackSwingCancelAttack(); } else - target->CombatStop(false, false); + target->CombatStop(false, false, isAffectedByFeignDeath); // prevent interrupt message if (GetCasterGUID() == target->GetGUID() && target->GetCurrentSpell(CURRENT_GENERIC_SPELL)) -- cgit v1.2.3