Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
MotionMaster.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Creature.h"
8#include "MotionMaster.h"
9
14#include "MoveSpline.h"
15#include "MoveSplineInit.h"
20#include <cassert>
21
23{
24 return (mv == &si_idleMovement);
25}
26
28{
29 // clear ALL movement generators (including default)
30 while (!empty())
31 {
32 MovementGenerator* curr = top();
33 pop();
34 if (curr)
35 DirectDelete(curr);
36 }
37
39}
40
41// set new default movement generator
43{
44 if (_owner->GetTypeId() == TypeID::TYPEID_UNIT)
45 {
47 Mutate(movement == NULL ? &si_idleMovement : movement, MOTION_SLOT_IDLE);
48 }
49 else
50 {
52 }
53}
54
56{
57 // clear ALL movement generators (including default)
58 while (!empty())
59 {
60 MovementGenerator* curr = top();
61 pop();
62 if (curr) DirectDelete(curr);
63 }
64}
65
67{
68 if (!_owner)
69 return;
70
71 if (_owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) // what about UNIT_STATE_DISTRACTED? Why is this not included?
72 return;
73
74 ASSERT(!empty());
75
77 if (!top()->Update(_owner, diff))
78 {
81 }
82 else
84
85 if (_expList)
86 {
87 for (size_t i = 0; i < _expList->size(); ++i)
88 {
89 MovementGenerator* mg = (*_expList)[i];
90 DirectDelete(mg);
91 }
92
93 delete _expList;
94 _expList = NULL;
95
96 if (empty())
97 Initialize();
98 else if (needInitTop())
99 InitTop();
100 else if (_cleanFlag & MMCF_RESET)
101 top()->Reset(_owner);
102
104 }
105
106 // probably not the best place to pu this but im not really sure where else to put it.
107 _owner->UpdateUnderwaterState(_owner->GetMap(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ());
108}
109
111{
112 while (size() > 1)
113 {
114 MovementGenerator* curr = top();
115 pop();
116 if (curr) DirectDelete(curr);
117 }
118
119 if (needInitTop())
120 InitTop();
121 else if (reset)
122 top()->Reset(_owner);
123}
124
126{
127 while (size() > 1)
128 {
129 MovementGenerator* curr = top();
130 pop();
131 if (curr)
132 DelayedDelete(curr);
133 }
134}
135
137{
138 if (size() > 1)
139 {
140 MovementGenerator* curr = top();
141 pop();
142 DirectDelete(curr);
143 }
144
145 while (!top())
146 --_top;
147
148 if (empty())
149 Initialize();
150 else if (needInitTop())
151 InitTop();
152 else if (reset)
153 top()->Reset(_owner);
154}
155
157{
158 if (size() > 1)
159 {
160 MovementGenerator* curr = top();
161 pop();
162 DelayedDelete(curr);
163 }
164
165 while (!top())
166 --_top;
167}
168
175
176void MotionMaster::MoveRandom(float spawndist)
177{
178 if (_owner->GetTypeId() == TypeID::TYPEID_UNIT)
179 {
180 SF_LOG_DEBUG("misc", "Creature (GUID: %u) start moving random", _owner->GetGUIDLow());
182 }
183}
184
186{
187 Clear(false);
188
189 if (_owner->GetTypeId() == TypeID::TYPEID_UNIT && !_owner->ToCreature()->GetCharmerOrOwnerGUID())
190 {
191 SF_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) targeted home", _owner->GetEntry(), _owner->GetGUIDLow());
193 }
194 else if (_owner->GetTypeId() == TypeID::TYPEID_UNIT && _owner->ToCreature()->GetCharmerOrOwnerGUID())
195 {
196 SF_LOG_DEBUG("misc", "Pet or controlled creature (Entry: %u GUID: %u) targeting home", _owner->GetEntry(), _owner->GetGUIDLow());
197 Unit* target = _owner->ToCreature()->GetCharmerOrOwner();
198 if (target)
199 {
200 SF_LOG_DEBUG("misc", "Following %s (GUID: %u)", target->GetTypeId() == TypeID::TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TypeID::TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow());
202 }
203 }
204 else
205 {
206 SF_LOG_ERROR("misc", "Player (GUID: %u) attempt targeted home", _owner->GetGUIDLow());
207 }
208}
209
211{
212 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
213 {
214 SF_LOG_DEBUG("misc", "Player (GUID: %u) move confused", _owner->GetGUIDLow());
216 }
217 else
218 {
219 SF_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) move confused",
220 _owner->GetEntry(), _owner->GetGUIDLow());
222 }
223}
224
225void MotionMaster::MoveChase(Unit* target, float dist, float angle)
226{
227 // ignore movement request if target not exist
228 if (!target || target == _owner || _owner->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
229 return;
230
231 //_owner->ClearUnitState(UNIT_STATE_FOLLOW);
232 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
233 {
234 SF_LOG_DEBUG("misc", "Player (GUID: %u) chase to %s (GUID: %u)",
235 _owner->GetGUIDLow(),
236 target->GetTypeId() == TypeID::TYPEID_PLAYER ? "player" : "creature",
237 target->GetTypeId() == TypeID::TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow());
239 }
240 else
241 {
242 SF_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) chase to %s (GUID: %u)",
243 _owner->GetEntry(), _owner->GetGUIDLow(),
244 target->GetTypeId() == TypeID::TYPEID_PLAYER ? "player" : "creature",
245 target->GetTypeId() == TypeID::TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow());
247 }
248}
249
250void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot)
251{
252 // ignore movement request if target not exist
253 if (!target || target == _owner || _owner->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
254 return;
255
256 //_owner->AddUnitState(UNIT_STATE_FOLLOW);
257 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
258 {
259 SF_LOG_DEBUG("misc", "Player (GUID: %u) follow to %s (GUID: %u)", _owner->GetGUIDLow(),
260 target->GetTypeId() == TypeID::TYPEID_PLAYER ? "player" : "creature",
261 target->GetTypeId() == TypeID::TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow());
262 Mutate(new FollowMovementGenerator<Player>(target, dist, angle), slot);
263 }
264 else
265 {
266 SF_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) follow to %s (GUID: %u)",
267 _owner->GetEntry(), _owner->GetGUIDLow(),
268 target->GetTypeId() == TypeID::TYPEID_PLAYER ? "player" : "creature",
269 target->GetTypeId() == TypeID::TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow());
270 Mutate(new FollowMovementGenerator<Creature>(target, dist, angle), slot);
271 }
272}
273
274void MotionMaster::MovePoint(uint32 id, float x, float y, float z, bool generatePath)
275{
276 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
277 {
278 SF_LOG_DEBUG("misc", "Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", _owner->GetGUIDLow(), id, x, y, z);
279 Mutate(new PointMovementGenerator<Player>(id, x, y, z, generatePath), MOTION_SLOT_ACTIVE);
280 }
281 else
282 {
283 SF_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f)",
284 _owner->GetEntry(), _owner->GetGUIDLow(), id, x, y, z);
285 Mutate(new PointMovementGenerator<Creature>(id, x, y, z, generatePath), MOTION_SLOT_ACTIVE);
286 }
287}
288
290{
291 float x, y, z;
292 pos.GetPosition(x, y, z);
293
294 SF_LOG_DEBUG("misc", "Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", _owner->GetEntry(), id, x, y, z);
295
297 init.MoveTo(x, y, z);
299 init.Launch();
301}
302
304{
305 float x, y, z;
306 pos.GetPosition(x, y, z);
307
308 SF_LOG_DEBUG("misc", "Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", _owner->GetEntry(), id, x, y, z);
309
311 init.MoveTo(x, y, z);
313 init.Launch();
315}
316
317void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ)
318{
319 //this function may make players fall below map
320 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
321 return;
322
323 float x, y, z;
324 float moveTimeHalf = speedZ / Movement::gravity;
325 float dist = 2 * moveTimeHalf * speedXY;
326 float max_height = -Movement::computeFallElevation(moveTimeHalf, false, -speedZ);
327
328 _owner->GetNearPoint(_owner, x, y, z, _owner->GetObjectSize(), dist, _owner->GetAngle(srcX, srcY) + M_PI);
329
331 init.MoveTo(x, y, z);
332 init.SetParabolic(max_height, 0);
333 init.SetOrientationFixed(true);
334 init.SetVelocity(speedXY);
335 init.Launch();
337}
338
339void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ)
340{
341 //this function may make players fall below map
342 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
343 return;
344
345 float x, y, z;
346
347 float moveTimeHalf = speedZ / Movement::gravity;
348 float dist = 2 * moveTimeHalf * speedXY;
349 _owner->GetClosePoint(x, y, z, _owner->GetObjectSize(), dist, angle);
350 MoveJump(x, y, z, speedXY, speedZ);
351}
352
353void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id)
354{
355 SF_LOG_DEBUG("misc", "Unit (GUID: %u) jump to point (X: %f Y: %f Z: %f)", _owner->GetGUIDLow(), x, y, z);
356
357 float moveTimeHalf = speedZ / Movement::gravity;
358 float max_height = -Movement::computeFallElevation(moveTimeHalf, false, -speedZ);
359
361 init.MoveTo(x, y, z, false);
362 init.SetParabolic(max_height, 0);
363 init.SetVelocity(speedXY);
364 init.Launch();
366}
367
369{
370 // use larger distance for vmap height search than in most other cases
371 float tz = _owner->GetMap()->GetHeight(_owner->GetPhaseMask(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ(), true, MAX_FALL_DISTANCE);
372 if (tz <= INVALID_HEIGHT)
373 {
374 SF_LOG_DEBUG("misc", "MotionMaster::MoveFall: unable retrive a proper height at map %u (x: %f, y: %f, z: %f).",
375 _owner->GetMap()->GetId(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ());
376 return;
377 }
378
379 // Abort too if the ground is very near
380 if (fabs(_owner->GetPositionZ() - tz) < 0.1f)
381 return;
382
383 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
384 _owner->SetFall(true);
385
387 init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz, false);
388 init.SetFall();
389 init.Launch();
391}
392
393void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, bool generatePath)
394{
395 if (Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE)
396 return;
397
398 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
399 {
400 SF_LOG_DEBUG("misc", "Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", _owner->GetGUIDLow(), x, y, z);
401 Mutate(new PointMovementGenerator<Player>(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED);
402 }
403 else
404 {
405 SF_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) charge point (X: %f Y: %f Z: %f)",
406 _owner->GetEntry(), _owner->GetGUIDLow(), x, y, z);
407 Mutate(new PointMovementGenerator<Creature>(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED);
408 }
409}
410
412{
413 G3D::Vector3 dest = path.GetActualEndPosition();
414
415 MoveCharge(dest.x, dest.y, dest.z, SPEED_CHARGE, EVENT_CHARGE_PREPATH);
416
417 // Charge movement is not started when using EVENT_CHARGE_PREPATH
419 init.MovebyPath(path.GetPath());
421 init.Launch();
422}
423
424void MotionMaster::MoveSeekAssistance(float x, float y, float z)
425{
426 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
427 {
428 SF_LOG_ERROR("misc", "Player (GUID: %u) attempt to seek assistance", _owner->GetGUIDLow());
429 }
430 else
431 {
432 SF_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) seek assistance (X: %f Y: %f Z: %f)",
433 _owner->GetEntry(), _owner->GetGUIDLow(), x, y, z);
434 _owner->AttackStop();
435 _owner->ToCreature()->SetReactState(REACT_PASSIVE);
437 }
438}
439
441{
442 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
443 {
444 SF_LOG_ERROR("misc", "Player (GUID: %u) attempt to call distract after assistance", _owner->GetGUIDLow());
445 }
446 else
447 {
448 SF_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) is distracted after assistance call (Time: %u)",
449 _owner->GetEntry(), _owner->GetGUIDLow(), time);
451 }
452}
453
455{
456 if (!enemy)
457 return;
458
459 if (_owner->HasAuraType(SPELL_AURA_PREVENTS_FLEEING))
460 return;
461
462 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
463 {
464 SF_LOG_DEBUG("misc", "Player (GUID: %u) flee from %s (GUID: %u)", _owner->GetGUIDLow(),
465 enemy->GetTypeId() == TypeID::TYPEID_PLAYER ? "player" : "creature",
466 enemy->GetTypeId() == TypeID::TYPEID_PLAYER ? enemy->GetGUIDLow() : enemy->ToCreature()->GetDBTableGUIDLow());
468 }
469 else
470 {
471 SF_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) flee from %s (GUID: %u)%s",
472 _owner->GetEntry(), _owner->GetGUIDLow(),
473 enemy->GetTypeId() == TypeID::TYPEID_PLAYER ? "player" : "creature",
474 enemy->GetTypeId() == TypeID::TYPEID_PLAYER ? enemy->GetGUIDLow() : enemy->ToCreature()->GetDBTableGUIDLow(),
475 time ? " for a limited time" : "");
476 if (time)
478 else
480 }
481}
482
484{
485 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
486 {
487 if (path < sTaxiPathNodesByPath.size())
488 {
489 SF_LOG_DEBUG("misc", "%s taxi to (Path %u node %u)", _owner->GetName().c_str(), path, pathnode);
492 }
493 else
494 {
495 SF_LOG_ERROR("misc", "%s attempt taxi to (not existed Path %u node %u)",
496 _owner->GetName().c_str(), path, pathnode);
497 }
498 }
499 else
500 {
501 SF_LOG_ERROR("misc", "Creature (Entry: %u GUID: %u) attempt taxi to (Path %u node %u)",
502 _owner->GetEntry(), _owner->GetGUIDLow(), path, pathnode);
503 }
504}
505
507{
509 return;
510
511 if (_owner->GetTypeId() == TypeID::TYPEID_PLAYER)
512 {
513 SF_LOG_DEBUG("misc", "Player (GUID: %u) distracted (timer: %u)", _owner->GetGUIDLow(), timer);
514 }
515 else
516 {
517 SF_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) (timer: %u)",
518 _owner->GetEntry(), _owner->GetGUIDLow(), timer);
519 }
520
523}
524
526{
527 if (MovementGenerator* curr = Impl[slot])
528 {
529 Impl[slot] = NULL; // in case a new one is generated in this slot during directdelete
530 if (_top == slot && (_cleanFlag & MMCF_UPDATE))
531 DelayedDelete(curr);
532 else
533 DirectDelete(curr);
534 }
535 else if (_top < slot)
536 {
537 _top = slot;
538 }
539
540 Impl[slot] = m;
541 if (_top > slot)
542 _needInit[slot] = true;
543 else
544 {
545 _needInit[slot] = false;
546 m->Initialize(_owner);
547 }
548}
549
550void MotionMaster::MovePath(uint32 path_id, bool repeatable)
551{
552 if (!path_id)
553 return;
554 //We set waypoint movement as new default movement generator
555 // clear ALL movement generators (including default)
556 /*while (!empty())
557 {
558 MovementGenerator *curr = top();
559 curr->Finalize(*_owner);
560 pop();
561 if (!isStatic(curr))
562 delete curr;
563 }*/
564
565 //_owner->GetTypeId() == TYPEID_PLAYER ?
566 //Mutate(new WaypointMovementGenerator<Player>(path_id, repeatable)):
568
569 SF_LOG_DEBUG("misc", "%s (GUID: %u) start moving over path(Id:%u, repeatable: %s)",
570 _owner->GetTypeId() == TypeID::TYPEID_PLAYER ? "Player" : "Creature",
571 _owner->GetGUIDLow(), path_id, repeatable ? "YES" : "NO");
572}
573
575{
576 if (!time)
577 return;
578
580}
581
583{
584 /*Impl::container_type::iterator it = Impl::c.begin();
585 for (; it != end(); ++it)
586 {
587 (*it)->unitSpeedChanged();
588 }*/
589 for (int i = 0; i <= _top; ++i)
590 {
591 if (Impl[i])
592 Impl[i]->unitSpeedChanged();
593 }
594}
595
603
605{
606 if (!Impl[slot])
607 return NULL_MOTION_TYPE;
608 else
609 return Impl[slot]->GetMovementGeneratorType();
610}
611
613{
615 _needInit[_top] = false;
616}
617
619{
620 if (isStatic(curr))
621 return;
622 curr->Finalize(_owner);
623 delete curr;
624}
625
627{
628 SF_LOG_FATAL("misc", "Unit (Entry %u) is trying to delete its updating MG (Type %u)!", _owner->GetEntry(), curr->GetMovementGeneratorType());
629 if (isStatic(curr))
630 return;
631 if (!_expList)
632 _expList = new ExpireList();
633 _expList->push_back(curr);
634}
635
636bool MotionMaster::GetDestination(float& x, float& y, float& z)
637{
638 if (_owner->movespline->Finalized())
639 return false;
640
641 G3D::Vector3 const& dest = _owner->movespline->FinalDestination();
642 x = dest.x;
643 y = dest.y;
644 z = dest.z;
645 return true;
646}
#define M_PI
Definition Common.h:192
TaxiPathNodesByPath sTaxiPathNodesByPath
std::uint32_t uint32
Definition Define.h:77
#define ASSERT
Definition Errors.h:29
IdleMovementGenerator si_idleMovement
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_FATAL(filterType__,...)
Definition Log.h:146
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define MAX_FALL_DISTANCE
Definition Map.h:143
#define INVALID_HEIGHT
Definition Map.h:142
bool isStatic(MovementGenerator *mv)
RotateDirection
@ MMCF_RESET
@ MMCF_UPDATE
MovementSlot
@ MOTION_SLOT_CONTROLLED
@ MOTION_SLOT_ACTIVE
@ MOTION_SLOT_IDLE
MovementGeneratorType
@ DISTRACT_MOTION_TYPE
@ IDLE_MOTION_TYPE
@ NULL_MOTION_TYPE
#define SPEED_CHARGE
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_UNIT
Definition Object.h:54
#define PET_FOLLOW_ANGLE
Definition PetDefines.h:58
#define PET_FOLLOW_DIST
Definition PetDefines.h:57
@ EVENT_CHARGE_PREPATH
@ SPELL_AURA_PREVENTS_FLEEING
@ UNIT_STATE_ROOT
Definition Unit.h:522
@ UNIT_STATE_STUNNED
Definition Unit.h:515
@ REACT_PASSIVE
Definition Unit.h:1156
@ UNIT_FLAG_DISABLE_MOVE
Definition Unit.h:627
@ UNIT_FIELD_FLAGS
uint32 GetDBTableGUIDLow() const
Definition Creature.h:445
MovementGenerator * _Ty
void UpdateMotion(uint32 diff)
void MoveTaxiFlight(uint32 path, uint32 pathnode)
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=EVENT_JUMP)
void DirectDelete(_Ty curr)
_Ty top() const
MovementGeneratorType GetMotionSlotType(int slot) const
std::vector< _Ty > ExpireList
MovementGeneratorType GetCurrentMovementGeneratorType() const
void propagateSpeedChange()
void MoveRotate(uint32 time, RotateDirection direction)
void DirectExpire(bool reset)
bool _needInit[MAX_MOTION_SLOT]
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
void DirectClean(bool reset)
ExpireList * _expList
int size() const
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ)
void MovementExpired(bool reset=true)
void MoveChase(Unit *target, float dist=0.0f, float angle=0.0f)
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, bool generatePath=false)
void Mutate(MovementGenerator *m, MovementSlot slot)
void MoveRandom(float spawndist=0.0f)
bool empty() const
void MoveSeekAssistance(float x, float y, float z)
void MoveSeekAssistanceDistract(uint32 timer)
void MoveLand(uint32 id, Position const &pos)
_Ty Impl[MAX_MOTION_SLOT]
void MovePoint(uint32 id, Position const &pos, bool generatePath=true)
bool GetDestination(float &x, float &y, float &z)
void DelayedDelete(_Ty curr)
void MoveTargetedHome()
void MovePath(uint32 path_id, bool repeatable)
void MoveDistract(uint32 time)
bool needInitTop() const
void MoveJumpTo(float angle, float speedXY, float speedZ)
void MoveFall(uint32 id=0)
void MoveTakeoff(uint32 id, Position const &pos)
void Clear(bool reset=true)
void MoveFleeing(Unit *enemy, uint32 time=0)
void SetAnimation(AnimType anim)
void SetParabolic(float amplitude, float start_time)
void SetVelocity(float velocity)
void MoveTo(const Vector3 &destination, bool generatePath=true, bool forceDestination=false)
void MovebyPath(const PointsArray &path, int32 pointId=0)
void SetOrientationFixed(bool enable)
virtual void Initialize(Unit *)=0
virtual MovementGeneratorType GetMovementGeneratorType()=0
virtual void Reset(Unit *)=0
virtual void Finalize(Unit *)=0
uint64 GetGUID() const
Definition Object.h:119
uint32 GetGUIDLow() const
Definition Object.h:120
TypeID GetTypeId() const
Definition Object.h:131
Creature * ToCreature()
Definition Object.h:207
Movement::PointsArray const & GetPath() const
G3D::Vector3 const & GetActualEndPosition() const
Definition Unit.h:1367
MovementGenerator * selectMovementGenerator(Creature *creature)
double gravity
float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity=0.0f)
void GetPosition(float &x, float &y) const
Definition Object.h:333