示例#1
0
/*
=======================
LevelPlayerRegionUpdate

Updates the tracking of which player is in which
region, and the general traffic of which players
have been spotted in which regions of the level.
=======================
*/
void LevelPlayerRegionUpdate(void)
{
	int player, neighbor, team, region_index, neighbor_index;
	int num_players[TEAM_NUM_TEAMS];
	region_t *region;
	gentity_t *ent;

	// Update which region each player is currently in
	memset(num_players, 0, sizeof(num_players));
	for (player = 0; player < MAX_CLIENTS; player++)
	{
		// Ignore spectators (and other teamless entities)
		ent = &g_entities[player];
		team = EntityTeam(ent);
		if (team == TEAM_SPECTATOR)
		{
			player_region[player] = -1;
			continue;
		}

		// Found another player of this team
		num_players[team]++;

		// Compute this player's region
		region = LevelNearestRegion(ent->r.currentOrigin);
		player_region[player] = LevelRegionIndex(region);

		// Don't track players without a region
		if (player_region[player] < 0)
			continue;

		// Remember which regions from which this player was probably visible
		for (neighbor = 0;
			 neighbor < MAX_REGION_NEIGHBORS && region->local_neighbor[neighbor];
			 neighbor++)
		{
			// Ignore neighbors that aren't visible from this region
			if ( !(region->visible & (1 << neighbor)) )
				continue;

			// Mark that this player was visible near this region
			neighbor_index = LevelRegionIndex(region->local_neighbor[neighbor]);
			region_traffic[neighbor_index][team].actual++;
		}
	}

	// Update the number of possible sightings of each team in each region
	for (region_index = 0; region_index < num_regions; region_index++)
		for (team = 0; team < TEAM_NUM_TEAMS; team++)
			region_traffic[region_index][team].potential += num_players[team];
}
示例#2
0
Node::Node() : m_nodeId(0),
			   m_pParentNode(nullptr),
			   m_gridPos(0.0f, 0.0f),
			   m_worldPos(0.0f, 0.0f),
			   m_isObstacle(false),
			   m_pObstacle(nullptr),
			   m_territoryOwner(EntityTeam(None)),
			   m_isEntranceToBase(false),
			   m_isAttackPosition(None),
			   m_movementCost(0.0f),
			   m_heuristicValue(0.0f)
{
	for(unsigned int i = 0; i < NumberOfDirections; ++i)
	{
		m_coverProvided[i] = false;
	}
}
示例#3
0
/*
==============
BotTrafficData

Obtains the traffic data at the given point for teammates and enemies
of the given bot.  Returns a pointer to the region nearest that point,
or NULL if there are no defined regions.
==============
*/
region_t *BotTrafficData(bot_state_t *bs, vec3_t loc, history_t *teammate, history_t *enemy)
{
	int i, num_neighbors, team;
	float dists[TRAFFIC_NEIGHBORS], weights[TRAFFIC_NEIGHBORS], weight_total, min_dist;
	region_t *neighbors[TRAFFIC_NEIGHBORS], *closest;
	history_t *traffic, *team_traffic, *enemy_traffic;
	static history_t no_traffic = { 0, 1 };	// Fudged traffic data for situations that
											// lack traffic (eg. teammates in free for all)

	// Find the closest regions to this point
	num_neighbors = LevelNearestRegions(loc, TRAFFIC_NEIGHBORS, neighbors, dists);

	// Setup nothing if no neighbors could be found
	if (num_neighbors < 0)
		return NULL;

	// Weight nearer regions more than further regions and find the nearest neighbor
	memset(weights, 0, sizeof(weights));
	weight_total = 0.0;
	min_dist = -1;
	closest = NULL;
	for (i = 0; i < num_neighbors; i++)
	{
		// If this point is the exact center of a region, use only that region's data
		if (dists[i] <= 0)
		{
			memset(weights, 0, sizeof(weights));
			weights[i] = 1.0;
			weight_total = weights[i];
			closest = neighbors[i];
			break;
		}

		// The weight is inversely proportional to the distance
		weights[i] = 1.0 / dists[i];
		weight_total += weights[i];

		// Test if this region is nearer than the other options
		if (!closest || dists[i] < min_dist)
		{
			closest = neighbors[i];
			min_dist = dists[i];
		}
	}

	// Normalize the sum of the weights to 1.0
	if (weight_total > 0.0)
	{
		for (i = 0; i < num_neighbors; i++)
			weights[i] /= weight_total;
	}

	// Find out what team the bot is on
	team = EntityTeam(bs->ent);

	// Add each region's data to the average
	memset(teammate, 0, sizeof(history_t));
	memset(enemy,    0, sizeof(history_t));
	for (i = 0; i < num_neighbors; i++)
	{
		// Look up the traffic data for this region
		traffic = region_traffic[LevelRegionIndex(neighbors[i])];

		// Organize the data as teammate traffic and enemy traffic
		switch (team)
		{
			case TEAM_RED:
				team_traffic  = &traffic[TEAM_RED ];
				enemy_traffic = &traffic[TEAM_BLUE];
				break;

			case TEAM_BLUE:
				team_traffic  = &traffic[TEAM_BLUE];
				enemy_traffic = &traffic[TEAM_RED ];
				break;

			case TEAM_FREE:
			default:
				team_traffic  = &no_traffic;
				enemy_traffic = &traffic[TEAM_FREE];
				break;
		}

		// Track teammate traffic
		teammate->actual    += weights[i] * team_traffic->actual;
		teammate->potential += weights[i] * team_traffic->potential;

		// Track enemy traffic
		enemy->actual    += weights[i] * enemy_traffic->actual;
		enemy->potential += weights[i] * enemy_traffic->potential;
	}

	// Inform the caller of the closest neighbor
	return closest;
}