mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-03-15 05:25:08 +00:00
fix(Core/SAI): idle casters (#23005)
This commit is contained in:
@@ -310,12 +310,29 @@ void MotionMaster::MoveConfused()
|
||||
/**
|
||||
* @brief Force the unit to chase this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE
|
||||
*/
|
||||
void MotionMaster::MoveChase(Unit* target, std::optional<ChaseRange> dist, std::optional<ChaseAngle> angle)
|
||||
void MotionMaster::MoveChase(Unit* target, std::optional<ChaseRange> dist, std::optional<ChaseAngle> angle)
|
||||
{
|
||||
// ignore movement request if target not exist
|
||||
if (!target || target == _owner || _owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE))
|
||||
return;
|
||||
|
||||
if (GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
|
||||
{
|
||||
if (_owner->IsPlayer())
|
||||
{
|
||||
ChaseMovementGenerator<Player>* gen = (ChaseMovementGenerator<Player>*)top();
|
||||
gen->SetOffsetAndAngle(dist, angle);
|
||||
gen->SetNewTarget(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChaseMovementGenerator<Creature>* gen = (ChaseMovementGenerator<Creature>*)top();
|
||||
gen->SetOffsetAndAngle(dist, angle);
|
||||
gen->SetNewTarget(target);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//_owner->ClearUnitState(UNIT_STATE_FOLLOW);
|
||||
if (_owner->IsPlayer())
|
||||
{
|
||||
@@ -331,6 +348,24 @@ void MotionMaster::MoveChase(Unit* target, std::optional<ChaseRange> dist, std:
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::DistanceYourself(float dist)
|
||||
{
|
||||
if (GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
|
||||
{
|
||||
if (_owner->IsPlayer())
|
||||
{
|
||||
ChaseMovementGenerator<Player>* gen = (ChaseMovementGenerator<Player>*)top();
|
||||
gen->DistanceYourself((Player*)_owner, dist);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChaseMovementGenerator<Creature>* gen = (ChaseMovementGenerator<Creature>*)top();
|
||||
gen->DistanceYourself((Creature*)_owner, dist);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MotionMaster::MoveBackwards(Unit* target, float dist)
|
||||
{
|
||||
if (!target)
|
||||
|
||||
@@ -247,6 +247,8 @@ public:
|
||||
void ReinitializeMovement();
|
||||
|
||||
bool GetDestination(float& x, float& y, float& z);
|
||||
|
||||
void DistanceYourself(float range);
|
||||
private:
|
||||
void Mutate(MovementGenerator* m, MovementSlot slot); // use Move* functions instead
|
||||
|
||||
|
||||
@@ -62,6 +62,81 @@ bool ChaseMovementGenerator<T>::PositionOkay(T* owner, Unit* target, Optional<fl
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ChaseMovementGenerator<T>::SetOffsetAndAngle(std::optional<ChaseRange> dist, std::optional<ChaseAngle> angle)
|
||||
{
|
||||
_range = dist;
|
||||
_angle = angle;
|
||||
_lastTargetPosition.reset();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ChaseMovementGenerator<T>::SetNewTarget(Unit* target)
|
||||
{
|
||||
i_target.link(target, this);
|
||||
_lastTargetPosition.reset();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ChaseMovementGenerator<T>::DistanceYourself(T* owner, float distance)
|
||||
{
|
||||
// make a new path if we have to...
|
||||
if (!i_path)
|
||||
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));
|
||||
if (DispatchSplineToPosition(owner, x, y, z, false, false, 0.f, false, false))
|
||||
{
|
||||
m_currentMode = CHASE_MODE_DISTANCING;
|
||||
if constexpr (!std::is_same_v<T, Player>)
|
||||
{
|
||||
owner->AI()->DistancingStarted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, float y, float z, bool walk, bool cutPath, float maxTarget, bool forceDest, bool target)
|
||||
{
|
||||
Creature* cOwner = owner->ToCreature();
|
||||
|
||||
if (owner->IsHovering())
|
||||
owner->UpdateAllowedPositionZ(x, y, z);
|
||||
|
||||
bool success = i_path->CalculatePath(x, y, z, forceDest);
|
||||
if (!success || i_path->GetPathType() & PATHFIND_NOPATH)
|
||||
{
|
||||
if (cOwner)
|
||||
{
|
||||
cOwner->SetCannotReachTarget(i_target.getTarget()->GetGUID());
|
||||
}
|
||||
|
||||
owner->StopMoving();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cutPath)
|
||||
i_path->ShortenPathUntilDist(G3D::Vector3(x, y, z), maxTarget);
|
||||
|
||||
if (cOwner)
|
||||
{
|
||||
cOwner->SetCannotReachTarget();
|
||||
}
|
||||
|
||||
owner->AddUnitState(UNIT_STATE_CHASE_MOVE);
|
||||
i_recalculateTravel = true;
|
||||
|
||||
Movement::MoveSplineInit init(owner);
|
||||
init.MovebyPath(i_path->GetPath());
|
||||
if (target)
|
||||
init.SetFacing(i_target.getTarget());
|
||||
init.SetWalk(walk);
|
||||
init.Launch();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool ChaseMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
||||
{
|
||||
@@ -71,6 +146,13 @@ bool ChaseMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
||||
if (!owner || !owner->IsAlive())
|
||||
return false;
|
||||
|
||||
if (owner->HasUnitState(UNIT_STATE_NO_COMBAT_MOVEMENT)) // script paused combat movement
|
||||
{
|
||||
owner->StopMoving();
|
||||
_lastTargetPosition.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
Creature* cOwner = owner->ToCreature();
|
||||
bool isStoppedBecauseOfCasting = cOwner && cOwner->IsMovementPreventedByCasting();
|
||||
|
||||
@@ -243,53 +325,23 @@ bool ChaseMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
||||
shortenPath = false;
|
||||
}
|
||||
|
||||
if (owner->IsHovering())
|
||||
owner->UpdateAllowedPositionZ(x, y, z);
|
||||
|
||||
bool success = i_path->CalculatePath(x, y, z, forceDest);
|
||||
if (!success || i_path->GetPathType() & PATHFIND_NOPATH)
|
||||
{
|
||||
if (cOwner)
|
||||
{
|
||||
cOwner->SetCannotReachTarget(target->GetGUID());
|
||||
}
|
||||
|
||||
owner->StopMoving();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shortenPath)
|
||||
i_path->ShortenPathUntilDist(G3D::Vector3(x, y, z), maxTarget);
|
||||
|
||||
if (cOwner)
|
||||
{
|
||||
cOwner->SetCannotReachTarget();
|
||||
}
|
||||
|
||||
bool walk = false;
|
||||
if (cOwner && !cOwner->IsPet())
|
||||
{
|
||||
switch (cOwner->GetMovementTemplate().GetChase())
|
||||
{
|
||||
case CreatureChaseMovementType::CanWalk:
|
||||
walk = owner->IsWalking();
|
||||
break;
|
||||
case CreatureChaseMovementType::AlwaysWalk:
|
||||
walk = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case CreatureChaseMovementType::CanWalk:
|
||||
walk = owner->IsWalking();
|
||||
break;
|
||||
case CreatureChaseMovementType::AlwaysWalk:
|
||||
walk = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
owner->AddUnitState(UNIT_STATE_CHASE_MOVE);
|
||||
i_recalculateTravel = true;
|
||||
|
||||
Movement::MoveSplineInit init(owner);
|
||||
init.MovebyPath(i_path->GetPath());
|
||||
init.SetFacing(target);
|
||||
init.SetWalk(walk);
|
||||
init.Launch();
|
||||
DispatchSplineToPosition(owner, x, y, z, walk, shortenPath, maxTarget, forceDest, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,9 +391,24 @@ void ChaseMovementGenerator<T>::MovementInform(T* owner)
|
||||
if (!owner->IsCreature())
|
||||
return;
|
||||
|
||||
// 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());
|
||||
switch (m_currentMode)
|
||||
{
|
||||
default:
|
||||
{
|
||||
// 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());
|
||||
break;
|
||||
}
|
||||
case CHASE_MODE_DISTANCING:
|
||||
{
|
||||
if (CreatureAI* AI = owner->ToCreature()->AI())
|
||||
AI->DistancingEnded();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_currentMode = CHASE_MODE_NORMAL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------//
|
||||
@@ -604,6 +671,13 @@ template bool ChaseMovementGenerator<Player>::DoUpdate(Player*, uint32);
|
||||
template bool ChaseMovementGenerator<Creature>::DoUpdate(Creature*, uint32);
|
||||
template void ChaseMovementGenerator<Unit>::MovementInform(Unit*);
|
||||
|
||||
template void ChaseMovementGenerator<Creature>::SetOffsetAndAngle(std::optional<ChaseRange>, std::optional<ChaseAngle>);
|
||||
template void ChaseMovementGenerator<Creature>::SetNewTarget(Unit*);
|
||||
template void ChaseMovementGenerator<Creature>::DistanceYourself(Creature*, float);
|
||||
template void ChaseMovementGenerator<Player>::SetOffsetAndAngle(std::optional<ChaseRange>, std::optional<ChaseAngle>);
|
||||
template void ChaseMovementGenerator<Player>::SetNewTarget(Unit*);
|
||||
template void ChaseMovementGenerator<Player>::DistanceYourself(Player*, float);
|
||||
|
||||
template void FollowMovementGenerator<Player>::DoInitialize(Player*);
|
||||
template void FollowMovementGenerator<Creature>::DoInitialize(Creature*);
|
||||
template void FollowMovementGenerator<Player>::DoFinalize(Player*);
|
||||
|
||||
@@ -34,12 +34,20 @@ protected:
|
||||
FollowerReference i_target;
|
||||
};
|
||||
|
||||
enum ChaseMovementMode
|
||||
{
|
||||
CHASE_MODE_NORMAL, // chasing target
|
||||
CHASE_MODE_BACKPEDAL, // collision movement
|
||||
CHASE_MODE_DISTANCING, // running away from melee
|
||||
CHASE_MODE_FANNING, // mob collision movement
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class ChaseMovementGenerator : public MovementGeneratorMedium<T, ChaseMovementGenerator<T>>, public TargetedMovementGeneratorBase
|
||||
{
|
||||
public:
|
||||
ChaseMovementGenerator(Unit* target, Optional<ChaseRange> range = {}, Optional<ChaseAngle> angle = {})
|
||||
: TargetedMovementGeneratorBase(target), i_leashExtensionTimer(5000), i_path(nullptr), i_recheckDistance(0), i_recalculateTravel(true), _range(range), _angle(angle) {}
|
||||
: TargetedMovementGeneratorBase(target), i_leashExtensionTimer(5000), i_path(nullptr), i_recheckDistance(0), i_recalculateTravel(true), _range(range), _angle(angle), m_currentMode(CHASE_MODE_NORMAL) {}
|
||||
~ChaseMovementGenerator() { }
|
||||
|
||||
MovementGeneratorType GetMovementGeneratorType() { return CHASE_MOTION_TYPE; }
|
||||
@@ -58,6 +66,11 @@ public:
|
||||
bool EnableWalking() const { return false; }
|
||||
bool HasLostTarget(Unit* unit) const { return unit->GetVictim() != this->GetTarget(); }
|
||||
|
||||
void SetOffsetAndAngle(std::optional<ChaseRange> dist, std::optional<ChaseAngle> angle);
|
||||
void SetNewTarget(Unit* target);
|
||||
|
||||
void DistanceYourself(T* owner, float distance);
|
||||
bool DispatchSplineToPosition(T* owner, float x, float y, float z, bool walk, bool cutPath, float maxTarget, bool forceDest, bool target = false);
|
||||
private:
|
||||
TimeTrackerSmall i_leashExtensionTimer;
|
||||
std::unique_ptr<PathGenerator> i_path;
|
||||
@@ -65,10 +78,12 @@ private:
|
||||
bool i_recalculateTravel;
|
||||
|
||||
Optional<Position> _lastTargetPosition;
|
||||
Optional<ChaseRange> const _range;
|
||||
Optional<ChaseAngle> const _angle;
|
||||
Optional<ChaseRange> _range;
|
||||
Optional<ChaseAngle> _angle;
|
||||
bool _movingTowards = true;
|
||||
bool _mutualChase = true;
|
||||
|
||||
ChaseMovementMode m_currentMode;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
||||
Reference in New Issue
Block a user