refactor(Core/Movement): follower management of references (#25060)
Co-authored-by: Shauren <shauren.trinity@gmail.com>
This commit is contained in:
@@ -20,9 +20,13 @@
|
||||
|
||||
void AbstractFollower::SetTarget(Unit* unit)
|
||||
{
|
||||
if (unit == GetTarget())
|
||||
if (unit == _target)
|
||||
return;
|
||||
|
||||
i_target.link(unit, this);
|
||||
_target = i_target.getTarget();
|
||||
if (_target)
|
||||
_target->FollowerRemoved(this);
|
||||
|
||||
_target = unit;
|
||||
if (_target)
|
||||
_target->FollowerAdded(this);
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#ifndef ACORE_ABSTRACTFOLLOWER_H
|
||||
#define ACORE_ABSTRACTFOLLOWER_H
|
||||
|
||||
#include "FollowerReference.h"
|
||||
|
||||
class Unit;
|
||||
|
||||
class AbstractFollower
|
||||
@@ -29,15 +27,10 @@ public:
|
||||
virtual ~AbstractFollower() { SetTarget(nullptr); }
|
||||
|
||||
void SetTarget(Unit* unit);
|
||||
Unit* GetTarget() const { return _target; }
|
||||
bool IsTargetValid() const { return i_target.isValid(); }
|
||||
|
||||
virtual void stopFollowing() { }
|
||||
[[nodiscard]] Unit* GetTarget() const { return _target; }
|
||||
|
||||
private:
|
||||
Unit* _target = nullptr;
|
||||
|
||||
protected:
|
||||
FollowerReference i_target;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _FOLLOWERREFMANAGER
|
||||
#define _FOLLOWERREFMANAGER
|
||||
|
||||
#include "RefMgr.h"
|
||||
|
||||
class Unit;
|
||||
class AbstractFollower;
|
||||
|
||||
class FollowerRefMgr : public RefMgr<Unit, AbstractFollower>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "FollowerReference.h"
|
||||
#include "AbstractFollower.h"
|
||||
#include "Unit.h"
|
||||
|
||||
void FollowerReference::targetObjectBuildLink()
|
||||
{
|
||||
getTarget()->AddFollower(this);
|
||||
}
|
||||
|
||||
void FollowerReference::targetObjectDestroyLink()
|
||||
{
|
||||
getTarget()->RemoveFollower(this);
|
||||
}
|
||||
|
||||
void FollowerReference::sourceObjectDestroyLink()
|
||||
{
|
||||
GetSource()->stopFollowing();
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _FOLLOWERREFERENCE_H
|
||||
#define _FOLLOWERREFERENCE_H
|
||||
|
||||
#include "Reference.h"
|
||||
|
||||
class AbstractFollower;
|
||||
class Unit;
|
||||
|
||||
class FollowerReference : public Reference<Unit, AbstractFollower>
|
||||
{
|
||||
protected:
|
||||
void targetObjectBuildLink() override;
|
||||
void targetObjectDestroyLink() override;
|
||||
void sourceObjectDestroyLink() override;
|
||||
};
|
||||
#endif
|
||||
@@ -85,7 +85,7 @@ void ChaseMovementGenerator<T>::DistanceYourself(T* owner, float distance)
|
||||
i_path = std::make_unique<PathGenerator>(owner);
|
||||
|
||||
float x, y, z;
|
||||
i_target->GetNearPoint(owner, x, y, z, owner->GetBoundaryRadius(), distance, i_target->GetAngle(owner));
|
||||
GetTarget()->GetNearPoint(owner, x, y, z, owner->GetBoundaryRadius(), distance, GetTarget()->GetAngle(owner));
|
||||
if (DispatchSplineToPosition(owner, x, y, z, false, false, 0.f, false, false))
|
||||
{
|
||||
m_currentMode = CHASE_MODE_DISTANCING;
|
||||
@@ -110,7 +110,7 @@ bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, floa
|
||||
|
||||
// For pets, treat incomplete paths as failures to avoid clipping through geometry
|
||||
// Players and Player-controlled units have more erratic movement, skip failure
|
||||
if (cOwner && (cOwner->IsPet() || cOwner->IsControlledByPlayer()) && !i_target.getTarget()->IsCharmedOwnedByPlayerOrPlayer())
|
||||
if (cOwner && (cOwner->IsPet() || cOwner->IsControlledByPlayer()) && !GetTarget()->IsCharmedOwnedByPlayerOrPlayer())
|
||||
if (pathType & PATHFIND_INCOMPLETE)
|
||||
pathFailed = true;
|
||||
|
||||
@@ -118,7 +118,7 @@ bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, floa
|
||||
{
|
||||
if (cOwner)
|
||||
{
|
||||
cOwner->SetCannotReachTarget(i_target.getTarget()->GetGUID());
|
||||
cOwner->SetCannotReachTarget(GetTarget()->GetGUID());
|
||||
|
||||
if (cOwner->IsPet() || cOwner->IsControlledByPlayer())
|
||||
cOwner->AttackStop();
|
||||
@@ -142,7 +142,7 @@ bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, floa
|
||||
Movement::MoveSplineInit init(owner);
|
||||
init.MovebyPath(i_path->GetPath());
|
||||
if (target)
|
||||
init.SetFacing(i_target.getTarget());
|
||||
init.SetFacing(GetTarget());
|
||||
init.SetWalk(walk);
|
||||
init.Launch();
|
||||
|
||||
@@ -152,7 +152,7 @@ bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, floa
|
||||
template<class T>
|
||||
bool ChaseMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
||||
{
|
||||
if (!i_target.isValid() || !i_target->IsInWorld() || !owner->IsInMap(i_target.getTarget()))
|
||||
if (!GetTarget() || !GetTarget()->IsInWorld() || !owner->IsInMap(GetTarget()))
|
||||
return false;
|
||||
|
||||
if (!owner || !owner->IsAlive())
|
||||
@@ -194,11 +194,11 @@ bool ChaseMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
||||
|
||||
bool forceDest =
|
||||
//(cOwner && (cOwner->isWorldBoss() || cOwner->IsDungeonBoss())) || // force for all bosses, even not in instances
|
||||
(i_target->IsPlayer() && i_target->ToPlayer()->IsGameMaster()) || // for .npc follow
|
||||
(GetTarget()->IsPlayer() && GetTarget()->ToPlayer()->IsGameMaster()) || // for .npc follow
|
||||
(owner->CanFly())
|
||||
; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
|
||||
|
||||
Unit* target = i_target.getTarget();
|
||||
Unit* target = GetTarget();
|
||||
|
||||
bool mutualChase = IsMutualChase(owner, target);
|
||||
bool const mutualTarget = target->GetVictim() == owner;
|
||||
@@ -414,7 +414,7 @@ void ChaseMovementGenerator<T>::MovementInform(T* owner)
|
||||
{
|
||||
// Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
|
||||
if (CreatureAI* AI = owner->ToCreature()->AI())
|
||||
AI->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUID().GetCounter());
|
||||
AI->MovementInform(CHASE_MOTION_TYPE, GetTarget()->GetGUID().GetCounter());
|
||||
break;
|
||||
}
|
||||
case CHASE_MODE_DISTANCING:
|
||||
@@ -552,14 +552,14 @@ bool FollowMovementGenerator<T>::PositionOkay(Unit* target, bool isPlayerPet, bo
|
||||
template<class T>
|
||||
bool FollowMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
||||
{
|
||||
if (!i_target.isValid() || !i_target->IsInWorld() || !owner->IsInMap(i_target.getTarget()))
|
||||
if (!GetTarget() || !GetTarget()->IsInWorld() || !owner->IsInMap(GetTarget()))
|
||||
return false;
|
||||
|
||||
if (!owner || !owner->IsAlive())
|
||||
return false;
|
||||
|
||||
Creature* cOwner = owner->ToCreature();
|
||||
Unit* target = i_target.getTarget();
|
||||
Unit* target = GetTarget();
|
||||
|
||||
// the owner might be unable to move (rooted or casting), or we have lost the target, pause movement
|
||||
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || (cOwner && owner->ToCreature()->IsMovementPreventedByCasting()))
|
||||
@@ -580,7 +580,7 @@ bool FollowMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
||||
|
||||
bool forceDest =
|
||||
(followingMaster) || // allow pets following their master to cheat while generating paths
|
||||
(i_target->IsPlayer() && i_target->ToPlayer()->IsGameMaster()) // for .npc follow
|
||||
(GetTarget()->IsPlayer() && GetTarget()->ToPlayer()->IsGameMaster()) // for .npc follow
|
||||
; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
|
||||
|
||||
bool targetIsMoving = false;
|
||||
@@ -725,7 +725,7 @@ void FollowMovementGenerator<T>::MovementInform(T* owner)
|
||||
|
||||
// Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
|
||||
if (CreatureAI* AI = owner->ToCreature()->AI())
|
||||
AI->MovementInform(FOLLOW_MOTION_TYPE, i_target.getTarget()->GetGUID().GetCounter());
|
||||
AI->MovementInform(FOLLOW_MOTION_TYPE, GetTarget()->GetGUID().GetCounter());
|
||||
}
|
||||
|
||||
//-----------------------------------------------//
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include "Timer.h"
|
||||
#include "Unit.h"
|
||||
|
||||
using TargetedMovementGeneratorBase = AbstractFollower;
|
||||
|
||||
enum ChaseMovementMode
|
||||
{
|
||||
CHASE_MODE_NORMAL, // chasing target
|
||||
|
||||
Reference in New Issue
Block a user