mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
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)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -319,9 +319,10 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, 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);
|
||||
|
||||
|
||||
@@ -2209,27 +2209,37 @@ void AuraEffect::HandleFeignDeath(AuraApplication const* aurApp, uint8 mode, boo
|
||||
|
||||
if (apply)
|
||||
{
|
||||
UnitList targets;
|
||||
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(target, target, target->GetMap()->GetVisibilityRange());
|
||||
Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(target, targets, u_check);
|
||||
Cell::VisitAllObjects(target, searcher, target->GetMap()->GetVisibilityRange());
|
||||
for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
|
||||
auto isAffectedByFeignDeath = [](Unit const* attacker)
|
||||
{
|
||||
if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
|
||||
Creature const* attackerCreature = attacker->ToCreature();
|
||||
return !attackerCreature || !attackerCreature->IsIgnoringFeignDeath();
|
||||
};
|
||||
|
||||
std::vector<Unit*> targets;
|
||||
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(target, target, target->GetMap()->GetVisibilityRange());
|
||||
Trinity::UnitListSearcher searcher(target, targets, u_check);
|
||||
Cell::VisitAllObjects(target, searcher, target->GetMap()->GetVisibilityRange());
|
||||
for (Unit* unit : targets)
|
||||
{
|
||||
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))
|
||||
|
||||
Reference in New Issue
Block a user