/* * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. * Copyright (C) 2008-2016 TrinityCore * Copyright (C) 2005-2009 MaNGOS */ #ifndef ACORE_TARGETEDMOVEMENTGENERATOR_H #define ACORE_TARGETEDMOVEMENTGENERATOR_H #include "FollowerReference.h" #include "MovementGenerator.h" #include "PathGenerator.h" #include "Timer.h" #include "Unit.h" #include class TargetedMovementGeneratorBase { public: TargetedMovementGeneratorBase(Unit* target) { i_target.link(target, this); } void stopFollowing() { } protected: FollowerReference i_target; }; template class ChaseMovementGenerator : public MovementGeneratorMedium>, public TargetedMovementGeneratorBase { public: ChaseMovementGenerator(Unit* target, std::optional range = {}, std::optional angle = {}) : TargetedMovementGeneratorBase(target), i_path(nullptr), i_recheckDistance(0), i_recalculateTravel(true), _range(range), _angle(angle) {} ~ChaseMovementGenerator() { delete i_path; } MovementGeneratorType GetMovementGeneratorType() { return CHASE_MOTION_TYPE; } bool DoUpdate(T*, uint32); void DoInitialize(T*); void DoFinalize(T*); void DoReset(T*); void MovementInform(T*); bool PositionOkay(T* owner, Unit* target, std::optional maxDistance, std::optional angle); void unitSpeedChanged() { _lastTargetPosition.reset(); } Unit* GetTarget() const { return i_target.getTarget(); } bool EnableWalking() const { return false; } bool HasLostTarget(Unit* unit) const { return unit->GetVictim() != this->GetTarget(); } private: PathGenerator* i_path; TimeTrackerSmall i_recheckDistance; bool i_recalculateTravel; std::optional _lastTargetPosition; std::optional const _range; std::optional const _angle; bool _movingTowards = true; bool _mutualChase = true; }; template class FollowMovementGenerator : public MovementGeneratorMedium>, public TargetedMovementGeneratorBase { public: FollowMovementGenerator(Unit* target, float range, ChaseAngle angle) : TargetedMovementGeneratorBase(target), i_path(nullptr), i_recheckDistance(0), i_recalculateTravel(true), _range(range), _angle(angle) {} ~FollowMovementGenerator() { delete i_path; } MovementGeneratorType GetMovementGeneratorType() { return FOLLOW_MOTION_TYPE; } bool DoUpdate(T*, uint32); void DoInitialize(T*); void DoFinalize(T*); void DoReset(T*); void MovementInform(T*); Unit* GetTarget() const { return i_target.getTarget(); } void unitSpeedChanged() { _lastTargetPosition.reset(); } bool PositionOkay(T* owner, Unit* target, float range, std::optional angle = {}); static void _clearUnitStateMove(T* u) { u->ClearUnitState(UNIT_STATE_FOLLOW_MOVE); } static void _addUnitStateMove(T* u) { u->AddUnitState(UNIT_STATE_FOLLOW_MOVE); } void _updateSpeed(T* owner); private: PathGenerator* i_path; TimeTrackerSmall i_recheckDistance; bool i_recalculateTravel; std::optional _lastTargetPosition; float _range; ChaseAngle _angle; }; #endif