Example #1
0
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;
}
Example #2
0
//==========================================
// 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++;
		}
	}
}