From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/server/ai_route.cpp | 1366 +++++++++++++++++++-------------------- 1 file changed, 683 insertions(+), 683 deletions(-) (limited to 'mp/src/game/server/ai_route.cpp') diff --git a/mp/src/game/server/ai_route.cpp b/mp/src/game/server/ai_route.cpp index 3a4a147d..91175b78 100644 --- a/mp/src/game/server/ai_route.cpp +++ b/mp/src/game/server/ai_route.cpp @@ -1,683 +1,683 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -//=============================================================================// - -#include "cbase.h" -#include "ai_link.h" -#include "ai_navtype.h" -#include "ai_waypoint.h" -#include "ai_pathfinder.h" -#include "ai_navgoaltype.h" -#include "ai_routedist.h" -#include "ai_route.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -BEGIN_SIMPLE_DATADESC(CAI_Path) - // m_Waypoints (reconsititute on load) - DEFINE_FIELD( m_goalTolerance, FIELD_FLOAT ), - DEFINE_CUSTOM_FIELD( m_activity, ActivityDataOps() ), - DEFINE_FIELD( m_target, FIELD_EHANDLE ), - DEFINE_FIELD( m_sequence, FIELD_INTEGER ), - DEFINE_FIELD( m_vecTargetOffset, FIELD_VECTOR ), - DEFINE_FIELD( m_waypointTolerance, FIELD_FLOAT ), - DEFINE_CUSTOM_FIELD( m_arrivalActivity, ActivityDataOps() ), - DEFINE_FIELD( m_arrivalSequence, FIELD_INTEGER ), - // m_iLastNodeReached - DEFINE_FIELD( m_bGoalPosSet, FIELD_BOOLEAN ), - DEFINE_FIELD( m_goalPos, FIELD_POSITION_VECTOR), - DEFINE_FIELD( m_bGoalTypeSet, FIELD_BOOLEAN ), - DEFINE_FIELD( m_goalType, FIELD_INTEGER ), - DEFINE_FIELD( m_goalFlags, FIELD_INTEGER ), - DEFINE_FIELD( m_routeStartTime, FIELD_TIME ), - DEFINE_FIELD( m_goalDirection, FIELD_VECTOR ), - DEFINE_FIELD( m_goalDirectionTarget, FIELD_EHANDLE ), - DEFINE_FIELD( m_goalSpeed, FIELD_FLOAT ), - DEFINE_FIELD( m_goalSpeedTarget, FIELD_EHANDLE ), - DEFINE_FIELD( m_goalStoppingDistance, FIELD_FLOAT ), -END_DATADESC() - -//----------------------------------------------------------------------------- -AI_Waypoint_t CAI_Path::gm_InvalidWaypoint( Vector(0,0,0), 0, NAV_NONE, 0, 0 ); - -//----------------------------------------------------------------------------- - -void CAI_Path::SetWaypoints(AI_Waypoint_t* route, bool fSetGoalFromLast) -{ - m_Waypoints.Set(route); - - AI_Waypoint_t *pLast = m_Waypoints.GetLast(); - if ( pLast ) - { - pLast->flPathDistGoal = -1; - if ( fSetGoalFromLast ) - { - if ( pLast ) - { - m_bGoalPosSet = false; - pLast->ModifyFlags( bits_WP_TO_GOAL, true ); - SetGoalPosition(pLast->GetPos()); - } - } - } - - AssertRouteValid( m_Waypoints.GetFirst() ); -} - -//----------------------------------------------------------------------------- - -void CAI_Path::PrependWaypoints( AI_Waypoint_t *pWaypoints ) -{ - m_Waypoints.PrependWaypoints( pWaypoints ); - AI_Waypoint_t *pLast = m_Waypoints.GetLast(); - pLast->flPathDistGoal = -1; - - AssertRouteValid( m_Waypoints.GetFirst() ); -} - -//----------------------------------------------------------------------------- - -void CAI_Path::PrependWaypoint( const Vector &newPoint, Navigation_t navType, unsigned waypointFlags ) -{ - m_Waypoints.PrependWaypoint( newPoint, navType, waypointFlags ); - AI_Waypoint_t *pLast = m_Waypoints.GetLast(); - pLast->flPathDistGoal = -1; - - AssertRouteValid( m_Waypoints.GetFirst() ); -} - -//----------------------------------------------------------------------------- - -float CAI_Path::GetPathLength() -{ - AI_Waypoint_t *pLast = m_Waypoints.GetLast(); - if ( pLast && pLast->flPathDistGoal == -1 ) - { - ComputeRouteGoalDistances( pLast ); - } - AI_Waypoint_t *pCurrent = GetCurWaypoint(); - return ( ( pCurrent ) ? pCurrent->flPathDistGoal : 0 ); -} - -//----------------------------------------------------------------------------- - -float CAI_Path::GetPathDistanceToGoal( const Vector &startPos ) -{ - AI_Waypoint_t *pCurrent = GetCurWaypoint(); - if ( pCurrent ) - { - return ( GetPathLength() + ComputePathDistance(pCurrent->NavType(), startPos, pCurrent->GetPos()) ); - } - return 0; -} - -//----------------------------------------------------------------------------- - -Activity CAI_Path::SetMovementActivity(Activity activity) -{ - Assert( activity != ACT_RESET && activity != ACT_INVALID ); - //Msg("Set movement to %s\n", ActivityList_NameForIndex(activity) ); - - m_sequence = ACT_INVALID; - return (m_activity = activity); -} - -//----------------------------------------------------------------------------- - -Activity CAI_Path::GetArrivalActivity( ) const -{ - if ( !m_Waypoints.IsEmpty() ) - { - return m_arrivalActivity; - } - return ACT_INVALID; -} - -//----------------------------------------------------------------------------- - -void CAI_Path::SetArrivalActivity(Activity activity) -{ - m_arrivalActivity = activity; - m_arrivalSequence = ACT_INVALID; -} - -//----------------------------------------------------------------------------- - -int CAI_Path::GetArrivalSequence( ) const -{ - if ( !m_Waypoints.IsEmpty() ) - { - return m_arrivalSequence; - } - return ACT_INVALID; -} - -//----------------------------------------------------------------------------- - -void CAI_Path::SetArrivalSequence( int sequence ) -{ - m_arrivalSequence = sequence; -} - - -//----------------------------------------------------------------------------- - -void CAI_Path::SetGoalDirection( const Vector &goalDirection ) -{ - m_goalDirectionTarget = NULL; - m_goalDirection = goalDirection; - VectorNormalize( m_goalDirection ); - /* - AI_Waypoint_t *pLast = m_Waypoints.GetLast(); - if ( pLast ) - { - NDebugOverlay::Box( pLast->vecLocation, Vector( -2, -2, -2 ), Vector( 2, 2, 2 ), 0,0,255, 0, 2.0 ); - NDebugOverlay::Line( pLast->vecLocation, pLast->vecLocation + m_goalDirection * 32, 0,0,255, true, 2.0 ); - } - */ -} - - -//----------------------------------------------------------------------------- - -void CAI_Path::SetGoalDirection( CBaseEntity *pTarget ) -{ - m_goalDirectionTarget = pTarget; - - if (pTarget) - { - AI_Waypoint_t *pLast = m_Waypoints.GetLast(); - if ( pLast ) - { - m_goalDirection = pTarget->GetAbsOrigin() - pLast->vecLocation; - VectorNormalize( m_goalDirection ); - /* - NDebugOverlay::Box( pLast->vecLocation, Vector( -2, -2, -2 ), Vector( 2, 2, 2 ), 0,0,255, 0, 2.0 ); - NDebugOverlay::Line( pLast->vecLocation, pLast->vecLocation + m_goalDirection * 32, 0,0,255, true, 2.0 ); - */ - } - } -} - -//----------------------------------------------------------------------------- - -Vector CAI_Path::GetGoalDirection( const Vector &startPos ) -{ - if (m_goalDirectionTarget) - { - AI_Waypoint_t *pLast = m_Waypoints.GetLast(); - if ( pLast ) - { - AI_Waypoint_t *pPrev = pLast->GetPrev(); - if (pPrev) - { - Vector goalDirection = m_goalDirectionTarget->GetAbsOrigin() - pPrev->vecLocation; - VectorNormalize( goalDirection ); - return goalDirection; - } - else - { - Vector goalDirection = m_goalDirectionTarget->GetAbsOrigin() - startPos; - VectorNormalize( goalDirection ); - return goalDirection; - } - } - } - else if (m_goalDirection == vec3_origin) - { - // Assert(0); // comment out the default directions in SetGoal() to find test cases for missing initialization - AI_Waypoint_t *pLast = m_Waypoints.GetLast(); - if ( pLast ) - { - AI_Waypoint_t *pPrev = pLast->GetPrev(); - if (pPrev) - { - Vector goalDirection = pLast->vecLocation - pPrev->vecLocation; - VectorNormalize( goalDirection ); - return goalDirection; - } - else - { - Vector goalDirection =pLast->vecLocation - startPos; - VectorNormalize( goalDirection ); - return goalDirection; - } - } - } - - return m_goalDirection; -} - -//----------------------------------------------------------------------------- - -void CAI_Path::SetGoalSpeed( float flSpeed ) -{ - m_goalSpeed = flSpeed; -} - - -//----------------------------------------------------------------------------- - -void CAI_Path::SetGoalSpeed( CBaseEntity *pTarget ) -{ - m_goalSpeedTarget = pTarget; -} - -//----------------------------------------------------------------------------- - -float CAI_Path::GetGoalSpeed( const Vector &startPos ) -{ - if (m_goalSpeedTarget) - { - Vector goalDirection = GetGoalDirection( startPos ); - Vector targetVelocity = m_goalSpeedTarget->GetSmoothedVelocity(); - float dot = DotProduct( goalDirection, targetVelocity ); - dot = MAX( 0.0f, dot ); - // return a relative impact speed of m_goalSpeed - if (m_goalSpeed > 0.0) - { - return dot + m_goalSpeed; - } - return dot; - } - return m_goalSpeed; -} - - - -//----------------------------------------------------------------------------- - -void CAI_Path::SetGoalStoppingDistance( float flDistance ) -{ - m_goalStoppingDistance = flDistance; -} - -//----------------------------------------------------------------------------- - -float CAI_Path::GetGoalStoppingDistance( ) const -{ - return m_goalStoppingDistance; -} - - -//----------------------------------------------------------------------------- -const Vector &CAI_Path::CurWaypointPos() const -{ - if ( GetCurWaypoint() ) - return GetCurWaypoint()->GetPos(); - AssertMsg(0, "Invalid call to CurWaypointPos()"); - return gm_InvalidWaypoint.GetPos(); -} - -//----------------------------------------------------------------------------- -const Vector &CAI_Path::NextWaypointPos() const -{ - if ( GetCurWaypoint() && GetCurWaypoint()->GetNext()) - return GetCurWaypoint()->GetNext()->GetPos(); - static Vector invalid( 0, 0, 0 ); - AssertMsg(0, "Invalid call to NextWaypointPos()"); - return gm_InvalidWaypoint.GetPos(); -} - -//----------------------------------------------------------------------------- -float CAI_Path::CurWaypointYaw() const -{ - return GetCurWaypoint()->flYaw; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : -// Output : -//----------------------------------------------------------------------------- -void CAI_Path::SetGoalPosition(const Vector &goalPos) -{ - -#ifdef _DEBUG - // Make sure goal position isn't set more than once - if (m_bGoalPosSet == true) - { - DevMsg( "GetCurWaypoint Goal Position Set Twice!\n"); - } -#endif - - m_bGoalPosSet = true; - VectorAdd( goalPos, m_vecTargetOffset, m_goalPos ); -} - -//----------------------------------------------------------------------------- -// Purpose: Sets last node as goal and goal position -// Input : -// Output : -//----------------------------------------------------------------------------- -void CAI_Path::SetLastNodeAsGoal(bool bReset) -{ - #ifdef _DEBUG - // Make sure goal position isn't set more than once - if (!bReset && m_bGoalPosSet == true) - { - DevMsg( "GetCurWaypoint Goal Position Set Twice!\n"); - } - #endif - - // Find the last node - if (GetCurWaypoint()) - { - AI_Waypoint_t* waypoint = GetCurWaypoint(); - - while (waypoint) - { - if (!waypoint->GetNext()) - { - m_goalPos = waypoint->GetPos(); - m_bGoalPosSet = true; - waypoint->ModifyFlags( bits_WP_TO_GOAL, true ); - return; - } - waypoint = waypoint->GetNext(); - } - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Explicitly change the goal position w/o check -// Input : -// Output : -//----------------------------------------------------------------------------- -void CAI_Path::ResetGoalPosition(const Vector &goalPos) -{ - m_bGoalPosSet = true; - VectorAdd( goalPos, m_vecTargetOffset, m_goalPos ); -} - - -//----------------------------------------------------------------------------- -// Returns the *base* goal position (without the offset applied) -//----------------------------------------------------------------------------- -const Vector& CAI_Path::BaseGoalPosition() const -{ -#ifdef _DEBUG - // Make sure goal position was set - if (m_bGoalPosSet == false) - { - DevMsg( "GetCurWaypoint Goal Position Never Set!\n"); - } -#endif - - // FIXME: A little risky; store the base if this becomes a problem - static Vector vecResult; - VectorSubtract( m_goalPos, m_vecTargetOffset, vecResult ); - return vecResult; -} - - -//----------------------------------------------------------------------------- - // Returns the *actual* goal position (with the offset applied) -//----------------------------------------------------------------------------- -const Vector & CAI_Path::ActualGoalPosition(void) const -{ -#ifdef _DEBUG - // Make sure goal position was set - if (m_bGoalPosSet == false) - { - DevMsg( "GetCurWaypoint Goal Position Never Set!\n"); - } -#endif - - return m_goalPos; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : -// Output : -//----------------------------------------------------------------------------- -void CAI_Path::SetGoalType(GoalType_t goalType) -{ - -#ifdef _DEBUG - // Make sure goal position isn't set more than once - if (m_goalType != GOALTYPE_NONE && goalType != GOALTYPE_NONE ) - { - DevMsg( "GetCurWaypoint Goal Type Set Twice!\n"); - } -#endif - - if (m_goalType != GOALTYPE_NONE) - { - m_routeStartTime = gpGlobals->curtime; - m_bGoalTypeSet = true; - } - else - m_bGoalTypeSet = false; - - m_goalType = goalType; - -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : -// Output : -//----------------------------------------------------------------------------- -GoalType_t CAI_Path::GoalType(void) const -{ - return m_goalType; -} - - -//----------------------------------------------------------------------------- - -void CAI_Path::Advance( void ) -{ - if ( CurWaypointIsGoal() ) - return; - - // ------------------------------------------------------- - // If I have another waypoint advance my path - // ------------------------------------------------------- - if (GetCurWaypoint()->GetNext()) - { - AI_Waypoint_t *pNext = GetCurWaypoint()->GetNext(); - - // If waypoint was a node take note of it - if (GetCurWaypoint()->Flags() & bits_WP_TO_NODE) - { - m_iLastNodeReached = GetCurWaypoint()->iNodeID; - } - - delete GetCurWaypoint(); - SetWaypoints(pNext); - - return; - } - // ------------------------------------------------- - // This is an error catch that should *not* happen - // It means a route was created with no goal - // ------------------------------------------------- - else - { - DevMsg( "!!ERROR!! Force end of route with no goal!\n"); - GetCurWaypoint()->ModifyFlags( bits_WP_TO_GOAL, true ); - } - - AssertRouteValid( m_Waypoints.GetFirst() ); -} - - - -//----------------------------------------------------------------------------- -// Purpose: Clears the route and resets all its fields to default values -// Input : -// Output : -//----------------------------------------------------------------------------- -void CAI_Path::Clear( void ) -{ - m_Waypoints.RemoveAll(); - - m_goalType = GOALTYPE_NONE; // Type of goal - m_goalPos = vec3_origin; // Our ultimate goal position - m_bGoalPosSet = false; // Was goal position set - m_bGoalTypeSet = false; // Was goal position set - m_goalFlags = false; - m_vecTargetOffset = vec3_origin; - m_routeStartTime = FLT_MAX; - - m_goalTolerance = 0.0; // How close do we need to get to the goal - // FIXME: split m_goalTolerance into m_buildTolerance and m_moveTolerance, let them be seperatly controllable. - - m_activity = ACT_INVALID; - m_sequence = ACT_INVALID; - m_target = NULL; - - m_arrivalActivity = ACT_INVALID; - m_arrivalSequence = ACT_INVALID; - - m_goalDirectionTarget = NULL; - m_goalDirection = vec3_origin; - - m_goalSpeedTarget = NULL; - m_goalSpeed = -1.0f; // init to an invalid speed - - m_goalStoppingDistance = 0.0; // How close to we want to get to the goal -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : -// Output : -//----------------------------------------------------------------------------- -Navigation_t CAI_Path::CurWaypointNavType() const -{ - if (!GetCurWaypoint()) - { - return NAV_NONE; - } - else - { - return GetCurWaypoint()->NavType(); - } -} - -int CAI_Path::CurWaypointFlags() const -{ - if (!GetCurWaypoint()) - { - return 0; - } - else - { - return GetCurWaypoint()->Flags(); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Get the goal's flags -// Output : unsigned -//----------------------------------------------------------------------------- -unsigned CAI_Path::GoalFlags( void ) const -{ - return m_goalFlags; -} - -//----------------------------------------------------------------------------- -// Purpose: Returns true if current waypoint is my goal -// Input : -// Output : -//----------------------------------------------------------------------------- -bool CAI_Path::CurWaypointIsGoal( void ) const -{ -// Assert( GetCurWaypoint() ); - - if( !GetCurWaypoint() ) - return false; - - - if ( GetCurWaypoint()->Flags() & bits_WP_TO_GOAL ) - { - #ifdef _DEBUG - if (GetCurWaypoint()->GetNext()) - { - DevMsg( "!!ERROR!! Goal is not last waypoint!\n"); - } - if ((GetCurWaypoint()->GetPos() - m_goalPos).Length() > 0.1) - { - DevMsg( "!!ERROR!! Last waypoint isn't in goal position!\n"); - } - #endif - return true; - } - if ( GetCurWaypoint()->Flags() & bits_WP_TO_PATHCORNER ) - { - // UNDONE: Refresh here or somewhere else? - } -#ifdef _DEBUG - if (!GetCurWaypoint()->GetNext()) - { - DevMsg( "!!ERROR!! GetCurWaypoint has no goal!\n"); - } -#endif - - return false; -} - - -//----------------------------------------------------------------------------- -// Computes the goal distance for each waypoint along the route -//----------------------------------------------------------------------------- -void CAI_Path::ComputeRouteGoalDistances(AI_Waypoint_t *pGoalWaypoint) -{ - // The goal distance is the distance from any waypoint to the goal waypoint - - // Backup through the list and calculate distance to goal - AI_Waypoint_t *pPrev; - AI_Waypoint_t *pCurWaypoint = pGoalWaypoint; - pCurWaypoint->flPathDistGoal = 0; - while (pCurWaypoint->GetPrev()) - { - pPrev = pCurWaypoint->GetPrev(); - - float flWaypointDist = ComputePathDistance(pCurWaypoint->NavType(), pPrev->GetPos(), pCurWaypoint->GetPos()); - pPrev->flPathDistGoal = pCurWaypoint->flPathDistGoal + flWaypointDist; - - pCurWaypoint = pPrev; - } -} - - - -//----------------------------------------------------------------------------- -// Purpose: Constructor -// Input : -// Output : -//----------------------------------------------------------------------------- -CAI_Path::CAI_Path() -{ - m_goalType = GOALTYPE_NONE; // Type of goal - m_goalPos = vec3_origin; // Our ultimate goal position - m_goalTolerance = 0.0; // How close do we need to get to the goal - m_activity = ACT_INVALID; // The activity to use during motion - m_sequence = ACT_INVALID; - m_target = NULL; - m_goalFlags = 0; - m_routeStartTime = FLT_MAX; - m_arrivalActivity = ACT_INVALID; - m_arrivalSequence = ACT_INVALID; - - m_iLastNodeReached = NO_NODE; - - m_waypointTolerance = DEF_WAYPOINT_TOLERANCE; - -} - -CAI_Path::~CAI_Path() -{ - DeleteAll( GetCurWaypoint() ); -} - - +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "ai_link.h" +#include "ai_navtype.h" +#include "ai_waypoint.h" +#include "ai_pathfinder.h" +#include "ai_navgoaltype.h" +#include "ai_routedist.h" +#include "ai_route.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +BEGIN_SIMPLE_DATADESC(CAI_Path) + // m_Waypoints (reconsititute on load) + DEFINE_FIELD( m_goalTolerance, FIELD_FLOAT ), + DEFINE_CUSTOM_FIELD( m_activity, ActivityDataOps() ), + DEFINE_FIELD( m_target, FIELD_EHANDLE ), + DEFINE_FIELD( m_sequence, FIELD_INTEGER ), + DEFINE_FIELD( m_vecTargetOffset, FIELD_VECTOR ), + DEFINE_FIELD( m_waypointTolerance, FIELD_FLOAT ), + DEFINE_CUSTOM_FIELD( m_arrivalActivity, ActivityDataOps() ), + DEFINE_FIELD( m_arrivalSequence, FIELD_INTEGER ), + // m_iLastNodeReached + DEFINE_FIELD( m_bGoalPosSet, FIELD_BOOLEAN ), + DEFINE_FIELD( m_goalPos, FIELD_POSITION_VECTOR), + DEFINE_FIELD( m_bGoalTypeSet, FIELD_BOOLEAN ), + DEFINE_FIELD( m_goalType, FIELD_INTEGER ), + DEFINE_FIELD( m_goalFlags, FIELD_INTEGER ), + DEFINE_FIELD( m_routeStartTime, FIELD_TIME ), + DEFINE_FIELD( m_goalDirection, FIELD_VECTOR ), + DEFINE_FIELD( m_goalDirectionTarget, FIELD_EHANDLE ), + DEFINE_FIELD( m_goalSpeed, FIELD_FLOAT ), + DEFINE_FIELD( m_goalSpeedTarget, FIELD_EHANDLE ), + DEFINE_FIELD( m_goalStoppingDistance, FIELD_FLOAT ), +END_DATADESC() + +//----------------------------------------------------------------------------- +AI_Waypoint_t CAI_Path::gm_InvalidWaypoint( Vector(0,0,0), 0, NAV_NONE, 0, 0 ); + +//----------------------------------------------------------------------------- + +void CAI_Path::SetWaypoints(AI_Waypoint_t* route, bool fSetGoalFromLast) +{ + m_Waypoints.Set(route); + + AI_Waypoint_t *pLast = m_Waypoints.GetLast(); + if ( pLast ) + { + pLast->flPathDistGoal = -1; + if ( fSetGoalFromLast ) + { + if ( pLast ) + { + m_bGoalPosSet = false; + pLast->ModifyFlags( bits_WP_TO_GOAL, true ); + SetGoalPosition(pLast->GetPos()); + } + } + } + + AssertRouteValid( m_Waypoints.GetFirst() ); +} + +//----------------------------------------------------------------------------- + +void CAI_Path::PrependWaypoints( AI_Waypoint_t *pWaypoints ) +{ + m_Waypoints.PrependWaypoints( pWaypoints ); + AI_Waypoint_t *pLast = m_Waypoints.GetLast(); + pLast->flPathDistGoal = -1; + + AssertRouteValid( m_Waypoints.GetFirst() ); +} + +//----------------------------------------------------------------------------- + +void CAI_Path::PrependWaypoint( const Vector &newPoint, Navigation_t navType, unsigned waypointFlags ) +{ + m_Waypoints.PrependWaypoint( newPoint, navType, waypointFlags ); + AI_Waypoint_t *pLast = m_Waypoints.GetLast(); + pLast->flPathDistGoal = -1; + + AssertRouteValid( m_Waypoints.GetFirst() ); +} + +//----------------------------------------------------------------------------- + +float CAI_Path::GetPathLength() +{ + AI_Waypoint_t *pLast = m_Waypoints.GetLast(); + if ( pLast && pLast->flPathDistGoal == -1 ) + { + ComputeRouteGoalDistances( pLast ); + } + AI_Waypoint_t *pCurrent = GetCurWaypoint(); + return ( ( pCurrent ) ? pCurrent->flPathDistGoal : 0 ); +} + +//----------------------------------------------------------------------------- + +float CAI_Path::GetPathDistanceToGoal( const Vector &startPos ) +{ + AI_Waypoint_t *pCurrent = GetCurWaypoint(); + if ( pCurrent ) + { + return ( GetPathLength() + ComputePathDistance(pCurrent->NavType(), startPos, pCurrent->GetPos()) ); + } + return 0; +} + +//----------------------------------------------------------------------------- + +Activity CAI_Path::SetMovementActivity(Activity activity) +{ + Assert( activity != ACT_RESET && activity != ACT_INVALID ); + //Msg("Set movement to %s\n", ActivityList_NameForIndex(activity) ); + + m_sequence = ACT_INVALID; + return (m_activity = activity); +} + +//----------------------------------------------------------------------------- + +Activity CAI_Path::GetArrivalActivity( ) const +{ + if ( !m_Waypoints.IsEmpty() ) + { + return m_arrivalActivity; + } + return ACT_INVALID; +} + +//----------------------------------------------------------------------------- + +void CAI_Path::SetArrivalActivity(Activity activity) +{ + m_arrivalActivity = activity; + m_arrivalSequence = ACT_INVALID; +} + +//----------------------------------------------------------------------------- + +int CAI_Path::GetArrivalSequence( ) const +{ + if ( !m_Waypoints.IsEmpty() ) + { + return m_arrivalSequence; + } + return ACT_INVALID; +} + +//----------------------------------------------------------------------------- + +void CAI_Path::SetArrivalSequence( int sequence ) +{ + m_arrivalSequence = sequence; +} + + +//----------------------------------------------------------------------------- + +void CAI_Path::SetGoalDirection( const Vector &goalDirection ) +{ + m_goalDirectionTarget = NULL; + m_goalDirection = goalDirection; + VectorNormalize( m_goalDirection ); + /* + AI_Waypoint_t *pLast = m_Waypoints.GetLast(); + if ( pLast ) + { + NDebugOverlay::Box( pLast->vecLocation, Vector( -2, -2, -2 ), Vector( 2, 2, 2 ), 0,0,255, 0, 2.0 ); + NDebugOverlay::Line( pLast->vecLocation, pLast->vecLocation + m_goalDirection * 32, 0,0,255, true, 2.0 ); + } + */ +} + + +//----------------------------------------------------------------------------- + +void CAI_Path::SetGoalDirection( CBaseEntity *pTarget ) +{ + m_goalDirectionTarget = pTarget; + + if (pTarget) + { + AI_Waypoint_t *pLast = m_Waypoints.GetLast(); + if ( pLast ) + { + m_goalDirection = pTarget->GetAbsOrigin() - pLast->vecLocation; + VectorNormalize( m_goalDirection ); + /* + NDebugOverlay::Box( pLast->vecLocation, Vector( -2, -2, -2 ), Vector( 2, 2, 2 ), 0,0,255, 0, 2.0 ); + NDebugOverlay::Line( pLast->vecLocation, pLast->vecLocation + m_goalDirection * 32, 0,0,255, true, 2.0 ); + */ + } + } +} + +//----------------------------------------------------------------------------- + +Vector CAI_Path::GetGoalDirection( const Vector &startPos ) +{ + if (m_goalDirectionTarget) + { + AI_Waypoint_t *pLast = m_Waypoints.GetLast(); + if ( pLast ) + { + AI_Waypoint_t *pPrev = pLast->GetPrev(); + if (pPrev) + { + Vector goalDirection = m_goalDirectionTarget->GetAbsOrigin() - pPrev->vecLocation; + VectorNormalize( goalDirection ); + return goalDirection; + } + else + { + Vector goalDirection = m_goalDirectionTarget->GetAbsOrigin() - startPos; + VectorNormalize( goalDirection ); + return goalDirection; + } + } + } + else if (m_goalDirection == vec3_origin) + { + // Assert(0); // comment out the default directions in SetGoal() to find test cases for missing initialization + AI_Waypoint_t *pLast = m_Waypoints.GetLast(); + if ( pLast ) + { + AI_Waypoint_t *pPrev = pLast->GetPrev(); + if (pPrev) + { + Vector goalDirection = pLast->vecLocation - pPrev->vecLocation; + VectorNormalize( goalDirection ); + return goalDirection; + } + else + { + Vector goalDirection =pLast->vecLocation - startPos; + VectorNormalize( goalDirection ); + return goalDirection; + } + } + } + + return m_goalDirection; +} + +//----------------------------------------------------------------------------- + +void CAI_Path::SetGoalSpeed( float flSpeed ) +{ + m_goalSpeed = flSpeed; +} + + +//----------------------------------------------------------------------------- + +void CAI_Path::SetGoalSpeed( CBaseEntity *pTarget ) +{ + m_goalSpeedTarget = pTarget; +} + +//----------------------------------------------------------------------------- + +float CAI_Path::GetGoalSpeed( const Vector &startPos ) +{ + if (m_goalSpeedTarget) + { + Vector goalDirection = GetGoalDirection( startPos ); + Vector targetVelocity = m_goalSpeedTarget->GetSmoothedVelocity(); + float dot = DotProduct( goalDirection, targetVelocity ); + dot = MAX( 0.0f, dot ); + // return a relative impact speed of m_goalSpeed + if (m_goalSpeed > 0.0) + { + return dot + m_goalSpeed; + } + return dot; + } + return m_goalSpeed; +} + + + +//----------------------------------------------------------------------------- + +void CAI_Path::SetGoalStoppingDistance( float flDistance ) +{ + m_goalStoppingDistance = flDistance; +} + +//----------------------------------------------------------------------------- + +float CAI_Path::GetGoalStoppingDistance( ) const +{ + return m_goalStoppingDistance; +} + + +//----------------------------------------------------------------------------- +const Vector &CAI_Path::CurWaypointPos() const +{ + if ( GetCurWaypoint() ) + return GetCurWaypoint()->GetPos(); + AssertMsg(0, "Invalid call to CurWaypointPos()"); + return gm_InvalidWaypoint.GetPos(); +} + +//----------------------------------------------------------------------------- +const Vector &CAI_Path::NextWaypointPos() const +{ + if ( GetCurWaypoint() && GetCurWaypoint()->GetNext()) + return GetCurWaypoint()->GetNext()->GetPos(); + static Vector invalid( 0, 0, 0 ); + AssertMsg(0, "Invalid call to NextWaypointPos()"); + return gm_InvalidWaypoint.GetPos(); +} + +//----------------------------------------------------------------------------- +float CAI_Path::CurWaypointYaw() const +{ + return GetCurWaypoint()->flYaw; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CAI_Path::SetGoalPosition(const Vector &goalPos) +{ + +#ifdef _DEBUG + // Make sure goal position isn't set more than once + if (m_bGoalPosSet == true) + { + DevMsg( "GetCurWaypoint Goal Position Set Twice!\n"); + } +#endif + + m_bGoalPosSet = true; + VectorAdd( goalPos, m_vecTargetOffset, m_goalPos ); +} + +//----------------------------------------------------------------------------- +// Purpose: Sets last node as goal and goal position +// Input : +// Output : +//----------------------------------------------------------------------------- +void CAI_Path::SetLastNodeAsGoal(bool bReset) +{ + #ifdef _DEBUG + // Make sure goal position isn't set more than once + if (!bReset && m_bGoalPosSet == true) + { + DevMsg( "GetCurWaypoint Goal Position Set Twice!\n"); + } + #endif + + // Find the last node + if (GetCurWaypoint()) + { + AI_Waypoint_t* waypoint = GetCurWaypoint(); + + while (waypoint) + { + if (!waypoint->GetNext()) + { + m_goalPos = waypoint->GetPos(); + m_bGoalPosSet = true; + waypoint->ModifyFlags( bits_WP_TO_GOAL, true ); + return; + } + waypoint = waypoint->GetNext(); + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Explicitly change the goal position w/o check +// Input : +// Output : +//----------------------------------------------------------------------------- +void CAI_Path::ResetGoalPosition(const Vector &goalPos) +{ + m_bGoalPosSet = true; + VectorAdd( goalPos, m_vecTargetOffset, m_goalPos ); +} + + +//----------------------------------------------------------------------------- +// Returns the *base* goal position (without the offset applied) +//----------------------------------------------------------------------------- +const Vector& CAI_Path::BaseGoalPosition() const +{ +#ifdef _DEBUG + // Make sure goal position was set + if (m_bGoalPosSet == false) + { + DevMsg( "GetCurWaypoint Goal Position Never Set!\n"); + } +#endif + + // FIXME: A little risky; store the base if this becomes a problem + static Vector vecResult; + VectorSubtract( m_goalPos, m_vecTargetOffset, vecResult ); + return vecResult; +} + + +//----------------------------------------------------------------------------- + // Returns the *actual* goal position (with the offset applied) +//----------------------------------------------------------------------------- +const Vector & CAI_Path::ActualGoalPosition(void) const +{ +#ifdef _DEBUG + // Make sure goal position was set + if (m_bGoalPosSet == false) + { + DevMsg( "GetCurWaypoint Goal Position Never Set!\n"); + } +#endif + + return m_goalPos; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CAI_Path::SetGoalType(GoalType_t goalType) +{ + +#ifdef _DEBUG + // Make sure goal position isn't set more than once + if (m_goalType != GOALTYPE_NONE && goalType != GOALTYPE_NONE ) + { + DevMsg( "GetCurWaypoint Goal Type Set Twice!\n"); + } +#endif + + if (m_goalType != GOALTYPE_NONE) + { + m_routeStartTime = gpGlobals->curtime; + m_bGoalTypeSet = true; + } + else + m_bGoalTypeSet = false; + + m_goalType = goalType; + +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +GoalType_t CAI_Path::GoalType(void) const +{ + return m_goalType; +} + + +//----------------------------------------------------------------------------- + +void CAI_Path::Advance( void ) +{ + if ( CurWaypointIsGoal() ) + return; + + // ------------------------------------------------------- + // If I have another waypoint advance my path + // ------------------------------------------------------- + if (GetCurWaypoint()->GetNext()) + { + AI_Waypoint_t *pNext = GetCurWaypoint()->GetNext(); + + // If waypoint was a node take note of it + if (GetCurWaypoint()->Flags() & bits_WP_TO_NODE) + { + m_iLastNodeReached = GetCurWaypoint()->iNodeID; + } + + delete GetCurWaypoint(); + SetWaypoints(pNext); + + return; + } + // ------------------------------------------------- + // This is an error catch that should *not* happen + // It means a route was created with no goal + // ------------------------------------------------- + else + { + DevMsg( "!!ERROR!! Force end of route with no goal!\n"); + GetCurWaypoint()->ModifyFlags( bits_WP_TO_GOAL, true ); + } + + AssertRouteValid( m_Waypoints.GetFirst() ); +} + + + +//----------------------------------------------------------------------------- +// Purpose: Clears the route and resets all its fields to default values +// Input : +// Output : +//----------------------------------------------------------------------------- +void CAI_Path::Clear( void ) +{ + m_Waypoints.RemoveAll(); + + m_goalType = GOALTYPE_NONE; // Type of goal + m_goalPos = vec3_origin; // Our ultimate goal position + m_bGoalPosSet = false; // Was goal position set + m_bGoalTypeSet = false; // Was goal position set + m_goalFlags = false; + m_vecTargetOffset = vec3_origin; + m_routeStartTime = FLT_MAX; + + m_goalTolerance = 0.0; // How close do we need to get to the goal + // FIXME: split m_goalTolerance into m_buildTolerance and m_moveTolerance, let them be seperatly controllable. + + m_activity = ACT_INVALID; + m_sequence = ACT_INVALID; + m_target = NULL; + + m_arrivalActivity = ACT_INVALID; + m_arrivalSequence = ACT_INVALID; + + m_goalDirectionTarget = NULL; + m_goalDirection = vec3_origin; + + m_goalSpeedTarget = NULL; + m_goalSpeed = -1.0f; // init to an invalid speed + + m_goalStoppingDistance = 0.0; // How close to we want to get to the goal +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +Navigation_t CAI_Path::CurWaypointNavType() const +{ + if (!GetCurWaypoint()) + { + return NAV_NONE; + } + else + { + return GetCurWaypoint()->NavType(); + } +} + +int CAI_Path::CurWaypointFlags() const +{ + if (!GetCurWaypoint()) + { + return 0; + } + else + { + return GetCurWaypoint()->Flags(); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Get the goal's flags +// Output : unsigned +//----------------------------------------------------------------------------- +unsigned CAI_Path::GoalFlags( void ) const +{ + return m_goalFlags; +} + +//----------------------------------------------------------------------------- +// Purpose: Returns true if current waypoint is my goal +// Input : +// Output : +//----------------------------------------------------------------------------- +bool CAI_Path::CurWaypointIsGoal( void ) const +{ +// Assert( GetCurWaypoint() ); + + if( !GetCurWaypoint() ) + return false; + + + if ( GetCurWaypoint()->Flags() & bits_WP_TO_GOAL ) + { + #ifdef _DEBUG + if (GetCurWaypoint()->GetNext()) + { + DevMsg( "!!ERROR!! Goal is not last waypoint!\n"); + } + if ((GetCurWaypoint()->GetPos() - m_goalPos).Length() > 0.1) + { + DevMsg( "!!ERROR!! Last waypoint isn't in goal position!\n"); + } + #endif + return true; + } + if ( GetCurWaypoint()->Flags() & bits_WP_TO_PATHCORNER ) + { + // UNDONE: Refresh here or somewhere else? + } +#ifdef _DEBUG + if (!GetCurWaypoint()->GetNext()) + { + DevMsg( "!!ERROR!! GetCurWaypoint has no goal!\n"); + } +#endif + + return false; +} + + +//----------------------------------------------------------------------------- +// Computes the goal distance for each waypoint along the route +//----------------------------------------------------------------------------- +void CAI_Path::ComputeRouteGoalDistances(AI_Waypoint_t *pGoalWaypoint) +{ + // The goal distance is the distance from any waypoint to the goal waypoint + + // Backup through the list and calculate distance to goal + AI_Waypoint_t *pPrev; + AI_Waypoint_t *pCurWaypoint = pGoalWaypoint; + pCurWaypoint->flPathDistGoal = 0; + while (pCurWaypoint->GetPrev()) + { + pPrev = pCurWaypoint->GetPrev(); + + float flWaypointDist = ComputePathDistance(pCurWaypoint->NavType(), pPrev->GetPos(), pCurWaypoint->GetPos()); + pPrev->flPathDistGoal = pCurWaypoint->flPathDistGoal + flWaypointDist; + + pCurWaypoint = pPrev; + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: Constructor +// Input : +// Output : +//----------------------------------------------------------------------------- +CAI_Path::CAI_Path() +{ + m_goalType = GOALTYPE_NONE; // Type of goal + m_goalPos = vec3_origin; // Our ultimate goal position + m_goalTolerance = 0.0; // How close do we need to get to the goal + m_activity = ACT_INVALID; // The activity to use during motion + m_sequence = ACT_INVALID; + m_target = NULL; + m_goalFlags = 0; + m_routeStartTime = FLT_MAX; + m_arrivalActivity = ACT_INVALID; + m_arrivalSequence = ACT_INVALID; + + m_iLastNodeReached = NO_NODE; + + m_waypointTolerance = DEF_WAYPOINT_TOLERANCE; + +} + +CAI_Path::~CAI_Path() +{ + DeleteAll( GetCurWaypoint() ); +} + + -- cgit v1.2.3