예제 #1
0
void npc_escortAI::MovementInform(uint32 type, uint32 id)
{
    if (type != POINT_MOTION_TYPE || !IsBeingEscorted)
        return;

    //Original position reached, continue waypoint movement
    if (id == WP_LAST_POINT)
    {
        debug_log("RSCR: EscortAI has returned to original position before combat");
        ReconnectWP = true;
        Returning = false;

        if(!WaitTimer)
            WaitTimer = 1;
    }
    else
    {
        //Make sure that we are still on the right waypoint
        if (CurrentWP->id != id)
        {
            debug_log("RSCR ERROR: EscortAI reached waypoint out of order %d, expected %d", id, CurrentWP->id);
            return;
        }

        debug_log("RSCR: EscortAI Waypoint %d reached", CurrentWP->id);

        //Call WP function
        WaypointReached(CurrentWP->id);

        WaitTimer = CurrentWP->WaitTimeMs + 1;

        ++CurrentWP;
    }
}
예제 #2
0
void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId)
{
    if (uiMoveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING))
    {
        return;
    }

    // Combat start position reached, continue waypoint movement
    if (uiPointId == POINT_LAST_POINT)
    {
        debug_log("SD2: EscortAI has returned to original position before combat");

        m_creature->SetWalk(!m_bIsRunning);
        RemoveEscortState(STATE_ESCORT_RETURNING);
    }
    else if (uiPointId == POINT_HOME)
    {
        debug_log("SD2: EscortAI has returned to original home location and will continue from beginning of waypoint list.");

        CurrentWP = WaypointList.begin();
        m_uiWPWaitTimer = 0;
    }
    else
    {
        // Make sure that we are still on the right waypoint
        if (CurrentWP->uiId != uiPointId)
        {
            script_error_log("EscortAI for Npc %u reached waypoint out of order %u, expected %u.", m_creature->GetEntry(), uiPointId, CurrentWP->uiId);
            return;
        }

        debug_log("SD2: EscortAI waypoint %u reached.", CurrentWP->uiId);

        // In case we were moving while in combat, we should evade back to this position
        m_creature->SetCombatStartPosition(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());

        // Call WP function
        WaypointReached(CurrentWP->uiId);

        m_uiWPWaitTimer = CurrentWP->uiWaitTime;

        ++CurrentWP;
    }

    if (!m_uiWPWaitTimer)
    {
        // Continue WP Movement if Can
        if (HasEscortState(STATE_ESCORT_ESCORTING) && !HasEscortState(STATE_ESCORT_PAUSED | STATE_ESCORT_RETURNING) && !m_creature->getVictim())
        {
            MoveToNextWaypoint();
        }
        else
        {
            m_uiWPWaitTimer = 1;
        }
    }
}
예제 #3
0
void npc_escortAI::MovementInform(uint32 moveType, uint32 pointId)
{
    if(moveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING))
        return;

    //Combat start position reached, continue waypoint movement
    if(pointId == POINT_LAST_POINT)
    {
        sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI has returned to original position before combat");

        if(m_bIsRunning && me->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
            me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
        else if(!m_bIsRunning && !me->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
            me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);

        RemoveEscortState(STATE_ESCORT_RETURNING);

        if(!m_uiWPWaitTimer)
            m_uiWPWaitTimer = 1;
    }
    else if(pointId == POINT_HOME)
    {
        sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI has returned to original home location and will continue from beginning of waypoint list.");

        CurrentWP = WaypointList.begin();
        m_uiWPWaitTimer = 1;
    }
    else
    {
        if(WaypointList.empty() || CurrentWP == WaypointList.end())
        {
            sLog->outError("TSCR ERROR: EscortAI has no current WP set up for point %u of creature entry %u", pointId, me->GetEntry());
            return;
        }

        //Make sure that we are still on the right waypoint
        if(CurrentWP->id != pointId)
        {
            sLog->outError("TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u, creature entry %u", pointId, CurrentWP->id, me->GetEntry());
            return;
        }

        sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI Waypoint %u reached", CurrentWP->id);

        //Call WP function
        WaypointReached(CurrentWP->id);

        m_uiWPWaitTimer = CurrentWP->WaitTimeMs + 1;

        ++CurrentWP;
    }
}
예제 #4
0
//-----------------------------------------------------------------------------
// Purpose: Check to see if we should teleport to the current path corner
//-----------------------------------------------------------------------------
void CNPC_VehicleDriver::CheckForTeleport( void )
{
	if ( !GetGoalEnt() )
		return;

	CPathTrack *pTrack = dynamic_cast<CPathTrack *>( GetGoalEnt() );
	if ( !pTrack )
		return;

	// Does it have the teleport flag set?
	if ( pTrack->HasSpawnFlags( SF_PATH_TELEPORT ) )
	{
		AddEffects( EF_NOINTERP );

		// Teleport the vehicle to the pathcorner
		Vector vecMins, vecMaxs;
		vecMins = m_hVehicleEntity->CollisionProp()->OBBMins();
		vecMaxs = m_hVehicleEntity->CollisionProp()->OBBMaxs();
		Vector vecTarget = pTrack->GetAbsOrigin() - (vecMins + vecMaxs) * 0.5;
		vecTarget.z += ((vecMaxs.z - vecMins.z) * 0.5) + 8;	// Safety buffer

		// Orient it to face the next point
		QAngle vecAngles = pTrack->GetAbsAngles();
		Vector vecToTarget = vec3_origin;
		if ( pTrack->GetNext() )
		{
			vecToTarget = (pTrack->GetNext()->GetAbsOrigin() - pTrack->GetAbsOrigin());
			VectorNormalize( vecToTarget );

			// Vehicles are rotated 90 degrees
			VectorAngles( vecToTarget, vecAngles );
			vecAngles[YAW] -= 90;
		}
		m_hVehicleEntity->Teleport( &vecTarget, &vecAngles, &vec3_origin );

		// Teleport the driver
		SetAbsOrigin( m_hVehicleEntity->WorldSpaceCenter() );
		SetAbsAngles( m_hVehicleEntity->GetAbsAngles() );

		m_vecPrevPoint = pTrack->GetAbsOrigin();

		// Move to the next waypoint, we've reached this one
		if ( GetNavigator()->GetPath() )
		{
			WaypointReached();
		}

		// Clear our waypoints, because the next waypoint is certainly invalid now.
		ClearWaypoints();
	}
}
예제 #5
0
void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId)
{
    if (uiMoveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING))
        return;

    //Combat start position reached, continue waypoint movement
    if (uiPointId == POINT_LAST_POINT)
    {
        debug_log("SD0: EscortAI has returned to original position before combat");

        if (m_bIsRunning && m_creature->HasSplineFlag(SPLINEFLAG_WALKMODE))
            m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
        else if (!m_bIsRunning && !m_creature->HasSplineFlag(SPLINEFLAG_WALKMODE))
            m_creature->AddSplineFlag(SPLINEFLAG_WALKMODE);

        RemoveEscortState(STATE_ESCORT_RETURNING);

        if (!m_uiWPWaitTimer)
            m_uiWPWaitTimer = 1;
    }
    else if (uiPointId == POINT_HOME)
    {
        debug_log("SD0: EscortAI has returned to original home location and will continue from beginning of waypoint list.");

        CurrentWP = WaypointList.begin();
        m_uiWPWaitTimer = 1;
    }
    else
    {
        //Make sure that we are still on the right waypoint
        if (CurrentWP->uiId != uiPointId)
        {
            error_log("SD0: EscortAI for Npc %u reached waypoint out of order %u, expected %u.", m_creature->GetEntry(), uiPointId, CurrentWP->uiId);
            return;
        }

        debug_log("SD0: EscortAI waypoint %u reached.", CurrentWP->uiId);

        // In case we were moving while in combat, we should evade back to this position
        m_creature->SetCombatStartPosition(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());

        //Call WP function
        WaypointReached(CurrentWP->uiId);

        m_uiWPWaitTimer = CurrentWP->uiWaitTime + 1;

        ++CurrentWP;
    }
}
예제 #6
0
void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId)
{
    if (uiMoveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING) || me->isInCombat())
        return;

    //Combat start position reached, continue waypoint movement
    if (uiPointId == POINT_LAST_POINT)
    {
        debug_log("TSCR: EscortAI has returned to original position before combat");

        if (IsRunning && me->IsWalking())
            me->SetWalk(false);
        else if (!IsRunning && !me->IsWalking())
            me->SetWalk(true);

        me->GetUnitStateMgr().InitDefaults(false);
        RemoveEscortState(STATE_ESCORT_INCOMBAT);

        if (!WPWaitTimer)
            WPWaitTimer = 1;
    }
    else if (uiPointId == POINT_HOME)
    {
        debug_log("TSCR: EscortAI has returned to original home location and will continue from beginning of waypoint list.");

        CurrentWP = WaypointList.begin();
        WPWaitTimer = 1;
    }
    else
    {
        //Make sure that we are still on the right waypoint
        if (CurrentWP->id != uiPointId)
        {
            error_log("TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u", uiPointId, CurrentWP->id);
            return;
        }

        debug_log("TSCR: EscortAI Waypoint %u reached", CurrentWP->id);

        //Call WP function
        WaypointReached(CurrentWP->id);

        WPWaitTimer = CurrentWP->WaitTimeMs + 1;

        ++CurrentWP;
    }
}
예제 #7
0
void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId)
{
    if (uiMoveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING))
        return;

    //Combat start position reached, continue waypoint movement
    if (uiPointId == POINT_LAST_POINT)
    {
        debug_log("TSCR: EscortAI has returned to original position before combat");

        if (m_bIsRunning && m_creature->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
            m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
        else if (!m_bIsRunning && !m_creature->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
            m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);

        RemoveEscortState(STATE_ESCORT_RETURNING);

        if (!m_uiWPWaitTimer)
            m_uiWPWaitTimer = 1;
    }
    else if (uiPointId == POINT_HOME)
    {
        debug_log("TSCR: EscortAI has returned to original home location and will continue from beginning of waypoint list.");

        CurrentWP = WaypointList.begin();
        m_uiWPWaitTimer = 1;
    }
    else
    {
        //Make sure that we are still on the right waypoint
        if (CurrentWP->id != uiPointId)
        {
            error_log("TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u", uiPointId, CurrentWP->id);
            return;
        }

        debug_log("TSCR: EscortAI Waypoint %u reached", CurrentWP->id);

        //Call WP function
        WaypointReached(CurrentWP->id);

        m_uiWPWaitTimer = CurrentWP->WaitTimeMs + 1;

        ++CurrentWP;
    }
}
예제 #8
0
void npc_escortAI::MovementInform(uint32 moveType, uint32 pointId)
{
    if (moveType != POINT_MOTION_TYPE || !HasEscortState(STATE_ESCORT_ESCORTING))
        return;

    //Combat start position reached, continue waypoint movement
    if (pointId == POINT_LAST_POINT)
    {
        TC_LOG_DEBUG("scripts", "EscortAI has returned to original position before combat");

        me->SetWalk(!m_bIsRunning);
        RemoveEscortState(STATE_ESCORT_RETURNING);

        if (!m_uiWPWaitTimer)
            m_uiWPWaitTimer = 1;
    }
    else if (pointId == POINT_HOME)
    {
        TC_LOG_DEBUG("scripts", "EscortAI has returned to original home location and will continue from beginning of waypoint list.");

        CurrentWP = WaypointList.begin();
        m_uiWPWaitTimer = 1;
    }
    else
    {
        //Make sure that we are still on the right waypoint
        if (CurrentWP->id != pointId)
        {
            TC_LOG_ERROR("misc", "TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u, creature entry %u", pointId, CurrentWP->id, me->GetEntry());
            return;
        }

        TC_LOG_DEBUG("scripts", "EscortAI Waypoint %u reached", CurrentWP->id);

        //Call WP function
        WaypointReached(CurrentWP->id);

        m_uiWPWaitTimer = CurrentWP->WaitTimeMs + 1;

        ++CurrentWP;
    }
}
예제 #9
0
void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId)
{
    if (!IsSD2EscortMovement(uiMoveType) || !HasEscortState(STATE_ESCORT_ESCORTING))
        return;

    //uint32 pathId = uiMoveType & 0xFF;

    if (uiMoveType < EXTERNAL_WAYPOINT_MOVE_START)
        WaypointReached(uiPointId);
    else if (uiMoveType < EXTERNAL_WAYPOINT_FINISHED_LAST)
        WaypointStart(uiPointId);
    else                                                    // Last WP Reached
    {
        if (m_bCanInstantRespawn)
        {
            m_creature->SetDeathState(JUST_DIED);
            m_creature->Respawn();
        }
        else
            m_creature->ForcedDespawn();
    }
}
예제 #10
0
void SmoothEscortAI::UpdateAI(uint32 diff)
{
    if (HasEscortState(ESCORT_STATE_COMBAT) && !me->IsInCombat())
        EnterEvadeMode();

    if (HasEscortState(ESCORT_STATE_PAUSED) || HasEscortState(ESCORT_STATE_NONE) || HasEscortState(ESCORT_STATE_COMBAT))
        return;

    if (me->HasUnitState(UNIT_STATE_ROOT) || me->HasUnitState(UNIT_STATE_STUNNED) || me->HasUnitState(UNIT_STATE_DISTRACTED))
        return;

    nextMoveTime.Update(diff);

    if (nextMoveTime.GetExpiry() <= timeDiff)
    {
        if (waypointList.empty())
        {
            RemoveEscortState(ESCORT_STATE_ESCORTING);
            AddEscortState(ESCORT_STATE_NONE);
            return;
        }

        if (HasEscortState(ESCORT_STATE_WAITING))
        {
            RemoveEscortState(ESCORT_STATE_WAITING);
            StartMove();
            return;
        }

        WaypointReached(currentWP->id);

        if (currentWP->waitTimeMs)
        {
            nextMoveTime.Reset(currentWP->waitTimeMs);
            AddEscortState(ESCORT_STATE_WAITING);
            return;
        }

        if (currentWPId == waypointList.size() - 1)
        {
            if (!repeat)
            {
                me->SetHomePosition(currentWP->x, currentWP->y, currentWP->z, me->GetOrientation());
                me->ClearUnitState(UNIT_STATE_ROAMING_MOVE);
                me->GetMotionMaster()->Initialize();
                waypointList.clear();
                FinishEscort();
                RemoveEscortState(ESCORT_STATE_ESCORTING);
                AddEscortState(ESCORT_STATE_NONE);

                if (despawnAtEnd)
                    me->DespawnOrUnsummon();

                return;
            }

            currentWP = waypointList.begin();
            currentWPId = 0;
        }
        else
        {
            ++currentWP;
            ++currentWPId;
        }

        StartMove();
    }
}
예제 #11
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CNPC_VehicleDriver::OverridePathMove( float flInterval )
{
	// Setup our initial path data if we've just started running a path
	if ( !m_pCurrentWaypoint )
	{
		m_vecPrevPoint = GetAbsOrigin();
		m_vecPrevPrevPoint = GetAbsOrigin();
		m_vecDesiredPosition = GetNavigator()->GetCurWaypointPos();	
		CalculatePostPoints();
	
		// Init our two waypoints
		m_Waypoints[0] = new CVehicleWaypoint( m_vecPrevPrevPoint, m_vecPrevPoint, m_vecDesiredPosition, m_vecPostPoint );
		m_Waypoints[1] = new CVehicleWaypoint( m_vecPrevPoint, m_vecDesiredPosition, m_vecPostPoint, m_vecPostPostPoint );
		m_pCurrentWaypoint = m_Waypoints[0];
		m_pNextWaypoint = m_Waypoints[1];

		m_flDistanceAlongSpline = 0.2;
	}

	// Have we reached our target? See if we've passed the current waypoint's plane.
	Vector vecAbsMins, vecAbsMaxs;
	CollisionProp()->WorldSpaceAABB( &vecAbsMins, &vecAbsMaxs );
	if ( BoxOnPlaneSide( vecAbsMins, vecAbsMaxs, &m_pCurrentWaypoint->planeWaypoint ) == 3 )
	{
		if ( WaypointReached() )
			return true;
	}

	// Did we bypass it and reach the next one already?
	if ( m_pNextWaypoint && BoxOnPlaneSide( vecAbsMins, vecAbsMaxs, &m_pNextWaypoint->planeWaypoint ) == 3 )
	{
		if ( WaypointReached() )
			return true;
	}

	// We may have just teleported, so check to make sure we have a waypoint
	if ( !m_pCurrentWaypoint || !m_pNextWaypoint )
		return false;

	// Figure out which spline we're trucking along
	CVehicleWaypoint *pCurrentSplineBeingTraversed = m_pCurrentWaypoint;
	if ( m_flDistanceAlongSpline > 1 )
	{
		pCurrentSplineBeingTraversed = m_pNextWaypoint;
	}

	// Get our current speed, and check it against the length of the spline to know how far to advance our marker
	AngularImpulse angVel;
	Vector vecVelocity;
	IPhysicsObject *pVehiclePhysics = m_hVehicleEntity->VPhysicsGetObject();

	if( !pVehiclePhysics )
	{
		// I think my vehicle has been destroyed.
		return false;
	}

	pVehiclePhysics->GetVelocity( &vecVelocity, &angVel );
	float flSpeed = vecVelocity.Length();
	float flIncTime = gpGlobals->curtime - GetLastThink();
	float flIncrement = flIncTime * (flSpeed / pCurrentSplineBeingTraversed->GetLength());

	// Now advance our point along the spline
	m_flDistanceAlongSpline = clamp( m_flDistanceAlongSpline + flIncrement, 0, 2);
	if ( m_flDistanceAlongSpline > 1 )
	{
		// We crossed the spline boundary
		pCurrentSplineBeingTraversed = m_pNextWaypoint;
	}

	Vector vSplinePoint = pCurrentSplineBeingTraversed->GetPointAt( m_flDistanceAlongSpline > 1 ? m_flDistanceAlongSpline-1 : m_flDistanceAlongSpline );
	Vector vSplineTangent = pCurrentSplineBeingTraversed->GetTangentAt( m_flDistanceAlongSpline > 1 ? m_flDistanceAlongSpline-1 : m_flDistanceAlongSpline );

	// Now that we've got the target spline point & tangent, use it to decide what our desired velocity is.
	// If we're close to the tangent, just use the tangent. Otherwise, Lerp towards it.
	Vector vecToDesired = (vSplinePoint - GetAbsOrigin());
	float flDistToDesired = VectorNormalize( vecToDesired );
	float flTangentLength = VectorNormalize( vSplineTangent );

	if ( flDistToDesired > (flTangentLength * 0.75) )
	{
		m_vecDesiredVelocity = vecToDesired * flTangentLength;
	}
	else
	{
		VectorLerp( vSplineTangent, vecToDesired * flTangentLength, (flDistToDesired / (flTangentLength * 0.5)), m_vecDesiredVelocity );
	}

	// Decrease speed according to the turn we're trying to make
	Vector vecRight;
	m_hVehicleEntity->GetVectors( NULL, &vecRight, NULL );
	Vector vecNormVel = m_vecDesiredVelocity;
	VectorNormalize( vecNormVel );
	float flDotRight = DotProduct( vecRight, vecNormVel );
	flSpeed = (1.0 - fabs(flDotRight));
	// Don't go slower than we've been told to go
	if ( flSpeed < m_flDriversMinSpeed )
	{
		flSpeed = m_flDriversMinSpeed;
	}
	m_vecDesiredVelocity = vecNormVel * (flSpeed * m_flMaxSpeed);

	// Bunch o'debug
	if ( g_debug_vehicledriver.GetInt() & DRIVER_DEBUG_PATH )
	{
		NDebugOverlay::Box( m_vecPrevPrevPoint, -Vector(15,15,15), Vector(15,15,15), 192,0,0, true, 0.1);
		NDebugOverlay::Box( m_vecPrevPoint, -Vector(20,20,20), Vector(20,20,20), 255,0,0, true, 0.1);
		NDebugOverlay::Box( m_vecPostPoint, -Vector(20,20,20), Vector(20,20,20), 0,192,0, true, 0.1);
		NDebugOverlay::Box( m_vecPostPostPoint, -Vector(20,20,20), Vector(20,20,20), 0,128,0, true, 0.1);
		NDebugOverlay::Box( vSplinePoint, -Vector(10,10,10), Vector(10,10,10), 0,0,255, true, 0.1);
		NDebugOverlay::Line( vSplinePoint, vSplinePoint + (vSplineTangent * 40), 0,0,255, true, 0.1);

		//NDebugOverlay::HorzArrow( pCurrentSplineBeingTraversed->splinePoints[0], pCurrentSplineBeingTraversed->splinePoints[1], 30, 255,255,255,0, false, 0.1f );
		//NDebugOverlay::HorzArrow( pCurrentSplineBeingTraversed->splinePoints[1], pCurrentSplineBeingTraversed->splinePoints[2], 20, 255,255,255,0, false, 0.1f );
		//NDebugOverlay::HorzArrow( pCurrentSplineBeingTraversed->splinePoints[2], pCurrentSplineBeingTraversed->splinePoints[3], 10, 255,255,255,0, false, 0.1f );

		// Draw the plane we're checking against for waypoint passing
		Vector vecPlaneRight;
		CrossProduct( m_pCurrentWaypoint->planeWaypoint.normal, Vector(0,0,1), vecPlaneRight );
		Vector vecPlane = m_pCurrentWaypoint->splinePoints[2];
		NDebugOverlay::Line( vecPlane + (vecPlaneRight * -100), vecPlane + (vecPlaneRight * 100), 255,0,0, true, 0.1);

		// Draw the next plane too
		CrossProduct( m_pNextWaypoint->planeWaypoint.normal, Vector(0,0,1), vecPlaneRight );
		vecPlane = m_pNextWaypoint->splinePoints[2];
		NDebugOverlay::Line( vecPlane + (vecPlaneRight * -100), vecPlane + (vecPlaneRight * 100), 192,0,0, true, 0.1);
	}

	if ( g_debug_vehicledriver.GetInt() & DRIVER_DEBUG_PATH_SPLINE )
	{
		for ( int i = 0; i < 10; i++ )
		{
			Vector vecTarget = m_pCurrentWaypoint->GetPointAt( 0.1 * i );
			Vector vecTangent = m_pCurrentWaypoint->GetTangentAt( 0.1 * i );
			VectorNormalize(vecTangent);
			NDebugOverlay::Box( vecTarget, -Vector(10,10,10), Vector(10,10,10), 255,0,0, true, 0.1 );
			NDebugOverlay::Line( vecTarget, vecTarget + (vecTangent * 10), 255,255,0, true, 0.1);
		}
	}

	return true;
}