//---------------------------------------------------// // [8/5/2009 Albert] // Description: 移动定时器 //---------------------------------------------------// bool CDynamicObject::UpdateTimer( unsigned int handle, unsigned short& repeat, unsigned int& timer ) { repeat = 1; timer = TIMER_SECONDS(1.0f); // 先移动到当前所在的位置. CGameMap* pScene = static_cast< CGameMap* >( CXObjectPool::GetInstance().GetObj( GetParent(), TypeGameMap ) ); if( pScene ) { if( pScene->DynamicMoveTo( this, m_vNextPosition, false ) ) { //CLogger::GetInstance(_T("Log"))->WriteLog( _T("角色[%08x]移动到路点[%f,%f,%f]") // , GetObjID() // , m_vNextPosition[0], m_vNextPosition[1], m_vNextPosition[2] ); OnStep( m_vNextPosition ); } else { OnArrived( m_vNextPosition ); return true; } } else { m_hUpdateTimer = INVALID_TIMER_HANDLE; return true; } // 计算下一个点 if( m_PointList.empty() ) { m_hUpdateTimer = INVALID_TIMER_HANDLE; OnArrived( m_vNextPosition ); return true; } const PathPoint& target = m_PointList.front(); XVector3 Vec = target.vPosition - m_vNextPosition; float distance = Vec.SqurLength(); float fSpeed = target.fSpeed; if( distance < fSpeed*fSpeed ) { // 当前坐标到目标点的距离小于速度值 m_vNextPosition = target.vPosition; float t = XMath::Sqrt( distance )/fSpeed; timer = TIMER_SECONDS(t); m_PointList.pop_front(); } else { Vec.NormalizeFast(); Vec *= fSpeed; m_vNextPosition += Vec; } return false; }
bool WaypointMovementGenerator<Creature>::DoUpdate(Creature* creature, uint32 diff) { // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (creature->HasUnitState(UNIT_STATE_NOT_MOVE)) { creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE); return true; } // prevent a crash at empty waypoint path. if (!i_path || i_path->empty()) return false; // Xinef: Dont allow dead creatures to move if (!creature->IsAlive()) return false; // prevent movement while casting spells with cast time or channel time if (creature->HasUnitState(UNIT_STATE_CASTING)) { bool stop = true; if (Spell* spell = creature->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) if (!(spell->GetSpellInfo()->ChannelInterruptFlags & (AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING)) && !(spell->GetSpellInfo()->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)) stop = false; if (stop) { Stop(1000); if (!creature->IsStopped()) creature->StopMoving(); return true; } } if (Stopped()) { if (CanMove(diff)) return StartMove(creature); } else { if (creature->IsStopped()) Stop(STOP_TIME_FOR_PLAYER); else { // xinef: code to detect pre-empetively if we should start movement to next waypoint // xinef: do not start pre-empetive movement if current node has delay or we are ending waypoint movement bool finished = creature->movespline->Finalized(); if (!finished && !i_path->at(i_currentNode)->delay && ((i_currentNode != i_path->size() - 1) || repeating)) finished = (creature->movespline->_Spline().length(creature->movespline->_currentSplineIdx()+1) - creature->movespline->timePassed()) < 200; if (finished) { OnArrived(creature); return StartMove(creature); } } } return true; }
bool WaypointMovementGenerator<Creature>::DoUpdate(Creature* creature, uint32 diff) { // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (creature->HasUnitState(UNIT_STATE_NOT_MOVE)) { creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE); return true; } // prevent a crash at empty waypoint path. if (!i_path || i_path->empty()) return false; if (Stopped()) { if (CanMove(diff)) return StartMove(creature); } else { if (creature->IsStopped()) Stop(STOP_TIME_FOR_PLAYER); else if (creature->movespline->Finalized()) { OnArrived(creature); return StartMove(creature); } } return true; }
bool WaypointMovementGenerator<Creature>::Update(Creature& creature, const uint32& diff) { // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (creature.hasUnitState(UNIT_STAT_NOT_MOVE)) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } // prevent a crash at empty waypoint path. if (!i_path || i_path->empty()) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } if (Stopped(creature)) { if (CanMove(diff, creature)) { StartMove(creature); } } else { if (creature.IsStopped()) { Stop(STOP_TIME_FOR_PLAYER); } else if (creature.movespline->Finalized()) { OnArrived(creature); StartMove(creature); } } return true; }
bool WaypointMovementGenerator<Creature>::DoUpdate(Creature* creature, uint32 diff) { // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (creature->HasUnitState(UNIT_STATE_NOT_MOVE)) { creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE); return true; } // prevent a crash at empty waypoint path. if (!i_path || i_path->empty()) return false; if (Stopped()) { if (CanMove(diff)) return StartMove(creature); } else { // Set home position at place on waypoint movement. if (!creature->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) || !creature->GetTransGUID()) creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); if (creature->IsStopped()) Stop(STOP_TIME_FOR_PLAYER); else if (creature->movespline->Finalized()) { OnArrived(creature); return StartMove(creature); } } return true; }
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff) { // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (creature.hasUnitState(UNIT_STAT_NOT_MOVE)) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } // prevent a crash at empty waypoint path. if (!i_path || i_path->empty()) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } if (Stopped()) { if (CanMove(diff)) StartMove(creature); } else { CreatureTraveller traveller(creature); if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true) && !IsActive(creature)) return true; if (creature.IsStopped()) Stop(STOP_TIME_FOR_PLAYER); if (i_destinationHolder.HasArrived()) { OnArrived(creature); StartMove(creature); } } return true; }
bool WaypointMovementGenerator<Creature>::DoUpdate(Creature* creature, uint32 diff) { if (!creature || !creature->IsAlive()) return false; // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (creature->HasUnitState(UNIT_STATE_NOT_MOVE)) { creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE); return true; } // prevent a crash at empty waypoint path. if (!i_path || i_path->nodes.empty()) return false; if (Stopped()) { if (CanMove(diff)) return StartMoveNow(creature); } else { // Set home position at place on waypoint movement. if (!creature->GetTransGUID()) creature->SetHomePosition(creature->GetPosition()); if (creature->IsStopped()) Stop(LoadedFromDB ? sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER) : 2 * HOUR * IN_MILLISECONDS); else if (creature->movespline->Finalized()) { OnArrived(creature); IsArrivalDone = true; if (!Stopped()) { if (creature->IsStopped()) Stop(LoadedFromDB ? sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER) : 2 * HOUR * IN_MILLISECONDS); else return StartMove(creature); } } else { // speed changed during path execution, calculate remaining path and launch it once more if (i_recalculateSpeed) { i_recalculateSpeed = false; if (!Stopped()) return StartMove(creature); } else { uint32 pointId = uint32(creature->movespline->currentPathIdx()); if (pointId > i_currentNode) { OnArrived(creature); i_currentNode = pointId; FormationMove(creature); } } } } return true; }