示例#1
0
//---------------------------------------------------//
// [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;
}