diff options
Diffstat (limited to 'src/game/MotionMaster.cpp')
-rw-r--r-- | src/game/MotionMaster.cpp | 156 |
1 files changed, 94 insertions, 62 deletions
diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp index 39fd7469a15..d74602844a5 100644 --- a/src/game/MotionMaster.cpp +++ b/src/game/MotionMaster.cpp @@ -1,7 +1,7 @@ /* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,11 +47,7 @@ MotionMaster::Initialize() { MovementGenerator *curr = top(); pop(); - if(!curr) - continue; - curr->Finalize(*i_owner); - if( !isStatic( curr ) ) - delete curr; + if(curr) DirectDelete(curr); } // set new default movement generator @@ -72,82 +68,103 @@ MotionMaster::~MotionMaster() { MovementGenerator *curr = top(); pop(); - if(!curr) - continue; - curr->Finalize(*i_owner); - if( !isStatic( curr ) ) - delete curr; + if(curr) DirectDelete(curr); } } void -MotionMaster::UpdateMotion(const uint32 &diff) +MotionMaster::UpdateMotion(uint32 diff) { if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) ) return; assert( !empty() ); + m_cleanFlag |= MMCF_UPDATE; if (!top()->Update(*i_owner, diff)) + { + m_cleanFlag &= ~MMCF_UPDATE; MovementExpired(); + } + else + m_cleanFlag &= ~MMCF_UPDATE; + + if (m_expList) + { + for (int i = 0; i < m_expList->size(); ++i) + { + MovementGenerator* mg = (*m_expList)[i]; + DirectDelete(mg); + } + + delete m_expList; + m_expList = NULL; + + if (empty()) + Initialize(); + + if (m_cleanFlag & MMCF_RESET) + { + top()->Reset(*i_owner); + m_cleanFlag &= ~MMCF_RESET; + } + } } void -MotionMaster::Clear(bool reset) +MotionMaster::DirectClean(bool reset) { while( !empty() && size() > 1 ) { MovementGenerator *curr = top(); pop(); - if(!curr) - continue; - curr->Finalize(*i_owner); - if( !isStatic( curr ) ) - delete curr; + if(curr) DirectDelete(curr); } - if (reset) - { - assert( !empty() ); + if(reset) top()->Reset(*i_owner); - } } void -MotionMaster::MoveRandom(float spawndist) +MotionMaster::DelayedClean() { - if(i_owner->GetTypeId()==TYPEID_UNIT) + while( !empty() && size() > 1 ) { - DEBUG_LOG("Creature (GUID: %u) start moving random", i_owner->GetGUIDLow() ); - Mutate(new RandomMovementGenerator<Creature>(spawndist), MOTION_SLOT_IDLE); + MovementGenerator *curr = top(); + pop(); + if(curr) DelayedDelete(curr); } } void -MotionMaster::MovementExpired(bool reset) +MotionMaster::DirectExpire(bool reset) { if( empty() || size() == 1 ) return; MovementGenerator *curr = top(); - curr->Finalize(*i_owner); pop(); + DirectDelete(curr); - if( !isStatic(curr) ) - delete curr; - - assert( !empty() ); while(!top()) --i_top; - /*while( !empty() && top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE ) - { - // Should check if target is still valid? If not valid it will crash. - curr = top(); - curr->Finalize(*i_owner); - pop(); - delete curr; - }*/ - if( empty() ) + + if(empty()) Initialize(); - if (reset) top()->Reset(*i_owner); + if(reset) + top()->Reset(*i_owner); +} + +void +MotionMaster::DelayedExpire() +{ + if( empty() || size() == 1 ) + return; + + MovementGenerator *curr = top(); + pop(); + DelayedDelete(curr); + + while(!top()) + --i_top; } void MotionMaster::MoveIdle(MovementSlot slot) @@ -159,10 +176,20 @@ void MotionMaster::MoveIdle(MovementSlot slot) } void +MotionMaster::MoveRandom(float spawndist) +{ + if(i_owner->GetTypeId()==TYPEID_UNIT) + { + DEBUG_LOG("Creature (GUID: %u) start moving random", i_owner->GetGUIDLow() ); + Mutate(new RandomMovementGenerator<Creature>(spawndist), MOTION_SLOT_IDLE); + } +} + +void MotionMaster::MoveTargetedHome() { - if(i_owner->hasUnitState(UNIT_STAT_FLEEING)) - return; + //if(i_owner->hasUnitState(UNIT_STAT_FLEEING)) + // return; Clear(false); @@ -360,9 +387,10 @@ void MotionMaster::Mutate(MovementGenerator *m, MovementSlot slot) { if(MovementGenerator *curr = Impl[slot]) { - curr->Finalize(*i_owner); - if( !isStatic( curr ) ) - delete curr; + if(i_top == slot && (m_cleanFlag & MMCF_UPDATE)) + DelayedDelete(curr); + else + DirectDelete(curr); } else if(i_top < slot) { @@ -370,20 +398,6 @@ void MotionMaster::Mutate(MovementGenerator *m, MovementSlot slot) } m->Initialize(*i_owner); Impl[slot] = m; - - /*if (!empty()) - { - switch(top()->GetMovementGeneratorType()) - { - // HomeMovement is not that important, delete it if meanwhile a new comes - case HOME_MOTION_TYPE: - // DistractMovement interrupted by any other movement - case DISTRACT_MOTION_TYPE: - MovementExpired(false); - } - } - m->Initialize(*i_owner); - push(m);*/ } void MotionMaster::MovePath(uint32 path_id, bool repeatable) @@ -432,6 +446,24 @@ MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const return top()->GetMovementGeneratorType(); } +void MotionMaster::DirectDelete(_Ty curr) +{ + if(isStatic(curr)) + return; + curr->Finalize(*i_owner); + delete curr; +} + +void MotionMaster::DelayedDelete(_Ty curr) +{ + sLog.outError("CRASH ALARM! Unit (Entry %u) is trying to delete its updating MG (Type %u)!", i_owner->GetEntry(), curr->GetMovementGeneratorType()); + if(isStatic(curr)) + return; + if(!m_expList) + m_expList = new ExpireList(); + m_expList->push_back(curr); +} + bool MotionMaster::GetDestination(float &x, float &y, float &z) { if(empty()) |