fix(Core/Combat): Fix guardians not attacking after threat system port (#25157)
Co-authored-by: blinkysc <blinkysc@users.noreply.github.com>
This commit is contained in:
@@ -239,14 +239,16 @@ void CreatureAI::EnterEvadeMode(EvadeReason why)
|
|||||||
{
|
{
|
||||||
if (Unit* owner = me->GetCharmerOrOwner())
|
if (Unit* owner = me->GetCharmerOrOwner())
|
||||||
{
|
{
|
||||||
|
// Owned creatures (pets/guardians) follow their owner — clear evade state
|
||||||
|
// so they can re-enter combat immediately via CanBeginCombat
|
||||||
|
me->ClearUnitState(UNIT_STATE_EVADE);
|
||||||
me->GetMotionMaster()->Clear(false);
|
me->GetMotionMaster()->Clear(false);
|
||||||
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE);
|
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Required to prevent attacking creatures that are evading and cause them to reenter combat
|
// Required to prevent attacking creatures that are evading and cause them to reenter combat
|
||||||
// Does not apply to MoveFollow
|
// Does not apply to MoveFollow — UNIT_STATE_EVADE is already set from _EnterEvadeMode
|
||||||
me->AddUnitState(UNIT_STATE_EVADE);
|
|
||||||
me->GetMotionMaster()->MoveTargetedHome();
|
me->GetMotionMaster()->MoveTargetedHome();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -381,8 +383,11 @@ bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set evade state early to prevent recursion when CombatStop triggers JustExitedCombat
|
// Set evade state early to prevent recursion: CombatStop below purges combat
|
||||||
// This will be cleared in MoveTargetedHome for pets/guardians following their owner
|
// refs, which triggers JustExitedCombat -> EnterEvadeMode -> _EnterEvadeMode.
|
||||||
|
// The IsInEvadeMode() check above will catch it.
|
||||||
|
// EnterEvadeMode will clear this for owned creatures (pets/guardians) that
|
||||||
|
// use MoveFollow instead of MoveTargetedHome.
|
||||||
me->AddUnitState(UNIT_STATE_EVADE);
|
me->AddUnitState(UNIT_STATE_EVADE);
|
||||||
|
|
||||||
// don't remove vehicle auras, passengers aren't supposed to drop off the vehicle
|
// don't remove vehicle auras, passengers aren't supposed to drop off the vehicle
|
||||||
|
|||||||
@@ -7333,19 +7333,22 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
|
|||||||
// set position before any AI calls/assistance
|
// set position before any AI calls/assistance
|
||||||
//if (IsCreature())
|
//if (IsCreature())
|
||||||
// ToCreature()->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ());
|
// ToCreature()->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||||
if (creature && !IsControlledByPlayer())
|
if (creature)
|
||||||
{
|
{
|
||||||
EngageWithTarget(victim);
|
EngageWithTarget(victim);
|
||||||
|
|
||||||
creature->SendAIReaction(AI_REACTION_HOSTILE);
|
if (!IsControlledByPlayer())
|
||||||
|
{
|
||||||
|
creature->SendAIReaction(AI_REACTION_HOSTILE);
|
||||||
|
|
||||||
/// @todo: Implement aggro range, detection range and assistance range templates
|
/// @todo: Implement aggro range, detection range and assistance range templates
|
||||||
if (!(creature->HasFlagsExtra(CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE)))
|
if (!(creature->HasFlagsExtra(CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE)))
|
||||||
creature->CallAssistance();
|
creature->CallAssistance();
|
||||||
|
|
||||||
creature->SetAssistanceTimer(sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_PERIOD));
|
creature->SetAssistanceTimer(sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_PERIOD));
|
||||||
|
|
||||||
SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
|
SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// delay offhand weapon attack by 50% of the base attack time
|
// delay offhand weapon attack by 50% of the base attack time
|
||||||
|
|||||||
@@ -306,6 +306,8 @@ struct npc_pet_dk_army_of_the_dead : public AggressorAI
|
|||||||
{
|
{
|
||||||
npc_pet_dk_army_of_the_dead(Creature* creature) : AggressorAI(creature) { }
|
npc_pet_dk_army_of_the_dead(Creature* creature) : AggressorAI(creature) { }
|
||||||
|
|
||||||
|
// Restrict MoveInLineOfSight aggro to targets already fighting our owner,
|
||||||
|
// so ghouls don't pull extra packs on their own.
|
||||||
bool CanAIAttack(Unit const* target) const override
|
bool CanAIAttack(Unit const* target) const override
|
||||||
{
|
{
|
||||||
if (!target)
|
if (!target)
|
||||||
@@ -315,6 +317,26 @@ struct npc_pet_dk_army_of_the_dead : public AggressorAI
|
|||||||
return false;
|
return false;
|
||||||
return AggressorAI::CanAIAttack(target);
|
return AggressorAI::CanAIAttack(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Owner started attacking a target — engage immediately.
|
||||||
|
// We bypass OnOwnerCombatInteraction because CanStartAttack -> CanAIAttack
|
||||||
|
// may reject the target before combat refs are established.
|
||||||
|
void OwnerAttacked(Unit* target) override
|
||||||
|
{
|
||||||
|
if (!target || !me->IsAlive() || me->HasReactState(REACT_PASSIVE))
|
||||||
|
return;
|
||||||
|
if (me->IsValidAttackTarget(target))
|
||||||
|
AttackStart(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Owner was attacked — help defend.
|
||||||
|
void OwnerAttackedBy(Unit* attacker) override
|
||||||
|
{
|
||||||
|
if (!attacker || !me->IsAlive() || me->HasReactState(REACT_PASSIVE))
|
||||||
|
return;
|
||||||
|
if (me->IsValidAttackTarget(attacker))
|
||||||
|
AttackStart(attacker);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct npc_pet_dk_dancing_rune_weapon : public NullCreatureAI
|
struct npc_pet_dk_dancing_rune_weapon : public NullCreatureAI
|
||||||
|
|||||||
Reference in New Issue
Block a user