/* * AI_ReachedEntity * Some nodes are declared so they are never reached until the entity says so. * This is a entity saying so. */ void AI_ReachedEntity( edict_t *self ) { nav_ents_t *goalEnt; edict_t *ent; if( ( goalEnt = AI_GetGoalentForEnt( self ) ) == NULL ) return; // find all bots which have this node as goal and tell them their goal is reached for( ent = game.edicts + 1; PLAYERNUM( ent ) < gs.maxclients; ent++ ) { if( !ent->ai || ent->ai->type == AI_INACTIVE ) continue; if( ent->ai->goal_node == goalEnt->node ) AI_ClearGoal( ent ); } }
static void AI_AddGoalEntityNode( edict_t *ent, qboolean customReach ) { int node = NODE_INVALID; int range = NODE_DENSITY * 0.75; if( !ent->r.inuse || !ent->classname ) return; if( AI_GetGoalentForEnt( ent ) != NULL ) return; if( ent->r.client ) { nav.goalEnts[nav.num_goalEnts].node = NODE_INVALID; nav.goalEnts[nav.num_goalEnts].ent = ent; nav.num_goalEnts++; return; } // // Goal entities // if( nav.loaded ) range = AI_GOAL_SR_RADIUS; // if we have a available node close enough to the entity, use it node = AI_FindClosestReachableNode( ent->s.origin, ent, range, NODE_ALL ); if( node != NODE_INVALID ) { if( nodes[node].flags & NODE_MASK_NOREUSE ) node = NODE_INVALID; else { float heightdiff = fabs( ent->s.origin[2] - nodes[node].origin[2] ); if( heightdiff > AI_STEPSIZE + 8 ) // not near enough node = NODE_INVALID; } } // link the node is spawned after the load process is done if( nav.loaded ) { if( node == NODE_INVALID ) // (BY NOW) can not create new nodes after the initialization was done return; if( nav.debugMode && bot_showlrgoal->integer > 2 ) G_Printf( "New Goal Entity added: %s\n", ent->classname ); } else { // didn't find a node we could reuse if( node == NODE_INVALID ) node = AI_AddNode_GoalEntityNode( ent ); } if( node != NODE_INVALID ) { nav.goalEnts[nav.num_goalEnts].node = node; nav.goalEnts[nav.num_goalEnts].ent = ent; nav.num_goalEnts++; if( customReach ) nodes[node].flags |= NODEFLAGS_ENTITYREACH; } }