Пример #1
0
bool AI_NodeHasTimedOut( edict_t *self )
{
	if( self->ai->goal_node == NODE_INVALID )
		return true;

	if( !GS_MatchPaused() )
		self->ai->node_timeout += game.frametime;

	// Try again?
	if( self->ai->node_timeout > NODE_TIMEOUT || self->ai->next_node == NODE_INVALID )
	{
		if( self->ai->tries++ > 3 )
			return true;
		else
			AI_SetGoal( self, self->ai->goal_node );
	}

	if( self->ai->current_node == NODE_INVALID || self->ai->next_node == NODE_INVALID )
		return true;

	return false;
}
Пример #2
0
//==========================================
// AI_PickLongRangeGoal
//
// Evaluate the best long range goal and send the bot on
// its way. This is a good time waster, so use it sparingly.
// Do not call it for every think cycle.
//
// jal: I don't think there is any problem by calling it,
// now that we have stored the costs at the nav.costs table (I don't do it anyway)
//==========================================
void AI_PickLongRangeGoal( edict_t *self )
{
#define WEIGHT_MAXDISTANCE_FACTOR 20000.0f
#define COST_INFLUENCE	0.5f
	int i;
	float weight, bestWeight = 0.0;
	int current_node;
	float cost;
	float dist;
	nav_ents_t *goalEnt, *bestGoalEnt = NULL;

	AI_ClearGoal( self );

	if( G_ISGHOSTING( self ) )
		return;

	if( self->ai->longRangeGoalTimeout > level.time )
		return;

	if( !self->r.client->ps.pmove.stats[PM_STAT_MAXSPEED] ) {
		return;
	}

	self->ai->longRangeGoalTimeout = level.time + AI_LONG_RANGE_GOAL_DELAY + brandom( 0, 1000 );

	// look for a target
	current_node = AI_FindClosestReachableNode( self->s.origin, self, ( ( 1 + self->ai->nearest_node_tries ) * NODE_DENSITY ), NODE_ALL );
	self->ai->current_node = current_node;

	if( current_node == NODE_INVALID )
	{
		if( nav.debugMode && bot_showlrgoal->integer )
			G_PrintChasersf( self, "%s: LRGOAL: Closest node not found. Tries:%i\n", self->ai->pers.netname, self->ai->nearest_node_tries );

		self->ai->nearest_node_tries++; // extend search radius with each try
		return;
	}

	self->ai->nearest_node_tries = 0;

	// Run the list of potential goal entities
	FOREACH_GOALENT( goalEnt )
	{
		i = goalEnt->id;
		if( !goalEnt->ent )
			continue;

		if( !goalEnt->ent->r.inuse )
		{
			goalEnt->node = NODE_INVALID;
			continue;
		}

		if( goalEnt->ent->r.client )
		{
			if( G_ISGHOSTING( goalEnt->ent ) || goalEnt->ent->flags & (FL_NOTARGET|FL_BUSY) )
				goalEnt->node = NODE_INVALID;
			else
				goalEnt->node = AI_FindClosestReachableNode( goalEnt->ent->s.origin, goalEnt->ent, NODE_DENSITY, NODE_ALL );
		}

		if( goalEnt->ent->item )
		{
			if( !G_Gametype_CanPickUpItem( goalEnt->ent->item ) )
				continue;
		}

		if( goalEnt->node == NODE_INVALID )
			continue;

		weight = self->ai->status.entityWeights[i];

		if( weight <= 0.0f )
			continue;

		// don't try to find cost for too far away objects
		dist = DistanceFast( self->s.origin, goalEnt->ent->s.origin );
		if( dist > WEIGHT_MAXDISTANCE_FACTOR * weight/* || dist < AI_GOAL_SR_RADIUS*/ )
			continue;

		cost = AI_FindCost( current_node, goalEnt->node, self->ai->status.moveTypesMask );
		if( cost == NODE_INVALID )
			continue;

		cost -= brandom( 0, 2000 ); // allow random variations
		clamp_low( cost, 1 );
		weight = ( 1000 * weight ) / ( cost * COST_INFLUENCE ); // Check against cost of getting there

		if( weight > bestWeight )
		{
			bestWeight = weight;
			bestGoalEnt = goalEnt;
		}
	}

	if( bestGoalEnt )
	{
		self->ai->goalEnt = bestGoalEnt;
		AI_SetGoal( self, bestGoalEnt->node );

		if( self->ai->goalEnt != NULL && nav.debugMode && bot_showlrgoal->integer )
			G_PrintChasersf( self, "%s: selected a %s at node %d for LR goal. (weight %f)\n", self->ai->pers.netname, self->ai->goalEnt->ent->classname, self->ai->goalEnt->node, bestWeight );

		return;
	}

	if( nav.debugMode && bot_showlrgoal->integer )
		G_PrintChasersf( self, "%s: did not find a LR goal.\n", self->ai->pers.netname );

#undef WEIGHT_MAXDISTANCE_FACTOR
#undef COST_INFLUENCE
}
Пример #3
0
//==========================================
// AI_FollowPath
// Move closer to goal by pointing the bot to the next node
// that is closer to the goal //jabot092 (path-> to path.)
//==========================================
qboolean AI_FollowPath( edict_t *self )
{
	vec3_t			v;
	float			dist;


	if( self->ai->goal_node == INVALID )
		return false;

	// Try again?
	if(self->ai->node_timeout++ > 30)
	{
		if(self->ai->tries++ > 3)
			return false;
		else
			AI_SetGoal( self, self->ai->goal_node );
	}

	// Are we there yet?
	VectorSubtract( self->s.origin, nodes[self->ai->next_node].origin, v );
	dist = VectorLength(v);

	//special lower plat reached check
	if( dist < 64
		&& nodes[self->ai->current_node].flags & NODEFLAGS_PLATFORM
		&& nodes[self->ai->next_node].flags & NODEFLAGS_PLATFORM
		&& self->groundentity && self->groundentity->use == Use_Plat)
		dist = 16;

	if( (dist < 32 && nodes[self->ai->next_node].flags != NODEFLAGS_JUMPPAD && nodes[self->ai->next_node].flags != NODEFLAGS_TELEPORTER_IN)
		|| (self->ai->status.jumpadReached && nodes[self->ai->next_node].flags & NODEFLAGS_JUMPPAD)
		|| (self->ai->status.TeleportReached && nodes[self->ai->next_node].flags & NODEFLAGS_TELEPORTER_IN) )
	{
		// reset timeout
		self->ai->node_timeout = 0;

		if( self->ai->next_node == self->ai->goal_node )
		{
			//if(AIDevel.debugChased && bot_showlrgoal->value)
			//	G_PrintMsg (AIDevel.chaseguy, PRINT_HIGH, "%s: GOAL REACHED!\n", self->ai->pers.netname);
			
			//if botroam, setup a timeout for it
			if( nodes[self->ai->goal_node].flags & NODEFLAGS_BOTROAM )
			{
				int		i;
				for( i=0; i<nav.num_broams; i++) {	//find the broam
					if( nav.broams[i].node != self->ai->goal_node )
						continue;

					//if(AIDevel.debugChased && bot_showlrgoal->integer)
					//	G_PrintMsg (AIDevel.chaseguy, PRINT_HIGH, "%s: BotRoam Time Out set up for node %i\n", self->ai->pers.netname, nav.broams[i].node);
					//Com_Printf( "%s: BotRoam Time Out set up for node %i\n", self->ai->pers.netname, nav.broams[i].node);
					self->ai->status.broam_timeouts[i] = level.time + 15.0;
					break;
				}
			}
		
			// Pick a new goal
			if (self->ai->state != BOT_STATE_CAMP)
				AI_PickLongRangeGoal(self);

		//	if (self->ai->next_node == self->ai->current_node)
		//	{	//gi.dprintf(DEVELOPER_MSG_GAME, "next_node\n");
				//AI_PickLongRangeGoal(self);
		//	}
				
		}
		else
		{
			self->ai->current_node = self->ai->next_node;
			if( self->ai->path.numNodes )
				self->ai->path.numNodes--;
			self->ai->next_node = self->ai->path.nodes[self->ai->path.numNodes];
		}
	}

	if(self->ai->current_node == -1 || self->ai->next_node == -1)
		return false;

	// Set bot's movement vector
	VectorSubtract( nodes[self->ai->next_node].origin, self->s.origin , self->ai->move_vector );
	return true;
}