TrinityCore
Loading...
Searching...
No Matches
RandomMovementGenerator.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 "Map.h"
21#include "MovementDefines.h"
22#include "MoveSpline.h"
23#include "MoveSplineInit.h"
24#include "PathGenerator.h"
25#include "Random.h"
26
27template<class T>
28RandomMovementGenerator<T>::RandomMovementGenerator(float distance) : _timer(0), _reference(), _wanderDistance(distance), _wanderSteps(0)
29{
33}
34
36
37template<class T>
42
43template<class T>
45{
46 if (timer)
47 {
49 _timer.Reset(timer);
50 this->RemoveFlag(MOVEMENTGENERATOR_FLAG_PAUSED);
51 }
52 else
53 {
54 this->AddFlag(MOVEMENTGENERATOR_FLAG_PAUSED);
56 }
57}
58
59template<class T>
60void RandomMovementGenerator<T>::Resume(uint32 overrideTimer /*= 0*/)
61{
62 if (overrideTimer)
63 _timer.Reset(overrideTimer);
64
65 this->RemoveFlag(MOVEMENTGENERATOR_FLAG_PAUSED);
66}
67
69
70template<class T>
72
73template<>
75{
78
79 if (!owner || !owner->IsAlive())
80 return false;
81
82 _reference = owner->GetPosition();
83
84 if (_wanderDistance == 0.f)
85 _wanderDistance = owner->GetWanderDistance();
86
87 // Retail seems to let a creature walk 2 up to 10 splines before triggering a pause
88 _wanderSteps = urand(2, 10);
89
90 _timer.Reset(0);
91 _path = nullptr;
92 return true;
93}
94
95template<class T>
96bool RandomMovementGenerator<T>::DoReset(T*) { return false; }
97
98template<>
100{
102
103 return DoInitialize(owner);
104}
105
106template<class T>
108
109template<>
111{
112 if (!owner)
113 return;
114
116 {
118 owner->StopMoving();
119 _path = nullptr;
120 return;
121 }
122
123 Position position(_reference);
124 float distance = frand(0.f, _wanderDistance);
125 float angle = frand(0.f, float(M_PI * 2));
126 owner->MovePositionToFirstCollision(position, distance, angle);
127
128 // Check if the destination is in LOS
129 if (!owner->IsWithinLOS(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ()))
130 {
131 // Retry later on
132 _timer.Reset(200);
133 return;
134 }
135
136 if (!_path)
137 {
138 _path = std::make_unique<PathGenerator>(owner);
139 _path->SetPathLengthLimit(30.0f);
140 }
141
142 bool result = _path->CalculatePath(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ());
143 // PATHFIND_FARFROMPOLY shouldn't be checked as creatures in water are most likely far from poly
144 if (!result || (_path->GetPathType() & PATHFIND_NOPATH)
145 || (_path->GetPathType() & PATHFIND_SHORTCUT)
146 /*|| (_path->GetPathType() & PATHFIND_FARFROMPOLY)*/)
147 {
148 _timer.Reset(100);
149 return;
150 }
151
153
155
156 bool walk = true;
157 switch (owner->GetMovementTemplate().GetRandom())
158 {
160 walk = owner->IsWalking();
161 break;
163 walk = false;
164 break;
165 default:
166 break;
167 }
168
169 Movement::MoveSplineInit init(owner);
170 init.MovebyPath(_path->GetPath());
171 init.SetWalk(walk);
172 int32 splineDuration = init.Launch();
173
174 --_wanderSteps;
175 if (_wanderSteps) // Creature has yet to do steps before pausing
176 _timer.Reset(splineDuration);
177 else
178 {
179 // Creature has made all its steps, time for a little break
180 _timer.Reset(splineDuration + urand(4, 10) * IN_MILLISECONDS); // Retails seems to use rounded numbers so we do as well
181 _wanderSteps = urand(2, 10);
182 }
183
184 // Call for creature group update
186}
187
188template<class T>
190{
191 return false;
192}
193
194template<>
196{
197 if (!owner || !owner->IsAlive())
198 return true;
199
201 return true;
202
204 {
206 owner->StopMoving();
207 _path = nullptr;
208 return true;
209 }
210 else
212
213 _timer.Update(diff);
214 if ((HasFlag(MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING) && !owner->movespline->Finalized()) || (_timer.Passed() && owner->movespline->Finalized()))
215 SetRandomLocation(owner);
216
217 return true;
218}
219
220template<class T>
222
223template<>
229
230template<class T>
232
233template<>
234void RandomMovementGenerator<Creature>::DoFinalize(Creature* owner, bool active, bool/* movementInform*/)
235{
237 if (active)
238 {
240 owner->StopMoving();
241
242 // TODO: Research if this modification is needed, which most likely isnt
243 owner->SetWalk(false);
244 }
245}
@ IN_MILLISECONDS
Definition Common.h:35
#define M_PI
Definition Common.h:72
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ MOTION_PRIORITY_NORMAL
MovementGeneratorType
@ RANDOM_MOTION_TYPE
@ MOVEMENTGENERATOR_FLAG_TIMED_PAUSED
@ MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING
@ MOVEMENTGENERATOR_FLAG_PAUSED
@ MOVEMENTGENERATOR_FLAG_DEACTIVATED
@ MOVEMENTGENERATOR_FLAG_FINALIZED
@ MOVEMENTGENERATOR_FLAG_TRANSITORY
@ MOVEMENTGENERATOR_FLAG_INTERRUPTED
@ MOVEMENTGENERATOR_FLAG_INITIALIZED
@ MOVEMENTGENERATOR_FLAG_SPEED_UPDATE_PENDING
@ PATHFIND_NOPATH
@ PATHFIND_SHORTCUT
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:265
@ UNIT_STATE_ROAMING_MOVE
Definition Unit.h:243
@ UNIT_STATE_LOST_CONTROL
Definition Unit.h:261
@ UNIT_STATE_ROAMING
Definition Unit.h:224
void SignalFormationMovement()
Definition Creature.cpp:349
float GetWanderDistance() const
Definition Creature.h:264
CreatureMovementData const & GetMovementTemplate() const
bool IsMovementPreventedByCasting() const override
void SetWalk(bool enable)
void MovebyPath(PointsArray const &path, int32 pointId=0)
bool Finalized() const
Definition MoveSpline.h:121
void Resume(uint32 overrideTimer=0) override
RandomMovementGenerator(float distance=0.0f)
MovementGeneratorType GetMovementGeneratorType() const override
void Pause(uint32 timer=0) override
void ClearUnitState(uint32 f)
Definition Unit.h:877
Movement::MoveSpline * movespline
Definition Unit.h:1804
void StopMoving(bool force=false)
Definition Unit.cpp:10312
bool IsAlive() const
Definition Unit.h:1234
void AddUnitState(uint32 f)
Definition Unit.h:875
bool SetWalk(bool enable)
Definition Unit.cpp:13268
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
bool IsWalking() const
Definition Unit.h:1219
bool IsWithinLOS(float x, float y, float z, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition Object.cpp:1206
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition Object.cpp:3323
CreatureRandomMovementType GetRandom() const
float GetPositionZ() const
Definition Position.h:81
float GetPositionX() const
Definition Position.h:79
void GetPosition(float &x, float &y) const
Definition Position.h:84
float GetPositionY() const
Definition Position.h:80