diff --git a/code/fgame/navigate.cpp b/code/fgame/navigate.cpp index bb80da6b..a7fa6393 100644 --- a/code/fgame/navigate.cpp +++ b/code/fgame/navigate.cpp @@ -1,6 +1,6 @@ /* =========================================================================== -Copyright (C) 2015 the OpenMoHAA team +Copyright (C) 2023 the OpenMoHAA team This file is part of OpenMoHAA source code. @@ -34,240 +34,213 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define PATHFILE_VERSION 103 -int path_checkthisframe; -cvar_t *ai_showroutes; -cvar_t *ai_showroutes_distance; -cvar_t *ai_shownodenums; -cvar_t *ai_shownode; -cvar_t *ai_showallnode; -cvar_t *ai_showpath; -cvar_t *ai_fallheight; -cvar_t *ai_debugpath; -cvar_t *ai_pathchecktime; -cvar_t *ai_pathcheckdist; +int path_checkthisframe; +cvar_t *ai_showroutes; +cvar_t *ai_showroutes_distance; +cvar_t *ai_shownodenums; +cvar_t *ai_shownode; +cvar_t *ai_showallnode; +cvar_t *ai_showpath; +cvar_t *ai_fallheight; +cvar_t *ai_debugpath; +cvar_t *ai_pathchecktime; +cvar_t *ai_pathcheckdist; -static float *path_start; -static float *path_end; +static float *path_start; +static float *path_end; static PathNode *Node; -static float path_totaldir[ 2 ]; -static float path_p[ 3 ]; -static float path_startdir[ 2 ]; +static float path_totaldir[2]; +static float path_p[3]; +static float path_startdir[2]; -static Entity *IgnoreObjects[ MAX_GENTITIES ]; -static int NumIgnoreObjects; +static Entity *IgnoreObjects[MAX_GENTITIES]; +static int NumIgnoreObjects; static qboolean pathnodesinitialized = false; -static qboolean loadingarchive = false; -static qboolean pathnodescalculated = false; -int ai_maxnode; +static qboolean loadingarchive = false; +static qboolean pathnodescalculated = false; +int ai_maxnode; -MapCell PathSearch::PathMap[ PATHMAP_GRIDSIZE ][ PATHMAP_GRIDSIZE ]; +MapCell PathSearch::PathMap[PATHMAP_GRIDSIZE][PATHMAP_GRIDSIZE]; PathNode *PathSearch::open; -int PathSearch::findFrame; -qboolean PathSearch::m_bNodesloaded; -qboolean PathSearch::m_NodeCheckFailed; -int PathSearch::m_LoadIndex; +int PathSearch::findFrame; +qboolean PathSearch::m_bNodesloaded; +qboolean PathSearch::m_NodeCheckFailed; +int PathSearch::m_LoadIndex; -PathNode *PathSearch::pathnodes[ MAX_PATHNODES ]; -int PathSearch::nodecount; -float PathSearch::total_dist; +PathNode *PathSearch::pathnodes[MAX_PATHNODES]; +int PathSearch::nodecount; +float PathSearch::total_dist; const char *PathSearch::last_error; -byte *bulkNavMemory = NULL; +byte *bulkNavMemory = NULL; byte *startBulkNavMemory = NULL; -Vector PLAYER_BASE_MIN( -15.5f, -15.5f, 0 ); -Vector PLAYER_BASE_MAX( 15.5f, 15.5f, 0 ); -Vector testpos[ 200 ]; +Vector PLAYER_BASE_MIN(-15.5f, -15.5f, 0); +Vector PLAYER_BASE_MAX(15.5f, 15.5f, 0); +Vector testpos[200]; Vector ai_startpath; Vector ai_endpath; -float NODE_MINS[ 3 ] = { -15, -15, 0 }; -float NODE_MAXS[ 3 ] = { 15, 15, 94 }; -float COLOR_PATHNODE_ERROR[ 3 ] = { 0, 0, 0 }; -float COLOR_PATHNODE_COVER[ 3 ] = { 0, 1, 0 }; -float COLOR_PATHNODE_CORNER_LEFT[ 3 ] = { 1, 1, 0 }; -float COLOR_PATHNODE_CORNER_RIGHT[ 3 ] = { 0.7f, 1, 0 }; -float COLOR_PATHNODE_SNIPER[ 3 ] = { 1, 0, 0 }; -float COLOR_PATHNODE_CRATE[ 3 ] = { 3, 0, 0 }; -float COLOR_PATHNODE_CONCEALMENT[ 3 ] = { 0, 0, 1 }; -float COLOR_PATHNODE_DUCK[ 3 ] = { 0, 1, 1 }; -float COLOR_PATHNODE_DEFAULT[ 3 ] = { 1, 0, 1 }; +float NODE_MINS[3] = {-15, -15, 0}; +float NODE_MAXS[3] = {15, 15, 94}; +float COLOR_PATHNODE_ERROR[3] = {0, 0, 0}; +float COLOR_PATHNODE_COVER[3] = {0, 1, 0}; +float COLOR_PATHNODE_CORNER_LEFT[3] = {1, 1, 0}; +float COLOR_PATHNODE_CORNER_RIGHT[3] = {0.7f, 1, 0}; +float COLOR_PATHNODE_SNIPER[3] = {1, 0, 0}; +float COLOR_PATHNODE_CRATE[3] = {3, 0, 0}; +float COLOR_PATHNODE_CONCEALMENT[3] = {0, 0, 1}; +float COLOR_PATHNODE_DUCK[3] = {0, 1, 1}; +float COLOR_PATHNODE_DEFAULT[3] = {1, 0, 1}; -int testcount = 0; +int testcount = 0; static ActorPath *test_path = NULL; struct { - float fMinRangeSquared; - float fMaxRangeSquared; - float fMinAngle; - float fMaxAngle; + float fMinRangeSquared; + float fMaxRangeSquared; + float fMinAngle; + float fMaxAngle; } -g_AttackParms[] = -{ - { 64 * 64, 2048 * 2048, 150.0f, 210.0f }, - { 64 * 64, 2048 * 2048, 150.0f, 210.0f }, - { 96 * 96, 2048 * 2048, 320.0f, 40.0f }, +g_AttackParms[] = { + {64 * 64, 2048 * 2048, 150.0f, 210.0f}, + {64 * 64, 2048 * 2048, 150.0f, 210.0f}, + {96 * 96, 2048 * 2048, 320.0f, 40.0f }, }; PathSearch PathManager; int path_checksthisframe; -void AI_AddNode - ( - PathNode *node - ) +void AI_AddNode(PathNode *node) { - int i = PathSearch::nodecount; + int i = PathSearch::nodecount; - assert( node ); + assert(node); - if( i < MAX_PATHNODES ) - { - if( i > ai_maxnode ) - { - ai_maxnode = i; - } - PathSearch::pathnodes[ i ] = node; - node->nodenum = i; - PathSearch::nodecount++; - return; - } + if (i < MAX_PATHNODES) { + if (i > ai_maxnode) { + ai_maxnode = i; + } + PathSearch::pathnodes[i] = node; + node->nodenum = i; + PathSearch::nodecount++; + return; + } - gi.Error( ERR_DROP, "Exceeded MAX_PATHNODES!\n" ); + gi.Error(ERR_DROP, "Exceeded MAX_PATHNODES!\n"); } -qboolean CheckMove - ( - Vector &origin, - Vector &pos, - short int *path_fallheight, - float size - ) +qboolean CheckMove(Vector& origin, Vector& pos, short int *path_fallheight, float size) { - mmove_t mm; - int i; - float air_z; - float fallheight; - float test_fallheight; - float error; - trace_t trace; - vec3_t dir; - vec3_t end; + mmove_t mm; + int i; + float air_z; + float fallheight; + float test_fallheight; + float error; + trace_t trace; + vec3_t dir; + vec3_t end; - memset( &mm, 0, sizeof( mmove_t ) ); + memset(&mm, 0, sizeof(mmove_t)); - VectorClear( mm.velocity ); - VectorCopy( origin, mm.origin ); - mm.desired_speed = 150.0f; - mm.entityNum = ENTITYNUM_NONE; - mm.tracemask = MASK_PATHSOLID; - mm.frametime = 0.1f; - mm.desired_dir[ 0 ] = pos[ 0 ] - origin[ 0 ]; - mm.desired_dir[ 1 ] = pos[ 1 ] - origin[ 1 ]; - VectorNormalize2D( mm.desired_dir ); + VectorClear(mm.velocity); + VectorCopy(origin, mm.origin); + mm.desired_speed = 150.0f; + mm.entityNum = ENTITYNUM_NONE; + mm.tracemask = MASK_PATHSOLID; + mm.frametime = 0.1f; + mm.desired_dir[0] = pos[0] - origin[0]; + mm.desired_dir[1] = pos[1] - origin[1]; + VectorNormalize2D(mm.desired_dir); - mm.groundPlane = qfalse; - mm.walking = qfalse; + mm.groundPlane = qfalse; + mm.walking = qfalse; - mm.mins[ 0 ] = -size; - mm.mins[ 1 ] = -size; - mm.mins[ 2 ] = 0; - mm.maxs[ 0 ] = size; - mm.maxs[ 1 ] = size; - mm.maxs[ 2 ] = 94.0f; + mm.mins[0] = -size; + mm.mins[1] = -size; + mm.mins[2] = 0; + mm.maxs[0] = size; + mm.maxs[1] = size; + mm.maxs[2] = 94.0f; - testcount = 0; - fallheight = 0.0f; - air_z = mm.origin[ 2 ]; + testcount = 0; + fallheight = 0.0f; + air_z = mm.origin[2]; - for( i = 200; i != 1; i-- ) - { - testpos[ i - 1 ] = mm.origin; - testcount++; + for (i = 200; i != 1; i--) { + testpos[i - 1] = mm.origin; + testcount++; - MmoveSingle( &mm ); + MmoveSingle(&mm); - if( mm.groundPlane ) - { - test_fallheight = air_z - mm.origin[ 2 ]; + if (mm.groundPlane) { + test_fallheight = air_z - mm.origin[2]; - if( test_fallheight > fallheight ) - { - if( test_fallheight > 1024.0f ) - return false; + if (test_fallheight > fallheight) { + if (test_fallheight > 1024.0f) { + return false; + } - fallheight = test_fallheight; - } + fallheight = test_fallheight; + } - air_z = mm.origin[ 2 ]; - } - - dir[ 0 ] = pos[ 0 ] - mm.origin[ 0 ]; - dir[ 1 ] = pos[ 1 ] - mm.origin[ 1 ]; - - if( DotProduct2D( dir, mm.desired_dir ) <= 0.1f ) - { - error = mm.origin[ 2 ] - pos[ 2 ]; + air_z = mm.origin[2]; + } - gi.Printf( "error = %f\n", error ); + dir[0] = pos[0] - mm.origin[0]; + dir[1] = pos[1] - mm.origin[1]; - *path_fallheight = ( short )fallheight; - if( fabs( error ) > 94.0f ) - { - if( mm.groundPlane ) - return false; + if (DotProduct2D(dir, mm.desired_dir) <= 0.1f) { + error = mm.origin[2] - pos[2]; - mm.desired_dir[ 0 ] = dir[ 0 ]; - mm.desired_dir[ 1 ] = dir[ 1 ]; - VectorNormalize2D( mm.desired_dir ); - } - else if( error > 0.0f && !mm.groundPlane ) - { - end[ 0 ] = mm.origin[ 0 ]; - end[ 1 ] = mm.origin[ 1 ]; - end[ 2 ] = pos[ 2 ]; + gi.Printf("error = %f\n", error); - trace = G_Trace( mm.origin, - mm.mins, - mm.maxs, - end, - NULL, - MASK_PATHSOLID, - true, - "CheckMove" ); + *path_fallheight = (short)fallheight; + if (fabs(error) > 94.0f) { + if (mm.groundPlane) { + return false; + } - test_fallheight = mm.origin[ 2 ] - trace.endpos[ 2 ]; + mm.desired_dir[0] = dir[0]; + mm.desired_dir[1] = dir[1]; + VectorNormalize2D(mm.desired_dir); + } else if (error > 0.0f && !mm.groundPlane) { + end[0] = mm.origin[0]; + end[1] = mm.origin[1]; + end[2] = pos[2]; - if( test_fallheight <= 18.0f ) - { - *path_fallheight = ( short )test_fallheight + fallheight; - return test_fallheight + fallheight <= 1024.0f; - } + trace = G_Trace(mm.origin, mm.mins, mm.maxs, end, NULL, MASK_PATHSOLID, true, "CheckMove"); - if( mm.groundPlane ) - return false; + test_fallheight = mm.origin[2] - trace.endpos[2]; - mm.desired_dir[ 0 ] = dir[ 0 ]; - mm.desired_dir[ 1 ] = dir[ 1 ]; - VectorNormalize2D( mm.desired_dir ); - } - else - { - return true; - } - } - - if( mm.hit_obstacle ) - { - gi.DPrintf( "obstacle hit\n" ); - return false; - } - } + if (test_fallheight <= 18.0f) { + *path_fallheight = (short)test_fallheight + fallheight; + return test_fallheight + fallheight <= 1024.0f; + } - return false; + if (mm.groundPlane) { + return false; + } + + mm.desired_dir[0] = dir[0]; + mm.desired_dir[1] = dir[1]; + VectorNormalize2D(mm.desired_dir); + } else { + return true; + } + } + + if (mm.hit_obstacle) { + gi.DPrintf("obstacle hit\n"); + return false; + } + } + + return false; } /*****************************************************************************/ @@ -286,797 +259,646 @@ JUMP marks the node as one to jump from when going to the node specified by targ ******************************************************************************/ -Event EV_Path_SetNodeFlags - ( - "spawnflags", - EV_DEFAULT, - "i", - "node_flags", - "Sets the path nodes flags.", - EV_NORMAL - ); +Event EV_Path_SetNodeFlags("spawnflags", EV_DEFAULT, "i", "node_flags", "Sets the path nodes flags.", EV_NORMAL); -CLASS_DECLARATION( SimpleEntity, PathNode, "info_pathnode" ) -{ - { &EV_Path_SetNodeFlags, &PathNode::SetNodeFlags }, - { &EV_IsTouching, &PathNode::IsTouching }, - { &EV_Delete, &PathNode::Remove }, - { &EV_Remove, &PathNode::Remove }, - { NULL, NULL } +CLASS_DECLARATION(SimpleEntity, PathNode, "info_pathnode") { + {&EV_Path_SetNodeFlags, &PathNode::SetNodeFlags}, + {&EV_IsTouching, &PathNode::IsTouching }, + {&EV_Delete, &PathNode::Remove }, + {&EV_Remove, &PathNode::Remove }, + {NULL, NULL } }; -static Vector pathNodesChecksum; -static int numLoadNodes = 0; -static int numNodes = 0; +static Vector pathNodesChecksum; +static int numLoadNodes = 0; +static int numNodes = 0; -void *PathNode::operator new( size_t size ) +void *PathNode::operator new(size_t size) { - return PathManager.AllocPathNode(); + return PathManager.AllocPathNode(); } -void PathNode::operator delete( void *ptr ) +void PathNode::operator delete(void *ptr) { - return PathManager.FreePathNode( ptr ); + return PathManager.FreePathNode(ptr); } PathNode::PathNode() { - entflags |= EF_PATHNODE; - findCount = 0; - numChildren = 0; - iAvailableTime = -1; + entflags |= EF_PATHNODE; + findCount = 0; + numChildren = 0; + iAvailableTime = -1; - if( !loadingarchive ) - { - // our archive function will take care of this stuff - AI_AddNode( this ); - nodeflags = 0; - virtualNumChildren = 0; - iAvailableTime = -1; - Child = NULL; - } + if (!loadingarchive) { + // our archive function will take care of this stuff + AI_AddNode(this); + nodeflags = 0; + virtualNumChildren = 0; + iAvailableTime = -1; + Child = NULL; + } } PathNode::~PathNode() { - entflags &= ~EF_PATHNODE; + entflags &= ~EF_PATHNODE; } -void PathNode::Claim - ( - Entity *pClaimer - ) +void PathNode::Claim(Entity *pClaimer) { - pLastClaimer = pClaimer; - iAvailableTime = 0; + pLastClaimer = pClaimer; + iAvailableTime = 0; } -const_str PathNode::GetSpecialAttack - ( - Actor *pActor - ) +const_str PathNode::GetSpecialAttack(Actor *pActor) { - int iSpecialAttack; - const_str csAnimation; - float fRangeSquared; - float vDelta[ 2 ]; - float fMinAngle; - float fMaxAngle; + int iSpecialAttack; + const_str csAnimation; + float fRangeSquared; + float vDelta[2]; + float fMinAngle; + float fMaxAngle; - if( nodeflags & AI_CORNER_LEFT ) - { - iSpecialAttack = 0; - csAnimation = STRING_ANIM_CORNERLEFT_SCR; - } - else if( nodeflags & AI_CORNER_RIGHT ) - { - iSpecialAttack = 1; - csAnimation = STRING_ANIM_CORNERRIGHT_SCR; - } - else - { - if( nodeflags >= 0 ) - return STRING_NULL; + if (nodeflags & AI_CORNER_LEFT) { + iSpecialAttack = 0; + csAnimation = STRING_ANIM_CORNERLEFT_SCR; + } else if (nodeflags & AI_CORNER_RIGHT) { + iSpecialAttack = 1; + csAnimation = STRING_ANIM_CORNERRIGHT_SCR; + } else { + if (nodeflags >= 0) { + return STRING_NULL; + } - iSpecialAttack = 2; - csAnimation = STRING_ANIM_OVERATTACK_SCR; - } + iSpecialAttack = 2; + csAnimation = STRING_ANIM_OVERATTACK_SCR; + } - if( pActor->m_Enemy ) - { - vDelta[ 0 ] = pActor->m_Enemy->origin[ 0 ] - origin[ 0 ]; - vDelta[ 1 ] = pActor->m_Enemy->origin[ 1 ] - origin[ 1 ]; - } - else - { - vDelta[ 0 ] = pActor->m_vLastEnemyPos[ 0 ] - origin[ 0 ]; - vDelta[ 1 ] = pActor->m_vLastEnemyPos[ 1 ] - origin[ 1 ]; - } + if (pActor->m_Enemy) { + vDelta[0] = pActor->m_Enemy->origin[0] - origin[0]; + vDelta[1] = pActor->m_Enemy->origin[1] - origin[1]; + } else { + vDelta[0] = pActor->m_vLastEnemyPos[0] - origin[0]; + vDelta[1] = pActor->m_vLastEnemyPos[1] - origin[1]; + } - fRangeSquared = vDelta[ 0 ] * vDelta[ 0 ] + vDelta[ 1 ] * vDelta[ 1 ]; + fRangeSquared = vDelta[0] * vDelta[0] + vDelta[1] * vDelta[1]; - if( fRangeSquared < g_AttackParms[ iSpecialAttack ].fMinRangeSquared || fRangeSquared > g_AttackParms[ iSpecialAttack ].fMaxRangeSquared ) - return STRING_NULL; + if (fRangeSquared < g_AttackParms[iSpecialAttack].fMinRangeSquared + || fRangeSquared > g_AttackParms[iSpecialAttack].fMaxRangeSquared) { + return STRING_NULL; + } - fMinAngle = atan2( vDelta[ 0 ], vDelta[ 1 ] ) * ( 180.0f / M_PI ) - angles[ 1 ]; + fMinAngle = atan2(vDelta[0], vDelta[1]) * (180.0f / M_PI) - angles[1]; - if( fMinAngle > -360.0f ) - { - if( fMinAngle >= 0.0f ) - { - if( fMinAngle >= 720.0f ) - fMaxAngle = fMinAngle - 720.0f; - else if( fMinAngle >= 360.0f ) - fMaxAngle = fMinAngle - 360.0f; - else - fMaxAngle = fMinAngle; - } - else - { - fMaxAngle = fMinAngle + 360.0f; - } - } - else - { - fMaxAngle = fMinAngle + 720.0f; - } + if (fMinAngle > -360.0f) { + if (fMinAngle >= 0.0f) { + if (fMinAngle >= 720.0f) { + fMaxAngle = fMinAngle - 720.0f; + } else if (fMinAngle >= 360.0f) { + fMaxAngle = fMinAngle - 360.0f; + } else { + fMaxAngle = fMinAngle; + } + } else { + fMaxAngle = fMinAngle + 360.0f; + } + } else { + fMaxAngle = fMinAngle + 720.0f; + } - if( g_AttackParms[ iSpecialAttack ].fMinAngle <= g_AttackParms[ iSpecialAttack ].fMaxAngle ) - { - if( g_AttackParms[ iSpecialAttack ].fMinAngle > fMaxAngle ) - return STRING_NULL; - } - else - { - if( g_AttackParms[ iSpecialAttack ].fMinAngle <= fMaxAngle ) - return STRING_NULL; - } + if (g_AttackParms[iSpecialAttack].fMinAngle <= g_AttackParms[iSpecialAttack].fMaxAngle) { + if (g_AttackParms[iSpecialAttack].fMinAngle > fMaxAngle) { + return STRING_NULL; + } + } else { + if (g_AttackParms[iSpecialAttack].fMinAngle <= fMaxAngle) { + return STRING_NULL; + } + } - if( fMaxAngle > g_AttackParms[ iSpecialAttack ].fMaxAngle ) - return STRING_NULL; + if (fMaxAngle > g_AttackParms[iSpecialAttack].fMaxAngle) { + return STRING_NULL; + } - return csAnimation; + return csAnimation; } -Entity *PathNode::GetClaimHolder - ( - void - ) const +Entity *PathNode::GetClaimHolder(void) const { - if( iAvailableTime ) - return NULL; - else - return pLastClaimer; + if (iAvailableTime) { + return NULL; + } else { + return pLastClaimer; + } } -bool PathNode::IsClaimedByOther - ( - Entity *pPossibleClaimer - ) const +bool PathNode::IsClaimedByOther(Entity *pPossibleClaimer) const { - if( pLastClaimer == pPossibleClaimer ) - return false; + if (pLastClaimer == pPossibleClaimer) { + return false; + } - if( iAvailableTime ) - { - return ( level.inttime < iAvailableTime ); - } - else - { - return ( pLastClaimer != NULL ); - } + if (iAvailableTime) { + return (level.inttime < iAvailableTime); + } else { + return (pLastClaimer != NULL); + } } -qboolean PathNode::IsTouching - ( - Entity *e1 - ) +qboolean PathNode::IsTouching(Entity *e1) { - return e1->absmin[ 0 ] <= origin[ 0 ] + 15.5f && - e1->absmin[ 1 ] <= origin[ 1 ] + 15.5f && - e1->absmin[ 0 ] <= origin[ 2 ] + 94.0f && - origin[ 0 ] - 15.5f <= e1->absmax[ 0 ] && - origin[ 1 ] - 15.5f <= e1->absmax[ 1 ] && - origin[ 2 ] + 0.0f <= e1->absmax[ 2 ]; + return e1->absmin[0] <= origin[0] + 15.5f && e1->absmin[1] <= origin[1] + 15.5f + && e1->absmin[0] <= origin[2] + 94.0f && origin[0] - 15.5f <= e1->absmax[0] + && origin[1] - 15.5f <= e1->absmax[1] && origin[2] + 0.0f <= e1->absmax[2]; } -void PathNode::SetNodeFlags - ( - Event *ev - ) +void PathNode::SetNodeFlags(Event *ev) { - nodeflags = ev->GetInteger( 1 ); + nodeflags = ev->GetInteger(1); } -void PathNode::IsTouching - ( - Event *ev - ) +void PathNode::IsTouching(Event *ev) { - Entity *ent = ev->GetEntity( 1 ); + Entity *ent = ev->GetEntity(1); - if( !ent ) - { - ScriptError( "IsTouching used with a NULL entity.\n" ); - } + if (!ent) { + ScriptError("IsTouching used with a NULL entity.\n"); + } - ev->AddInteger( IsTouching( ev->GetEntity( 1 ) ) ); + ev->AddInteger(IsTouching(ev->GetEntity(1))); } -void PathNode::Remove - ( - Event *ev - ) +void PathNode::Remove(Event *ev) { - // Pathnodes mustn't be removed - ScriptError( "Not allowed to delete a path node" ); + // Pathnodes mustn't be removed + ScriptError("Not allowed to delete a path node"); } -void PathNode::setOriginEvent - ( - Vector org - ) +void PathNode::setOriginEvent(Vector org) { - if( !PathManager.m_bNodesloaded ) - { - origin = org; - centroid = org; - } + if (!PathManager.m_bNodesloaded) { + origin = org; + centroid = org; + } } -void PathNode::Archive - ( - Archiver &arc - ) +void PathNode::Archive(Archiver& arc) {} + +void PathNode::ArchiveDynamic(Archiver& arc) { + SimpleEntity::SimpleArchive(arc); + + arc.ArchiveObjectPosition(this); + arc.ArchiveSafePointer(&pLastClaimer); + arc.ArchiveInteger(&iAvailableTime); + arc.ArchiveInteger(&numChildren); + + if (numChildren != virtualNumChildren) { + for (int i = 0; i < virtualNumChildren; i++) { + arc.ArchiveByte(&Child[i].numBlockers); + arc.ArchiveShort(&Child[i].node); + arc.ArchiveShort(&Child[i].fallheight); + arc.ArchiveFloat(&Child[i].dist); + arc.ArchiveVec2(Child[i].dir); + arc.ArchiveVec3(Child[i].pos1); + arc.ArchiveVec3(Child[i].pos2); + } + } } -void PathNode::ArchiveDynamic - ( - Archiver &arc - ) +void PathNode::ArchiveStatic(Archiver& arc) { - SimpleEntity::SimpleArchive( arc ); + arc.ArchiveVector(&origin); + arc.ArchiveVector(¢roid); + arc.ArchiveInteger(&nodeflags); + arc.ArchiveInteger(&virtualNumChildren); - arc.ArchiveObjectPosition( this ); - arc.ArchiveSafePointer( &pLastClaimer ); - arc.ArchiveInteger( &iAvailableTime ); - arc.ArchiveInteger( &numChildren ); + numChildren = virtualNumChildren; - if( numChildren != virtualNumChildren ) - { - for( int i = 0; i < virtualNumChildren; i++ ) - { - arc.ArchiveByte( &Child[ i ].numBlockers ); - arc.ArchiveShort( &Child[ i ].node ); - arc.ArchiveShort( &Child[ i ].fallheight ); - arc.ArchiveFloat( &Child[ i ].dist ); - arc.ArchiveVec2( Child[ i ].dir ); - arc.ArchiveVec3( Child[ i ].pos1 ); - arc.ArchiveVec3( Child[ i ].pos2 ); - } - } + if (arc.Loading()) { + bulkNavMemory -= virtualNumChildren * sizeof(pathway_t) * sizeof(pathway_t *); + Child = virtualNumChildren ? (pathway_t *)bulkNavMemory : NULL; + } + + for (int i = 0; i < virtualNumChildren; i++) { + arc.ArchiveShort(&Child[i].node); + arc.ArchiveShort(&Child[i].fallheight); + arc.ArchiveFloat(&Child[i].dist); + arc.ArchiveVec2(Child[i].dir); + arc.ArchiveVec3(Child[i].pos1); + arc.ArchiveVec3(Child[i].pos2); + + if (arc.Loading()) { + Child[i].numBlockers = 0; + } + } } -void PathNode::ArchiveStatic - ( - Archiver &arc - ) +void PathNode::ConnectChild(int i) { - arc.ArchiveVector( &origin ); - arc.ArchiveVector( ¢roid ); - arc.ArchiveInteger( &nodeflags ); - arc.ArchiveInteger( &virtualNumChildren ); + int j; + pathway_t child = Child[i]; - numChildren = virtualNumChildren; + for (j = i - 1; j >= numChildren; j--) { + Child[j + 1] = Child[j]; + } - if( arc.Loading() ) - { - bulkNavMemory -= virtualNumChildren * sizeof( pathway_t ) * sizeof( pathway_t * ); - Child = virtualNumChildren ? ( pathway_t * )bulkNavMemory : NULL; - } - - for( int i = 0; i < virtualNumChildren; i++ ) - { - arc.ArchiveShort( &Child[ i ].node ); - arc.ArchiveShort( &Child[ i ].fallheight ); - arc.ArchiveFloat( &Child[ i ].dist ); - arc.ArchiveVec2( Child[ i ].dir ); - arc.ArchiveVec3( Child[ i ].pos1 ); - arc.ArchiveVec3( Child[ i ].pos2 ); - - if( arc.Loading() ) - Child[ i ].numBlockers = 0; - } + Child[numChildren] = child; + numChildren++; } -void PathNode::ConnectChild - ( - int i - ) +void PathNode::DisconnectChild(int i) { - int j; - pathway_t child = Child[ i ]; + int j; + pathway_t child = Child[i]; - for( j = i - 1; j >= numChildren; j-- ) - { - Child[ j + 1 ] = Child[ j ]; - } + for (j = i + 1; j < numChildren; j++) { + Child[j - 1] = Child[j]; + } - Child[ numChildren ] = child; - numChildren++; + numChildren--; + Child[numChildren] = child; } -void PathNode::DisconnectChild - ( - int i - ) +void PathNode::ConnectTo(PathNode *node) { - int j; - pathway_t child = Child[ i ]; - - for( j = i + 1; j < numChildren; j++ ) - { - Child[ j - 1 ] = Child[ j ]; - } - - numChildren--; - Child[ numChildren ] = child; + Child[virtualNumChildren].node = nodenum; + Child[virtualNumChildren].numBlockers = 0; + virtualNumChildren++; + numChildren++; } -void PathNode::ConnectTo - ( - PathNode *node - ) +bool PathNode::CheckPathTo(PathNode *node) { - Child[ virtualNumChildren ].node = nodenum; - Child[ virtualNumChildren ].numBlockers = 0; - virtualNumChildren++; - numChildren++; + if (virtualNumChildren < NUM_PATHSPERNODE) { + CheckPathToDefault(node, &Child[virtualNumChildren]); + return true; + } else { + Com_Printf( + "^~^~^ %d paths per node at (%.2f %.2f %.2f) exceeded\n - use DONT_LINK on some nodes to conserve cpu and " + "memory usage\n", + NUM_PATHSPERNODE, + node->origin[0], + node->origin[1], + node->origin[2] + ); + PathSearch::m_NodeCheckFailed = true; + return false; + } } -bool PathNode::CheckPathTo - ( - PathNode *node - ) +void PathNode::CheckPathToDefault(PathNode *node, pathway_t *pathway) { + float dist; + float delta[2]; + Vector start; + Vector end; - if( virtualNumChildren < NUM_PATHSPERNODE ) - { - CheckPathToDefault( node, &Child[ virtualNumChildren ] ); - return true; - } - else - { - Com_Printf( "^~^~^ %d paths per node at (%.2f %.2f %.2f) exceeded\n - use DONT_LINK on some nodes to conserve cpu and memory usage\n", NUM_PATHSPERNODE, node->origin[ 0 ], node->origin[ 1 ], node->origin[ 2 ] ); - PathSearch::m_NodeCheckFailed = true; - return false; - } + delta[0] = node->origin[0] - origin[0]; + delta[1] = node->origin[1] - origin[1]; + + dist = VectorNormalize2D(delta); + + if (dist >= 384.0f) { + return; + } + + start = origin + Vector(0, 0, 36.0f); + end = start - Vector(0, 0, 2048.0f); + + trace_t trace = G_Trace(start, PLAYER_BASE_MIN, PLAYER_BASE_MAX, end, NULL, MASK_PATHSOLID, qfalse, "droptofloor"); + + start = node->origin + Vector(0, 0, 36.0f); + end = start - Vector(0, 0, 2048.0f); + + trace_t trace2 = G_Trace(start, PLAYER_BASE_MIN, PLAYER_BASE_MAX, end, NULL, MASK_PATHSOLID, qfalse, "droptofloor"); + + start = trace.endpos; + end = trace2.endpos; + + if (CheckMove(start, end, &pathway->fallheight, 15.5f)) { + pathway->dist = dist; + pathway->dir[0] = delta[0]; + pathway->dir[1] = delta[1]; + VectorCopy(start, pathway->pos1); + VectorCopy(end, pathway->pos2); + Child[virtualNumChildren].node = node->nodenum; + Child[virtualNumChildren].numBlockers = 0; + + virtualNumChildren++; + numChildren++; + } } -void PathNode::CheckPathToDefault - ( - PathNode *node, - pathway_t *pathway - ) +void PathNode::MarkTemporarilyBad(void) { - float dist; - float delta[ 2 ]; - Vector start; - Vector end; - - delta[ 0 ] = node->origin[ 0 ] - origin[ 0 ]; - delta[ 1 ] = node->origin[ 1 ] - origin[ 1 ]; - - dist = VectorNormalize2D( delta ); - - if( dist >= 384.0f ) - return; - - start = origin + Vector( 0, 0, 36.0f ); - end = start - Vector( 0, 0, 2048.0f ); - - trace_t trace = G_Trace( - start, - PLAYER_BASE_MIN, - PLAYER_BASE_MAX, - end, - NULL, - MASK_PATHSOLID, - qfalse, - "droptofloor" ); - - start = node->origin + Vector( 0, 0, 36.0f ); - end = start - Vector( 0, 0, 2048.0f ); - - trace_t trace2 = G_Trace( - start, - PLAYER_BASE_MIN, - PLAYER_BASE_MAX, - end, - NULL, - MASK_PATHSOLID, - qfalse, - "droptofloor" ); - - start = trace.endpos; - end = trace2.endpos; - - if( CheckMove( start, end, &pathway->fallheight, 15.5f ) ) - { - pathway->dist = dist; - pathway->dir[ 0 ] = delta[ 0 ]; - pathway->dir[ 1 ] = delta[ 1 ]; - VectorCopy( start, pathway->pos1 ); - VectorCopy( end, pathway->pos2 ); - Child[ virtualNumChildren ].node = node->nodenum; - Child[ virtualNumChildren ].numBlockers = 0; - - virtualNumChildren++; - numChildren++; - } + iAvailableTime = level.inttime + 5000; + pLastClaimer = NULL; } -void PathNode::MarkTemporarilyBad - ( - void - ) +void PathNode::Relinquish(void) { - iAvailableTime = level.inttime + 5000; - pLastClaimer = NULL; + iAvailableTime = level.inttime + 4000; } -void PathNode::Relinquish - ( - void - ) +void PathNode::DrawConnections(void) { - iAvailableTime = level.inttime + 4000; + int i; + pathway_t *path; + PathNode *node; + + for (i = 0; i < numChildren; i++) { + path = &Child[i]; + node = PathSearch::pathnodes[path->node]; + + G_DebugLine(origin + Vector("0 0 24"), node->origin + Vector("0 0 24"), 0.7f, 0.7f, 0, 1); + } } -void PathNode::DrawConnections - ( - void - ) +static bool IsValidPathnode(int spawnflags) { - int i; - pathway_t *path; - PathNode *node; + if ((spawnflags & AI_DUCK) && (spawnflags & AI_COVERFLAGS2)) { + return false; + } - for( i = 0; i < numChildren; i++ ) - { - path = &Child[ i ]; - node = PathSearch::pathnodes[ path->node ]; + if ((spawnflags & AI_CONCEALMENT) && (spawnflags & AI_SNIPERFLAGS)) { + return false; + } - G_DebugLine( origin + Vector( "0 0 24" ), node->origin + Vector( "0 0 24" ), 0.7f, 0.7f, 0, 1 ); - } + if ((spawnflags & AI_CORNER_LEFT) && (spawnflags & AI_COVER_LEFT_FLAGS)) { + return false; + } + + if ((spawnflags & AI_CORNER_RIGHT) && (spawnflags & AI_COVER_RIGHT_FLAGS)) { + return false; + } + + if ((spawnflags & AI_SNIPER) && (spawnflags & AI_CRATEFLAGS)) { + return false; + } + + if ((spawnflags & AI_ALL) && (spawnflags & AI_COVERFLAGS3)) { + return false; + } + + return true; } -static bool IsValidPathnode - ( - int spawnflags - ) +static void GetPathnodeColor(int spawnflags, vec3_t color) { - if( ( spawnflags & AI_DUCK ) && ( spawnflags & AI_COVERFLAGS2 ) ) - return false; - - if( ( spawnflags & AI_CONCEALMENT ) && ( spawnflags & AI_SNIPERFLAGS ) ) - return false; - - if( ( spawnflags & AI_CORNER_LEFT ) && ( spawnflags & AI_COVER_LEFT_FLAGS ) ) - return false; - - if( ( spawnflags & AI_CORNER_RIGHT ) && ( spawnflags & AI_COVER_RIGHT_FLAGS ) ) - return false; - - if( ( spawnflags & AI_SNIPER ) && ( spawnflags & AI_CRATEFLAGS ) ) - return false; - - if( ( spawnflags & AI_ALL ) && ( spawnflags & AI_COVERFLAGS3 ) ) - return false; - - return true; + if (IsValidPathnode(spawnflags)) { + if (spawnflags & AI_CORNER_LEFT) { + VectorCopy(COLOR_PATHNODE_CORNER_LEFT, color); + } else if (spawnflags & AI_CORNER_RIGHT) { + VectorCopy(COLOR_PATHNODE_CORNER_RIGHT, color); + } else if (spawnflags & AI_DUCK) { + VectorCopy(COLOR_PATHNODE_DUCK, color); + } else if (spawnflags & AI_SNIPER) { + VectorCopy(COLOR_PATHNODE_SNIPER, color); + } else if (spawnflags & AI_CONCEALMENT) { + VectorCopy(COLOR_PATHNODE_CONCEALMENT, color); + } else if (spawnflags & AI_COVER) { + VectorCopy(COLOR_PATHNODE_COVER, color); + } else if (spawnflags & AI_CRATE) { + VectorCopy(COLOR_PATHNODE_CRATE, color); + } else { + VectorCopy(COLOR_PATHNODE_DEFAULT, color); + } + } else { + VectorCopy(COLOR_PATHNODE_ERROR, color); + } } -static void GetPathnodeColor - ( - int spawnflags, - vec3_t color - ) +void DrawNode(int iNodeCount) { - if( IsValidPathnode( spawnflags ) ) - { - if( spawnflags & AI_CORNER_LEFT ) - { - VectorCopy( COLOR_PATHNODE_CORNER_LEFT, color ); - } - else if( spawnflags & AI_CORNER_RIGHT ) - { - VectorCopy( COLOR_PATHNODE_CORNER_RIGHT, color ); - } - else if( spawnflags & AI_DUCK ) - { - VectorCopy( COLOR_PATHNODE_DUCK, color ); - } - else if( spawnflags & AI_SNIPER ) - { - VectorCopy( COLOR_PATHNODE_SNIPER, color ); - } - else if( spawnflags & AI_CONCEALMENT ) - { - VectorCopy( COLOR_PATHNODE_CONCEALMENT, color ); - } - else if( spawnflags & AI_COVER ) - { - VectorCopy( COLOR_PATHNODE_COVER, color ); - } - else if( spawnflags & AI_CRATE ) - { - VectorCopy( COLOR_PATHNODE_CRATE, color ); - } - else - { - VectorCopy( COLOR_PATHNODE_DEFAULT, color ); - } - } - else - { - VectorCopy( COLOR_PATHNODE_ERROR, color ); - } + Vector down; + Vector up; + Vector dir; + Vector p1; + Vector p2; + Vector p3; + Vector p4; + Vector q1; + Vector q2; + Vector q3; + Vector q4; + Vector playerorigin; + Vector aStart; + Vector aEnd; + PathNode *node; + PathNode *nodelist[4096]; + Vector end; + Vector start; + Vector p; + vec3_t color; + + playerorigin = g_entities[0].client->ps.origin; + + if (iNodeCount > 4096) { + iNodeCount = 4096; + } + + if (ai_showallnode->integer) { + iNodeCount = PathSearch::DebugNearestNodeList2(playerorigin, nodelist, iNodeCount); + } else { + iNodeCount = PathSearch::DebugNearestNodeList(playerorigin, nodelist, iNodeCount); + } + + if (iNodeCount) { + for (int i = 0; i < iNodeCount; i++) { + node = nodelist[i]; + GetPathnodeColor(node->nodeflags, color); + + p1.x = PLAYER_BASE_MAX.x + node->origin.x; + p1.y = PLAYER_BASE_MAX.y + node->origin.y; + + p2.x = PLAYER_BASE_MAX.x + node->origin.x; + p2.y = PLAYER_BASE_MIN.y + node->origin.y; + + p3.x = PLAYER_BASE_MIN.x + node->origin.x; + p3.y = PLAYER_BASE_MIN.y + node->origin.y; + + p4.x = PLAYER_BASE_MIN.x + node->origin.x; + p4.y = PLAYER_BASE_MAX.y + node->origin.y; + + start = node->origin + Vector(0, 0, 18); + end = node->origin + Vector(0, 0, 18); + + aStart = start; + aEnd[0] = node->origin[0] + cos(M_PI / 180.0f * node->angles[1]) * 16.0f; + aEnd[1] = node->origin[1] + sin(M_PI / 180.0f * node->angles[1]) * 16.0f; + aEnd[2] = end[2]; + + G_DebugLine(aStart, aEnd, 1, 1, 1, 1); + + p1.z = node->origin.z + 36.0f; + p2.z = node->origin.z + 36.0f; + p3.z = node->origin.z + 36.0f; + p4.z = node->origin.z + 36.0f; + + G_DebugLine(p1, p2, color[0], color[1], color[2], 1); + G_DebugLine(p2, p3, color[0], color[1], color[2], 1); + G_DebugLine(p3, p4, color[0], color[1], color[2], 1); + G_DebugLine(p4, p1, color[0], color[1], color[2], 1); + + q1 = p1; + q2 = p2; + q3 = p3; + q4 = p4; + + q1.z = node->origin.z; + q2.z = node->origin.z; + q3.z = node->origin.z; + q4.z = node->origin.z; + + G_DebugLine(q1, q2, color[0], color[1], color[2], 1); + G_DebugLine(q2, q3, color[0], color[1], color[2], 1); + G_DebugLine(q3, q4, color[0], color[1], color[2], 1); + G_DebugLine(q4, q1, color[0], color[1], color[2], 1); + + G_DebugLine(p1, q1, color[0], color[1], color[2], 1); + G_DebugLine(p2, q2, color[0], color[1], color[2], 1); + G_DebugLine(p3, q3, color[0], color[1], color[2], 1); + G_DebugLine(p4, q4, color[0], color[1], color[2], 1); + } + } else { + G_DebugCircle(playerorigin + Vector(0, 0, 48), 128, 1, 0, 0, 1, true); + } } -void DrawNode - ( - int iNodeCount - ) +void DrawAllConnections(void) { - Vector down; - Vector up; - Vector dir; - Vector p1; - Vector p2; - Vector p3; - Vector p4; - Vector q1; - Vector q2; - Vector q3; - Vector q4; - Vector playerorigin; - Vector aStart; - Vector aEnd; - PathNode *node; - PathNode *nodelist[ 4096 ]; - Vector end; - Vector start; - Vector p; - vec3_t color; + pathway_t *path; + pathway_t *path2; + PathNode *node; + PathNode *to; + Vector down; + Vector up; + Vector dir; + Vector p1; + Vector p2; + Vector p3; + Vector p4; + Vector playerorigin; + qboolean showroutes; + qboolean shownums; + bool reverse; - playerorigin = g_entities[ 0 ].client->ps.origin; + showroutes = (ai_showroutes->integer != 0); + shownums = (ai_shownodenums->integer != 0); - if( iNodeCount > 4096 ) - iNodeCount = 4096; + // Figure out where the camera is - if( ai_showallnode->integer ) - iNodeCount = PathSearch::DebugNearestNodeList2( playerorigin, nodelist, iNodeCount ); - else - iNodeCount = PathSearch::DebugNearestNodeList( playerorigin, nodelist, iNodeCount ); + if (!g_entities[0].client) { + return; + } - if( iNodeCount ) - { - for( int i = 0; i < iNodeCount; i++ ) - { - node = nodelist[ i ]; - GetPathnodeColor( node->nodeflags, color ); + playerorigin.x = g_entities[0].client->ps.origin[0]; + playerorigin.y = g_entities[0].client->ps.origin[1]; + playerorigin.z = g_entities[0].client->ps.origin[2]; - p1.x = PLAYER_BASE_MAX.x + node->origin.x; - p1.y = PLAYER_BASE_MAX.y + node->origin.y; + playerorigin[2] += g_entities[0].client->ps.viewheight; - p2.x = PLAYER_BASE_MAX.x + node->origin.x; - p2.y = PLAYER_BASE_MIN.y + node->origin.y; + for (int i = 0; i < PathSearch::nodecount; i++) { + node = PathSearch::pathnodes[i]; - p3.x = PLAYER_BASE_MIN.x + node->origin.x; - p3.y = PLAYER_BASE_MIN.y + node->origin.y; + if (Vector(node->origin - playerorigin).length() > ai_showroutes_distance->integer) { + continue; + } - p4.x = PLAYER_BASE_MIN.x + node->origin.x; - p4.y = PLAYER_BASE_MAX.y + node->origin.y; + if (shownums) { + G_DrawDebugNumber(node->origin + Vector(0, 0, 14), node->nodenum, 1.5, 1, 1, 0); + } - start = node->origin + Vector( 0, 0, 18 ); - end = node->origin + Vector( 0, 0, 18 ); + for (int j = 0; j < node->numChildren; j++) { + path = &node->Child[j]; - aStart = start; - aEnd[ 0 ] = node->origin[ 0 ] + cos( M_PI / 180.0f * node->angles[ 1 ] ) * 16.0f; - aEnd[ 1 ] = node->origin[ 1 ] + sin( M_PI / 180.0f * node->angles[ 1 ] ) * 16.0f; - aEnd[ 2 ] = end[ 2 ]; + if (path->fallheight > ai_fallheight->integer) { + continue; + } - G_DebugLine( aStart, aEnd, 1, 1, 1, 1 ); + reverse = false; + to = PathSearch::pathnodes[path->node]; - p1.z = node->origin.z + 36.0f; - p2.z = node->origin.z + 36.0f; - p3.z = node->origin.z + 36.0f; - p4.z = node->origin.z + 36.0f; + for (int k = to->numChildren - 1; k >= 0; k--) { + path2 = &to->Child[k]; - G_DebugLine( p1, p2, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); - G_DebugLine( p2, p3, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); - G_DebugLine( p3, p4, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); - G_DebugLine( p4, p1, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); + if (path2->fallheight < ai_fallheight->integer && PathSearch::pathnodes[path2->node] == node) { + reverse = true; + break; + } + } - q1 = p1; - q2 = p2; - q3 = p3; - q4 = p4; + p1 = path->pos1 + Vector(0, 0, 36); + p2 = path->pos2 + Vector(0, 0, 36); - q1.z = node->origin.z; - q2.z = node->origin.z; - q3.z = node->origin.z; - q4.z = node->origin.z; + if (node->nodenum < to->nodenum || !reverse) { + // draw connected lines in green + G_DebugLine(p1, p2, 0, 1, 0, 1); - G_DebugLine( q1, q2, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); - G_DebugLine( q2, q3, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); - G_DebugLine( q3, q4, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); - G_DebugLine( q4, q1, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); + if (!reverse) { + dir = Vector(path->pos2) - Vector(path->pos1); + dir.z = 0; + VectorNormalize(dir); - G_DebugLine( p1, q1, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); - G_DebugLine( p2, q2, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); - G_DebugLine( p3, q3, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); - G_DebugLine( p4, q4, color[ 0 ], color[ 1 ], color[ 2 ], 1 ); - } - } - else - { - G_DebugCircle( playerorigin + Vector( 0, 0, 48 ), 128, 1, 0, 0, 1, true ); - } -} + p3 = dir * 8.0f + dir * 8.0f; + p4 = dir * 8.0f; + p4.z += 8.0f; -void DrawAllConnections - ( - void - ) -{ - pathway_t *path; - pathway_t *path2; - PathNode *node; - PathNode *to; - Vector down; - Vector up; - Vector dir; - Vector p1; - Vector p2; - Vector p3; - Vector p4; - Vector playerorigin; - qboolean showroutes; - qboolean shownums; - bool reverse; + G_DebugLine(p1 + p3 + up, p1 + p3 + up - p4, 1, 0, 0, 1); - showroutes = ( ai_showroutes->integer != 0 ); - shownums = ( ai_shownodenums->integer != 0 ); + p4.z -= 16.0f; - // Figure out where the camera is + G_DebugLine(p1 + p3 + down, p1 + p3 + down - p4, 1, 0, 0, 1); + } + } + } - if( !g_entities[ 0 ].client ) - return; + if (!node->numChildren) { + // Put a little X where the node is to show that it had no connections + p1 = node->origin; + p1.z += 2; - playerorigin.x = g_entities[ 0 ].client->ps.origin[ 0 ]; - playerorigin.y = g_entities[ 0 ].client->ps.origin[ 1 ]; - playerorigin.z = g_entities[ 0 ].client->ps.origin[ 2 ]; + if (node->nodeflags & PATH_DONT_LINK) { + G_DebugCircle(p1, 12, 0, 0, 1, 1, true); + } else { + p2 = Vector(12, 12, 0); + G_DebugLine(p1 - p2, p1 + p2, 1, 0, 0, 1); - playerorigin[ 2 ] += g_entities[ 0 ].client->ps.viewheight; - - for( int i = 0; i < PathSearch::nodecount; i++ ) - { - node = PathSearch::pathnodes[ i ]; - - if( Vector( node->origin - playerorigin ).length() > ai_showroutes_distance->integer ) - { - continue; - } - - if( shownums ) - { - G_DrawDebugNumber( node->origin + Vector( 0, 0, 14 ), node->nodenum, 1.5, 1, 1, 0 ); - } - - for( int j = 0; j < node->numChildren; j++ ) - { - path = &node->Child[ j ]; - - if( path->fallheight > ai_fallheight->integer ) - continue; - - reverse = false; - to = PathSearch::pathnodes[ path->node ]; - - for( int k = to->numChildren - 1; k >= 0; k-- ) - { - path2 = &to->Child[ k ]; - - if( path2->fallheight < ai_fallheight->integer && PathSearch::pathnodes[ path2->node ] == node ) - { - reverse = true; - break; - } - } - - p1 = path->pos1 + Vector( 0, 0, 36 ); - p2 = path->pos2 + Vector( 0, 0, 36 ); - - if( node->nodenum < to->nodenum || !reverse ) - { - // draw connected lines in green - G_DebugLine( p1, p2, 0, 1, 0, 1 ); - - if( !reverse ) - { - dir = Vector( path->pos2 ) - Vector( path->pos1 ); - dir.z = 0; - VectorNormalize( dir ); - - p3 = dir * 8.0f + dir * 8.0f; - p4 = dir * 8.0f; - p4.z += 8.0f; - - G_DebugLine( p1 + p3 + up , p1 + p3 + up - p4, 1, 0, 0, 1 ); - - p4.z -= 16.0f; - - G_DebugLine( p1 + p3 + down, p1 + p3 + down - p4, 1, 0, 0, 1 ); - } - } - } - - if( !node->numChildren ) - { - // Put a little X where the node is to show that it had no connections - p1 = node->origin; - p1.z += 2; - - if( node->nodeflags & PATH_DONT_LINK ) - { - G_DebugCircle( p1, 12, 0, 0, 1, 1, true ); - } - else - { - p2 = Vector( 12, 12, 0 ); - G_DebugLine( p1 - p2, p1 + p2, 1, 0, 0, 1 ); - - p2.x = -12; - G_DebugLine( p1 - p2, p1 + p2, 1, 0, 0, 1 ); - } - } - } + p2.x = -12; + G_DebugLine(p1 - p2, p1 + p2, 1, 0, 0, 1); + } + } + } } MapCell::MapCell() { - numnodes = 0; - nodes = NULL; + numnodes = 0; + nodes = NULL; } MapCell::~MapCell() { - numnodes = 0; - nodes = NULL; + numnodes = 0; + nodes = NULL; } -qboolean MapCell::AddNode - ( - PathNode *node - ) + +qboolean MapCell::AddNode(PathNode *node) { - nodes[ numnodes ] = ( short )node->nodenum; - numnodes++; + nodes[numnodes] = (short)node->nodenum; + numnodes++; - return true; + return true; } -int MapCell::NumNodes - ( - void - ) +int MapCell::NumNodes(void) { - return numnodes; + return numnodes; } - /* All work and no play makes Jim a dull boy. All @@ -1122,2747 +944,2352 @@ int MapCell::NumNodes Jim a */ -CLASS_DECLARATION( Class, PathSearch, NULL ) -{ - { NULL, NULL } +CLASS_DECLARATION(Class, PathSearch, NULL) { + {NULL, NULL} }; - PathSearch::PathSearch() { - memset( pathnodes, 0, sizeof( pathnodes ) ); - open = 0; - findFrame = 0; + memset(pathnodes, 0, sizeof(pathnodes)); + open = 0; + findFrame = 0; } PathSearch::~PathSearch() { - ResetNodes(); + ResetNodes(); } -void PathSearch::AddToGrid - ( - PathNode *node, - int x, - int y - ) +void PathSearch::AddToGrid(PathNode *node, int x, int y) { - MapCell *cell; + MapCell *cell; - if( x > PATHMAP_GRIDSIZE || y > PATHMAP_GRIDSIZE ) - cell = NULL; - else - cell = &PathMap[ x ][ y ]; + if (x > PATHMAP_GRIDSIZE || y > PATHMAP_GRIDSIZE) { + cell = NULL; + } else { + cell = &PathMap[x][y]; + } - if( !cell ) - return; + if (!cell) { + return; + } - if( cell->NumNodes() >= PATHMAP_NODES ) - Com_Printf( "^~^~^ PathSearch::AddToGrid: Node overflow at ( %d, %d )\n", x, y ); - else - cell->AddNode( node ); + if (cell->NumNodes() >= PATHMAP_NODES) { + Com_Printf("^~^~^ PathSearch::AddToGrid: Node overflow at ( %d, %d )\n", x, y); + } else { + cell->AddNode(node); + } } -int PathSearch::NodeCoordinate - ( - float coord - ) +int PathSearch::NodeCoordinate(float coord) { - float c; + float c; - //return ( ( int )coord + MAX_MAP_BOUNDS - ( PATHMAP_CELLSIZE / 2 ) ) / PATHMAP_CELLSIZE; + //return ( ( int )coord + MAX_MAP_BOUNDS - ( PATHMAP_CELLSIZE / 2 ) ) / PATHMAP_CELLSIZE; - c = coord + MAX_MAP_BOUNDS - ( PATHMAP_CELLSIZE / 2 ); + c = coord + MAX_MAP_BOUNDS - (PATHMAP_CELLSIZE / 2); - if( c < 0 ) - c = coord + MAX_MAP_BOUNDS + ( PATHMAP_CELLSIZE / 2 ) - 1; + if (c < 0) { + c = coord + MAX_MAP_BOUNDS + (PATHMAP_CELLSIZE / 2) - 1; + } - return ( int )c >> 8; + return (int)c >> 8; } -int PathSearch::GridCoordinate - ( - float coord - ) +int PathSearch::GridCoordinate(float coord) { - float c; + float c; - //return ( ( int )coord + MAX_MAP_BOUNDS ) / PATHMAP_CELLSIZE; + //return ( ( int )coord + MAX_MAP_BOUNDS ) / PATHMAP_CELLSIZE; - c = coord + MAX_MAP_BOUNDS; + c = coord + MAX_MAP_BOUNDS; - if( c < 0 ) - c = coord + MAX_MAP_BOUNDS + PATHMAP_CELLSIZE - 1; + if (c < 0) { + c = coord + MAX_MAP_BOUNDS + PATHMAP_CELLSIZE - 1; + } - return ( int )c >> 8; + return (int)c >> 8; } -void PathSearch::AddNode - ( - PathNode *node - ) +void PathSearch::AddNode(PathNode *node) { - int x; - int y; + int x; + int y; - assert( node ); + assert(node); - x = NodeCoordinate( node->origin[ 0 ] ); - y = NodeCoordinate( node->origin[ 1 ] ); + x = NodeCoordinate(node->origin[0]); + y = NodeCoordinate(node->origin[1]); - AddToGrid( node, x, y ); - AddToGrid( node, x + 1, y ); - AddToGrid( node, x, y + 1 ); - AddToGrid( node, x + 1, y + 1 ); + AddToGrid(node, x, y); + AddToGrid(node, x + 1, y); + AddToGrid(node, x, y + 1); + AddToGrid(node, x + 1, y + 1); } -void PathSearch::LoadAddToGrid - ( - int x, - int y - ) +void PathSearch::LoadAddToGrid(int x, int y) { - MapCell *cell; + MapCell *cell; - if( x > PATHMAP_GRIDSIZE || y > PATHMAP_GRIDSIZE ) - cell = NULL; - else - cell = &PathMap[ x ][ y ]; + if (x > PATHMAP_GRIDSIZE || y > PATHMAP_GRIDSIZE) { + cell = NULL; + } else { + cell = &PathMap[x][y]; + } - if( cell ) - cell->numnodes++; + if (cell) { + cell->numnodes++; + } } -void PathSearch::LoadAddToGrid2 - ( - PathNode *node, - int x, - int y - ) +void PathSearch::LoadAddToGrid2(PathNode *node, int x, int y) { - MapCell *cell; + MapCell *cell; - if( x > PATHMAP_GRIDSIZE || y > PATHMAP_GRIDSIZE ) - cell = NULL; - else - cell = &PathMap[ x ][ y ]; + if (x > PATHMAP_GRIDSIZE || y > PATHMAP_GRIDSIZE) { + cell = NULL; + } else { + cell = &PathMap[x][y]; + } - if( cell ) - cell->AddNode( node ); + if (cell) { + cell->AddNode(node); + } } -MapCell *PathSearch::GetNodesInCell - ( - int x, - int y - ) +MapCell *PathSearch::GetNodesInCell(int x, int y) { - if( ( x < 0 ) || ( x >= PATHMAP_GRIDSIZE ) || ( y < 0 ) || ( y >= PATHMAP_GRIDSIZE ) ) - { - return NULL; - } + if ((x < 0) || (x >= PATHMAP_GRIDSIZE) || (y < 0) || (y >= PATHMAP_GRIDSIZE)) { + return NULL; + } - return &PathMap[ x ][ y ]; + return &PathMap[x][y]; } -MapCell *PathSearch::GetNodesInCell - ( - float *pos - ) +MapCell *PathSearch::GetNodesInCell(float *pos) { - int x; - int y; + int x; + int y; - x = GridCoordinate( pos[ 0 ] ); - y = GridCoordinate( pos[ 1 ] ); + x = GridCoordinate(pos[0]); + y = GridCoordinate(pos[1]); - return GetNodesInCell( x, y ); + return GetNodesInCell(x, y); } - -PathNode *PathSearch::DebugNearestStartNode - ( - float *pos, - Entity *ent - ) +PathNode *PathSearch::DebugNearestStartNode(float *pos, Entity *ent) { - PathNode *node = NULL; - int i; - MapCell *cell; - int nodes[ 128 ]; - vec3_t deltas[ 128 ]; - vec3_t start; - vec3_t end; + PathNode *node = NULL; + int i; + MapCell *cell; + int nodes[128]; + vec3_t deltas[128]; + vec3_t start; + vec3_t end; - cell = GetNodesInCell( pos ); + cell = GetNodesInCell(pos); - if( !cell ) - return NULL; + if (!cell) { + return NULL; + } - int node_count = NearestNodeSetup( pos, cell, nodes, deltas ); + int node_count = NearestNodeSetup(pos, cell, nodes, deltas); - if( !node_count ) - return NULL; + if (!node_count) { + return NULL; + } - VectorCopy( pos, start ); - start[ 2 ] += 32.0f; + VectorCopy(pos, start); + start[2] += 32.0f; - for( i = 0; i < node_count; i++ ) - { - node = pathnodes[ cell->nodes[ nodes[ i ] ] ]; + for (i = 0; i < node_count; i++) { + node = pathnodes[cell->nodes[nodes[i]]]; - VectorCopy( start, end ); - VectorAdd( end, deltas[ nodes[ i ] ], end ); + VectorCopy(start, end); + VectorAdd(end, deltas[nodes[i]], end); - Vector vStart = start; - Vector vMins = Vector( -15, -15, 0 ); - Vector vMaxs = Vector( 15, 15, 62 ); - Vector vEnd = end; + Vector vStart = start; + Vector vMins = Vector(-15, -15, 0); + Vector vMaxs = Vector(15, 15, 62); + Vector vEnd = end; - if( G_SightTrace( - vStart, - vMins, - vMaxs, - vEnd, - ent, - NULL, - MASK_TARGETPATH, - qtrue, - "PathSearch::DebugNearestStartNode" ) ) - { - return node; - } - } + if (G_SightTrace( + vStart, vMins, vMaxs, vEnd, ent, NULL, MASK_TARGETPATH, qtrue, "PathSearch::DebugNearestStartNode" + )) { + return node; + } + } - return pathnodes[ cell->nodes[ nodes[ 0 ] ] ]; + return pathnodes[cell->nodes[nodes[0]]]; } -PathNode *PathSearch::NearestStartNode - ( - float *pos, - SimpleActor *ent - ) +PathNode *PathSearch::NearestStartNode(float *pos, SimpleActor *ent) { - PathNode *node = NULL; - int i; - MapCell *cell; - int nodes[128]; - vec3_t deltas[128]; - vec3_t start; - vec3_t end; + PathNode *node = NULL; + int i; + MapCell *cell; + int nodes[128]; + vec3_t deltas[128]; + vec3_t start; + vec3_t end; - cell = GetNodesInCell(pos); + cell = GetNodesInCell(pos); - if (!cell) - return NULL; + if (!cell) { + return NULL; + } - int node_count = NearestNodeSetup(pos, cell, nodes, deltas); - int n = 0; - int j = 0; + int node_count = NearestNodeSetup(pos, cell, nodes, deltas); + int n = 0; + int j = 0; - VectorCopy(pos, start); - start[2] += 32.0f; + VectorCopy(pos, start); + start[2] += 32.0f; - Vector vMins = Vector(-15, -15, 0); - Vector vMaxs = Vector(15, 15, 62); + Vector vMins = Vector(-15, -15, 0); + Vector vMaxs = Vector(15, 15, 62); - for (i = 0; i < node_count; i++) - { - node = pathnodes[cell->nodes[nodes[i]]]; + for (i = 0; i < node_count; i++) { + node = pathnodes[cell->nodes[nodes[i]]]; - VectorAdd(start, deltas[nodes[i]], end); + VectorAdd(start, deltas[nodes[i]], end); - Vector vStart = start; - Vector vEnd = end; + Vector vStart = start; + Vector vEnd = end; - if (G_SightTrace( - vStart, - vMins, - vMaxs, - vEnd, - (gentity_t *)NULL, - (gentity_t *)NULL, - 1107437825, //FIXME: macro - qtrue, - "PathSearch::NearestStartNode 1")) - { - ent->m_NearestNode = node; - ent->m_vNearestNodePos = end; - return node; - } - } + if (G_SightTrace( + vStart, + vMins, + vMaxs, + vEnd, + (gentity_t *)NULL, + (gentity_t *)NULL, + 1107437825, //FIXME: macro + qtrue, + "PathSearch::NearestStartNode 1" + )) { + ent->m_NearestNode = node; + ent->m_vNearestNodePos = end; + return node; + } + } - if ((ent->m_NearestNode && - (G_SightTrace( - Vector(start), - vMins, - vMaxs, - ent->m_vNearestNodePos, - ent->edict, - (gentity_t*)NULL, - 1073883393, //FIXME: macro - qtrue, - "PathSearch::NearestStartNode 2"))) - || node_count <= 0 - ) - { - node = ent->m_NearestNode; - } - else - { - node = pathnodes[cell->nodes[nodes[0]]]; - } + if ((ent->m_NearestNode + && (G_SightTrace( + Vector(start), + vMins, + vMaxs, + ent->m_vNearestNodePos, + ent->edict, + (gentity_t *)NULL, + 1073883393, //FIXME: macro + qtrue, + "PathSearch::NearestStartNode 2" + ))) + || node_count <= 0) { + node = ent->m_NearestNode; + } else { + node = pathnodes[cell->nodes[nodes[0]]]; + } - return node; + return node; } -PathNode *PathSearch::NearestEndNode - ( - float *pos - ) +PathNode *PathSearch::NearestEndNode(float *pos) { - PathNode *node = NULL; - int i; - MapCell *cell; - int nodes[ 128 ]; - vec3_t deltas[ 128 ]; - vec3_t start; - vec3_t end; + PathNode *node = NULL; + int i; + MapCell *cell; + int nodes[128]; + vec3_t deltas[128]; + vec3_t start; + vec3_t end; - cell = GetNodesInCell( pos ); + cell = GetNodesInCell(pos); - if( !cell ) - return NULL; + if (!cell) { + return NULL; + } - int node_count = NearestNodeSetup( pos, cell, nodes, deltas ); - int n = 0; - int j = 0; + int node_count = NearestNodeSetup(pos, cell, nodes, deltas); + int n = 0; + int j = 0; - if( !node_count ) - return NULL; + if (!node_count) { + return NULL; + } - VectorCopy( pos, start ); - start[ 2 ] += 32.0f; + VectorCopy(pos, start); + start[2] += 32.0f; - for( i = 0; i < node_count; i++ ) - { - node = pathnodes[ cell->nodes[ nodes[ i ] ] ]; + for (i = 0; i < node_count; i++) { + node = pathnodes[cell->nodes[nodes[i]]]; - VectorAdd(start, deltas[nodes[i]], end); + VectorAdd(start, deltas[nodes[i]], end); - Vector vStart = start; - Vector vMins = Vector( -15, -15, 0 ); - Vector vMaxs = Vector( 15, 15, 62 ); - Vector vEnd = end; + Vector vStart = start; + Vector vMins = Vector(-15, -15, 0); + Vector vMaxs = Vector(15, 15, 62); + Vector vEnd = end; - if( G_SightTrace( - vStart, - vMins, - vMaxs, - vEnd, - ( gentity_t * )NULL, - ( gentity_t * )NULL, - MASK_TARGETPATH, - qtrue, - "PathSearch::NearestEndNode" ) ) - { - return node; - } - } + if (G_SightTrace( + vStart, + vMins, + vMaxs, + vEnd, + (gentity_t *)NULL, + (gentity_t *)NULL, + MASK_TARGETPATH, + qtrue, + "PathSearch::NearestEndNode" + )) { + return node; + } + } - return pathnodes[ cell->nodes[ nodes[ 0 ] ] ]; + return pathnodes[cell->nodes[nodes[0]]]; } -int PathSearch::DebugNearestNodeList - ( - float *pos, - PathNode **nodelist, - int iMaxNodes - ) +int PathSearch::DebugNearestNodeList(float *pos, PathNode **nodelist, int iMaxNodes) { - PathNode *node; - int i; - MapCell *cell; - int nodes[ 128 ]; - vec3_t deltas[ 128 ]; - vec3_t start; - vec3_t end; + PathNode *node; + int i; + MapCell *cell; + int nodes[128]; + vec3_t deltas[128]; + vec3_t start; + vec3_t end; - cell = GetNodesInCell( pos ); + cell = GetNodesInCell(pos); - if( !cell ) - return 0; + if (!cell) { + return 0; + } - int node_count = NearestNodeSetup( pos, cell, nodes, deltas ); - int n = 0; - int j = 0; + int node_count = NearestNodeSetup(pos, cell, nodes, deltas); + int n = 0; + int j = 0; - for( i = 0; i < node_count && j < iMaxNodes; i++ ) - { - node = pathnodes[ cell->nodes[ nodes[ i ] ] ]; + for (i = 0; i < node_count && j < iMaxNodes; i++) { + node = pathnodes[cell->nodes[nodes[i]]]; - VectorCopy( pos, start ); - VectorCopy( pos, end ); + VectorCopy(pos, start); + VectorCopy(pos, end); - VectorAdd( end, deltas[ i ], end ); + VectorAdd(end, deltas[i], end); - Vector vStart = start; - Vector vMins = Vector( -15, -15, 0 ); - Vector vMaxs = Vector( 15, 15, 62 ); - Vector vEnd = end; + Vector vStart = start; + Vector vMins = Vector(-15, -15, 0); + Vector vMaxs = Vector(15, 15, 62); + Vector vEnd = end; - if( G_SightTrace( - vStart, - vMins, - vMaxs, - vEnd, - ( gentity_t *)NULL, - ( gentity_t * )NULL, - MASK_PATHSOLID, - qtrue, - "PathSearch::DebugNearestNodeList" ) ) - { - nodelist[ n ] = node; - n++; - } - } + if (G_SightTrace( + vStart, + vMins, + vMaxs, + vEnd, + (gentity_t *)NULL, + (gentity_t *)NULL, + MASK_PATHSOLID, + qtrue, + "PathSearch::DebugNearestNodeList" + )) { + nodelist[n] = node; + n++; + } + } - if( !n && node_count ) - { - nodelist[ 0 ] = pathnodes[ cell->nodes[ nodes[ 0 ] ] ]; - return 1; - } - else - { - return n; - } + if (!n && node_count) { + nodelist[0] = pathnodes[cell->nodes[nodes[0]]]; + return 1; + } else { + return n; + } - return 0; + return 0; } -int PathSearch::DebugNearestNodeList2 - ( - float *pos, - PathNode **nodelist, - int iMaxNodes - ) +int PathSearch::DebugNearestNodeList2(float *pos, PathNode **nodelist, int iMaxNodes) { - vec3_t delta; - PathNode *node; - float dist; - int n = 0; - int i; - int j; - static float node_dist[ MAX_PATHNODES ]; - int node_count; + vec3_t delta; + PathNode *node; + float dist; + int n = 0; + int i; + int j; + static float node_dist[MAX_PATHNODES]; + int node_count; - node_count = nodecount; + node_count = nodecount; - for( i = 0; i < node_count; i++ ) - { - node = pathnodes[ i ]; + for (i = 0; i < node_count; i++) { + node = pathnodes[i]; - if( pos[ 2 ] > node->origin[ 2 ] + 94.0f ) - continue; + if (pos[2] > node->origin[2] + 94.0f) { + continue; + } - if( node->origin[ 2 ] > pos[ 2 ] + 94.0f ) - continue; + if (node->origin[2] > pos[2] + 94.0f) { + continue; + } - delta[ 0 ] = node->origin[ 0 ] - pos[ 0 ]; - delta[ 1 ] = node->origin[ 1 ] - pos[ 1 ]; - delta[ 2 ] = node->origin[ 2 ] - pos[ 2 ]; + delta[0] = node->origin[0] - pos[0]; + delta[1] = node->origin[1] - pos[1]; + delta[2] = node->origin[2] - pos[2]; - dist = VectorLengthSquared( delta ); + dist = VectorLengthSquared(delta); - for( j = n; j > 0; j-- ) - { - if( dist >= node_dist[ j - 1 ] ) - break; + for (j = n; j > 0; j--) { + if (dist >= node_dist[j - 1]) { + break; + } - node_dist[ j ] = node_dist[ j - 1 ]; - nodelist[ j ] = nodelist[ j - 1 ]; - } + node_dist[j] = node_dist[j - 1]; + nodelist[j] = nodelist[j - 1]; + } - n++; - nodelist[ j ] = node; - node_dist[ j ] = dist; - } + n++; + nodelist[j] = node; + node_dist[j] = dist; + } - return n; + return n; } -void PathSearch::ArchiveStaticLoad - ( - Archiver& arc - ) +void PathSearch::ArchiveStaticLoad(Archiver& arc) { - int i; - PathNode *node; - int total_nodes; - int total_children; - int x; - int y; - int size; + int i; + PathNode *node; + int total_nodes; + int total_children; + int x; + int y; + int size; - loadingarchive = true; + loadingarchive = true; - arc.ArchiveInteger( &nodecount ); - arc.ArchiveInteger( &total_nodes ); - arc.ArchiveInteger( &total_children ); + arc.ArchiveInteger(&nodecount); + arc.ArchiveInteger(&total_nodes); + arc.ArchiveInteger(&total_children); - size = total_nodes + total_children * ( sizeof( pathway_t ) * 2 ) + nodecount * ( sizeof( PathNode ) / 2 ); - size *= sizeof(void*) / 2; + size = total_nodes + total_children * (sizeof(pathway_t) * 2) + nodecount * (sizeof(PathNode) / 2); + size *= sizeof(void *) / 2; - gi.DPrintf( "%d memory allocated for navigation.\n", size ); + gi.DPrintf("%d memory allocated for navigation.\n", size); - if( size ) - startBulkNavMemory = ( byte * )gi.Malloc( size ); - else - startBulkNavMemory = NULL; + if (size) { + startBulkNavMemory = (byte *)gi.Malloc(size); + } else { + startBulkNavMemory = NULL; + } - bulkNavMemory = startBulkNavMemory + size; + bulkNavMemory = startBulkNavMemory + size; - for( i = 0; i < nodecount; i++ ) - { - node = new PathNode; + for (i = 0; i < nodecount; i++) { + node = new PathNode; - arc.ArchiveObjectPosition( node ); - node->ArchiveStatic( arc ); - node->nodenum = i; + arc.ArchiveObjectPosition(node); + node->ArchiveStatic(arc); + node->nodenum = i; - pathnodes[ i ] = node; + pathnodes[i] = node; - if( !( node->nodeflags & PATH_DONT_LINK ) ) - { - x = NodeCoordinate( node->origin[ 0 ] ); - y = NodeCoordinate( node->origin[ 1 ] ); + if (!(node->nodeflags & PATH_DONT_LINK)) { + x = NodeCoordinate(node->origin[0]); + y = NodeCoordinate(node->origin[1]); - LoadAddToGrid( x, y ); - LoadAddToGrid( x + 1, y ); - LoadAddToGrid( x, y + 1 ); - LoadAddToGrid( x + 1, y + 1 ); - } - } + LoadAddToGrid(x, y); + LoadAddToGrid(x + 1, y); + LoadAddToGrid(x, y + 1); + LoadAddToGrid(x + 1, y + 1); + } + } - for( x = 0; x < PATHMAP_GRIDSIZE; x++ ) - { - for( y = 0; y < PATHMAP_GRIDSIZE; y++ ) - { - bulkNavMemory -= PathMap[ x ][ y ].numnodes * sizeof( short ); + for (x = 0; x < PATHMAP_GRIDSIZE; x++) { + for (y = 0; y < PATHMAP_GRIDSIZE; y++) { + bulkNavMemory -= PathMap[x][y].numnodes * sizeof(short); - PathMap[ x ][ y ].nodes = PathMap[ x ][ y ].numnodes ? ( short * )bulkNavMemory : NULL; - PathMap[ x ][ y ].numnodes = 0; - } - } + PathMap[x][y].nodes = PathMap[x][y].numnodes ? (short *)bulkNavMemory : NULL; + PathMap[x][y].numnodes = 0; + } + } - for( i = 0; i < nodecount; i++ ) - { - node = pathnodes[ i ]; + for (i = 0; i < nodecount; i++) { + node = pathnodes[i]; - if( !( node->nodeflags & PATH_DONT_LINK ) ) - { - x = NodeCoordinate( node->origin[ 0 ] ); - y = NodeCoordinate( node->origin[ 1 ] ); + if (!(node->nodeflags & PATH_DONT_LINK)) { + x = NodeCoordinate(node->origin[0]); + y = NodeCoordinate(node->origin[1]); - LoadAddToGrid2( node, x, y ); - LoadAddToGrid2( node, x + 1, y ); - LoadAddToGrid2( node, x, y + 1 ); - LoadAddToGrid2( node, x + 1, y + 1 ); - } - } + LoadAddToGrid2(node, x, y); + LoadAddToGrid2(node, x + 1, y); + LoadAddToGrid2(node, x, y + 1); + LoadAddToGrid2(node, x + 1, y + 1); + } + } - loadingarchive = false; + loadingarchive = false; } -void PathSearch::ArchiveStaticSave - ( - Archiver& arc - ) +void PathSearch::ArchiveStaticSave(Archiver& arc) { - int i; - PathNode *node; - int total_nodes = 0; - int total_children = 0; - int x = 0; - int y = 0; + int i; + PathNode *node; + int total_nodes = 0; + int total_children = 0; + int x = 0; + int y = 0; - for( x = 0; x < PATHMAP_GRIDSIZE; x++ ) - { - for( y = 0; y < PATHMAP_GRIDSIZE; y++ ) - { - total_nodes += PathMap[ x ][ y ].NumNodes(); - } - } + for (x = 0; x < PATHMAP_GRIDSIZE; x++) { + for (y = 0; y < PATHMAP_GRIDSIZE; y++) { + total_nodes += PathMap[x][y].NumNodes(); + } + } - for( i = 0; i < nodecount; i++ ) - { - node = pathnodes[ i ]; - total_children += node->virtualNumChildren; - } + for (i = 0; i < nodecount; i++) { + node = pathnodes[i]; + total_children += node->virtualNumChildren; + } - arc.ArchiveInteger( &nodecount ); - arc.ArchiveInteger( &total_nodes ); - arc.ArchiveInteger( &total_children ); + arc.ArchiveInteger(&nodecount); + arc.ArchiveInteger(&total_nodes); + arc.ArchiveInteger(&total_children); - for( i = 0; i < nodecount; i++ ) - { - node = pathnodes[ i ]; - arc.ArchiveObjectPosition( node ); - node->ArchiveStatic( arc ); - } + for (i = 0; i < nodecount; i++) { + node = pathnodes[i]; + arc.ArchiveObjectPosition(node); + node->ArchiveStatic(arc); + } } bool PathSearch::ArchiveDynamic(Archiver& arc) { - PathNode* node; - int i; - int count; + PathNode *node; + int i; + int count; - if (arc.Loading()) - { - arc.ArchiveInteger(&count); - if (count != nodecount) { - Com_Printf("Path file invalid - cannot load save game\n"); - return false; - } - } - else - { - arc.ArchiveInteger(&nodecount); - } + if (arc.Loading()) { + arc.ArchiveInteger(&count); + if (count != nodecount) { + Com_Printf("Path file invalid - cannot load save game\n"); + return false; + } + } else { + arc.ArchiveInteger(&nodecount); + } - for (i = 0; i < nodecount; i++) { - node = PathSearch::pathnodes[i]; - node->ArchiveDynamic(arc); - } + for (i = 0; i < nodecount; i++) { + node = PathSearch::pathnodes[i]; + node->ArchiveDynamic(arc); + } - return true; + return true; } -void PathSearch::ArchiveLoadNodes - ( - void - ) +void PathSearch::ArchiveLoadNodes(void) { - Archiver arc; - qboolean success; + Archiver arc; + qboolean success; - success = qfalse; - if( arc.Read( level.m_pathfile, false ) ) - { - int file_version; - str maptime; + success = qfalse; + if (arc.Read(level.m_pathfile, false)) { + int file_version; + str maptime; - // get file values - arc.ArchiveInteger( &file_version ); - if( file_version != PATHFILE_VERSION ) - { - Com_Printf( "Expecting version %d path file. Path file is version %d.\n", PATHFILE_VERSION, file_version ); - arc.Close(); - return; - } + // get file values + arc.ArchiveInteger(&file_version); + if (file_version != PATHFILE_VERSION) { + Com_Printf("Expecting version %d path file. Path file is version %d.\n", PATHFILE_VERSION, file_version); + arc.Close(); + return; + } - arc.ArchiveString( &maptime ); - if( gi.MapTime() == maptime && gi.FS_FileNewer( level.m_mapfile.c_str(), level.m_pathfile.c_str() ) <= 0 ) - { - arc.ArchiveInteger( &m_NodeCheckFailed ); + arc.ArchiveString(&maptime); + if (gi.MapTime() == maptime && gi.FS_FileNewer(level.m_mapfile.c_str(), level.m_pathfile.c_str()) <= 0) { + arc.ArchiveInteger(&m_NodeCheckFailed); - if( !g_nodecheck->integer || !m_NodeCheckFailed ) - { - ArchiveStaticLoad( arc ); - m_bNodesloaded = arc.NoErrors(); - } - else - { - gi.Printf( "Rebuilding pathnodes to view node errors.\n" ); - } - } - else - { - gi.Printf( "Pathnodes have changed, rebuilding.\n" ); - } - } + if (!g_nodecheck->integer || !m_NodeCheckFailed) { + ArchiveStaticLoad(arc); + m_bNodesloaded = arc.NoErrors(); + } else { + gi.Printf("Rebuilding pathnodes to view node errors.\n"); + } + } else { + gi.Printf("Pathnodes have changed, rebuilding.\n"); + } + } - arc.Close(); + arc.Close(); } -qboolean PathSearch::ArchiveSaveNodes - ( - void - ) +qboolean PathSearch::ArchiveSaveNodes(void) { - Archiver arc; - str maptime; - int tempInt; + Archiver arc; + str maptime; + int tempInt; - arc.Create( level.m_pathfile ); - tempInt = PATHFILE_VERSION; - arc.ArchiveInteger( &tempInt ); - maptime = gi.MapTime(); - arc.ArchiveString( &maptime ); - arc.ArchiveInteger( &m_NodeCheckFailed ); - ArchiveStaticSave( arc ); - arc.Close(); + arc.Create(level.m_pathfile); + tempInt = PATHFILE_VERSION; + arc.ArchiveInteger(&tempInt); + maptime = gi.MapTime(); + arc.ArchiveString(&maptime); + arc.ArchiveInteger(&m_NodeCheckFailed); + ArchiveStaticSave(arc); + arc.Close(); - return true; + return true; } -void PathSearch::Connect - ( - PathNode *node - ) +void PathSearch::Connect(PathNode *node) { - int x; - int y; + int x; + int y; - findFrame++; - node->findCount = findFrame; + findFrame++; + node->findCount = findFrame; - x = NodeCoordinate( node->origin[ 0 ] ); - y = NodeCoordinate( node->origin[ 1 ] ); + x = NodeCoordinate(node->origin[0]); + y = NodeCoordinate(node->origin[1]); - if( Connect( node, x - 1, y - 1 ) ) - { - if( Connect( node, x - 1, y ) ) - { - if( Connect( node, x - 1, y + 1 ) ) - { - if( Connect( node, x, y - 1 ) ) - { - if( Connect( node, x, y ) ) - { - if( Connect( node, x, y + 1 ) ) - { - if( Connect( node, x + 1, y - 1 ) ) - { - if( Connect( node, x + 1, y ) ) - { - Connect( node, x + 1, y + 1 ); - } - } - } - } - } - } - } - } + if (Connect(node, x - 1, y - 1)) { + if (Connect(node, x - 1, y)) { + if (Connect(node, x - 1, y + 1)) { + if (Connect(node, x, y - 1)) { + if (Connect(node, x, y)) { + if (Connect(node, x, y + 1)) { + if (Connect(node, x + 1, y - 1)) { + if (Connect(node, x + 1, y)) { + Connect(node, x + 1, y + 1); + } + } + } + } + } + } + } + } } -bool PathSearch::Connect - ( - PathNode *node, - int x, - int y - ) +bool PathSearch::Connect(PathNode *node, int x, int y) { - MapCell *cell; - int i; - PathNode *node2; + MapCell *cell; + int i; + PathNode *node2; - if( x > PATHMAP_GRIDSIZE || y > PATHMAP_GRIDSIZE ) - cell = NULL; - else - cell = &PathMap[ x ][ y ]; + if (x > PATHMAP_GRIDSIZE || y > PATHMAP_GRIDSIZE) { + cell = NULL; + } else { + cell = &PathMap[x][y]; + } - if( !cell ) - return true; + if (!cell) { + return true; + } - if( cell->numnodes <= 0 ) - return true; + if (cell->numnodes <= 0) { + return true; + } - for( i = 0; i < cell->numnodes; i++ ) - { - node2 = pathnodes[ cell->nodes[ i ] ]; + for (i = 0; i < cell->numnodes; i++) { + node2 = pathnodes[cell->nodes[i]]; - if( node2->findCount != findFrame ) - { - node2->findCount = findFrame; + if (node2->findCount != findFrame) { + node2->findCount = findFrame; - if( !node->CheckPathTo( node2 ) ) - return false; - } - } + if (!node->CheckPathTo(node2)) { + return false; + } + } + } - return true; + return true; } -void PathSearch::ShowNodes - ( - void - ) +void PathSearch::ShowNodes(void) { - if( g_entities->client ) - { - if( ai_shownode->integer ) - { - DrawNode( ai_shownode->integer ); - } - if( ai_showroutes->integer || ai_shownodenums->integer ) - { - DrawAllConnections(); - } - } + if (g_entities->client) { + if (ai_shownode->integer) { + DrawNode(ai_shownode->integer); + } + if (ai_showroutes->integer || ai_shownodenums->integer) { + DrawAllConnections(); + } + } - if( ai_showpath->integer ) - { - if( !test_path ) - test_path = new ActorPath; + if (ai_showpath->integer) { + if (!test_path) { + test_path = new ActorPath; + } - if( ai_showpath->integer == 1 ) - { - ai_startpath = g_entities[ 0 ].entity->origin; - } - if( ai_showpath->integer == 2 ) - { - ai_endpath = g_entities[ 0 ].entity->origin; - } - if( ai_showpath->integer <= 2 ) - { - test_path->SetFallHeight( ai_fallheight->integer ); - test_path->FindPath( ai_startpath, ai_endpath, NULL, 0, NULL, 0 ); - } - if( ai_showpath->integer == 3 ) - { - if( test_path->CurrentNode() ) - { - test_path->UpdatePos( g_entities[ 0 ].entity->origin ); + if (ai_showpath->integer == 1) { + ai_startpath = g_entities[0].entity->origin; + } + if (ai_showpath->integer == 2) { + ai_endpath = g_entities[0].entity->origin; + } + if (ai_showpath->integer <= 2) { + test_path->SetFallHeight(ai_fallheight->integer); + test_path->FindPath(ai_startpath, ai_endpath, NULL, 0, NULL, 0); + } + if (ai_showpath->integer == 3) { + if (test_path->CurrentNode()) { + test_path->UpdatePos(g_entities[0].entity->origin); - Vector vStart = g_entities[ 0 ].entity->origin + Vector( 0, 0, 32 ); - Vector vEnd = g_entities[ 0 ].entity->origin + test_path->CurrentDelta() + Vector( 0, 0, 32 ); + Vector vStart = g_entities[0].entity->origin + Vector(0, 0, 32); + Vector vEnd = g_entities[0].entity->origin + test_path->CurrentDelta() + Vector(0, 0, 32); - G_DebugLine( vStart, vEnd, 1, 1, 0, 1 ); - } - } + G_DebugLine(vStart, vEnd, 1, 1, 0, 1); + } + } - G_DebugLine( ai_startpath, ai_endpath, 0, 0, 1, 1 ); + G_DebugLine(ai_startpath, ai_endpath, 0, 0, 1, 1); - if( test_path->CurrentNode() ) - { - PathInfo *pos = test_path->CurrentNode(); + if (test_path->CurrentNode()) { + PathInfo *pos = test_path->CurrentNode(); - while( pos != test_path->LastNode() ) - { - Vector vStart = pos->point + Vector( 0, 0, 32 ); + while (pos != test_path->LastNode()) { + Vector vStart = pos->point + Vector(0, 0, 32); - pos--; + pos--; - Vector vEnd = pos->point + Vector( 0, 0, 32 ); + Vector vEnd = pos->point + Vector(0, 0, 32); - G_DebugLine( vStart, vEnd, 1, 0, 0, 1 ); - } - } - } + G_DebugLine(vStart, vEnd, 1, 0, 0, 1); + } + } + } } -void PathSearch::LoadNodes - ( - void - ) +void PathSearch::LoadNodes(void) { - Init(); + Init(); - ArchiveLoadNodes(); + ArchiveLoadNodes(); } -void PathSearch::CreatePaths - ( - void - ) +void PathSearch::CreatePaths(void) { - int i; - int j; - int x; - int y; - PathNode *node; - Vector start; - Vector end; - gentity_t *ent; - int t1; - int t2; + int i; + int j; + int x; + int y; + PathNode *node; + Vector start; + Vector end; + gentity_t *ent; + int t1; + int t2; - if( m_bNodesloaded ) - return; + if (m_bNodesloaded) { + return; + } - if( !nodecount ) - { - m_bNodesloaded = true; - return; - } + if (!nodecount) { + m_bNodesloaded = true; + return; + } - m_NodeCheckFailed = false; + m_NodeCheckFailed = false; - gi.DPrintf( "***********************************\n" - "***********************************\n" - "\n" - "Creating paths...\n" - "\n" - "***********************************\n" - "***********************************\n" ); + gi.DPrintf( + "***********************************\n" + "***********************************\n" + "\n" + "Creating paths...\n" + "\n" + "***********************************\n" + "***********************************\n" + ); - t1 = gi.Milliseconds(); + t1 = gi.Milliseconds(); - for( i = 0, ent = g_entities; i < game.maxentities; i++, ent++ ) - { - if( ent->entity && ent->entity->IsSubclassOfDoor() ) - gi.unlinkentity( ent ); - } + for (i = 0, ent = g_entities; i < game.maxentities; i++, ent++) { + if (ent->entity && ent->entity->IsSubclassOfDoor()) { + gi.unlinkentity(ent); + } + } - for( x = 0; x < PATHMAP_GRIDSIZE; x++ ) - { - for( y = 0; y < PATHMAP_GRIDSIZE; y++ ) - { - MapCell *cell = &PathMap[ x ][ y ]; + for (x = 0; x < PATHMAP_GRIDSIZE; x++) { + for (y = 0; y < PATHMAP_GRIDSIZE; y++) { + MapCell *cell = &PathMap[x][y]; - cell->nodes = ( short * )gi.Malloc( PATHMAP_CELLSIZE ); - cell->numnodes = 0; - memset( cell->nodes, 0, PATHMAP_CELLSIZE ); - } - } + cell->nodes = (short *)gi.Malloc(PATHMAP_CELLSIZE); + cell->numnodes = 0; + memset(cell->nodes, 0, PATHMAP_CELLSIZE); + } + } - for( i = 0; i < nodecount; i++ ) - { - node = pathnodes[ i ]; + for (i = 0; i < nodecount; i++) { + node = pathnodes[i]; - start = node->origin + Vector( 0, 0, 36.0f ); - end = node->origin - Vector( 0, 0, 2048.0f ); + start = node->origin + Vector(0, 0, 36.0f); + end = node->origin - Vector(0, 0, 2048.0f); - trace_t trace = G_Trace( start, - PLAYER_BASE_MIN, - PLAYER_BASE_MAX, - end, - NULL, - MASK_PATHSOLID, - qfalse, - "droptofloor" ); + trace_t trace = + G_Trace(start, PLAYER_BASE_MIN, PLAYER_BASE_MAX, end, NULL, MASK_PATHSOLID, qfalse, "droptofloor"); - node->origin = trace.endpos; - node->centroid = trace.endpos; + node->origin = trace.endpos; + node->centroid = trace.endpos; - if( !( node->nodeflags & PATH_DONT_LINK ) ) - { - for( j = i - 1; j >= 0; j-- ) - { - PathNode *node2 = pathnodes[ j ]; + if (!(node->nodeflags & PATH_DONT_LINK)) { + for (j = i - 1; j >= 0; j--) { + PathNode *node2 = pathnodes[j]; - if( node2->origin == node->origin ) - { - Com_Printf( "^~^~^ Duplicate node at (%.2f %.2f %.2f) not linked\n", node->origin[ 0 ], node->origin[ 1 ], node->origin[ 2 ] ); - node->nodeflags |= PATH_DONT_LINK; - break; - } - } + if (node2->origin == node->origin) { + Com_Printf( + "^~^~^ Duplicate node at (%.2f %.2f %.2f) not linked\n", + node->origin[0], + node->origin[1], + node->origin[2] + ); + node->nodeflags |= PATH_DONT_LINK; + break; + } + } - if( !( node->nodeflags & PATH_DONT_LINK ) ) - node->Child = ( pathway_t * )gi.Malloc( sizeof( pathway_t ) * PATHMAP_NODES ); - } - } + if (!(node->nodeflags & PATH_DONT_LINK)) { + node->Child = (pathway_t *)gi.Malloc(sizeof(pathway_t) * PATHMAP_NODES); + } + } + } - for( i = 0; i < nodecount; i++ ) - { - node = pathnodes[ i ]; + for (i = 0; i < nodecount; i++) { + node = pathnodes[i]; - if( node->nodeflags & PATH_DONT_LINK ) - continue; + if (node->nodeflags & PATH_DONT_LINK) { + continue; + } - AddNode( node ); - } + AddNode(node); + } - for( i = 0; i < nodecount; i++ ) - { - node = pathnodes[ i ]; + for (i = 0; i < nodecount; i++) { + node = pathnodes[i]; - if( node->nodeflags & PATH_DONT_LINK ) - continue; + if (node->nodeflags & PATH_DONT_LINK) { + continue; + } - Connect( node ); - } + Connect(node); + } - for( i = 0, ent = g_entities; i < game.maxentities; i++, ent++ ) - { - if( ent->entity && ent->entity->IsSubclassOfDoor() ) - ent->entity->link(); - } + for (i = 0, ent = g_entities; i < game.maxentities; i++, ent++) { + if (ent->entity && ent->entity->IsSubclassOfDoor()) { + ent->entity->link(); + } + } - gi.DPrintf( "\nSaving path nodes to '%s'\n", level.m_pathfile.c_str() ); - Com_Printf( "Archiving\n" ); - ArchiveSaveNodes(); - m_bNodesloaded = true; - Com_Printf( "done.\n" ); - - t2 = gi.Milliseconds(); - Com_Printf( "Path connection: %5.2f seconds\n", ( t2 - t1 ) / 1000.0f ); - Com_Printf( "Number of nodes: %d\n", nodecount ); - gi.ClearResource(); + gi.DPrintf("\nSaving path nodes to '%s'\n", level.m_pathfile.c_str()); + Com_Printf("Archiving\n"); + ArchiveSaveNodes(); + m_bNodesloaded = true; + Com_Printf("done.\n"); - if( g_nodecheck->integer && m_NodeCheckFailed ) - { - gi.Error( ERR_DROP, "Node check failed" ); - } + t2 = gi.Milliseconds(); + Com_Printf("Path connection: %5.2f seconds\n", (t2 - t1) / 1000.0f); + Com_Printf("Number of nodes: %d\n", nodecount); + gi.ClearResource(); + + if (g_nodecheck->integer && m_NodeCheckFailed) { + gi.Error(ERR_DROP, "Node check failed"); + } } -void *PathSearch::AllocPathNode - ( - void - ) +void *PathSearch::AllocPathNode(void) { - if( bulkNavMemory && !m_bNodesloaded ) - { - bulkNavMemory -= sizeof( PathNode ); - return bulkNavMemory; - } - else - { - return gi.Malloc( sizeof( PathNode ) ); - } + if (bulkNavMemory && !m_bNodesloaded) { + bulkNavMemory -= sizeof(PathNode); + return bulkNavMemory; + } else { + return gi.Malloc(sizeof(PathNode)); + } } -void PathSearch::FreePathNode - ( - void *ptr - ) +void PathSearch::FreePathNode(void *ptr) { - if( !bulkNavMemory || m_bNodesloaded ) - { - gi.Free( ptr ); - } + if (!bulkNavMemory || m_bNodesloaded) { + gi.Free(ptr); + } } -void PathSearch::ResetNodes - ( - void - ) +void PathSearch::ResetNodes(void) { - int i; - int x; - int y; + int i; + int x; + int y; - m_LoadIndex = -1; - m_bNodesloaded = false; + m_LoadIndex = -1; + m_bNodesloaded = false; - if( !startBulkNavMemory ) - { - for( x = PATHMAP_GRIDSIZE - 1; x >= 0; x-- ) - { - for( y = PATHMAP_GRIDSIZE - 1; y >= 0; y-- ) - { - if( PathMap[ x ][ y ].nodes ) - gi.Free( PathMap[ x ][ y ].nodes ); - } - } + if (!startBulkNavMemory) { + for (x = PATHMAP_GRIDSIZE - 1; x >= 0; x--) { + for (y = PATHMAP_GRIDSIZE - 1; y >= 0; y--) { + if (PathMap[x][y].nodes) { + gi.Free(PathMap[x][y].nodes); + } + } + } - for( i = 0; i < nodecount; i++ ) - { - if( pathnodes[ i ]->Child ) - gi.Free( pathnodes[ i ]->Child ); - } - } + for (i = 0; i < nodecount; i++) { + if (pathnodes[i]->Child) { + gi.Free(pathnodes[i]->Child); + } + } + } - for( x = PATHMAP_GRIDSIZE - 1; x >= 0; x-- ) - { - for( y = PATHMAP_GRIDSIZE - 1; y >= 0; y-- ) - { - PathMap[ x ][ y ].numnodes = 0; - PathMap[ x ][ y ].nodes = NULL; - } - } + for (x = PATHMAP_GRIDSIZE - 1; x >= 0; x--) { + for (y = PATHMAP_GRIDSIZE - 1; y >= 0; y--) { + PathMap[x][y].numnodes = 0; + PathMap[x][y].nodes = NULL; + } + } - for( i = 0; i < nodecount; i++ ) - { - delete pathnodes[ i ]; - pathnodes[ i ] = NULL; - } + for (i = 0; i < nodecount; i++) { + delete pathnodes[i]; + pathnodes[i] = NULL; + } - nodecount = 0; + nodecount = 0; - // Free the bulk nav' memory - if( startBulkNavMemory ) - { - gi.Free( startBulkNavMemory ); - bulkNavMemory = NULL; - startBulkNavMemory = NULL; - } + // Free the bulk nav' memory + if (startBulkNavMemory) { + gi.Free(startBulkNavMemory); + bulkNavMemory = NULL; + startBulkNavMemory = NULL; + } } void PathSearch::UpdatePathwaysForBadPlace(const Vector& origin, float radius, int dir, int team) { - float radiusSqr; - int i, j, k; + float radiusSqr; + int i, j, k; - radiusSqr = radius * radius; + radiusSqr = radius * radius; - for (i = 0; i < nodecount; i++) { - PathNode* node = pathnodes[i]; + for (i = 0; i < nodecount; i++) { + PathNode *node = pathnodes[i]; - for (j = node->virtualNumChildren; j > 0; j--) { - pathway_t& pathway = node->Child[j - 1]; - if (PointToSegmentDistanceSquared(origin, pathway.pos1, pathway.pos2) < radiusSqr) { - for (k = 0; k < 2; k++) { - if ((1 << i) & team) { - pathway.numBlockers += dir; - } - } - } - } - } + for (j = node->virtualNumChildren; j > 0; j--) { + pathway_t& pathway = node->Child[j - 1]; + if (PointToSegmentDistanceSquared(origin, pathway.pos1, pathway.pos2) < radiusSqr) { + for (k = 0; k < 2; k++) { + if ((1 << i) & team) { + pathway.numBlockers += dir; + } + } + } + } + } } -PathInfo *PathSearch::GeneratePath - ( - PathInfo *path - ) +PathInfo *PathSearch::GeneratePath(PathInfo *path) { - PathNode *ParentNode; - pathway_t *pathway; - float dist; - float dir[ 2 ]; - PathInfo *current_path; + PathNode *ParentNode; + pathway_t *pathway; + float dist; + float dir[2]; + PathInfo *current_path; - current_path = path; + current_path = path; - dir[ 0 ] = path_end[ 0 ] - Node->m_PathPos[ 0 ]; - dir[ 1 ] = path_end[ 1 ] - Node->m_PathPos[ 1 ]; + dir[0] = path_end[0] - Node->m_PathPos[0]; + dir[1] = path_end[1] - Node->m_PathPos[1]; - dist = VectorNormalize2D( dir ); + dist = VectorNormalize2D(dir); - total_dist = dist + Node->g; + total_dist = dist + Node->g; - path->point[ 0 ] = path_end[ 0 ]; - path->point[ 1 ] = path_end[ 1 ]; - path->point[ 2 ] = path_end[ 2 ]; + path->point[0] = path_end[0]; + path->point[1] = path_end[1]; + path->point[2] = path_end[2]; - ParentNode = Node->Parent; - if( ParentNode ) - { - pathway = &ParentNode->Child[ Node->pathway ]; + ParentNode = Node->Parent; + if (ParentNode) { + pathway = &ParentNode->Child[Node->pathway]; - path->dir[ 0 ] = path_end[ 0 ] - pathway->pos2[ 0 ]; - path->dir[ 1 ] = path_end[ 1 ] - pathway->pos2[ 1 ]; - path->dist = VectorNormalize2D( path->dir ); + path->dir[0] = path_end[0] - pathway->pos2[0]; + path->dir[1] = path_end[1] - pathway->pos2[1]; + path->dist = VectorNormalize2D(path->dir); - if( path->dist ) - { - path->bAccurate = false; - current_path = path + 1; - } + if (path->dist) { + path->bAccurate = false; + current_path = path + 1; + } - if( pathway->dist ) - { - VectorCopy( pathway->pos2, current_path->point ); - current_path->dir[ 0 ] = pathway->dir[ 0 ]; - current_path->dir[ 1 ] = pathway->dir[ 1 ]; - current_path->dist = pathway->dist; - current_path->bAccurate = true; - current_path++; - } + if (pathway->dist) { + VectorCopy(pathway->pos2, current_path->point); + current_path->dir[0] = pathway->dir[0]; + current_path->dir[1] = pathway->dir[1]; + current_path->dist = pathway->dist; + current_path->bAccurate = true; + current_path++; + } - for( Node = ParentNode, ParentNode = ParentNode->Parent; ParentNode != NULL; Node = ParentNode, ParentNode = ParentNode->Parent ) - { - pathway = &ParentNode->Child[ Node->pathway ]; - if( pathway->dist ) - { - VectorCopy( pathway->pos2, current_path->point ); - current_path->dir[ 0 ] = pathway->dir[ 0 ]; - current_path->dir[ 1 ] = pathway->dir[ 1 ]; - current_path->dist = pathway->dist; - current_path->bAccurate = true; - current_path++; - } - } + for (Node = ParentNode, ParentNode = ParentNode->Parent; ParentNode != NULL; + Node = ParentNode, ParentNode = ParentNode->Parent) { + pathway = &ParentNode->Child[Node->pathway]; + if (pathway->dist) { + VectorCopy(pathway->pos2, current_path->point); + current_path->dir[0] = pathway->dir[0]; + current_path->dir[1] = pathway->dir[1]; + current_path->dist = pathway->dist; + current_path->bAccurate = true; + current_path++; + } + } - VectorCopy( pathway->pos1, current_path->point ); - current_path->dir[ 0 ] = path_startdir[ 0 ]; - current_path->dir[ 1 ] = path_startdir[ 1 ]; - current_path->dist = Node->g; - } - else - { - path->dir[ 0 ] = path_totaldir[ 0 ]; - path->dir[ 1 ] = path_totaldir[ 1 ]; - path->dist = Node->h; - } + VectorCopy(pathway->pos1, current_path->point); + current_path->dir[0] = path_startdir[0]; + current_path->dir[1] = path_startdir[1]; + current_path->dist = Node->g; + } else { + path->dir[0] = path_totaldir[0]; + path->dir[1] = path_totaldir[1]; + path->dist = Node->h; + } - if( current_path->dist ) - { - current_path->bAccurate = false; - current_path++; + if (current_path->dist) { + current_path->bAccurate = false; + current_path++; - VectorCopy( path_start, current_path->point ); - current_path->dist = 0; - VectorClear2D( current_path->dir ); - } + VectorCopy(path_start, current_path->point); + current_path->dist = 0; + VectorClear2D(current_path->dir); + } - current_path->bAccurate = false; - return current_path; + current_path->bAccurate = false; + return current_path; } -PathInfo *PathSearch::GeneratePathNear - ( - PathInfo *path - ) +PathInfo *PathSearch::GeneratePathNear(PathInfo *path) { - PathInfo *current_path = path; - pathway_t *pathway; - PathNode *ParentNode; + PathInfo *current_path = path; + pathway_t *pathway; + PathNode *ParentNode; - total_dist = Node->g; - VectorCopy( Node->m_PathPos, path->point ); + total_dist = Node->g; + VectorCopy(Node->m_PathPos, path->point); - ParentNode = Node->Parent; - if( ParentNode ) - { - pathway = &ParentNode->Child[ Node->pathway ]; + ParentNode = Node->Parent; + if (ParentNode) { + pathway = &ParentNode->Child[Node->pathway]; - if( pathway->dist ) - { - VectorCopy( pathway->pos2, path->point ); - path->dir[ 0 ] = pathway->dir[ 0 ]; - path->dir[ 1 ] = pathway->dir[ 1 ]; - path->dist = pathway->dist; + if (pathway->dist) { + VectorCopy(pathway->pos2, path->point); + path->dir[0] = pathway->dir[0]; + path->dir[1] = pathway->dir[1]; + path->dist = pathway->dist; - current_path->bAccurate = true; - current_path++; - } + current_path->bAccurate = true; + current_path++; + } - for( Node = ParentNode, ParentNode = ParentNode->Parent; ParentNode != NULL; Node = ParentNode, ParentNode = ParentNode->Parent ) - { - pathway = &ParentNode->Child[ Node->pathway ]; - if( pathway->dist ) - { - VectorCopy( pathway->pos2, current_path->point ); - current_path->dir[ 0 ] = pathway->dir[ 0 ]; - current_path->dir[ 1 ] = pathway->dir[ 1 ]; - current_path->dist = pathway->dist; - current_path->bAccurate = true; - current_path++; - } - } + for (Node = ParentNode, ParentNode = ParentNode->Parent; ParentNode != NULL; + Node = ParentNode, ParentNode = ParentNode->Parent) { + pathway = &ParentNode->Child[Node->pathway]; + if (pathway->dist) { + VectorCopy(pathway->pos2, current_path->point); + current_path->dir[0] = pathway->dir[0]; + current_path->dir[1] = pathway->dir[1]; + current_path->dist = pathway->dist; + current_path->bAccurate = true; + current_path++; + } + } - VectorCopy( pathway->pos1, current_path->point ); - current_path->dir[ 0 ] = path_startdir[ 0 ]; - current_path->dir[ 1 ] = path_startdir[ 1 ]; + VectorCopy(pathway->pos1, current_path->point); + current_path->dir[0] = path_startdir[0]; + current_path->dir[1] = path_startdir[1]; - current_path->dist = Node->g; - } - else - { - path->dir[ 0 ] = path_totaldir[ 0 ]; - path->dir[ 1 ] = path_totaldir[ 1 ]; - path->dist = Node->h; - } + current_path->dist = Node->g; + } else { + path->dir[0] = path_totaldir[0]; + path->dir[1] = path_totaldir[1]; + path->dist = Node->h; + } - if( current_path->dist ) - { - current_path->bAccurate = false; - current_path++; + if (current_path->dist) { + current_path->bAccurate = false; + current_path++; - VectorCopy( path_start, current_path->point ); - current_path->dist = 0; - VectorClear2D( current_path->dir ); - } + VectorCopy(path_start, current_path->point); + current_path->dist = 0; + VectorClear2D(current_path->dir); + } - current_path->bAccurate = false; - return current_path; + current_path->bAccurate = false; + return current_path; } -PathInfo *PathSearch::GeneratePathAway - ( - PathInfo *path - ) +PathInfo *PathSearch::GeneratePathAway(PathInfo *path) { - PathInfo *current_path = path; - pathway_t *pathway; - PathNode *ParentNode; + PathInfo *current_path = path; + pathway_t *pathway; + PathNode *ParentNode; - VectorCopy( Node->m_PathPos, path->point ); + VectorCopy(Node->m_PathPos, path->point); - ParentNode = Node->Parent; - if( ParentNode ) - { - pathway = &ParentNode->Child[ Node->pathway ]; + ParentNode = Node->Parent; + if (ParentNode) { + pathway = &ParentNode->Child[Node->pathway]; - if( pathway->dist ) - { - VectorCopy( pathway->pos2, path->point ); - path->dir[ 0 ] = pathway->dir[ 0 ]; - path->dir[ 1 ] = pathway->dir[ 1 ]; - path->dist = pathway->dist; + if (pathway->dist) { + VectorCopy(pathway->pos2, path->point); + path->dir[0] = pathway->dir[0]; + path->dir[1] = pathway->dir[1]; + path->dist = pathway->dist; - current_path->bAccurate = true; - current_path++; - } + current_path->bAccurate = true; + current_path++; + } - for( Node = ParentNode, ParentNode = ParentNode->Parent; ParentNode != NULL; Node = ParentNode, ParentNode = ParentNode->Parent ) - { - pathway = &ParentNode->Child[ Node->pathway ]; - if( pathway->dist ) - { - VectorCopy( pathway->pos2, current_path->point ); - current_path->dir[ 0 ] = pathway->dir[ 0 ]; - current_path->dir[ 1 ] = pathway->dir[ 1 ]; - current_path->dist = pathway->dist; - current_path->bAccurate = true; - current_path++; - } - } + for (Node = ParentNode, ParentNode = ParentNode->Parent; ParentNode != NULL; + Node = ParentNode, ParentNode = ParentNode->Parent) { + pathway = &ParentNode->Child[Node->pathway]; + if (pathway->dist) { + VectorCopy(pathway->pos2, current_path->point); + current_path->dir[0] = pathway->dir[0]; + current_path->dir[1] = pathway->dir[1]; + current_path->dist = pathway->dist; + current_path->bAccurate = true; + current_path++; + } + } - VectorCopy( pathway->pos1, current_path->point ); - current_path->dir[ 0 ] = path_startdir[ 0 ]; - current_path->dir[ 1 ] = path_startdir[ 1 ]; + VectorCopy(pathway->pos1, current_path->point); + current_path->dir[0] = path_startdir[0]; + current_path->dir[1] = path_startdir[1]; - current_path->dist = Node->g; + current_path->dist = Node->g; - if( Node->g ) - { - current_path->bAccurate = false; - current_path++; - VectorCopy( path_start, current_path->point ); - current_path->dist = 0; - VectorClear2D( current_path->dir ); - } - } - else - { - VectorClear2D( path->dir ); - path->dist = 0; - } + if (Node->g) { + current_path->bAccurate = false; + current_path++; + VectorCopy(path_start, current_path->point); + current_path->dist = 0; + VectorClear2D(current_path->dir); + } + } else { + VectorClear2D(path->dir); + path->dist = 0; + } - current_path->bAccurate = false; - return current_path; + current_path->bAccurate = false; + return current_path; } -PathNode *PathSearch::GetSpawnNode - ( - ClassDef *cls - ) +PathNode *PathSearch::GetSpawnNode(ClassDef *cls) { - if( m_bNodesloaded ) - { - return pathnodes[ m_LoadIndex++ ]; - } - else - { - // Otherwise create a new node - return ( PathNode * )cls->newInstance(); - } + if (m_bNodesloaded) { + return pathnodes[m_LoadIndex++]; + } else { + // Otherwise create a new node + return (PathNode *)cls->newInstance(); + } } -int PathSearch::FindPath - ( - float *start, - float *end, - Entity *ent, - float maxPath, - float *vLeashHome, - float fLeashDistSquared, - int fallheight - ) +int PathSearch::FindPath( + float *start, float *end, Entity *ent, float maxPath, float *vLeashHome, float fLeashDistSquared, int fallheight +) { - int i; - int g; - PathNode *NewNode; - pathway_t *pathway; - PathNode *prev; - PathNode *next; - int f; - vec2_t delta; - PathNode *to; + int i; + int g; + PathNode *NewNode; + pathway_t *pathway; + PathNode *prev; + PathNode *next; + int f; + vec2_t delta; + PathNode *to; - if( ent ) - { - if( ent->IsSubclassOfActor() ) - { - Node = NearestStartNode( start, ( SimpleActor * )ent ); - } - else - { - Node = DebugNearestStartNode( start, ent ); - } - } - else - { - Node = DebugNearestStartNode( start ); - } + if (ent) { + if (ent->IsSubclassOfActor()) { + Node = NearestStartNode(start, (SimpleActor *)ent); + } else { + Node = DebugNearestStartNode(start, ent); + } + } else { + Node = DebugNearestStartNode(start); + } - if( !Node ) - { - last_error = "couldn't find start node"; - return 0; - } + if (!Node) { + last_error = "couldn't find start node"; + return 0; + } - to = NearestEndNode( end ); - if( !to ) - { - last_error = "couldn't find end node"; - return 0; - } + to = NearestEndNode(end); + if (!to) { + last_error = "couldn't find end node"; + return 0; + } - total_dist = 9e+11f; + total_dist = 9e+11f; - if( !maxPath ) - maxPath = 9e+11f; + if (!maxPath) { + maxPath = 9e+11f; + } - findFrame++; - open = NULL; + findFrame++; + open = NULL; - path_startdir[ 0 ] = Node->origin[ 0 ] - start[ 0 ]; - path_startdir[ 1 ] = Node->origin[ 1 ] - start[ 1 ]; + path_startdir[0] = Node->origin[0] - start[0]; + path_startdir[1] = Node->origin[1] - start[1]; - Node->g = VectorNormalize2D( path_startdir ); + Node->g = VectorNormalize2D(path_startdir); - path_totaldir[ 0 ] = end[ 0 ] - start[ 0 ]; - path_totaldir[ 1 ] = end[ 1 ] - start[ 1 ]; + path_totaldir[0] = end[0] - start[0]; + path_totaldir[1] = end[1] - start[1]; - Node->h = VectorNormalize2D( path_totaldir ); - Node->inopen = true; - Node->Parent = NULL; - Node->m_Depth = 3; - Node->m_PathPos = start; - Node->findCount = findFrame; - Node->PrevNode = NULL; - Node->NextNode = NULL; + Node->h = VectorNormalize2D(path_totaldir); + Node->inopen = true; + Node->Parent = NULL; + Node->m_Depth = 3; + Node->m_PathPos = start; + Node->findCount = findFrame; + Node->PrevNode = NULL; + Node->NextNode = NULL; - open = Node; + open = Node; - while( 1 ) - { - Node = open; - Node->inopen = false; + while (1) { + Node = open; + Node->inopen = false; - open = Node->NextNode; - if( open ) - open->PrevNode = NULL; + open = Node->NextNode; + if (open) { + open->PrevNode = NULL; + } - if( Node == to ) - break; + if (Node == to) { + break; + } - for( i = Node->numChildren - 1; i >= 0; i-- ) - { - vec2_t vDist; + for (i = Node->numChildren - 1; i >= 0; i--) { + vec2_t vDist; - pathway = &Node->Child[ i ]; + pathway = &Node->Child[i]; - NewNode = pathnodes[ pathway->node ]; + NewNode = pathnodes[pathway->node]; - if( vLeashHome ) - { - vDist[ 0 ] = pathway->pos2[ 0 ] - vLeashHome[ 0 ]; - vDist[ 1 ] = pathway->pos2[ 1 ] - vLeashHome[ 1 ]; - } + if (vLeashHome) { + vDist[0] = pathway->pos2[0] - vLeashHome[0]; + vDist[1] = pathway->pos2[1] - vLeashHome[1]; + } - if( !vLeashHome || VectorLength2DSquared( vDist ) <= fLeashDistSquared ) - { - g = ( int )( pathway->dist + Node->g + 1.0f ); + if (!vLeashHome || VectorLength2DSquared(vDist) <= fLeashDistSquared) { + g = (int)(pathway->dist + Node->g + 1.0f); - if( NewNode->findCount == findFrame ) - { - if( g >= NewNode->g ) - continue; + if (NewNode->findCount == findFrame) { + if (g >= NewNode->g) { + continue; + } - if( NewNode->inopen ) - { - NewNode->inopen = false; - next = NewNode->NextNode; - prev = NewNode->PrevNode; + if (NewNode->inopen) { + NewNode->inopen = false; + next = NewNode->NextNode; + prev = NewNode->PrevNode; - if( next ) - next->PrevNode = prev; + if (next) { + next->PrevNode = prev; + } - if( prev ) - prev->NextNode = next; - else - open = next; - } - } + if (prev) { + prev->NextNode = next; + } else { + open = next; + } + } + } - delta[ 0 ] = end[ 0 ] - pathway->pos2[ 0 ]; - delta[ 1 ] = end[ 1 ] - pathway->pos2[ 1 ]; + delta[0] = end[0] - pathway->pos2[0]; + delta[1] = end[1] - pathway->pos2[1]; - NewNode->h = VectorLength2D( delta ); + NewNode->h = VectorLength2D(delta); - f = ( int )( ( float )g + NewNode->h ); + f = (int)((float)g + NewNode->h); - if( f >= maxPath ) - { - last_error = "specified path distance exceeded"; - return 0; - } + if (f >= maxPath) { + last_error = "specified path distance exceeded"; + return 0; + } - if( pathway->fallheight <= fallheight ) - { - NewNode->f = f; - NewNode->pathway = i; - NewNode->g = g; - NewNode->Parent = Node; - NewNode->m_Depth = Node->m_Depth + 1; - NewNode->inopen = true; - NewNode->m_PathPos = pathway->pos2; - NewNode->findCount = findFrame; + if (pathway->fallheight <= fallheight) { + NewNode->f = f; + NewNode->pathway = i; + NewNode->g = g; + NewNode->Parent = Node; + NewNode->m_Depth = Node->m_Depth + 1; + NewNode->inopen = true; + NewNode->m_PathPos = pathway->pos2; + NewNode->findCount = findFrame; - if( !open ) - { - NewNode->NextNode = NULL; - NewNode->PrevNode = NULL; - open = NewNode; - continue; - } + if (!open) { + NewNode->NextNode = NULL; + NewNode->PrevNode = NULL; + open = NewNode; + continue; + } - if( open->f >= f ) - { - NewNode->PrevNode = NULL; - NewNode->NextNode = open; + if (open->f >= f) { + NewNode->PrevNode = NULL; + NewNode->NextNode = open; - open->PrevNode = NewNode; - open = NewNode; - continue; - } + open->PrevNode = NewNode; + open = NewNode; + continue; + } - prev = open; - next = open->NextNode; - while( next && next->f < f ) - { - prev = next; - next = next->NextNode; - } + prev = open; + next = open->NextNode; + while (next && next->f < f) { + prev = next; + next = next->NextNode; + } - NewNode->NextNode = next; - if( next ) - next->PrevNode = NewNode; - prev->NextNode = NewNode; - NewNode->PrevNode = prev; - } - } - } + NewNode->NextNode = next; + if (next) { + next->PrevNode = NewNode; + } + prev->NextNode = NewNode; + NewNode->PrevNode = prev; + } + } + } - if( !open ) - { - last_error = "unreachable path"; - return 0; - } - } + if (!open) { + last_error = "unreachable path"; + return 0; + } + } - path_start = start; - path_end = end; + path_start = start; + path_end = end; - return Node->m_Depth; + return Node->m_Depth; } -int PathSearch::FindPathAway - ( - float *start, - float *avoid, - float *vPreferredDir, - Entity *ent, - float fMinSafeDist, - float *vLeashHome, - float fLeashDistSquared, - int fallheight - ) +int PathSearch::FindPathAway( + float *start, + float *avoid, + float *vPreferredDir, + Entity *ent, + float fMinSafeDist, + float *vLeashHome, + float fLeashDistSquared, + int fallheight +) { - int i; - int g; - PathNode *NewNode; - pathway_t *pathway; - PathNode *prev; - PathNode *next; - int f; - float fBias; - vec2_t delta; - float fMinSafeDistSquared = fMinSafeDist * fMinSafeDist; + int i; + int g; + PathNode *NewNode; + pathway_t *pathway; + PathNode *prev; + PathNode *next; + int f; + float fBias; + vec2_t delta; + float fMinSafeDistSquared = fMinSafeDist * fMinSafeDist; - if( ent ) - { - if( ent->IsSubclassOfActor() ) - { - Node = NearestStartNode( start, ( SimpleActor * )ent ); - } - else - { - Node = DebugNearestStartNode( start, ent ); - } - } - else - { - Node = DebugNearestStartNode( start ); - } + if (ent) { + if (ent->IsSubclassOfActor()) { + Node = NearestStartNode(start, (SimpleActor *)ent); + } else { + Node = DebugNearestStartNode(start, ent); + } + } else { + Node = DebugNearestStartNode(start); + } - if( !Node ) - { - last_error = "couldn't find start node"; - return 0; - } + if (!Node) { + last_error = "couldn't find start node"; + return 0; + } - findFrame++; - open = NULL; + findFrame++; + open = NULL; - path_startdir[ 0 ] = Node->origin[ 0 ] - start[ 0 ]; - path_startdir[ 1 ] = Node->origin[ 1 ] - start[ 1 ]; + path_startdir[0] = Node->origin[0] - start[0]; + path_startdir[1] = Node->origin[1] - start[1]; - delta[ 0 ] = start[ 0 ] - avoid[ 0 ]; - delta[ 1 ] = start[ 1 ] - avoid[ 1 ]; + delta[0] = start[0] - avoid[0]; + delta[1] = start[1] - avoid[1]; - fBias = VectorLength2D( vPreferredDir ); + fBias = VectorLength2D(vPreferredDir); - Node->inopen = true; - Node->g = VectorNormalize2D( path_startdir ); - Node->h = fMinSafeDist - VectorNormalize2D( delta ); - Node->h += fBias - DotProduct2D( vPreferredDir, delta ); - Node->Parent = NULL; - Node->m_Depth = 2; - Node->findCount = findFrame; - Node->PrevNode = NULL; - Node->NextNode = NULL; - Node->m_PathPos = start; + Node->inopen = true; + Node->g = VectorNormalize2D(path_startdir); + Node->h = fMinSafeDist - VectorNormalize2D(delta); + Node->h += fBias - DotProduct2D(vPreferredDir, delta); + Node->Parent = NULL; + Node->m_Depth = 2; + Node->findCount = findFrame; + Node->PrevNode = NULL; + Node->NextNode = NULL; + Node->m_PathPos = start; - open = Node; + open = Node; - while( 1 ) - { - Node = open; - Node->inopen = false; + while (1) { + Node = open; + Node->inopen = false; - open = Node->NextNode; + open = Node->NextNode; - if( open ) - open->PrevNode = NULL; + if (open) { + open->PrevNode = NULL; + } - delta[ 0 ] = Node->m_PathPos[ 0 ] - avoid[ 0 ]; - delta[ 1 ] = Node->m_PathPos[ 1 ] - avoid[ 1 ]; + delta[0] = Node->m_PathPos[0] - avoid[0]; + delta[1] = Node->m_PathPos[1] - avoid[1]; - if( VectorLength2DSquared( delta ) >= fMinSafeDistSquared ) - break; + if (VectorLength2DSquared(delta) >= fMinSafeDistSquared) { + break; + } - for( i = Node->numChildren - 1; i >= 0; i-- ) - { - vec2_t vDist; + for (i = Node->numChildren - 1; i >= 0; i--) { + vec2_t vDist; - pathway = &Node->Child[ i ]; - NewNode = pathnodes[ pathway->node ]; + pathway = &Node->Child[i]; + NewNode = pathnodes[pathway->node]; - if( vLeashHome ) - { - vDist[ 0 ] = pathway->pos2[ 0 ] - vLeashHome[ 0 ]; - vDist[ 1 ] = pathway->pos2[ 1 ] - vLeashHome[ 1 ]; - } + if (vLeashHome) { + vDist[0] = pathway->pos2[0] - vLeashHome[0]; + vDist[1] = pathway->pos2[1] - vLeashHome[1]; + } - if( !vLeashHome || VectorLength2DSquared( vDist ) <= fLeashDistSquared ) - { - g = ( int )( pathway->dist + Node->g + 1.0f ); + if (!vLeashHome || VectorLength2DSquared(vDist) <= fLeashDistSquared) { + g = (int)(pathway->dist + Node->g + 1.0f); - if( NewNode->findCount == findFrame ) - { - if( g >= NewNode->g ) - continue; + if (NewNode->findCount == findFrame) { + if (g >= NewNode->g) { + continue; + } - if( NewNode->inopen ) - { - NewNode->inopen = false; - next = NewNode->NextNode; - prev = NewNode->PrevNode; + if (NewNode->inopen) { + NewNode->inopen = false; + next = NewNode->NextNode; + prev = NewNode->PrevNode; - if( next ) - next->PrevNode = prev; + if (next) { + next->PrevNode = prev; + } - if( prev ) - prev->NextNode = next; - else - open = next; - } - } + if (prev) { + prev->NextNode = next; + } else { + open = next; + } + } + } - delta[ 0 ] = pathway->pos2[ 0 ] - avoid[ 0 ]; - delta[ 1 ] = pathway->pos2[ 1 ] - avoid[ 1 ]; + delta[0] = pathway->pos2[0] - avoid[0]; + delta[1] = pathway->pos2[1] - avoid[1]; - NewNode->h = fMinSafeDist - VectorNormalize2D( delta ); - f = NewNode->h + fBias - DotProduct2D( vPreferredDir, delta ); - NewNode->h += f; + NewNode->h = fMinSafeDist - VectorNormalize2D(delta); + f = NewNode->h + fBias - DotProduct2D(vPreferredDir, delta); + NewNode->h += f; - if( pathway->fallheight <= fallheight ) - { - NewNode->Parent = Node; - NewNode->m_Depth = Node->m_Depth + 1; - NewNode->g = g; - NewNode->pathway = i; - NewNode->inopen = true; - NewNode->m_PathPos = pathway->pos2; - NewNode->findCount = findFrame; - NewNode->f = f; + if (pathway->fallheight <= fallheight) { + NewNode->Parent = Node; + NewNode->m_Depth = Node->m_Depth + 1; + NewNode->g = g; + NewNode->pathway = i; + NewNode->inopen = true; + NewNode->m_PathPos = pathway->pos2; + NewNode->findCount = findFrame; + NewNode->f = f; - if( !open ) - { - NewNode->NextNode = NULL; - NewNode->PrevNode = NULL; - open = NewNode; - continue; - } + if (!open) { + NewNode->NextNode = NULL; + NewNode->PrevNode = NULL; + open = NewNode; + continue; + } - if( open->f >= f ) - { - NewNode->PrevNode = NULL; - NewNode->NextNode = open; + if (open->f >= f) { + NewNode->PrevNode = NULL; + NewNode->NextNode = open; - open->PrevNode = NewNode; - open = NewNode; - continue; - } + open->PrevNode = NewNode; + open = NewNode; + continue; + } - prev = open; - next = open->NextNode; - while( next && next->f < f ) - { - prev = next; - next = next->NextNode; - } + prev = open; + next = open->NextNode; + while (next && next->f < f) { + prev = next; + next = next->NextNode; + } - NewNode->NextNode = next; - if( next ) - next->PrevNode = NewNode; - prev->NextNode = NewNode; - NewNode->PrevNode = prev; - } - } - } + NewNode->NextNode = next; + if (next) { + next->PrevNode = NewNode; + } + prev->NextNode = NewNode; + NewNode->PrevNode = prev; + } + } + } - if( !open ) - { - last_error = "unreachable path"; - return 0; - } - } + if (!open) { + last_error = "unreachable path"; + return 0; + } + } - path_start = start; - return Node->m_Depth; + path_start = start; + return Node->m_Depth; } -int PathSearch::FindPathNear - ( - float *start, - float *end, - Entity *ent, - float maxPath, - float fRadiusSquared, - float *vLeashHome, - float fLeashDistSquared, - int fallheight - ) +int PathSearch::FindPathNear( + float *start, + float *end, + Entity *ent, + float maxPath, + float fRadiusSquared, + float *vLeashHome, + float fLeashDistSquared, + int fallheight +) { - int i; - int g; - PathNode *NewNode; - pathway_t *pathway; - PathNode *prev; - PathNode *next; - int f; - vec2_t dir; - vec2_t delta; + int i; + int g; + PathNode *NewNode; + pathway_t *pathway; + PathNode *prev; + PathNode *next; + int f; + vec2_t dir; + vec2_t delta; - if( ent ) - { - if( ent->IsSubclassOfActor() ) - { - Node = NearestStartNode( start, ( SimpleActor * )ent ); - } - else - { - Node = DebugNearestStartNode( start, ent ); - } - } - else - { - Node = DebugNearestStartNode( start ); - } + if (ent) { + if (ent->IsSubclassOfActor()) { + Node = NearestStartNode(start, (SimpleActor *)ent); + } else { + Node = DebugNearestStartNode(start, ent); + } + } else { + Node = DebugNearestStartNode(start); + } - if( !Node ) - { - last_error = "no start node"; - return 0; - } + if (!Node) { + last_error = "no start node"; + return 0; + } - total_dist = 9e11f; + total_dist = 9e11f; - if( !maxPath ) - maxPath = 9e11f; + if (!maxPath) { + maxPath = 9e11f; + } - findFrame++; - open = NULL; + findFrame++; + open = NULL; - path_startdir[ 0 ] = Node->origin[ 0 ] - start[ 0 ]; - path_startdir[ 1 ] = Node->origin[ 1 ] - start[ 1 ]; + path_startdir[0] = Node->origin[0] - start[0]; + path_startdir[1] = Node->origin[1] - start[1]; - dir[ 0 ] = end[ 0 ] - start[ 0 ]; - dir[ 1 ] = end[ 1 ] - start[ 1 ]; + dir[0] = end[0] - start[0]; + dir[1] = end[1] - start[1]; - Node->inopen = true; - Node->g = VectorNormalize2D( path_startdir ); - Node->h = VectorNormalize2D( delta ); - Node->Parent = NULL; - Node->m_Depth = 3; - Node->findCount = findFrame; - Node->PrevNode = NULL; - Node->NextNode = NULL; - Node->m_PathPos = start; + Node->inopen = true; + Node->g = VectorNormalize2D(path_startdir); + Node->h = VectorNormalize2D(delta); + Node->Parent = NULL; + Node->m_Depth = 3; + Node->findCount = findFrame; + Node->PrevNode = NULL; + Node->NextNode = NULL; + Node->m_PathPos = start; - open = Node; + open = Node; - while( 1 ) - { - Node = open; - Node->inopen = false; + while (1) { + Node = open; + Node->inopen = false; - open = Node->NextNode; + open = Node->NextNode; - if( open ) - open->PrevNode = NULL; + if (open) { + open->PrevNode = NULL; + } - delta[ 0 ] = end[ 0 ] - Node->m_PathPos[ 0 ]; - delta[ 1 ] = end[ 1 ] - Node->m_PathPos[ 1 ]; + delta[0] = end[0] - Node->m_PathPos[0]; + delta[1] = end[1] - Node->m_PathPos[1]; - if( fRadiusSquared >= VectorLength2DSquared( delta ) ) - break; + if (fRadiusSquared >= VectorLength2DSquared(delta)) { + break; + } - for( i = Node->numChildren - 1; i >= 0; i-- ) - { - pathway = &Node->Child[ i ]; - NewNode = pathnodes[ pathway->node ]; + for (i = Node->numChildren - 1; i >= 0; i--) { + pathway = &Node->Child[i]; + NewNode = pathnodes[pathway->node]; - g = ( int )( pathway->dist + Node->g + 1.0f ); + g = (int)(pathway->dist + Node->g + 1.0f); - if( NewNode->findCount == findFrame ) - { - if( g >= NewNode->g ) - continue; + if (NewNode->findCount == findFrame) { + if (g >= NewNode->g) { + continue; + } - if( NewNode->inopen ) - { - NewNode->inopen = false; - next = NewNode->NextNode; - prev = NewNode->PrevNode; + if (NewNode->inopen) { + NewNode->inopen = false; + next = NewNode->NextNode; + prev = NewNode->PrevNode; - if( next ) - next->PrevNode = prev; + if (next) { + next->PrevNode = prev; + } - if( prev ) - prev->NextNode = next; - else - open = next; - } - } + if (prev) { + prev->NextNode = next; + } else { + open = next; + } + } + } - delta[ 0 ] = end[ 0 ] - pathway->pos2[ 0 ]; - delta[ 1 ] = end[ 1 ] - pathway->pos2[ 1 ]; + delta[0] = end[0] - pathway->pos2[0]; + delta[1] = end[1] - pathway->pos2[1]; - NewNode->h = VectorLength2D( delta ); - f = ( int )( ( float )g + NewNode->h ); + NewNode->h = VectorLength2D(delta); + f = (int)((float)g + NewNode->h); - if( f >= maxPath ) - { - last_error = "specified path distance exceeded"; - return 0; - } + if (f >= maxPath) { + last_error = "specified path distance exceeded"; + return 0; + } - if( pathway->fallheight <= fallheight ) - { - NewNode->f = f; - NewNode->pathway = i; - NewNode->g = g; - NewNode->Parent = Node; - NewNode->m_Depth = Node->m_Depth + 1; - NewNode->inopen = true; - NewNode->m_PathPos = pathway->pos2; - NewNode->findCount = findFrame; + if (pathway->fallheight <= fallheight) { + NewNode->f = f; + NewNode->pathway = i; + NewNode->g = g; + NewNode->Parent = Node; + NewNode->m_Depth = Node->m_Depth + 1; + NewNode->inopen = true; + NewNode->m_PathPos = pathway->pos2; + NewNode->findCount = findFrame; - if( !open ) - { - NewNode->NextNode = NULL; - NewNode->PrevNode = NULL; - open = NewNode; - continue; - } + if (!open) { + NewNode->NextNode = NULL; + NewNode->PrevNode = NULL; + open = NewNode; + continue; + } - if( open->f >= f ) - { - NewNode->PrevNode = NULL; - NewNode->NextNode = open; + if (open->f >= f) { + NewNode->PrevNode = NULL; + NewNode->NextNode = open; - open->PrevNode = NewNode; - open = NewNode; - continue; - } + open->PrevNode = NewNode; + open = NewNode; + continue; + } - prev = open; - next = open->NextNode; - while( next && next->f < f ) - { - prev = next; - next = next->NextNode; - } + prev = open; + next = open->NextNode; + while (next && next->f < f) { + prev = next; + next = next->NextNode; + } - NewNode->NextNode = next; - if( next ) - next->PrevNode = NewNode; - prev->NextNode = NewNode; - NewNode->PrevNode = prev; - } - } + NewNode->NextNode = next; + if (next) { + next->PrevNode = NewNode; + } + prev->NextNode = NewNode; + NewNode->PrevNode = prev; + } + } - if( !open ) - { - last_error = "unreachable path"; - return 0; - } - } + if (!open) { + last_error = "unreachable path"; + return 0; + } + } - path_start = start; - path_end = end; - return Node->m_Depth; + path_start = start; + path_end = end; + return Node->m_Depth; } -int node_compare(const void *pe1, const void *pe2) +int node_compare(const void *pe1, const void *pe2) { - nodeinfo *Pe1 = (nodeinfo *) pe1; - nodeinfo *Pe2 = (nodeinfo *) pe2; - int iConcealment; + nodeinfo *Pe1 = (nodeinfo *)pe1; + nodeinfo *Pe2 = (nodeinfo *)pe2; + int iConcealment; - iConcealment = (Pe1->pNode->nodeflags & 0xB0) != 0; - if (Pe2->pNode->nodeflags & 0xB0) - --iConcealment; - return ((Pe1->fDistSquared) - + (iConcealment << 23) - + (((Pe1->pNode->nodeflags & 8) - (Pe2->pNode->nodeflags & 8)) << 21) - - (Pe2->fDistSquared)); - -} -PathNode *PathSearch::FindCornerNodeForWall - ( - float *start, - float *end, - SimpleActor *ent, - float maxPath, - float *plane - ) -{ - PathNode *ParentNode; - PathNode *OpenNode; - int i; - - Node = NearestStartNode(start, ent); - if (!Node) - { - last_error = "couldn't find start node"; - return NULL; - } - - if (DotProduct(start, plane) - plane[3] < 0.0) - { - last_error = "starting point is already behind the wall"; - return NULL; - } - - if (DotProduct(plane, end) - plane[3] > 0.0) - { - last_error = "end point is in front of the wall"; - return NULL; - } - - total_dist = 1.0e12f; - - if (maxPath == 0.0) - maxPath = 1.0e12f; - - findFrame++; - open = NULL; - - VectorSub2D(Node->origin, start, path_startdir); - Node->g = VectorNormalize2D(path_startdir); - - VectorSub2D(end, start, path_totaldir); - Node->h = VectorNormalize2D(path_totaldir); - - Node->inopen = true; - - Node->Parent = NULL; - - Node->m_Depth = 3; - Node->m_PathPos = start; - Node->findCount = findFrame; - Node->PrevNode = 0; - Node->NextNode = 0; - - OpenNode = Node; - open = Node; - - if (!open) - { - last_error = "unreachable path"; - return NULL; - } - - while (true) - { - Node = OpenNode; - - Node->inopen = false; - - open = Node->NextNode; - if (open) - { - open->PrevNode = NULL; - } - - ParentNode = Node->Parent; - - if (ParentNode - && DotProduct(plane, Node->m_PathPos) - plane[3] < 0.0) - { - vec2_t delta; - VectorSub2D(ParentNode->m_PathPos, start, delta); - if (VectorLength2DSquared(delta) < Square(16)) - ParentNode = Node; - return ParentNode; - } - - i = Node->numChildren; - if (i) - break; -weird_lbl: - OpenNode = open; - if (!OpenNode) - { - last_error = "unreachable path"; - return NULL; - } - } - - int f, g, h; - while (true) - { - pathway_t *pathway = &Node->Child[--i]; - PathNode *pSomeNode = PathSearch::pathnodes[pathway->node]; - g = (pathway->dist + Node->g + 1.0); - if (pSomeNode->findCount == PathSearch::findFrame) - { - if (g >= pSomeNode->g) - { - if (i == 0) - goto weird_lbl; - - continue; - } - if (pSomeNode->inopen) - { - pSomeNode->inopen = false; - - if (pSomeNode->NextNode) - pSomeNode->NextNode->PrevNode = pSomeNode->PrevNode; - if (pSomeNode->PrevNode) - pSomeNode->PrevNode->NextNode = pSomeNode->NextNode; - else - PathSearch::open = pSomeNode->NextNode; - } - } - - vec2_t vDelta2; - VectorSub2D(end, pathway->pos1, vDelta2); - pSomeNode->h = h = VectorLength2D(vDelta2); - - f = (h + g); - - if (f >= maxPath) - break; - - pSomeNode->f = f; - pSomeNode->pathway = i; - pSomeNode->g = g; - pSomeNode->Parent = Node; - pSomeNode->inopen = true; - pSomeNode->m_PathPos = pathway->pos2; - pSomeNode->findCount = PathSearch::findFrame; - pSomeNode->m_Depth = Node->m_Depth + 1; - - if (!PathSearch::open) - { - pSomeNode->NextNode = NULL; - pSomeNode->PrevNode = NULL; - PathSearch::open = pSomeNode; - if (i == 0) - goto weird_lbl; - - continue; - } - - if (PathSearch::open->f == f) - { - pSomeNode->PrevNode = NULL; - pSomeNode->NextNode = PathSearch::open; - PathSearch::open->PrevNode = pSomeNode; - PathSearch::open = pSomeNode; - if (i == 0) - goto weird_lbl; - - continue; - } - PathNode * pNextOpenNode = PathSearch::open->NextNode; - if (pNextOpenNode) - { - if (f > pNextOpenNode->f) - { - do - { - pNextOpenNode = pNextOpenNode->NextNode; - if (!pNextOpenNode) - break; - - } while (f > pNextOpenNode->f); - } - } - - pSomeNode->NextNode = pNextOpenNode; - - if (pNextOpenNode) - pNextOpenNode->PrevNode = pSomeNode; - - pNextOpenNode->NextNode = pSomeNode; - pSomeNode->PrevNode = pNextOpenNode; - - if (i == 0) - goto weird_lbl; - } - PathSearch::last_error = "specified path distance exceeded"; - return NULL; + iConcealment = (Pe1->pNode->nodeflags & 0xB0) != 0; + if (Pe2->pNode->nodeflags & 0xB0) { + --iConcealment; + } + return ( + (Pe1->fDistSquared) + (iConcealment << 23) + (((Pe1->pNode->nodeflags & 8) - (Pe2->pNode->nodeflags & 8)) << 21) + - (Pe2->fDistSquared) + ); } -PathNode *PathSearch::FindCornerNodeForExactPath - ( - SimpleActor *pSelf, - Sentient *enemy, - float fMaxPath - ) +PathNode *PathSearch::FindCornerNodeForWall(float *start, float *end, SimpleActor *ent, float maxPath, float *plane) { - PathNode *pPathNode[4096]; - PathNode *pParentNode; - size_t i, iDepth, index; + PathNode *ParentNode; + PathNode *OpenNode; + int i; - if (!PathSearch::FindPath(enemy->origin, pSelf->origin, pSelf, fMaxPath, 0, 0.0, 100)) - return NULL; + Node = NearestStartNode(start, ent); + if (!Node) { + last_error = "couldn't find start node"; + return NULL; + } - for (pParentNode = Node->Parent, i = 0; pParentNode; pParentNode = pParentNode->Parent, i++) - { - pPathNode[i] = pParentNode; - } + if (DotProduct(start, plane) - plane[3] < 0.0) { + last_error = "starting point is already behind the wall"; + return NULL; + } - iDepth = i; - if (!iDepth) { - return NULL; - } + if (DotProduct(plane, end) - plane[3] > 0.0) { + last_error = "end point is in front of the wall"; + return NULL; + } - Node = pPathNode[iDepth -1]; + total_dist = 1.0e12f; - for (i = 1; i < iDepth; i += 2) - { - if (!G_SightTrace( - pSelf->EyePosition(), - vec_zero, - vec_zero, - pSelf->EyePosition() - pSelf->origin + pPathNode[i]->m_PathPos, - pSelf, - enemy, - 0x2040B19, - 0, - "FindCornerNodeFoExactPath 1")) - { - break; - } - } + if (maxPath == 0.0) { + maxPath = 1.0e12f; + } - index = i - 1; - if (index < iDepth) - { - if (index) - { - if (!G_SightTrace( - pSelf->EyePosition(), - vec_zero, - vec_zero, - pSelf->EyePosition() - pSelf->origin + pPathNode[index]->m_PathPos, - pSelf, - enemy, - 0x2040B19, - 0, - "FindCornerNodeFoExactPath 2")) - { - index--; - } - } - } - else - { - index = iDepth - 1; - } + findFrame++; + open = NULL; - return pPathNode[index]; + VectorSub2D(Node->origin, start, path_startdir); + Node->g = VectorNormalize2D(path_startdir); + + VectorSub2D(end, start, path_totaldir); + Node->h = VectorNormalize2D(path_totaldir); + + Node->inopen = true; + + Node->Parent = NULL; + + Node->m_Depth = 3; + Node->m_PathPos = start; + Node->findCount = findFrame; + Node->PrevNode = 0; + Node->NextNode = 0; + + OpenNode = Node; + open = Node; + + if (!open) { + last_error = "unreachable path"; + return NULL; + } + + while (true) { + Node = OpenNode; + + Node->inopen = false; + + open = Node->NextNode; + if (open) { + open->PrevNode = NULL; + } + + ParentNode = Node->Parent; + + if (ParentNode && DotProduct(plane, Node->m_PathPos) - plane[3] < 0.0) { + vec2_t delta; + VectorSub2D(ParentNode->m_PathPos, start, delta); + if (VectorLength2DSquared(delta) < Square(16)) { + ParentNode = Node; + } + return ParentNode; + } + + i = Node->numChildren; + if (i) { + break; + } + weird_lbl: + OpenNode = open; + if (!OpenNode) { + last_error = "unreachable path"; + return NULL; + } + } + + int f, g, h; + while (true) { + pathway_t *pathway = &Node->Child[--i]; + PathNode *pSomeNode = PathSearch::pathnodes[pathway->node]; + g = (pathway->dist + Node->g + 1.0); + if (pSomeNode->findCount == PathSearch::findFrame) { + if (g >= pSomeNode->g) { + if (i == 0) { + goto weird_lbl; + } + + continue; + } + if (pSomeNode->inopen) { + pSomeNode->inopen = false; + + if (pSomeNode->NextNode) { + pSomeNode->NextNode->PrevNode = pSomeNode->PrevNode; + } + if (pSomeNode->PrevNode) { + pSomeNode->PrevNode->NextNode = pSomeNode->NextNode; + } else { + PathSearch::open = pSomeNode->NextNode; + } + } + } + + vec2_t vDelta2; + VectorSub2D(end, pathway->pos1, vDelta2); + pSomeNode->h = h = VectorLength2D(vDelta2); + + f = (h + g); + + if (f >= maxPath) { + break; + } + + pSomeNode->f = f; + pSomeNode->pathway = i; + pSomeNode->g = g; + pSomeNode->Parent = Node; + pSomeNode->inopen = true; + pSomeNode->m_PathPos = pathway->pos2; + pSomeNode->findCount = PathSearch::findFrame; + pSomeNode->m_Depth = Node->m_Depth + 1; + + if (!PathSearch::open) { + pSomeNode->NextNode = NULL; + pSomeNode->PrevNode = NULL; + PathSearch::open = pSomeNode; + if (i == 0) { + goto weird_lbl; + } + + continue; + } + + if (PathSearch::open->f == f) { + pSomeNode->PrevNode = NULL; + pSomeNode->NextNode = PathSearch::open; + PathSearch::open->PrevNode = pSomeNode; + PathSearch::open = pSomeNode; + if (i == 0) { + goto weird_lbl; + } + + continue; + } + PathNode *pNextOpenNode = PathSearch::open->NextNode; + if (pNextOpenNode) { + if (f > pNextOpenNode->f) { + do { + pNextOpenNode = pNextOpenNode->NextNode; + if (!pNextOpenNode) { + break; + } + + } while (f > pNextOpenNode->f); + } + } + + pSomeNode->NextNode = pNextOpenNode; + + if (pNextOpenNode) { + pNextOpenNode->PrevNode = pSomeNode; + } + + pNextOpenNode->NextNode = pSomeNode; + pSomeNode->PrevNode = pNextOpenNode; + + if (i == 0) { + goto weird_lbl; + } + } + PathSearch::last_error = "specified path distance exceeded"; + return NULL; } -int PathSearch::FindPotentialCover - ( - SimpleActor *pEnt, - Vector& vPos, - Entity *pEnemy, - PathNode **ppFoundNodes, - int iMaxFind - ) +PathNode *PathSearch::FindCornerNodeForExactPath(SimpleActor *pSelf, Sentient *enemy, float fMaxPath) { - Actor *pSelf = (Actor *)pEnt; - PathNode *pNode; - Vector delta; - int nNodes = 0; - nodeinfo nodes[MAX_PATHNODES]; + PathNode *pPathNode[4096]; + PathNode *pParentNode; + size_t i, iDepth, index; - for (int i = 0; i < nodecount; i++) - { - pNode = pathnodes[i]; - if (pNode && pNode->nodeflags & AI_SNIPER) - { - if (pNode->pLastClaimer == pSelf || (pNode->iAvailableTime && level.inttime >= pNode->iAvailableTime) || (pNode->pLastClaimer == NULL)) - { - delta = pNode->origin - pSelf->m_vHome; - if (delta.lengthSquared() <= pSelf->m_fLeashSquared) - { - delta = pNode->origin - pEnemy->origin; - if (delta.lengthSquared() >= pSelf->m_fMinDistanceSquared && delta.lengthSquared() <= pSelf->m_fMaxDistanceSquared) - { - delta = pNode->origin - pSelf->origin; - nodes[nNodes].pNode = pNode; - nodes[nNodes].fDistSquared = delta.lengthSquared(); - nNodes++; - } - } - } - } - } + if (!PathSearch::FindPath(enemy->origin, pSelf->origin, pSelf, fMaxPath, 0, 0.0, 100)) { + return NULL; + } - if (nNodes) - { - qsort(nodes, nNodes, sizeof(nodeinfo), node_compare); + for (pParentNode = Node->Parent, i = 0; pParentNode; pParentNode = pParentNode->Parent, i++) { + pPathNode[i] = pParentNode; + } - if (nNodes > iMaxFind) - nNodes = iMaxFind; + iDepth = i; + if (!iDepth) { + return NULL; + } - if (nNodes > 0) - { - pNode = ppFoundNodes[nNodes - 1]; + Node = pPathNode[iDepth - 1]; - for (int i = 0; i < nNodes; i++) - { - pNode = nodes[i].pNode; - pNode--; - } - } + for (i = 1; i < iDepth; i += 2) { + if (!G_SightTrace( + pSelf->EyePosition(), + vec_zero, + vec_zero, + pSelf->EyePosition() - pSelf->origin + pPathNode[i]->m_PathPos, + pSelf, + enemy, + 0x2040B19, + 0, + "FindCornerNodeFoExactPath 1" + )) { + break; + } + } - } - return nNodes; + index = i - 1; + if (index < iDepth) { + if (index) { + if (!G_SightTrace( + pSelf->EyePosition(), + vec_zero, + vec_zero, + pSelf->EyePosition() - pSelf->origin + pPathNode[index]->m_PathPos, + pSelf, + enemy, + 0x2040B19, + 0, + "FindCornerNodeFoExactPath 2" + )) { + index--; + } + } + } else { + index = iDepth - 1; + } + + return pPathNode[index]; } -void PathSearch::PlayerCover - ( - Player *pPlayer - ) +int PathSearch::FindPotentialCover( + SimpleActor *pEnt, Vector& vPos, Entity *pEnemy, PathNode **ppFoundNodes, int iMaxFind +) { - int i; - PathNode *node; - Vector delta; - Entity *pOwner; + Actor *pSelf = (Actor *)pEnt; + PathNode *pNode; + Vector delta; + int nNodes = 0; + nodeinfo nodes[MAX_PATHNODES]; - for( i = 0; i < nodecount; i++ ) - { - node = pathnodes[ i ]; + for (int i = 0; i < nodecount; i++) { + pNode = pathnodes[i]; + if (pNode && pNode->nodeflags & AI_SNIPER) { + if (pNode->pLastClaimer == pSelf || (pNode->iAvailableTime && level.inttime >= pNode->iAvailableTime) + || (pNode->pLastClaimer == NULL)) { + delta = pNode->origin - pSelf->m_vHome; + if (delta.lengthSquared() <= pSelf->m_fLeashSquared) { + delta = pNode->origin - pEnemy->origin; + if (delta.lengthSquared() >= pSelf->m_fMinDistanceSquared + && delta.lengthSquared() <= pSelf->m_fMaxDistanceSquared) { + delta = pNode->origin - pSelf->origin; + nodes[nNodes].pNode = pNode; + nodes[nNodes].fDistSquared = delta.lengthSquared(); + nNodes++; + } + } + } + } + } - if( !node || !( node->nodeflags & AI_COVERFLAGS ) ) - continue; + if (nNodes) { + qsort(nodes, nNodes, sizeof(nodeinfo), node_compare); - pOwner = node->GetClaimHolder(); + if (nNodes > iMaxFind) { + nNodes = iMaxFind; + } - delta = node->origin - pPlayer->origin; + if (nNodes > 0) { + pNode = ppFoundNodes[nNodes - 1]; - // Check if we need to cover - if( VectorLengthSquared( delta ) > 2304.0f ) - { - if( pOwner == pPlayer ) - node->Relinquish(); - - continue; - } - - if( pOwner != pPlayer ) - { - if( pOwner ) - pOwner->PathnodeClaimRevoked( node ); - - // Player claim the node - node->Claim( pPlayer ); - } - } + for (int i = 0; i < nNodes; i++) { + pNode = nodes[i].pNode; + pNode--; + } + } + } + return nNodes; } -PathNode *PathSearch::FindNearestCover - ( - SimpleActor *pEnt, - Vector& vPos, - Entity *pEnemy - ) +void PathSearch::PlayerCover(Player *pPlayer) { - // not found in ida - return NULL; + int i; + PathNode *node; + Vector delta; + Entity *pOwner; + + for (i = 0; i < nodecount; i++) { + node = pathnodes[i]; + + if (!node || !(node->nodeflags & AI_COVERFLAGS)) { + continue; + } + + pOwner = node->GetClaimHolder(); + + delta = node->origin - pPlayer->origin; + + // Check if we need to cover + if (VectorLengthSquared(delta) > 2304.0f) { + if (pOwner == pPlayer) { + node->Relinquish(); + } + + continue; + } + + if (pOwner != pPlayer) { + if (pOwner) { + pOwner->PathnodeClaimRevoked(node); + } + + // Player claim the node + node->Claim(pPlayer); + } + } } -PathNode *PathSearch::FindNearestSniperNode - ( - SimpleActor *pEnt, - Vector& vPos, - Entity *pEnemy - ) +PathNode *PathSearch::FindNearestCover(SimpleActor *pEnt, Vector& vPos, Entity *pEnemy) { - Actor *pSelf = (Actor *)pEnt; - PathNode *pNode; - Vector delta; - int nNodes = 0; - nodeinfo nodes[MAX_PATHNODES]; - - for (int i = 0; i < nodecount; i++) - { - pNode = pathnodes[i]; - if (pNode && pNode->nodeflags & AI_SNIPER) - { - if (pNode->pLastClaimer == pSelf || (pNode->iAvailableTime && level.inttime >= pNode->iAvailableTime) || (pNode->pLastClaimer == NULL)) - { - delta = pNode->origin - pSelf->m_vHome; - if (delta.lengthSquared() <= pSelf->m_fLeashSquared) - { - delta = pNode->origin - pEnemy->origin; - if (delta.lengthSquared() >= pSelf->m_fMinDistanceSquared && delta.lengthSquared() <= pSelf->m_fMaxDistanceSquared) - { - delta = pNode->origin - pSelf->origin; - nodes[nNodes].pNode = pNode; - nodes[nNodes].fDistSquared = delta.lengthSquared(); - nNodes++; - } - } - } - } - } - - if (nNodes == 0) - { - return NULL; - } - - qsort(nodes, nNodes, sizeof(nodeinfo), node_compare); - - if (nNodes <= 0) - return NULL; - - for (int i = 0; i < nNodes; i++) - { - pNode = nodes[i].pNode; - if (pSelf->CanSeeFrom(pSelf->EyePosition() + pNode->origin, pEnemy)) - { - return pNode; - } - - pNode->iAvailableTime = level.inttime + 5000; - pNode->pLastClaimer = NULL; - } - - return NULL; + // not found in ida + return NULL; } -int PathSearch::NearestNodeSetup - ( - vec3_t pos, - MapCell *cell, - int *nodes, - vec3_t *deltas - ) +PathNode *PathSearch::FindNearestSniperNode(SimpleActor *pEnt, Vector& vPos, Entity *pEnemy) { - vec3_t delta; - PathNode *node; - float dist; - int n = 0; - int i; - int j; - float node_dist[ 128 ]; - int node_count; + Actor *pSelf = (Actor *)pEnt; + PathNode *pNode; + Vector delta; + int nNodes = 0; + nodeinfo nodes[MAX_PATHNODES]; - node_count = cell->numnodes; + for (int i = 0; i < nodecount; i++) { + pNode = pathnodes[i]; + if (pNode && pNode->nodeflags & AI_SNIPER) { + if (pNode->pLastClaimer == pSelf || (pNode->iAvailableTime && level.inttime >= pNode->iAvailableTime) + || (pNode->pLastClaimer == NULL)) { + delta = pNode->origin - pSelf->m_vHome; + if (delta.lengthSquared() <= pSelf->m_fLeashSquared) { + delta = pNode->origin - pEnemy->origin; + if (delta.lengthSquared() >= pSelf->m_fMinDistanceSquared + && delta.lengthSquared() <= pSelf->m_fMaxDistanceSquared) { + delta = pNode->origin - pSelf->origin; + nodes[nNodes].pNode = pNode; + nodes[nNodes].fDistSquared = delta.lengthSquared(); + nNodes++; + } + } + } + } + } - for( i = 0; i < node_count; i++ ) - { - node = pathnodes[ cell->nodes[ i ] ]; + if (nNodes == 0) { + return NULL; + } - if( pos[ 2 ] > node->origin[ 2 ] + 94.0f ) - continue; + qsort(nodes, nNodes, sizeof(nodeinfo), node_compare); - if( node->origin[ 2 ] > pos[ 2 ] + 94.0f ) - continue; + if (nNodes <= 0) { + return NULL; + } - delta[ 0 ] = node->origin[ 0 ] - pos[ 0 ]; - delta[ 1 ] = node->origin[ 1 ] - pos[ 1 ]; - delta[ 2 ] = node->origin[ 2 ] - pos[ 2 ]; + for (int i = 0; i < nNodes; i++) { + pNode = nodes[i].pNode; + if (pSelf->CanSeeFrom(pSelf->EyePosition() + pNode->origin, pEnemy)) { + return pNode; + } - VectorCopy( delta, deltas[ i ] ); + pNode->iAvailableTime = level.inttime + 5000; + pNode->pLastClaimer = NULL; + } - dist = VectorLengthSquared( delta ); - - for( j = n; j > 0; j-- ) - { - if( dist >= node_dist[ j - 1 ] ) - break; - - node_dist[ j ] = node_dist[ j - 1 ]; - nodes[ j ] = nodes[ j - 1 ]; - } - - n++; - nodes[ j ] = i; - node_dist[ j ] = dist; - } - - return n; + return NULL; } -void PathSearch::Init - ( - void - ) +int PathSearch::NearestNodeSetup(vec3_t pos, MapCell *cell, int *nodes, vec3_t *deltas) { - ai_showroutes = gi.Cvar_Get( "ai_showroutes", "0", 0 ); - ai_showroutes_distance = gi.Cvar_Get( "ai_showroutes_distance", "1000", 0 ); - ai_shownodenums = gi.Cvar_Get( "ai_shownodenums", "0", 0 ); - ai_shownode = gi.Cvar_Get( "ai_shownode", "0", 0 ); - ai_showallnode = gi.Cvar_Get( "ai_showallnode", "0", 0 ); - ai_showpath = gi.Cvar_Get( "ai_showpath", "0", 0 ); - ai_fallheight = gi.Cvar_Get( "ai_fallheight", "96", 0 ); - ai_debugpath = gi.Cvar_Get( "ai_debugpath", "0", 0 ); - ai_pathchecktime = gi.Cvar_Get( "ai_pathchecktime", "1.5", CVAR_CHEAT ); - ai_pathcheckdist = gi.Cvar_Get( "ai_pathcheckdist", "4096", CVAR_CHEAT ); + vec3_t delta; + PathNode *node; + float dist; + int n = 0; + int i; + int j; + float node_dist[128]; + int node_count; + + node_count = cell->numnodes; + + for (i = 0; i < node_count; i++) { + node = pathnodes[cell->nodes[i]]; + + if (pos[2] > node->origin[2] + 94.0f) { + continue; + } + + if (node->origin[2] > pos[2] + 94.0f) { + continue; + } + + delta[0] = node->origin[0] - pos[0]; + delta[1] = node->origin[1] - pos[1]; + delta[2] = node->origin[2] - pos[2]; + + VectorCopy(delta, deltas[i]); + + dist = VectorLengthSquared(delta); + + for (j = n; j > 0; j--) { + if (dist >= node_dist[j - 1]) { + break; + } + + node_dist[j] = node_dist[j - 1]; + nodes[j] = nodes[j - 1]; + } + + n++; + nodes[j] = i; + node_dist[j] = dist; + } + + return n; } -Event EV_AttractiveNode_GetPriority - ( - "priority", - EV_DEFAULT, - NULL, - NULL, - "Get the node priority", - EV_GETTER - ); - -Event EV_AttractiveNode_SetPriority - ( - "priority", - EV_DEFAULT, - "i", - "priority", - "Set the node priority", - EV_SETTER - ); - -Event EV_AttractiveNode_GetDistance - ( - "max_dist", - EV_DEFAULT, - NULL, - NULL, - "Get the max distance for this node", - EV_GETTER - ); - -Event EV_AttractiveNode_SetDistance - ( - "max_dist", - EV_DEFAULT, - "f", - "max_dist", - "Set the max distance for this node to be attracted, -1 for unlimited distance.", - EV_SETTER - ); - -Event EV_AttractiveNode_GetStayTime - ( - "stay_time", - EV_DEFAULT, - NULL, - NULL, - "Get the max stay time for this node", - EV_GETTER - ); - -Event EV_AttractiveNode_SetStayTime - ( - "stay_time", - EV_DEFAULT, - "f", - "stay_time", - "Set the maximum stay time AI will stay on this node", - EV_SETTER - ); - -Event EV_AttractiveNode_GetRespawnTime - ( - "respawn_time", - EV_DEFAULT, - NULL, - NULL, - "Get the how much time will this node re-attract already attracted AIs", - EV_GETTER - ); - -Event EV_AttractiveNode_SetRespawnTime - ( - "respawn_time", - EV_DEFAULT, - "f", - "respawn_time", - "Set the how much time will this node re-attract already attracted AIs. The minimum required value is 1, otherwise AI will get stuck.", - EV_SETTER - ); - -Event EV_AttractiveNode_GetTeam - ( - "team", - EV_DEFAULT, - NULL, - NULL, - "Get the attractive node team. 'none' for no team.", - EV_GETTER - ); - -Event EV_AttractiveNode_SetTeam - ( - "team", - EV_DEFAULT, - "s", - "team", - "Set the attractive node team. 'none' for no team.", - EV_SETTER - ); - -Event EV_AttractiveNode_SetUse - ( - "setuse", - EV_DEFAULT, - "b", - "use", - "Set if AI should use or not" - ); - -CLASS_DECLARATION( SimpleArchivedEntity, AttractiveNode, NULL ) +void PathSearch::Init(void) { - { &EV_AttractiveNode_GetPriority, &AttractiveNode::GetPriority }, - { &EV_AttractiveNode_SetPriority, &AttractiveNode::SetPriority }, - { &EV_AttractiveNode_GetDistance, &AttractiveNode::GetDistance }, - { &EV_AttractiveNode_SetDistance, &AttractiveNode::SetDistance }, - { &EV_AttractiveNode_GetStayTime, &AttractiveNode::GetStayTime }, - { &EV_AttractiveNode_SetStayTime, &AttractiveNode::SetStayTime }, - { &EV_AttractiveNode_GetRespawnTime, &AttractiveNode::GetRespawnTime }, - { &EV_AttractiveNode_SetRespawnTime, &AttractiveNode::SetRespawnTime }, - { &EV_AttractiveNode_GetTeam, &AttractiveNode::GetTeam }, - { &EV_AttractiveNode_SetTeam, &AttractiveNode::SetTeam }, - { &EV_AttractiveNode_SetUse, &AttractiveNode::SetUse }, - { NULL, NULL } + ai_showroutes = gi.Cvar_Get("ai_showroutes", "0", 0); + ai_showroutes_distance = gi.Cvar_Get("ai_showroutes_distance", "1000", 0); + ai_shownodenums = gi.Cvar_Get("ai_shownodenums", "0", 0); + ai_shownode = gi.Cvar_Get("ai_shownode", "0", 0); + ai_showallnode = gi.Cvar_Get("ai_showallnode", "0", 0); + ai_showpath = gi.Cvar_Get("ai_showpath", "0", 0); + ai_fallheight = gi.Cvar_Get("ai_fallheight", "96", 0); + ai_debugpath = gi.Cvar_Get("ai_debugpath", "0", 0); + ai_pathchecktime = gi.Cvar_Get("ai_pathchecktime", "1.5", CVAR_CHEAT); + ai_pathcheckdist = gi.Cvar_Get("ai_pathcheckdist", "4096", CVAR_CHEAT); +} + +Event EV_AttractiveNode_GetPriority("priority", EV_DEFAULT, NULL, NULL, "Get the node priority", EV_GETTER); + +Event EV_AttractiveNode_SetPriority("priority", EV_DEFAULT, "i", "priority", "Set the node priority", EV_SETTER); + +Event + EV_AttractiveNode_GetDistance("max_dist", EV_DEFAULT, NULL, NULL, "Get the max distance for this node", EV_GETTER); + +Event EV_AttractiveNode_SetDistance( + "max_dist", + EV_DEFAULT, + "f", + "max_dist", + "Set the max distance for this node to be attracted, -1 for unlimited distance.", + EV_SETTER +); + +Event EV_AttractiveNode_GetStayTime( + "stay_time", EV_DEFAULT, NULL, NULL, "Get the max stay time for this node", EV_GETTER +); + +Event EV_AttractiveNode_SetStayTime( + "stay_time", EV_DEFAULT, "f", "stay_time", "Set the maximum stay time AI will stay on this node", EV_SETTER +); + +Event EV_AttractiveNode_GetRespawnTime( + "respawn_time", + EV_DEFAULT, + NULL, + NULL, + "Get the how much time will this node re-attract already attracted AIs", + EV_GETTER +); + +Event EV_AttractiveNode_SetRespawnTime( + "respawn_time", + EV_DEFAULT, + "f", + "respawn_time", + "Set the how much time will this node re-attract already attracted AIs. The minimum required value is 1, otherwise " + "AI will get stuck.", + EV_SETTER +); + +Event EV_AttractiveNode_GetTeam( + "team", EV_DEFAULT, NULL, NULL, "Get the attractive node team. 'none' for no team.", EV_GETTER +); + +Event EV_AttractiveNode_SetTeam( + "team", EV_DEFAULT, "s", "team", "Set the attractive node team. 'none' for no team.", EV_SETTER +); + +Event EV_AttractiveNode_SetUse("setuse", EV_DEFAULT, "b", "use", "Set if AI should use or not"); + +CLASS_DECLARATION(SimpleArchivedEntity, AttractiveNode, NULL) { + {&EV_AttractiveNode_GetPriority, &AttractiveNode::GetPriority }, + {&EV_AttractiveNode_SetPriority, &AttractiveNode::SetPriority }, + {&EV_AttractiveNode_GetDistance, &AttractiveNode::GetDistance }, + {&EV_AttractiveNode_SetDistance, &AttractiveNode::SetDistance }, + {&EV_AttractiveNode_GetStayTime, &AttractiveNode::GetStayTime }, + {&EV_AttractiveNode_SetStayTime, &AttractiveNode::SetStayTime }, + {&EV_AttractiveNode_GetRespawnTime, &AttractiveNode::GetRespawnTime}, + {&EV_AttractiveNode_SetRespawnTime, &AttractiveNode::SetRespawnTime}, + {&EV_AttractiveNode_GetTeam, &AttractiveNode::GetTeam }, + {&EV_AttractiveNode_SetTeam, &AttractiveNode::SetTeam }, + {&EV_AttractiveNode_SetUse, &AttractiveNode::SetUse }, + {NULL, NULL } }; -Container< AttractiveNode * > attractiveNodes; +Container attractiveNodes; AttractiveNode::AttractiveNode() { + m_iPriority = 0; // set to default 0 + m_fMaxStayTime = 0; // set to default 0, could be just a pickup + m_fMaxDistance = 1024; + m_fMaxDistanceSquared = m_fMaxDistance * m_fMaxDistance; + m_fRespawnTime = 15.0f; // set to default 15 seconds + m_bUse = false; + m_csTeam = STRING_EMPTY; + m_iTeam = TEAM_NONE; - m_iPriority = 0; // set to default 0 - m_fMaxStayTime = 0; // set to default 0, could be just a pickup - m_fMaxDistance = 1024; - m_fMaxDistanceSquared = m_fMaxDistance * m_fMaxDistance; - m_fRespawnTime = 15.0f; // set to default 15 seconds - m_bUse = false; - m_csTeam = STRING_EMPTY; - m_iTeam = TEAM_NONE; - - attractiveNodes.AddObject( this ); + attractiveNodes.AddObject(this); } AttractiveNode::~AttractiveNode() { - attractiveNodes.RemoveObject( this ); + attractiveNodes.RemoveObject(this); } -bool AttractiveNode::CheckTeam - ( - Sentient *sent - ) +bool AttractiveNode::CheckTeam(Sentient *sent) { - if( !m_iTeam ) - { - return true; - } + if (!m_iTeam) { + return true; + } - if( sent->IsSubclassOfPlayer() ) - { - Player *p = ( Player * )sent; + if (sent->IsSubclassOfPlayer()) { + Player *p = (Player *)sent; - if( ( m_iTeam == TEAM_FREEFORALL && g_gametype->integer >= GT_TEAM ) || - p->GetTeam() != m_iTeam ) - { - return false; - } - } - else - { - if( m_iTeam == TEAM_ALLIES && sent->m_Team != TEAM_AMERICAN ) - { - return false; - } - else if( m_iTeam == TEAM_AXIS && sent->m_Team != TEAM_GERMAN ) - { - return false; - } - } + if ((m_iTeam == TEAM_FREEFORALL && g_gametype->integer >= GT_TEAM) || p->GetTeam() != m_iTeam) { + return false; + } + } else { + if (m_iTeam == TEAM_ALLIES && sent->m_Team != TEAM_AMERICAN) { + return false; + } else if (m_iTeam == TEAM_AXIS && sent->m_Team != TEAM_GERMAN) { + return false; + } + } - return true; + return true; } -void AttractiveNode::setMaxDist - ( - float dist - ) +void AttractiveNode::setMaxDist(float dist) { - m_fMaxDistance = dist; + m_fMaxDistance = dist; - if( dist < 0 ) - { - m_fMaxDistanceSquared = -1; - } - else - { - m_fMaxDistanceSquared = dist * dist; - } + if (dist < 0) { + m_fMaxDistanceSquared = -1; + } else { + m_fMaxDistanceSquared = dist * dist; + } } -void AttractiveNode::GetPriority - ( - Event *ev - ) +void AttractiveNode::GetPriority(Event *ev) { - ev->AddInteger( m_iPriority ); + ev->AddInteger(m_iPriority); } -void AttractiveNode::SetPriority - ( - Event *ev - ) +void AttractiveNode::SetPriority(Event *ev) { - m_iPriority = ev->GetInteger( 1 ); + m_iPriority = ev->GetInteger(1); } -void AttractiveNode::GetDistance - ( - Event *ev - ) +void AttractiveNode::GetDistance(Event *ev) { - ev->AddFloat( m_fMaxDistance ); + ev->AddFloat(m_fMaxDistance); } -void AttractiveNode::SetDistance - ( - Event *ev - ) +void AttractiveNode::SetDistance(Event *ev) { - setMaxDist( ev->GetFloat( 1 ) ); + setMaxDist(ev->GetFloat(1)); } -void AttractiveNode::GetStayTime - ( - Event *ev - ) +void AttractiveNode::GetStayTime(Event *ev) { - ev->AddFloat( m_fMaxStayTime ); + ev->AddFloat(m_fMaxStayTime); } -void AttractiveNode::SetStayTime - ( - Event *ev - ) +void AttractiveNode::SetStayTime(Event *ev) { - m_fMaxStayTime = ev->GetFloat( 1 ); + m_fMaxStayTime = ev->GetFloat(1); } -void AttractiveNode::GetRespawnTime - ( - Event *ev - ) +void AttractiveNode::GetRespawnTime(Event *ev) { - ev->AddFloat( m_fRespawnTime ); + ev->AddFloat(m_fRespawnTime); } -void AttractiveNode::SetRespawnTime - ( - Event *ev - ) +void AttractiveNode::SetRespawnTime(Event *ev) { - m_fRespawnTime = ev->GetFloat( 1 ); - if( m_fRespawnTime < 1.0f ) - { - m_fRespawnTime = 1.0f; - } + m_fRespawnTime = ev->GetFloat(1); + if (m_fRespawnTime < 1.0f) { + m_fRespawnTime = 1.0f; + } } -void AttractiveNode::GetTeam - ( - Event *ev - ) +void AttractiveNode::GetTeam(Event *ev) { - ev->AddConstString( m_csTeam ); + ev->AddConstString(m_csTeam); } -void AttractiveNode::SetTeam - ( - Event *ev - ) +void AttractiveNode::SetTeam(Event *ev) { - if( ev->IsNilAt( 1 ) ) - { - m_csTeam = STRING_EMPTY; - m_iTeam = TEAM_NONE; - return; - } + if (ev->IsNilAt(1)) { + m_csTeam = STRING_EMPTY; + m_iTeam = TEAM_NONE; + return; + } - m_csTeam = ev->GetConstString( 1 ); + m_csTeam = ev->GetConstString(1); - switch( m_csTeam ) - { - case STRING_EMPTY: - m_iTeam = TEAM_NONE; - break; - case STRING_SPECTATOR: - m_iTeam = TEAM_SPECTATOR; - break; - case STRING_FREEFORALL: - m_iTeam = TEAM_FREEFORALL; - break; - case STRING_ALLIES: - case STRING_AMERICAN: - m_iTeam = TEAM_ALLIES; - break; - case STRING_AXIS: - case STRING_GERMAN: - m_iTeam = TEAM_AXIS; - break; - default: - m_iTeam = TEAM_NONE; - ScriptError( "Invalid team %s\n", ev->GetString( 1 ).c_str() ); - } + switch (m_csTeam) { + case STRING_EMPTY: + m_iTeam = TEAM_NONE; + break; + case STRING_SPECTATOR: + m_iTeam = TEAM_SPECTATOR; + break; + case STRING_FREEFORALL: + m_iTeam = TEAM_FREEFORALL; + break; + case STRING_ALLIES: + case STRING_AMERICAN: + m_iTeam = TEAM_ALLIES; + break; + case STRING_AXIS: + case STRING_GERMAN: + m_iTeam = TEAM_AXIS; + break; + default: + m_iTeam = TEAM_NONE; + ScriptError("Invalid team %s\n", ev->GetString(1).c_str()); + } } -void AttractiveNode::SetUse - ( - Event *ev - ) +void AttractiveNode::SetUse(Event *ev) { - m_bUse = ev->GetBoolean( 1 ); + m_bUse = ev->GetBoolean(1); } diff --git a/code/fgame/navigate.h b/code/fgame/navigate.h index 8eaa6f57..444016ba 100644 --- a/code/fgame/navigate.h +++ b/code/fgame/navigate.h @@ -1,6 +1,6 @@ /* =========================================================================== -Copyright (C) 2015 the OpenMoHAA team +Copyright (C) 2023 the OpenMoHAA team This file is part of OpenMoHAA source code. @@ -25,8 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // is currently unfinished. // -#ifndef __NAVIGATE_H__ -#define __NAVIGATE_H__ +#pragma once #include "g_local.h" #include "class.h" @@ -37,7 +36,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "sentient.h" #include "../qcommon/qfiles.h" - extern Event EV_AI_SavePaths; extern Event EV_AI_SaveNodes; extern Event EV_AI_LoadNodes; @@ -46,327 +44,346 @@ extern Event EV_AI_RecalcPaths; extern Event EV_AI_CalcPath; extern Event EV_AI_DisconnectPath; -extern cvar_t *ai_showroutes; -extern cvar_t *ai_showroutes_distance; -extern cvar_t *ai_shownodenums; -extern cvar_t *ai_shownode; -extern cvar_t *ai_showallnode; -extern cvar_t *ai_showpath; -extern cvar_t *ai_fallheight; -extern cvar_t *ai_debugpath; -extern cvar_t *ai_pathchecktime; -extern cvar_t *ai_pathcheckdist; +extern cvar_t *ai_showroutes; +extern cvar_t *ai_showroutes_distance; +extern cvar_t *ai_shownodenums; +extern cvar_t *ai_shownode; +extern cvar_t *ai_showallnode; +extern cvar_t *ai_showpath; +extern cvar_t *ai_fallheight; +extern cvar_t *ai_debugpath; +extern cvar_t *ai_pathchecktime; +extern cvar_t *ai_pathcheckdist; -extern int ai_maxnode; +extern int ai_maxnode; #define MAX_PATHCHECKSPERFRAME 4 extern int path_checksthisframe; -#define MAX_PATH_LENGTH 128 // should be more than plenty -#define NUM_PATHSPERNODE 48 +#define MAX_PATH_LENGTH 128 // should be more than plenty +#define NUM_PATHSPERNODE 48 class Path; class PathNode; -#define NUM_WIDTH_VALUES 16 -#define WIDTH_STEP 8 -#define MAX_WIDTH ( WIDTH_STEP * NUM_WIDTH_VALUES ) -#define MAX_HEIGHT 128 +#define NUM_WIDTH_VALUES 16 +#define WIDTH_STEP 8 +#define MAX_WIDTH (WIDTH_STEP * NUM_WIDTH_VALUES) +#define MAX_HEIGHT 128 -#define CHECK_PATH( path, width, height ) \ - ( ( ( ( width ) >= MAX_WIDTH ) || ( ( width ) < 0 ) ) ? false : \ - ( ( int )( path )->maxheight[ ( ( width ) / WIDTH_STEP ) - 1 ] < ( int )( height ) ) ) +#define CHECK_PATH(path, width, height) \ + ((((width) >= MAX_WIDTH) || ((width) < 0)) ? false \ + : ((int)(path)->maxheight[((width) / WIDTH_STEP) - 1] < (int)(height))) -class pathway_ref { +class pathway_ref +{ public: - short int from; - short int to; + short int from; + short int to; }; typedef struct { - byte numBlockers; - short int node; - short int fallheight; - float dist; - float dir[ 2 ]; - float pos1[ 3 ]; - float pos2[ 3 ]; + byte numBlockers; + short int node; + short int fallheight; + float dist; + float dir[2]; + float pos1[3]; + float pos2[3]; } pathway_t; -class PathInfo { +class PathInfo +{ public: - bool bAccurate; - float point[ 3 ]; - float dist; - float dir[ 2 ]; + bool bAccurate; + float point[3]; + float dist; + float dir[2]; public: - void Archive( Archiver& arc ); + void Archive(Archiver& arc); }; -inline void PathInfo::Archive - ( - Archiver& arc - ) +inline void PathInfo::Archive(Archiver& arc) { - arc.ArchiveBool( &bAccurate ); - arc.ArchiveVec3( point ); - arc.ArchiveFloat( &dist ); - arc.ArchiveVec2( dir ); + arc.ArchiveBool(&bAccurate); + arc.ArchiveVec3(point); + arc.ArchiveFloat(&dist); + arc.ArchiveVec2(dir); } -typedef enum { NOT_IN_LIST, IN_OPEN, IN_CLOSED } pathlist_t; +typedef enum { + NOT_IN_LIST, + IN_OPEN, + IN_CLOSED +} pathlist_t; -#define PATH_DONT_LINK 1 -#define AI_DUCK 2 -#define AI_COVER 4 -#define AI_CONCEALMENT 8 -#define AI_CORNER_LEFT 16 -#define AI_CORNER_RIGHT 32 -#define AI_SNIPER 64 -#define AI_CRATE 128 +#define PATH_DONT_LINK 1 +#define AI_DUCK 2 +#define AI_COVER 4 +#define AI_CONCEALMENT 8 +#define AI_CORNER_LEFT 16 +#define AI_CORNER_RIGHT 32 +#define AI_SNIPER 64 +#define AI_CRATE 128 -#define AI_COVERFLAGS (AI_CRATE|AI_SNIPER|AI_CORNER_RIGHT|AI_CORNER_LEFT|AI_CONCEALMENT|AI_COVER) -#define AI_COVERFLAGS2 (AI_SNIPER|AI_CORNER_RIGHT|AI_CORNER_LEFT|AI_CONCEALMENT) -#define AI_COVERFLAGS3 (AI_SNIPER|AI_CORNER_RIGHT|AI_CORNER_LEFT|AI_CONCEALMENT|AI_DUCK|AI_CONCEALMENT) -#define AI_SNIPERFLAGS (AI_SNIPER|AI_CORNER_RIGHT|AI_CORNER_LEFT|AI_COVER) -#define AI_CRATEFLAGS (AI_CRATE|AI_CORNER_LEFT|AI_CORNER_RIGHT|AI_CONCEALMENT|AI_COVER|AI_DUCK) -#define AI_COVER_LEFT_FLAGS (AI_CRATE|AI_SNIPER|AI_CORNER_LEFT|AI_CONCEALMENT|AI_DUCK) -#define AI_COVER_RIGHT_FLAGS (AI_CRATE|AI_SNIPER|AI_CORNER_RIGHT|AI_CONCEALMENT|AI_DUCK) -#define AI_ALL (AI_DUCK|AI_COVER|AI_CONCEALMENT|AI_CORNER_LEFT|AI_CORNER_RIGHT|AI_SNIPER|AI_CRATE) +#define AI_COVERFLAGS (AI_CRATE | AI_SNIPER | AI_CORNER_RIGHT | AI_CORNER_LEFT | AI_CONCEALMENT | AI_COVER) +#define AI_COVERFLAGS2 (AI_SNIPER | AI_CORNER_RIGHT | AI_CORNER_LEFT | AI_CONCEALMENT) +#define AI_COVERFLAGS3 (AI_SNIPER | AI_CORNER_RIGHT | AI_CORNER_LEFT | AI_CONCEALMENT | AI_DUCK | AI_CONCEALMENT) +#define AI_SNIPERFLAGS (AI_SNIPER | AI_CORNER_RIGHT | AI_CORNER_LEFT | AI_COVER) +#define AI_CRATEFLAGS (AI_CRATE | AI_CORNER_LEFT | AI_CORNER_RIGHT | AI_CONCEALMENT | AI_COVER | AI_DUCK) +#define AI_COVER_LEFT_FLAGS (AI_CRATE | AI_SNIPER | AI_CORNER_LEFT | AI_CONCEALMENT | AI_DUCK) +#define AI_COVER_RIGHT_FLAGS (AI_CRATE | AI_SNIPER | AI_CORNER_RIGHT | AI_CONCEALMENT | AI_DUCK) +#define AI_ALL (AI_DUCK | AI_COVER | AI_CONCEALMENT | AI_CORNER_LEFT | AI_CORNER_RIGHT | AI_SNIPER | AI_CRATE) -void DrawNode( int iNodeCount ); -void DrawAllConnections( void ); +void DrawNode(int iNodeCount); +void DrawAllConnections(void); class PathNode : public SimpleEntity - { - public: - int findCount; - pathway_t *Child; - int numChildren; - int virtualNumChildren; - float f; - float h; - float g; - class PathNode *Parent; - bool inopen; - PathNode *PrevNode; - PathNode *NextNode; - short int pathway; - vec_t *m_PathPos; - float dist; - float dir[ 2 ]; - int nodeflags; - SafePtr pLastClaimer; - int iAvailableTime; - int nodenum; - short int m_Depth; +{ +public: + int findCount; + pathway_t *Child; + int numChildren; + int virtualNumChildren; + float f; + float h; + float g; + class PathNode *Parent; + bool inopen; + PathNode *PrevNode; + PathNode *NextNode; + short int pathway; + vec_t *m_PathPos; + float dist; + float dir[2]; + int nodeflags; + SafePtr pLastClaimer; + int iAvailableTime; + int nodenum; + short int m_Depth; - friend class PathSearch; - friend void DrawAllConnections( void ); + friend class PathSearch; + friend void DrawAllConnections(void); - private: - void ConnectTo( PathNode *node ); - void SetNodeFlags( Event *ev ); - void Remove( Event *ev ); +private: + void ConnectTo(PathNode *node); + void SetNodeFlags(Event *ev); + void Remove(Event *ev); - public: - CLASS_PROTOTYPE( PathNode ); +public: + CLASS_PROTOTYPE(PathNode); - void *operator new( size_t size ); - void operator delete( void *ptr ); + void *operator new(size_t size); + void operator delete(void *ptr); - PathNode(); - virtual ~PathNode(); + PathNode(); + virtual ~PathNode(); - void Archive( Archiver& arc ) override; - void ArchiveDynamic( Archiver& arc ); - void ArchiveStatic( Archiver& arc ); + void Archive(Archiver& arc) override; + void ArchiveDynamic(Archiver& arc); + void ArchiveStatic(Archiver& arc); - bool CheckPathTo( PathNode *node ); - void CheckPathToDefault( PathNode *node, pathway_t *pathway ); - qboolean LadderTo( PathNode *node, pathway_t *pathway ); + bool CheckPathTo(PathNode *node); + void CheckPathToDefault(PathNode *node, pathway_t *pathway); + qboolean LadderTo(PathNode *node, pathway_t *pathway); - void DrawConnections( void ); - void Claim( Entity *pClaimer ); - void Relinquish( void ); - Entity *GetClaimHolder( void ) const; - bool IsClaimedByOther( Entity *pPossibleClaimer ) const; - void MarkTemporarilyBad( void ); - void ConnectChild( int i ); - void DisconnectChild( int i ); - const_str GetSpecialAttack( class Actor *pActor ); - void IsTouching( Event *ev ); - qboolean IsTouching( Entity *e1 ); - void setOriginEvent( Vector org ) override; - - }; + void DrawConnections(void); + void Claim(Entity *pClaimer); + void Relinquish(void); + Entity *GetClaimHolder(void) const; + bool IsClaimedByOther(Entity *pPossibleClaimer) const; + void MarkTemporarilyBad(void); + void ConnectChild(int i); + void DisconnectChild(int i); + const_str GetSpecialAttack(class Actor *pActor); + void IsTouching(Event *ev); + qboolean IsTouching(Entity *e1); + void setOriginEvent(Vector org) override; +}; typedef SafePtr PathNodePtr; -class nodeinfo { +class nodeinfo +{ public: - PathNode *pNode; - float fDistSquared; + PathNode *pNode; + float fDistSquared; }; -#define PATHMAP_CELLSIZE 256 -#define PATHMAP_GRIDSIZE ( MAX_MAP_BOUNDS * 2 / PATHMAP_CELLSIZE ) +#define PATHMAP_CELLSIZE 256 +#define PATHMAP_GRIDSIZE (MAX_MAP_BOUNDS * 2 / PATHMAP_CELLSIZE) -#define PATHMAP_NODES 128 // 128 - sizeof( int ) / sizeof( short ) +#define PATHMAP_NODES 128 // 128 - sizeof( int ) / sizeof( short ) -#define MAX_PATHNODES 4096 +#define MAX_PATHNODES 4096 class MapCell : public Class { private: - int numnodes; - short *nodes; + int numnodes; + short *nodes; - friend class PathSearch; + friend class PathSearch; public: - MapCell(); - ~MapCell(); + MapCell(); + ~MapCell(); - qboolean AddNode( PathNode *node ); - int NumNodes( void ); + qboolean AddNode(PathNode *node); + int NumNodes(void); }; class PathSearch : public Listener { - friend class PathNode; + friend class PathNode; private: - static MapCell PathMap[ PATHMAP_GRIDSIZE ][ PATHMAP_GRIDSIZE ]; - static PathNode *open; - static int findFrame; - static qboolean m_bNodesloaded; - static qboolean m_NodeCheckFailed; - static int m_LoadIndex; + static MapCell PathMap[PATHMAP_GRIDSIZE][PATHMAP_GRIDSIZE]; + static PathNode *open; + static int findFrame; + static qboolean m_bNodesloaded; + static qboolean m_NodeCheckFailed; + static int m_LoadIndex; public: - static PathNode *pathnodes[ 4096 ]; - static int nodecount; - static float total_dist; - static const char *last_error; + static PathNode *pathnodes[4096]; + static int nodecount; + static float total_dist; + static const char *last_error; private: - static void LoadAddToGrid( int x, int y ); - static void LoadAddToGrid2( PathNode *node, int x, int y ); - static void AddToGrid( PathNode *node, int x, int y ); - static bool Connect( PathNode *node, int x, int y ); - static int NodeCoordinate( float coord ); - static int GridCoordinate( float coord ); - static qboolean ArchiveSaveNodes( void ); - static void ArchiveLoadNodes( void ); - static void Init( void ); + static void LoadAddToGrid(int x, int y); + static void LoadAddToGrid2(PathNode *node, int x, int y); + static void AddToGrid(PathNode *node, int x, int y); + static bool Connect(PathNode *node, int x, int y); + static int NodeCoordinate(float coord); + static int GridCoordinate(float coord); + static qboolean ArchiveSaveNodes(void); + static void ArchiveLoadNodes(void); + static void Init(void); public: - CLASS_PROTOTYPE( PathSearch ); + CLASS_PROTOTYPE(PathSearch); - PathSearch(); - virtual ~PathSearch(); + PathSearch(); + virtual ~PathSearch(); - static void ArchiveStaticLoad( Archiver& arc ); - static void ArchiveStaticSave( Archiver& arc ); - static bool ArchiveDynamic( Archiver& arc ); - static void AddNode( PathNode *node ); - static void Connect( PathNode *node ); - static void UpdateNode( PathNode *node ); - static MapCell *GetNodesInCell( int x, int y ); - static MapCell *GetNodesInCell( float *pos ); - static class PathNode *DebugNearestStartNode( float *pos, Entity *ent = NULL ); - static class PathNode *NearestStartNode( float *pos, class SimpleActor *ent ); - static class PathNode *NearestEndNode( float *pos ); - static int DebugNearestNodeList( float *pos, PathNode **nodelist, int iMaxNodes ); - static int DebugNearestNodeList2( float *pos, PathNode **nodelist, int iMaxNodes ); - static void ShowNodes( void ); - static void LoadNodes( void ); - static void CreatePaths( void ); - static void *AllocPathNode( void ); - static void FreePathNode( void * ); - static void ResetNodes( void ); - static void UpdatePathwaysForBadPlace(const Vector& origin, float radius, int dir, int team); - static PathInfo *GeneratePath( PathInfo *path ); - static PathInfo *GeneratePathNear( PathInfo *path ); - static PathInfo *GeneratePathAway( PathInfo *path ); - static class PathNode *GetSpawnNode( ClassDef *cls ); - static int FindPath( float *start, float *end, Entity *ent, float maxPath, float *vLeashHome, float fLeashDistSquared, int fallheight ); - static int FindPathAway( float *start, float *avoid, float *vPreferredDir, Entity *ent, float fMinSafeDist, float *vLeashHome, float fLeashDistSquared, int fallheight ); - static int FindPathNear( float *start, float *end, Entity *ent, float maxPath, float fRadiusSquared, float *vLeashHome, float fLeashDistSquared, int fallheight ); - static class PathNode *FindCornerNodeForWall( float *start, float *end, class SimpleActor *ent, float maxPath, float *plane ); - static class PathNode *FindCornerNodeForExactPath( class SimpleActor *self, Sentient *enemy, float fMaxPath ); - static int FindPotentialCover( class SimpleActor *pEnt, Vector& vPos, Entity *pEnemy, PathNode **ppFoundNodes, int iMaxFind ); - static void PlayerCover( class Player *pPlayer ); - static class PathNode *FindNearestCover( class SimpleActor *pEnt, Vector& vPos, Entity *pEnemy ); - static class PathNode *FindNearestSniperNode( class SimpleActor *pEnt, Vector& vPos, Entity *pEnemy ); + static void ArchiveStaticLoad(Archiver &arc); + static void ArchiveStaticSave(Archiver &arc); + static bool ArchiveDynamic(Archiver &arc); + static void AddNode(PathNode *node); + static void Connect(PathNode *node); + static void UpdateNode(PathNode *node); + static MapCell *GetNodesInCell(int x, int y); + static MapCell *GetNodesInCell(float *pos); + static class PathNode *DebugNearestStartNode(float *pos, Entity *ent = NULL); + static class PathNode *NearestStartNode(float *pos, class SimpleActor *ent); + static class PathNode *NearestEndNode(float *pos); + static int DebugNearestNodeList(float *pos, PathNode **nodelist, int iMaxNodes); + static int DebugNearestNodeList2(float *pos, PathNode **nodelist, int iMaxNodes); + static void ShowNodes(void); + static void LoadNodes(void); + static void CreatePaths(void); + static void *AllocPathNode(void); + static void FreePathNode(void *); + static void ResetNodes(void); + static void UpdatePathwaysForBadPlace(const Vector &origin, float radius, int dir, int team); + static PathInfo *GeneratePath(PathInfo *path); + static PathInfo *GeneratePathNear(PathInfo *path); + static PathInfo *GeneratePathAway(PathInfo *path); + static class PathNode *GetSpawnNode(ClassDef *cls); + static int FindPath( + float *start, float *end, Entity *ent, float maxPath, float *vLeashHome, float fLeashDistSquared, int fallheight + ); + static int FindPathAway( + float *start, + float *avoid, + float *vPreferredDir, + Entity *ent, + float fMinSafeDist, + float *vLeashHome, + float fLeashDistSquared, + int fallheight + ); + static int FindPathNear( + float *start, + float *end, + Entity *ent, + float maxPath, + float fRadiusSquared, + float *vLeashHome, + float fLeashDistSquared, + int fallheight + ); + static class PathNode * + FindCornerNodeForWall(float *start, float *end, class SimpleActor *ent, float maxPath, float *plane); + static class PathNode *FindCornerNodeForExactPath(class SimpleActor *self, Sentient *enemy, float fMaxPath); + static int + FindPotentialCover(class SimpleActor *pEnt, Vector& vPos, Entity *pEnemy, PathNode **ppFoundNodes, int iMaxFind); + static void PlayerCover(class Player *pPlayer); + static class PathNode *FindNearestCover(class SimpleActor *pEnt, Vector& vPos, Entity *pEnemy); + static class PathNode *FindNearestSniperNode(class SimpleActor *pEnt, Vector& vPos, Entity *pEnemy); private: - static int NearestNodeSetup( vec3_t pos, MapCell *cell, int *nodes, vec3_t *deltas ); - + static int NearestNodeSetup(vec3_t pos, MapCell *cell, int *nodes, vec3_t *deltas); }; extern PathSearch PathManager; -PathNode *AI_FindNode( const char *name ); -void AI_AddNode( PathNode *node ); -void AI_RemoveNode( PathNode *node ); -void AI_ResetNodes( void ); +PathNode *AI_FindNode(const char *name); +void AI_AddNode(PathNode *node); +void AI_RemoveNode(PathNode *node); +void AI_ResetNodes(void); class AttractiveNode : public SimpleArchivedEntity { public: - int m_iPriority; - bool m_bUse; - float m_fMaxStayTime; - float m_fMaxDistance; - float m_fMaxDistanceSquared; - float m_fRespawnTime; - const_str m_csTeam; - int m_iTeam; + int m_iPriority; + bool m_bUse; + float m_fMaxStayTime; + float m_fMaxDistance; + float m_fMaxDistanceSquared; + float m_fRespawnTime; + const_str m_csTeam; + int m_iTeam; private: -// Container< SafePtr< Sentient > > m_pSentList; + // Container< SafePtr< Sentient > > m_pSentList; public: - CLASS_PROTOTYPE( AttractiveNode ); + CLASS_PROTOTYPE(AttractiveNode); - AttractiveNode(); - ~AttractiveNode(); + AttractiveNode(); + ~AttractiveNode(); - bool CheckTeam( Sentient *sent ); - void setMaxDist( float dist ); + bool CheckTeam(Sentient *sent); + void setMaxDist(float dist); - void GetPriority( Event *ev ); - void SetPriority( Event *ev ); - void GetDistance( Event *ev ); - void SetDistance( Event *ev ); - void GetStayTime( Event *ev ); - void SetStayTime( Event *ev ); - void GetRespawnTime( Event *ev ); - void SetRespawnTime( Event *ev ); - void GetTeam( Event *ev ); - void SetTeam( Event *ev ); - void SetUse( Event *ev ); + void GetPriority(Event *ev); + void SetPriority(Event *ev); + void GetDistance(Event *ev); + void SetDistance(Event *ev); + void GetStayTime(Event *ev); + void SetStayTime(Event *ev); + void GetRespawnTime(Event *ev); + void SetRespawnTime(Event *ev); + void GetTeam(Event *ev); + void SetTeam(Event *ev); + void SetUse(Event *ev); - void Archive( Archiver& arc ) override; + void Archive(Archiver& arc) override; }; -typedef SafePtr< AttractiveNode > AttractiveNodePtr; +typedef SafePtr AttractiveNodePtr; -inline void AttractiveNode::Archive - ( - Archiver& arc - ) +inline void AttractiveNode::Archive(Archiver& arc) { - arc.ArchiveInteger( &m_iPriority ); - arc.ArchiveBool( &m_bUse ); - arc.ArchiveFloat( &m_fMaxStayTime ); - arc.ArchiveFloat( &m_fMaxDistanceSquared ); + arc.ArchiveInteger(&m_iPriority); + arc.ArchiveBool(&m_bUse); + arc.ArchiveFloat(&m_fMaxStayTime); + arc.ArchiveFloat(&m_fMaxDistanceSquared); } -extern Container< AttractiveNode * > attractiveNodes; - -#endif +extern Container attractiveNodes;