TrinityCore
FleeingMovementGenerator.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
19#include "Creature.h"
20#include "CreatureAI.h"
21#include "MoveSpline.h"
22#include "MoveSplineInit.h"
23#include "ObjectAccessor.h"
24#include "PathGenerator.h"
25
26#define MIN_QUIET_DISTANCE 28.0f
27#define MAX_QUIET_DISTANCE 43.0f
28
29FleeingMovementGenerator::FleeingMovementGenerator(ObjectGuid fleeTargetGUID) : _fleeTargetGUID(fleeTargetGUID), _timer(0)
30{
35}
36
38{
40}
41
43{
46
47 if (!owner || !owner->IsAlive())
48 return;
49
50 _path = nullptr;
51 SetTargetLocation(owner);
52}
53
55{
57
58 Initialize(owner);
59}
60
62{
63 if (!owner || !owner->IsAlive())
64 return false;
65
67 {
69 owner->StopMoving();
70 _path = nullptr;
71 return true;
72 }
73 else
75
76 _timer.Update(diff);
77 if ((HasFlag(MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING) && !owner->movespline->Finalized()) || (_timer.Passed() && owner->movespline->Finalized()))
78 {
80 SetTargetLocation(owner);
81 }
82
83 return true;
84}
85
87{
90}
91
92void FleeingMovementGenerator::Finalize(Unit* owner, bool active, bool /*movementInform*/)
93{
95
96 if (active)
97 {
99
100 if (owner->IsCreature())
101 {
102 if (Unit const* victim = owner->GetVictim())
103 owner->SetTarget(victim->GetGUID());
104 }
105 else if (owner->IsPlayer())
106 owner->StopMoving();
107 }
108}
109
111{
112 if (!owner || !owner->IsAlive())
113 return;
114
116 {
118 owner->StopMoving();
119 _path = nullptr;
120 return;
121 }
122
123 Position destination = owner->GetPosition();
124 GetPoint(owner, destination);
125
126 // Add LOS check for target point
127 if (!owner->IsWithinLOS(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()))
128 {
129 _timer.Reset(200);
130 return;
131 }
132
133 if (!_path)
134 {
135 _path = std::make_unique<PathGenerator>(owner);
136 _path->SetPathLengthLimit(30.0f);
137 }
138
139 bool result = _path->CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
140 if (!result || (_path->GetPathType() & PATHFIND_NOPATH)
141 || (_path->GetPathType() & PATHFIND_SHORTCUT)
142 || (_path->GetPathType() & PATHFIND_FARFROMPOLY))
143 {
144 _timer.Reset(100);
145 return;
146 }
147
149
150 Movement::MoveSplineInit init(owner);
151 init.MovebyPath(_path->GetPath());
152 init.SetWalk(false);
153 int32 traveltime = init.Launch();
154 _timer.Reset(traveltime + urand(800, 1500));
155}
156
158{
159 float casterDistance, casterAngle;
160 if (Unit* fleeTarget = ObjectAccessor::GetUnit(*owner, _fleeTargetGUID))
161 {
162 casterDistance = fleeTarget->GetDistance(owner);
163 if (casterDistance > 0.2f)
164 casterAngle = fleeTarget->GetAbsoluteAngle(owner);
165 else
166 casterAngle = frand(0.0f, 2.0f * float(M_PI));
167 }
168 else
169 {
170 casterDistance = 0.0f;
171 casterAngle = frand(0.0f, 2.0f * float(M_PI));
172 }
173
174 float distance, angle;
175 if (casterDistance < MIN_QUIET_DISTANCE)
176 {
177 distance = frand(0.4f, 1.3f) * (MIN_QUIET_DISTANCE - casterDistance);
178 angle = casterAngle + frand(-float(M_PI) / 8.0f, float(M_PI) / 8.0f);
179 }
180 else if (casterDistance > MAX_QUIET_DISTANCE)
181 {
182 distance = frand(0.4f, 1.0f) * (MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE);
183 angle = -casterAngle + frand(-float(M_PI) / 4.0f, float(M_PI) / 4.0f);
184 }
185 else // we are inside quiet range
186 {
187 distance = frand(0.6f, 1.2f) * (MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE);
188 angle = frand(0.0f, 2.0f * float(M_PI));
189 }
190
191 owner->MovePositionToFirstCollision(position, distance, angle);
192}
193
194//---- TimedFleeingMovementGenerator
195
197{
198 if (!owner || !owner->IsAlive())
199 return false;
200
203 return false;
204
205 return FleeingMovementGenerator::Update(owner, diff);
206}
207
208void TimedFleeingMovementGenerator::Finalize(Unit* owner, bool active, bool movementInform)
209{
211 if (!active)
212 return;
213
214 owner->StopMoving();
215 if (owner->IsCreature() && owner->IsAlive())
216 {
217 if (Unit* victim = owner->GetVictim())
218 {
219 owner->AttackStop();
220 owner->GetAI()->AttackStart(victim);
221 }
222 }
223
224 if (movementInform)
225 {
226 Creature* ownerCreature = owner->ToCreature();
227 if (CreatureAI* AI = ownerCreature ? ownerCreature->AI() : nullptr)
228 AI->MovementInform(TIMED_FLEEING_MOTION_TYPE, 0);
229 }
230}
231
233{
235}
#define M_PI
Definition: Common.h:115
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
#define MAX_QUIET_DISTANCE
#define MIN_QUIET_DISTANCE
@ MOTION_MODE_DEFAULT
@ MOTION_PRIORITY_HIGHEST
MovementGeneratorType
@ TIMED_FLEEING_MOTION_TYPE
@ FLEEING_MOTION_TYPE
@ MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING
@ MOVEMENTGENERATOR_FLAG_DEACTIVATED
@ MOVEMENTGENERATOR_FLAG_FINALIZED
@ MOVEMENTGENERATOR_FLAG_TRANSITORY
@ MOVEMENTGENERATOR_FLAG_INTERRUPTED
@ MOVEMENTGENERATOR_FLAG_INITIALIZED
@ MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING
@ PATHFIND_NOPATH
Definition: PathGenerator.h:47
@ PATHFIND_FARFROMPOLY
Definition: PathGenerator.h:52
@ PATHFIND_SHORTCUT
Definition: PathGenerator.h:45
float frand(float min, float max)
Definition: Random.cpp:55
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
@ UNIT_STATE_NOT_MOVE
Definition: Unit.h:300
@ UNIT_STATE_FLEEING_MOVE
Definition: Unit.h:280
@ UNIT_STATE_FLEEING
Definition: Unit.h:262
CreatureAI * AI() const
Definition: Creature.h:214
void GetPoint(Unit *owner, Position &position) const
void Deactivate(Unit *owner) override
FleeingMovementGenerator(ObjectGuid fleeTargetGUID)
void Reset(Unit *owner) override
bool Update(Unit *owner, uint32 diff) override
std::unique_ptr< PathGenerator > _path
void Initialize(Unit *owner) override
MovementGeneratorType GetMovementGeneratorType() const override
void Finalize(Unit *owner, bool, bool) override
void AddFlag(uint16 const flag)
bool HasFlag(uint16 const flag) const
void RemoveFlag(uint16 const flag)
void SetWalk(bool enable)
void MovebyPath(PointsArray const &path, int32 pointId=0)
static Creature * ToCreature(Object *o)
Definition: Object.h:219
bool IsPlayer() const
Definition: Object.h:212
bool IsCreature() const
Definition: Object.h:218
bool Update(Unit *, uint32) override
MovementGeneratorType GetMovementGeneratorType() const override
void Finalize(Unit *, bool, bool) override
virtual void AttackStart(Unit *victim)
Definition: UnitAI.cpp:29
Definition: Unit.h:627
void ClearUnitState(uint32 f)
Definition: Unit.h:733
virtual bool IsMovementPreventedByCasting() const
Definition: Unit.cpp:3119
bool IsAlive() const
Definition: Unit.h:1164
void StopMoving()
Definition: Unit.cpp:10049
UnitAI * GetAI() const
Definition: Unit.h:660
void AddUnitState(uint32 f)
Definition: Unit.h:731
virtual void SetTarget(ObjectGuid const &)=0
Unit * GetVictim() const
Definition: Unit.h:715
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
std::unique_ptr< Movement::MoveSpline > movespline
Definition: Unit.h:1766
bool AttackStop()
Definition: Unit.cpp:5781
bool IsWithinLOS(float x, float y, float z, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition: Object.cpp:1161
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:3482
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
constexpr float GetPositionZ() const
Definition: Position.h:78
void Update(int32 diff)
Definition: Timer.h:121
bool Passed() const
Definition: Timer.h:131
void Reset(int32 expiry)
Definition: Timer.h:136