static qboolean AI_AddNavigableEntity( edict_t *ent ) { qboolean handled = qfalse; if( !ent->r.inuse || !ent->classname || ent->r.client ) return handled; // can't add navigable entities after the spawn process (at least by now) if( nav.loaded ) return handled; // // Navigable entities // // platforms if( !Q_stricmp( ent->classname, "func_plat" ) ) { AI_AddNode_Platform( ent ); handled = qtrue; } // teleporters else if( !Q_stricmp( ent->classname, "trigger_teleport" ) || !Q_stricmp( ent->classname, "misc_teleporter" ) ) { AI_AddNode_Teleporter( ent ); handled = qtrue; } // jump pads else if( !Q_stricmp( ent->classname, "trigger_push" ) ) { AI_AddNode_JumpPad( ent ); handled = qtrue; } // doors else if( !Q_stricmp( ent->classname, "func_door" ) ) { AI_AddNode_Door( ent ); handled = qtrue; } return handled; }
//========================================== // AI_CreateNodesForEntities // // Entities aren't saved into nodes files anymore. // They generate and link it's nodes at map load. //========================================== void AI_CreateNodesForEntities ( void ) { edict_t *ent; int node; nav.num_ents = 0; memset( nav.ents, 0, sizeof(nav_ents_t) * MAX_EDICTS ); // Add special entities // for( ent = game.edicts; ent < &game.edicts[game.numentities]; ent++ ) for( ent = g_edicts; ent < &g_edicts[game.maxentities]; ent++ ) { if( !ent->classname ) continue; // platforms if( !strcmp( ent->classname,"func_plat" ) ) { AI_AddNode_Platform( ent ); } // teleporters else if( !strcmp( ent->classname,"trigger_teleport" ) ) { AI_AddNode_Teleporter( ent ); } // jump pads else if( !strcmp( ent->classname,"trigger_push" ) ) { AI_AddNode_JumpPad( ent ); } // doors else if( !strcmp( ent->classname,"func_door" ) ) { AI_AddNode_Door( ent ); } } // bot roams nav.num_broams = 0; memset( nav.broams, 0, sizeof(nav_broam_t) * MAX_BOT_ROAMS ); //visit world nodes first, and put in list what we find in there for( node=0; node < nav.num_nodes; node++ ) { if( nodes[node].flags & NODEFLAGS_BOTROAM && nav.num_broams < MAX_BOT_ROAMS) { nav.broams[nav.num_broams].node = node; nav.broams[nav.num_broams].weight = 0.3; nav.num_broams++; } } //now add bot roams from entities // for(ent = game.edicts; ent < &game.edicts[game.numentities]; ent++) for( ent = g_edicts; ent < &g_edicts[game.maxentities]; ent++ ) { if( !ent->classname ) continue; if( !strcmp( ent->classname,"item_botroam" ) ) { //if we have a available node close enough to the item, use it instead of dropping a new node node = AI_FindClosestReachableNode( ent->s.origin, NULL, 48, NODE_ALL ); if( node != -1 && !(nodes[node].flags & NODEFLAGS_SERVERLINK) && !(nodes[node].flags & NODEFLAGS_LADDER) ) { float heightdiff = 0; heightdiff = ent->s.origin[2] - nodes[node].origin[2]; if( heightdiff < 0 ) heightdiff = -heightdiff; if( heightdiff < AI_STEPSIZE && nav.num_broams < MAX_BOT_ROAMS ) //near enough { nodes[node].flags |= NODEFLAGS_BOTROAM; //add node to botroam list if( ent->count ) nav.broams[nav.num_broams].weight = ent->count * 0.01;//count is a int with a value in between 0 and 100 else nav.broams[nav.num_broams].weight = 0.3; //jalfixme: add cmd to weight (dropped by console cmd, self is player) nav.broams[nav.num_broams].node = node; nav.num_broams++; continue; } } //drop a new node if( nav.num_broams < MAX_BOT_ROAMS ){ AI_AddNode_BotRoam( ent ); } } } // game items (I want all them on top of the nodes array) nav.num_items = 0; memset( nav.items, 0, sizeof(nav_item_t) * MAX_EDICTS ); // for( ent = game.edicts; ent < &game.edicts[game.numentities]; ent++ ) for( ent = g_edicts; ent < &g_edicts[game.maxentities]; ent++ ) { int item_index; if( !ent->classname || !ent->item ) continue; item_index = ITEM_INDEX( ent->item ); if(item_index == INVALID) continue; //if we have a available node close enough to the item, use it node = AI_FindClosestReachableNode( ent->s.origin, NULL, 48, NODE_ALL ); if( node != INVALID ) { if( nodes[node].flags & NODEFLAGS_SERVERLINK || nodes[node].flags & NODEFLAGS_LADDER ) node = INVALID; else { float heightdiff = 0; heightdiff = ent->s.origin[2] - nodes[node].origin[2]; if( heightdiff < 0 ) heightdiff = -heightdiff; if( heightdiff > AI_STEPSIZE ) //not near enough node = INVALID; } } //drop a new node if( node == INVALID ) node = AI_AddNode_ItemNode( ent ); if( node != INVALID ) { nav.items[nav.num_items].node = node; nav.items[nav.num_items].ent = ent; nav.items[nav.num_items].item = item_index; nav.num_items++; } } }