fix(Core/Creature): Prevent combat movement disabled creatures from r… (#18428)

* fix(Core/Creature): Prevent combat movement disabled creatures from repositioning if target moves within model boundary

* fixbuild

* Apply suggestions from code review
This commit is contained in:
Andrew
2024-02-27 10:11:39 -03:00
committed by GitHub
parent b2e2cbfc13
commit 6df652a8dd
32 changed files with 71 additions and 74 deletions

View File

@@ -348,7 +348,7 @@ void CreatureAI::MoveCircleChecks()
!victim ||
!me->IsFreeToMove() || me->HasUnitMovementFlag(MOVEMENTFLAG_ROOT) ||
!me->IsWithinMeleeRange(victim) || me == victim->GetVictim() ||
(victim->GetTypeId() != TYPEID_PLAYER && !victim->IsPet()) // only player & pets to save CPU
(!victim->IsPlayer() && !victim->IsPet()) // only player & pets to save CPU
)
{
return;
@@ -357,14 +357,12 @@ void CreatureAI::MoveCircleChecks()
me->GetMotionMaster()->MoveCircleTarget(me->GetVictim());
}
void CreatureAI::MoveBackwardsChecks() {
void CreatureAI::MoveBackwardsChecks()
{
Unit *victim = me->GetVictim();
if (
!victim ||
!me->IsFreeToMove() || me->HasUnitMovementFlag(MOVEMENTFLAG_ROOT) ||
(victim->GetTypeId() != TYPEID_PLAYER && !victim->IsPet())
)
if (!victim || !me->IsFreeToMove() || me->HasUnitMovementFlag(MOVEMENTFLAG_ROOT) ||
(!victim->IsPlayer() && !victim->IsPet()))
{
return;
}

View File

@@ -191,8 +191,7 @@ bool SummonList::IsAnyCreatureInCombat() const
ScriptedAI::ScriptedAI(Creature* creature) : CreatureAI(creature),
me(creature),
IsFleeing(false),
_isCombatMovementAllowed(true)
IsFleeing(false)
{
_isHeroic = me->GetMap()->IsHeroic();
_difficulty = Difficulty(me->GetMap()->GetSpawnMode());
@@ -209,7 +208,7 @@ void ScriptedAI::AttackStartNoMove(Unit* who)
void ScriptedAI::AttackStart(Unit* who)
{
if (IsCombatMovementAllowed())
if (me->IsCombatMovementAllowed())
CreatureAI::AttackStart(who);
else
AttackStartNoMove(who);
@@ -537,11 +536,6 @@ void ScriptedAI::SetEquipmentSlots(bool loadDefault, int32 mainHand /*= EQUIP_NO
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, uint32(ranged));
}
void ScriptedAI::SetCombatMovement(bool allowMovement)
{
_isCombatMovementAllowed = allowMovement;
}
enum eNPCs
{
NPC_BROODLORD = 12017,

View File

@@ -373,14 +373,6 @@ struct ScriptedAI : public CreatureAI
void SetEquipmentSlots(bool loadDefault, int32 mainHand = EQUIP_NO_CHANGE, int32 offHand = EQUIP_NO_CHANGE, int32 ranged = EQUIP_NO_CHANGE);
// Used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims
// NOTE: If you use SetCombatMovement while the creature is in combat, it will do NOTHING - This only affects AttackStart
// You should make the necessary to make it happen so.
// Remember that if you modified _isCombatMovementAllowed (e.g: using SetCombatMovement) it will not be reset at Reset().
// It will keep the last value you set.
void SetCombatMovement(bool allowMovement);
bool IsCombatMovementAllowed() const { return _isCombatMovementAllowed; }
virtual bool CheckEvadeIfOutOfCombatArea() const { return false; }
// return true for heroic mode. i.e.
@@ -452,7 +444,6 @@ struct ScriptedAI : public CreatureAI
private:
Difficulty _difficulty;
bool _isCombatMovementAllowed;
bool _isHeroic;
std::unordered_set<uint32> _uniqueTimedEvents;
};

View File

@@ -64,7 +64,7 @@ void npc_escortAI::AttackStart(Unit* who)
me->StopMoving();
}
if (IsCombatMovementAllowed())
if (me->IsCombatMovementAllowed())
me->GetMotionMaster()->MoveChase(who);
}
}
@@ -178,8 +178,8 @@ void npc_escortAI::JustRespawned()
{
RemoveEscortState(STATE_ESCORT_ESCORTING | STATE_ESCORT_RETURNING | STATE_ESCORT_PAUSED);
if (!IsCombatMovementAllowed())
SetCombatMovement(true);
if (!me->IsCombatMovementAllowed())
me->SetCombatMovement(true);
//add a small delay before going to first waypoint, normal in near all cases
m_uiWPWaitTimer = 1000;

View File

@@ -55,7 +55,7 @@ void FollowerAI::AttackStart(Unit* who)
if (me->HasUnitState(UNIT_STATE_FOLLOW))
me->ClearUnitState(UNIT_STATE_FOLLOW);
if (IsCombatMovementAllowed())
if (me->IsCombatMovementAllowed())
me->GetMotionMaster()->MoveChase(who);
}
}
@@ -141,8 +141,8 @@ void FollowerAI::JustRespawned()
{
m_uiFollowState = STATE_FOLLOW_NONE;
if (!IsCombatMovementAllowed())
SetCombatMovement(true);
if (!me->IsCombatMovementAllowed())
me->SetCombatMovement(true);
if (me->GetFaction() != me->GetCreatureTemplate()->faction)
me->SetFaction(me->GetCreatureTemplate()->faction);

View File

@@ -220,7 +220,7 @@ Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(),
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_regenPower(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_moveInLineOfSightDisabled(false), m_moveInLineOfSightStrictlyDisabled(false),
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), _lastDamagedTime(nullptr), m_cannotReachTimer(0),
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0), _playerDamageReq(0), _damagedByPlayer(false)
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0), _playerDamageReq(0), _damagedByPlayer(false), _isCombatMovementAllowed(true)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
m_valuesCount = UNIT_END;
@@ -877,7 +877,7 @@ bool Creature::IsFreeToMove()
{
uint32 moveFlags = m_movementInfo.GetMovementFlags();
// Do not reposition ourself when we are not allowed to move
if ((IsMovementPreventedByCasting() || isMoving() || !CanFreeMove()) &&
if ((IsMovementPreventedByCasting() || isMoving() || !CanFreeMove() || !IsCombatMovementAllowed()) &&
(GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE ||
moveFlags & MOVEMENTFLAG_SPLINE_ENABLED))
{
@@ -3738,6 +3738,11 @@ bool Creature::CanCastSpell(uint32 spellID) const
return true;
}
void Creature::SetCombatMovement(bool allowMovement)
{
_isCombatMovementAllowed = allowMovement;
}
ObjectGuid Creature::GetSummonerGUID() const
{
if (TempSummon const* temp = ToTempSummon())

View File

@@ -413,6 +413,14 @@ public:
* */
[[nodiscard]] ObjectGuid GetSummonerGUID() const;
// Used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims
// NOTE: If you use SetCombatMovement while the creature is in combat, it will do NOTHING - This only affects AttackStart
// You should make the necessary to make it happen so.
// Remember that if you modified _isCombatMovementAllowed (e.g: using SetCombatMovement) it will not be reset at Reset().
// It will keep the last value you set.
void SetCombatMovement(bool allowMovement);
bool IsCombatMovementAllowed() const { return _isCombatMovementAllowed; }
std::string GetDebugInfo() const override;
protected:
@@ -501,6 +509,7 @@ private:
uint32 _playerDamageReq;
bool _damagedByPlayer;
bool _isCombatMovementAllowed;
};
class AssistDelayEvent : public BasicEvent