diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Movement/MotionMaster.cpp | 469 | ||||
-rw-r--r-- | src/server/game/Movement/MotionMaster.h | 165 |
2 files changed, 312 insertions, 322 deletions
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index e53af3650c0..463ba3a5da1 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -34,9 +34,21 @@ #include "MoveSpline.h" #include "MoveSplineInit.h" -inline bool isStatic(MovementGenerator *mv) +inline bool IsStatic(MovementGenerator* movement) { - return (mv == &si_idleMovement); + return (movement == &si_idleMovement); +} + +MotionMaster::~MotionMaster() +{ + // clear ALL movement generators (including default) + while (!empty()) + { + MovementGenerator *curr = top(); + pop(); + if (curr && !IsStatic(curr)) + delete curr; // Skip finalizing on delete, it might launch new movement + } } void MotionMaster::Initialize() @@ -67,18 +79,6 @@ void MotionMaster::InitDefault() } } -MotionMaster::~MotionMaster() -{ - // clear ALL movement generators (including default) - while (!empty()) - { - MovementGenerator *curr = top(); - pop(); - if (curr && !isStatic(curr)) - delete curr; // Skip finalizing on delete, it might launch new movement - } -} - void MotionMaster::UpdateMotion(uint32 diff) { if (!_owner) @@ -98,20 +98,20 @@ void MotionMaster::UpdateMotion(uint32 diff) else _cleanFlag &= ~MMCF_UPDATE; - if (_expList) + if (_expireList) { - for (size_t i = 0; i < _expList->size(); ++i) + for (size_t i = 0; i < _expireList->size(); ++i) { - MovementGenerator* mg = (*_expList)[i]; + MovementGenerator* mg = (*_expireList)[i]; DirectDelete(mg); } - delete _expList; - _expList = NULL; + delete _expireList; + _expireList = nullptr; if (empty()) Initialize(); - else if (needInitTop()) + else if (NeedInitTop()) InitTop(); else if (_cleanFlag & MMCF_RESET) top()->Reset(_owner); @@ -123,84 +123,84 @@ void MotionMaster::UpdateMotion(uint32 diff) _owner->UpdateUnderwaterState(_owner->GetMap(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); } -void MotionMaster::DirectClean(bool reset) +void MotionMaster::Clear(bool reset /*= true*/) { - while (size() > 1) + if (_cleanFlag & MMCF_UPDATE) { - MovementGenerator *curr = top(); - pop(); - if (curr) DirectDelete(curr); + if (reset) + _cleanFlag |= MMCF_RESET; + else + _cleanFlag &= ~MMCF_RESET; + DelayedClean(); } - - if (empty()) - return; - - if (needInitTop()) - InitTop(); - else if (reset) - top()->Reset(_owner); + else + DirectClean(reset); } -void MotionMaster::DelayedClean() +void MotionMaster::MovementExpired(bool reset /*= true*/) { - while (size() > 1) + if (_cleanFlag & MMCF_UPDATE) { - MovementGenerator *curr = top(); - pop(); - if (curr) - DelayedDelete(curr); + if (reset) + _cleanFlag |= MMCF_RESET; + else + _cleanFlag &= ~MMCF_RESET; + DelayedExpire(); } + else + DirectExpire(reset); } -void MotionMaster::DirectExpire(bool reset) +MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const { - if (size() > 1) - { - MovementGenerator *curr = top(); - pop(); - DirectDelete(curr); - } + if (empty()) + return IDLE_MOTION_TYPE; - while (!empty() && !top()) - --_top; + return top()->GetMovementGeneratorType(); +} - if (empty()) - Initialize(); - else if (needInitTop()) - InitTop(); - else if (reset) - top()->Reset(_owner); +MovementGeneratorType MotionMaster::GetMotionSlotType(int slot) const +{ + if (!_slot[slot]) + return NULL_MOTION_TYPE; + else + return _slot[slot]->GetMovementGeneratorType(); } -void MotionMaster::DelayedExpire() +MovementGenerator* MotionMaster::GetMotionSlot(int slot) const { - if (size() > 1) + ASSERT(slot >= 0); + return _slot[slot]; +} + +void MotionMaster::propagateSpeedChange() +{ + for (int i = 0; i <= _top; ++i) { - MovementGenerator *curr = top(); - pop(); - DelayedDelete(curr); + if (_slot[i]) + _slot[i]->unitSpeedChanged(); } +} - while (!empty() && !top()) - --_top; +bool MotionMaster::GetDestination(float &x, float &y, float &z) +{ + if (_owner->movespline->Finalized()) + return false; + + G3D::Vector3 const& dest = _owner->movespline->FinalDestination(); + x = dest.x; + y = dest.y; + z = dest.z; + return true; } void MotionMaster::MoveIdle() { //! Should be preceded by MovementExpired or Clear if there's an overlying movementgenerator active - if (empty() || !isStatic(top())) + if (empty() || !IsStatic(top())) Mutate(&si_idleMovement, MOTION_SLOT_IDLE); } -void MotionMaster::MoveRandom(float spawndist) -{ - if (_owner->GetTypeId() == TYPEID_UNIT) - { - TC_LOG_DEBUG("misc", "Creature (%s) started random movement.", _owner->GetGUID().ToString().c_str()); - Mutate(new RandomMovementGenerator<Creature>(spawndist), MOTION_SLOT_IDLE); - } -} - void MotionMaster::MoveTargetedHome() { Clear(false); @@ -226,18 +226,31 @@ void MotionMaster::MoveTargetedHome() } } -void MotionMaster::MoveConfused() +void MotionMaster::MoveRandom(float spawndist) { + if (_owner->GetTypeId() == TYPEID_UNIT) + { + TC_LOG_DEBUG("misc", "Creature (%s) started random movement.", _owner->GetGUID().ToString().c_str()); + Mutate(new RandomMovementGenerator<Creature>(spawndist), MOTION_SLOT_IDLE); + } +} + +void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot) +{ + // ignore movement request if target not exist + if (!target || target == _owner) + return; + + //_owner->AddUnitState(UNIT_STATE_FOLLOW); if (_owner->GetTypeId() == TYPEID_PLAYER) { - TC_LOG_DEBUG("misc", "Player (%s) move confused", _owner->GetGUID().ToString().c_str()); - Mutate(new ConfusedMovementGenerator<Player>(), MOTION_SLOT_CONTROLLED); + TC_LOG_DEBUG("misc", "Player (%s) follows (%s)", _owner->GetGUID().ToString().c_str(), target->GetGUID().ToString().c_str()); + Mutate(new FollowMovementGenerator<Player>(target, dist, angle), slot); } else { - TC_LOG_DEBUG("misc", "Creature (Entry: %u %s) move confused", - _owner->GetEntry(), _owner->GetGUID().ToString().c_str()); - Mutate(new ConfusedMovementGenerator<Creature>(), MOTION_SLOT_CONTROLLED); + TC_LOG_DEBUG("misc", "Creature (Entry: %u %s) follows (%s)", _owner->GetEntry(), _owner->GetGUID().ToString().c_str(), target->GetGUID().ToString().c_str()); + Mutate(new FollowMovementGenerator<Creature>(target, dist, angle), slot); } } @@ -265,22 +278,42 @@ void MotionMaster::MoveChase(Unit* target, float dist, float angle) } } -void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot) +void MotionMaster::MoveConfused() { - // ignore movement request if target not exist - if (!target || target == _owner) + if (_owner->GetTypeId() == TYPEID_PLAYER) + { + TC_LOG_DEBUG("misc", "Player (%s) move confused", _owner->GetGUID().ToString().c_str()); + Mutate(new ConfusedMovementGenerator<Player>(), MOTION_SLOT_CONTROLLED); + } + else + { + TC_LOG_DEBUG("misc", "Creature (Entry: %u %s) move confused", + _owner->GetEntry(), _owner->GetGUID().ToString().c_str()); + Mutate(new ConfusedMovementGenerator<Creature>(), MOTION_SLOT_CONTROLLED); + } +} + +void MotionMaster::MoveFleeing(Unit* enemy, uint32 time) +{ + if (!enemy) return; - //_owner->AddUnitState(UNIT_STATE_FOLLOW); if (_owner->GetTypeId() == TYPEID_PLAYER) { - TC_LOG_DEBUG("misc", "Player (%s) follows (%s)", _owner->GetGUID().ToString().c_str(), target->GetGUID().ToString().c_str()); - Mutate(new FollowMovementGenerator<Player>(target, dist, angle), slot); + TC_LOG_DEBUG("misc", "Player (%s) flees from (%s).", _owner->GetGUID().ToString().c_str(), + enemy->GetGUID().ToString().c_str()); + Mutate(new FleeingMovementGenerator<Player>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED); } else { - TC_LOG_DEBUG("misc", "Creature (Entry: %u %s) follows (%s)", _owner->GetEntry(), _owner->GetGUID().ToString().c_str(), target->GetGUID().ToString().c_str()); - Mutate(new FollowMovementGenerator<Creature>(target, dist, angle), slot); + TC_LOG_DEBUG("misc", "Creature (Entry: %u %s) flees from (%s)%s.", + _owner->GetEntry(), _owner->GetGUID().ToString().c_str(), + enemy->GetGUID().ToString().c_str(), + time ? " for a limited time" : ""); + if (time) + Mutate(new TimedFleeingMovementGenerator(enemy->GetGUID(), time), MOTION_SLOT_CONTROLLED); + else + Mutate(new FleeingMovementGenerator<Creature>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED); } } @@ -348,6 +381,43 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos) Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE); } +void MotionMaster::MoveCharge(float x, float y, float z, float speed /*= SPEED_CHARGE*/, uint32 id /*= EVENT_CHARGE*/, bool generatePath /*= false*/, + Unit const* target /*= nullptr*/, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/) +{ + if (_slot[MOTION_SLOT_CONTROLLED] && _slot[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE) + return; + + if (_owner->GetTypeId() == TYPEID_PLAYER) + { + TC_LOG_DEBUG("misc", "Player (%s) charged point (X: %f Y: %f Z: %f).", _owner->GetGUID().ToString().c_str(), x, y, z); + Mutate(new PointMovementGenerator<Player>(id, x, y, z, generatePath, speed, target, spellEffectExtraData), MOTION_SLOT_CONTROLLED); + } + else + { + TC_LOG_DEBUG("misc", "Creature (Entry: %u %s) charged point (X: %f Y: %f Z: %f).", + _owner->GetEntry(), _owner->GetGUID().ToString().c_str(), x, y, z); + Mutate(new PointMovementGenerator<Creature>(id, x, y, z, generatePath, speed, target, spellEffectExtraData), MOTION_SLOT_CONTROLLED); + } +} + +void MotionMaster::MoveCharge(PathGenerator const& path, float speed /*= SPEED_CHARGE*/, Unit const* target /*= nullptr*/, + Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/) +{ + G3D::Vector3 dest = path.GetActualEndPosition(); + + MoveCharge(dest.x, dest.y, dest.z, speed, EVENT_CHARGE_PREPATH); + + // Charge movement is not started when using EVENT_CHARGE_PREPATH + Movement::MoveSplineInit init(_owner); + init.MovebyPath(path.GetPath()); + init.SetVelocity(speed); + if (target) + init.SetFacing(target); + if (spellEffectExtraData) + init.SetSpellEffectExtraData(*spellEffectExtraData); + init.Launch(); +} + void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/) { //this function may make players fall below map @@ -546,43 +616,6 @@ void MotionMaster::MoveFall(uint32 id /*=0*/) Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); } -void MotionMaster::MoveCharge(float x, float y, float z, float speed /*= SPEED_CHARGE*/, uint32 id /*= EVENT_CHARGE*/, bool generatePath /*= false*/, - Unit const* target /*= nullptr*/, Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/) -{ - if (Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE) - return; - - if (_owner->GetTypeId() == TYPEID_PLAYER) - { - TC_LOG_DEBUG("misc", "Player (%s) charged point (X: %f Y: %f Z: %f).", _owner->GetGUID().ToString().c_str(), x, y, z); - Mutate(new PointMovementGenerator<Player>(id, x, y, z, generatePath, speed, target, spellEffectExtraData), MOTION_SLOT_CONTROLLED); - } - else - { - TC_LOG_DEBUG("misc", "Creature (Entry: %u %s) charged point (X: %f Y: %f Z: %f).", - _owner->GetEntry(), _owner->GetGUID().ToString().c_str(), x, y, z); - Mutate(new PointMovementGenerator<Creature>(id, x, y, z, generatePath, speed, target, spellEffectExtraData), MOTION_SLOT_CONTROLLED); - } -} - -void MotionMaster::MoveCharge(PathGenerator const& path, float speed /*= SPEED_CHARGE*/, Unit const* target /*= nullptr*/, - Movement::SpellEffectExtraData const* spellEffectExtraData /*= nullptr*/) -{ - G3D::Vector3 dest = path.GetActualEndPosition(); - - MoveCharge(dest.x, dest.y, dest.z, speed, EVENT_CHARGE_PREPATH); - - // Charge movement is not started when using EVENT_CHARGE_PREPATH - Movement::MoveSplineInit init(_owner); - init.MovebyPath(path.GetPath()); - init.SetVelocity(speed); - if (target) - init.SetFacing(target); - if (spellEffectExtraData) - init.SetSpellEffectExtraData(*spellEffectExtraData); - init.Launch(); -} - void MotionMaster::MoveSeekAssistance(float x, float y, float z) { if (_owner->GetTypeId() == TYPEID_PLAYER) @@ -614,30 +647,6 @@ void MotionMaster::MoveSeekAssistanceDistract(uint32 time) } } -void MotionMaster::MoveFleeing(Unit* enemy, uint32 time) -{ - if (!enemy) - return; - - if (_owner->GetTypeId() == TYPEID_PLAYER) - { - TC_LOG_DEBUG("misc", "Player (%s) flees from (%s).", _owner->GetGUID().ToString().c_str(), - enemy->GetGUID().ToString().c_str()); - Mutate(new FleeingMovementGenerator<Player>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED); - } - else - { - TC_LOG_DEBUG("misc", "Creature (Entry: %u %s) flees from (%s)%s.", - _owner->GetEntry(), _owner->GetGUID().ToString().c_str(), - enemy->GetGUID().ToString().c_str(), - time ? " for a limited time" : ""); - if (time) - Mutate(new TimedFleeingMovementGenerator(enemy->GetGUID(), time), MOTION_SLOT_CONTROLLED); - else - Mutate(new FleeingMovementGenerator<Creature>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED); - } -} - void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode) { if (_owner->GetTypeId() == TYPEID_PLAYER) @@ -664,7 +673,7 @@ void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode) void MotionMaster::MoveDistract(uint32 timer) { - if (Impl[MOTION_SLOT_CONTROLLED]) + if (_slot[MOTION_SLOT_CONTROLLED]) return; if (_owner->GetTypeId() == TYPEID_PLAYER) @@ -681,11 +690,55 @@ void MotionMaster::MoveDistract(uint32 timer) Mutate(mgen, MOTION_SLOT_CONTROLLED); } +void MotionMaster::MovePath(uint32 path_id, bool repeatable) +{ + if (!path_id) + return; + + Mutate(new WaypointMovementGenerator<Creature>(path_id, repeatable), MOTION_SLOT_IDLE); + + TC_LOG_DEBUG("misc", "%s starts moving over path (Id:%u, repeatable: %s).", + _owner->GetGUID().ToString().c_str(), path_id, repeatable ? "YES" : "NO"); +} + +void MotionMaster::MoveRotate(uint32 time, RotateDirection direction) +{ + if (!time) + return; + + Mutate(new RotateMovementGenerator(time, direction), MOTION_SLOT_ACTIVE); +} + +/******************** Private methods ********************/ + +void MotionMaster::pop() +{ + if (empty()) + return; + + _slot[_top] = nullptr; + while (!empty() && !top()) + --_top; +} + +bool MotionMaster::NeedInitTop() const +{ + if (empty()) + return false; + return _initialize[_top]; +} + +void MotionMaster::InitTop() +{ + top()->Initialize(_owner); + _initialize[_top] = false; +} + void MotionMaster::Mutate(MovementGenerator *m, MovementSlot slot) { - if (MovementGenerator *curr = Impl[slot]) + if (MovementGenerator *curr = _slot[slot]) { - Impl[slot] = NULL; // in case a new one is generated in this slot during directdelete + _slot[slot] = nullptr; // in case a new one is generated in this slot during directdelete if (_top == slot && (_cleanFlag & MMCF_UPDATE)) DelayedDelete(curr); else @@ -696,109 +749,93 @@ void MotionMaster::Mutate(MovementGenerator *m, MovementSlot slot) _top = slot; } - Impl[slot] = m; + _slot[slot] = m; if (_top > slot) - _needInit[slot] = true; + _initialize[slot] = true; else { - _needInit[slot] = false; + _initialize[slot] = false; m->Initialize(_owner); } } -void MotionMaster::MovePath(uint32 path_id, bool repeatable) +void MotionMaster::DirectClean(bool reset) { - if (!path_id) - return; - //We set waypoint movement as new default movement generator - // clear ALL movement generators (including default) - /*while (!empty()) + while (size() > 1) { MovementGenerator *curr = top(); - curr->Finalize(*_owner); pop(); - if (!isStatic(curr)) - delete curr; - }*/ - - //_owner->GetTypeId() == TYPEID_PLAYER ? - //Mutate(new WaypointMovementGenerator<Player>(path_id, repeatable)): - Mutate(new WaypointMovementGenerator<Creature>(path_id, repeatable), MOTION_SLOT_IDLE); - - TC_LOG_DEBUG("misc", "%s starts moving over path (Id:%u, repeatable: %s).", - _owner->GetGUID().ToString().c_str(), path_id, repeatable ? "YES" : "NO"); -} + if (curr) + DirectDelete(curr); + } -void MotionMaster::MoveRotate(uint32 time, RotateDirection direction) -{ - if (!time) + if (empty()) return; - Mutate(new RotateMovementGenerator(time, direction), MOTION_SLOT_ACTIVE); + if (NeedInitTop()) + InitTop(); + else if (reset) + top()->Reset(_owner); } -void MotionMaster::propagateSpeedChange() +void MotionMaster::DelayedClean() { - /*Impl::container_type::iterator it = Impl::c.begin(); - for (; it != end(); ++it) - { - (*it)->unitSpeedChanged(); - }*/ - for (int i = 0; i <= _top; ++i) + while (size() > 1) { - if (Impl[i]) - Impl[i]->unitSpeedChanged(); + MovementGenerator *curr = top(); + pop(); + if (curr) + DelayedDelete(curr); } } -MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const +void MotionMaster::DirectExpire(bool reset) { - if (empty()) - return IDLE_MOTION_TYPE; + if (size() > 1) + { + MovementGenerator *curr = top(); + pop(); + DirectDelete(curr); + } - return top()->GetMovementGeneratorType(); -} + while (!empty() && !top()) + --_top; -MovementGeneratorType MotionMaster::GetMotionSlotType(int slot) const -{ - if (!Impl[slot]) - return NULL_MOTION_TYPE; - else - return Impl[slot]->GetMovementGeneratorType(); + if (empty()) + Initialize(); + else if (NeedInitTop()) + InitTop(); + else if (reset) + top()->Reset(_owner); } -void MotionMaster::InitTop() +void MotionMaster::DelayedExpire() { - top()->Initialize(_owner); - _needInit[_top] = false; + if (size() > 1) + { + MovementGenerator *curr = top(); + pop(); + DelayedDelete(curr); + } + + while (!empty() && !top()) + --_top; } -void MotionMaster::DirectDelete(_Ty curr) +void MotionMaster::DirectDelete(MovementGenerator* curr) { - if (isStatic(curr)) + if (IsStatic(curr)) return; curr->Finalize(_owner); delete curr; } -void MotionMaster::DelayedDelete(_Ty curr) +void MotionMaster::DelayedDelete(MovementGenerator* curr) { TC_LOG_FATAL("misc", "Unit (Entry %u) is trying to delete its updating Movement Generator (Type %u)!", _owner->GetEntry(), curr->GetMovementGeneratorType()); - if (isStatic(curr)) + if (IsStatic(curr)) return; - if (!_expList) - _expList = new ExpireList(); - _expList->push_back(curr); -} - -bool MotionMaster::GetDestination(float &x, float &y, float &z) -{ - if (_owner->movespline->Finalized()) - return false; - - G3D::Vector3 const& dest = _owner->movespline->FinalDestination(); - x = dest.x; - y = dest.y; - z = dest.z; - return true; + if (!_expireList) + _expireList = new ExpireList(); + _expireList->push_back(curr); } diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 2112fe0ba10..fcf20e2aa7e 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -16,8 +16,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef TRINITY_MOTIONMASTER_H -#define TRINITY_MOTIONMASTER_H +#ifndef MOTIONMASTER_H +#define MOTIONMASTER_H #include "Common.h" #include "Errors.h" @@ -44,31 +44,32 @@ namespace Movement // Creature Entry ID used for waypoints show, visible only for GMs #define VISUAL_WAYPOINT 1 +// assume it is 25 yard per 0.6 second +#define SPEED_CHARGE 42.0f -// values 0 ... MAX_DB_MOTION_TYPE-1 used in DB enum MovementGeneratorType : uint8 { - IDLE_MOTION_TYPE = 0, // IdleMovementGenerator.h - RANDOM_MOTION_TYPE = 1, // RandomMovementGenerator.h - WAYPOINT_MOTION_TYPE = 2, // WaypointMovementGenerator.h - MAX_DB_MOTION_TYPE = 3, // *** this and below motion types can't be set in DB. - ANIMAL_RANDOM_MOTION_TYPE = MAX_DB_MOTION_TYPE, // AnimalRandomMovementGenerator.h - CONFUSED_MOTION_TYPE = 4, // ConfusedMovementGenerator.h - CHASE_MOTION_TYPE = 5, // TargetedMovementGenerator.h - HOME_MOTION_TYPE = 6, // HomeMovementGenerator.h - FLIGHT_MOTION_TYPE = 7, // WaypointMovementGenerator.h - POINT_MOTION_TYPE = 8, // PointMovementGenerator.h - FLEEING_MOTION_TYPE = 9, // FleeingMovementGenerator.h - DISTRACT_MOTION_TYPE = 10, // IdleMovementGenerator.h - ASSISTANCE_MOTION_TYPE= 11, // PointMovementGenerator.h (first part of flee for assistance) - ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h (second part of flee for assistance) - TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance) - FOLLOW_MOTION_TYPE = 14, - ROTATE_MOTION_TYPE = 15, - EFFECT_MOTION_TYPE = 16, - NULL_MOTION_TYPE = 17, - SPLINE_CHAIN_MOTION_TYPE = 18, // SplineChainMovementGenerator.h - MAX_MOTION_TYPE // limit + IDLE_MOTION_TYPE = 0, // IdleMovementGenerator.h + RANDOM_MOTION_TYPE = 1, // RandomMovementGenerator.h + WAYPOINT_MOTION_TYPE = 2, // WaypointMovementGenerator.h + MAX_DB_MOTION_TYPE = 3, // Below motion types can't be set in DB. + ANIMAL_RANDOM_MOTION_TYPE = MAX_DB_MOTION_TYPE, // AnimalRandomMovementGenerator.h + CONFUSED_MOTION_TYPE = 4, // ConfusedMovementGenerator.h + CHASE_MOTION_TYPE = 5, // TargetedMovementGenerator.h + HOME_MOTION_TYPE = 6, // HomeMovementGenerator.h + FLIGHT_MOTION_TYPE = 7, // WaypointMovementGenerator.h + POINT_MOTION_TYPE = 8, // PointMovementGenerator.h + FLEEING_MOTION_TYPE = 9, // FleeingMovementGenerator.h + DISTRACT_MOTION_TYPE = 10, // IdleMovementGenerator.h + ASSISTANCE_MOTION_TYPE = 11, // PointMovementGenerator.h (first part of flee for assistance) + ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h (second part of flee for assistance) + TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance) + FOLLOW_MOTION_TYPE = 14, + ROTATE_MOTION_TYPE = 15, + EFFECT_MOTION_TYPE = 16, + NULL_MOTION_TYPE = 17, + SPLINE_CHAIN_MOTION_TYPE = 18, // SplineChainMovementGenerator.h + MAX_MOTION_TYPE // limit }; enum MovementSlot @@ -98,91 +99,41 @@ struct JumpArrivalCastArgs ObjectGuid Target; }; -// assume it is 25 yard per 0.6 second -#define SPEED_CHARGE 42.0f - -class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *> +class TC_GAME_API MotionMaster { private: - //typedef std::stack<MovementGenerator *> Impl; - typedef MovementGenerator* _Ty; - - void pop() - { - if (empty()) - return; + typedef std::vector<MovementGenerator*> ExpireList; - Impl[_top] = NULL; - while (!empty() && !top()) - --_top; - } - void push(_Ty _Val) { ++_top; Impl[_top] = _Val; } - - bool needInitTop() const - { - if (empty()) - return false; - return _needInit[_top]; - } - void InitTop(); public: - - explicit MotionMaster(Unit* unit) : _expList(NULL), _top(-1), _owner(unit), _cleanFlag(MMCF_NONE) + explicit MotionMaster(Unit* unit) : _expireList(nullptr), _top(-1), _owner(unit), _cleanFlag(MMCF_NONE) { for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i) { - Impl[i] = NULL; - _needInit[i] = true; + _slot[i] = nullptr; + _initialize[i] = true; } } ~MotionMaster(); - void Initialize(); - void InitDefault(); - bool empty() const { return (_top < 0); } int size() const { return _top + 1; } - _Ty top() const - { - ASSERT(!empty()); - return Impl[_top]; - } - _Ty GetMotionSlot(int slot) const - { - ASSERT(slot >= 0); - return Impl[slot]; - } + MovementGenerator* top() const { ASSERT(!empty()); return _slot[_top]; } - void DirectDelete(_Ty curr); - void DelayedDelete(_Ty curr); + void Initialize(); + void InitDefault(); void UpdateMotion(uint32 diff); - void Clear(bool reset = true) - { - if (_cleanFlag & MMCF_UPDATE) - { - if (reset) - _cleanFlag |= MMCF_RESET; - else - _cleanFlag &= ~MMCF_RESET; - DelayedClean(); - } - else - DirectClean(reset); - } - void MovementExpired(bool reset = true) - { - if (_cleanFlag & MMCF_UPDATE) - { - if (reset) - _cleanFlag |= MMCF_RESET; - else - _cleanFlag &= ~MMCF_RESET; - DelayedExpire(); - } - else - DirectExpire(reset); - } + + void Clear(bool reset = true); + void MovementExpired(bool reset = true); + + MovementGeneratorType GetCurrentMovementGeneratorType() const; + MovementGeneratorType GetMotionSlotType(int slot) const; + MovementGenerator* GetMotionSlot(int slot) const; + + void propagateSpeedChange(); + + bool GetDestination(float &x, float &y, float &z); void MoveIdle(); void MoveTargetedHome(); @@ -192,7 +143,9 @@ class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *> void MoveConfused(); void MoveFleeing(Unit* enemy, uint32 time = 0); void MovePoint(uint32 id, Position const& pos, bool generatePath = true) - { MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, generatePath); } + { + MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, generatePath); + } void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true); /* Makes the unit move toward the target until it is at a certain distance from it. The unit then stops. @@ -229,27 +182,27 @@ class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *> void MovePath(uint32 path_id, bool repeatable); void MoveRotate(uint32 time, RotateDirection direction); - MovementGeneratorType GetCurrentMovementGeneratorType() const; - MovementGeneratorType GetMotionSlotType(int slot) const; + private: + void pop(); - void propagateSpeedChange(); + bool NeedInitTop() const; + void InitTop(); - bool GetDestination(float &x, float &y, float &z); - private: - void Mutate(MovementGenerator *m, MovementSlot slot); // use Move* functions instead + void Mutate(MovementGenerator *m, MovementSlot slot); void DirectClean(bool reset); void DelayedClean(); - void DirectExpire(bool reset); void DelayedExpire(); + void DirectDelete(MovementGenerator* curr); + void DelayedDelete(MovementGenerator* curr); - typedef std::vector<_Ty> ExpireList; - ExpireList* _expList; - _Ty Impl[MAX_MOTION_SLOT]; + ExpireList* _expireList; + MovementGenerator* _slot[MAX_MOTION_SLOT]; int _top; Unit* _owner; - bool _needInit[MAX_MOTION_SLOT]; + bool _initialize[MAX_MOTION_SLOT]; uint8 _cleanFlag; }; -#endif + +#endif // MOTIONMASTER_H |