⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aaisector.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ------------------------------------------------------------------------
// AAI
//
// A skirmish AI for the TA Spring engine.
// Copyright Alexander Seizinger
// 
// Released under GPL license: see LICENSE.html for more information.
// ------------------------------------------------------------------------

#include "AAISector.h"
#include "AAI.h"
#include "AAIMap.h"

AAISector::AAISector()
{
}

AAISector::~AAISector(void)
{	
	defences.clear();
	
	attacked_by_this_game.clear(); 
	attacked_by_learned.clear(); 

	stat_combat_power.clear(); 
	mobile_combat_power.clear(); 

	combats_learned.clear();
	combats_this_game.clear();

	lost_units.clear();
}

void AAISector::Init(AAI *ai, int x, int y, int left, int right, int top, int bottom)
{
	this->ai = ai;
	this->ut = ai->ut;
	this->map = ai->map;

	// set coordinates of the corners
	this->x = x;
	this->y = y;

	this->left = left;
	this->right = right;
	this->top = top;
	this->bottom = bottom;

	// init all kind of stuff
	freeMetalSpots = false;
	interior = false;
	distance_to_base = -1;
	last_scout = 1;
	
	// nothing sighted in that sector
	enemy_structures = 0;
	own_structures = 0;
	allied_structures = 0;
	threat = 0;
	failed_defences = 0;
	
	int categories = ai->bt->assault_categories.size();

	combats_learned.resize(categories, 0);
	combats_this_game.resize(categories, 0);

	importance_this_game = 1.0f + (rand()%5)/20.0f;

	attacked_by_this_game.resize(categories, 0);
	attacked_by_learned.resize(categories, 0);

	lost_units.resize((int)MOBILE_CONSTRUCTOR-(int)COMMANDER+1.0);

	enemyUnitsOfType.resize((int)MOBILE_CONSTRUCTOR+1, 0);
	unitsOfType.resize((int)MOBILE_CONSTRUCTOR+1, 0);

	stat_combat_power.resize(categories, 0);
	mobile_combat_power.resize(categories+1, 0);
}

void AAISector::AddMetalSpot(AAIMetalSpot *spot)
{
	metalSpots.push_back(spot);
	freeMetalSpots = true;
}

int AAISector::GetNumberOfMetalSpots()
{
	return metalSpots.size();
}

bool AAISector::SetBase(bool base)
{
	if(base)
	{
		// check if already occupied (may happen if two coms start in same sector)
		if(map->team_sector_map[x][y] >= 0)
		{
			fprintf(ai->file, "\nTeam %i could not add sector %i,%i to base, already occupied by ally team %i!\n\n",ai->cb->GetMyTeam(), x, y, map->team_sector_map[x][y]);
			return false;
		}

		distance_to_base = 0;

		// if free metal spots in this sectors, base has free spots
		for(list<AAIMetalSpot*>::iterator spot = metalSpots.begin(); spot != metalSpots.end(); ++spot)
		{
			if(!(*spot)->occupied)
			{
				ai->brain->freeBaseSpots = true;
				break;
			}
		}

		// increase importance
		importance_this_game += 1;

		map->team_sector_map[x][y] = ai->cb->GetMyAllyTeam();

		if(importance_this_game > cfg->MAX_SECTOR_IMPORTANCE)
			importance_this_game = cfg->MAX_SECTOR_IMPORTANCE;

		return true;
	}
	else	// remove from base
	{
		distance_to_base = 1;

		map->team_sector_map[x][y] = -1;

		return true;
	}
}

void AAISector::Update()
{
	// decrease values (so the ai "forgets" values from time to time)...
	//ground_threat *= 0.995;
	//air_threat *= 0.995;
	for(int i = 0; i < MOBILE_CONSTRUCTOR-COMMANDER; ++i)
		lost_units[i] *= 0.92f;
}

AAIMetalSpot* AAISector::GetFreeMetalSpot()
{
	// look for the first unoccupied metalspot
	for(list<AAIMetalSpot*>::iterator i = metalSpots.begin(); i != metalSpots.end(); i++)
	{
		// if metalspot is occupied, try next one
		if(!(*i)->occupied)
			return *i;
	}
	
	
	return 0;
}
void AAISector::FreeMetalSpot(float3 pos, const UnitDef *extractor)
{
	float3 spot_pos;

	// get metalspot according to position
	for(list<AAIMetalSpot*>::iterator spot = metalSpots.begin(); spot != metalSpots.end(); ++spot)
	{
		// only check occupied spots
		if((*spot)->occupied)
		{
			// compare positions
			spot_pos = (*spot)->pos;
			ai->map->Pos2FinalBuildPos(&spot_pos, extractor);

			if(pos.x == spot_pos.x && pos.z == spot_pos.z)
			{
				(*spot)->occupied = false;
				(*spot)->extractor = -1;
				(*spot)->extractor_def = -1;

				freeMetalSpots = true;
				
				// if part of the base, tell the brain that the base has now free spots again
				if(distance_to_base == 0)
					ai->brain->freeBaseSpots = true;

				return;
			}
		}
	}
}

void AAISector::AddExtractor(int unit_id, int def_id, float3 *pos)
{
	float3 spot_pos;

	// get metalspot according to position
	for(list<AAIMetalSpot*>::iterator spot = metalSpots.begin(); spot != metalSpots.end(); ++spot)
	{
		// only check occupied spots
		if((*spot)->occupied)
		{
			// compare positions
			spot_pos = (*spot)->pos;
			ai->map->Pos2FinalBuildPos(&spot_pos, ai->bt->unitList[def_id-1]);

			if(pos->x == spot_pos.x && pos->z == spot_pos.z)	
			{
				(*spot)->extractor = unit_id;
				(*spot)->extractor_def = def_id;
			}
		}
	}
}

float3 AAISector::GetCenter()
{
	float3 pos;
	pos.x = (left + right)/2.0;
	pos.z = (top + bottom)/2.0;

	return pos;
}

float3 AAISector::GetBuildsite(int building, bool water)
{
	int xStart, xEnd, yStart, yEnd;

	GetBuildsiteRectangle(&xStart, &xEnd, &yStart, &yEnd);

	return map->GetBuildSiteInRect(ai->bt->unitList[building-1], xStart, xEnd, yStart, yEnd, water);
}

float3 AAISector::GetDefenceBuildsite(int building, UnitCategory category, float terrain_modifier, bool water)
{
	float3 best_pos = ZeroVector, pos;
	const UnitDef *def = ai->bt->unitList[building-1];

	int my_team = ai->cb->GetMyAllyTeam();

	float my_rating, best_rating = -10000;

	list<Direction> directions;

	// get possible directions 
	if(category == AIR_ASSAULT && !cfg->AIR_ONLY_MOD)
	{
		directions.push_back(CENTER);
	}
	else
	{
		if(distance_to_base > 0)
			directions.push_back(CENTER);
		else
		{
			// filter out frontiers to other base sectors
			if(x > 0 && map->sector[x-1][y].distance_to_base > 0 && map->sector[x-1][y].allied_structures < 100 && map->team_sector_map[x-1][y] != my_team )
				directions.push_back(WEST);
	
			if(x < map->xSectors-1 && map->sector[x+1][y].distance_to_base > 0 && map->sector[x+1][y].allied_structures < 100 && map->team_sector_map[x+1][y] != my_team)
				directions.push_back(EAST);

			if(y > 0 && map->sector[x][y-1].distance_to_base > 0 && map->sector[x][y-1].allied_structures < 100 && map->team_sector_map[x][y-1] != my_team)
				directions.push_back(NORTH);
	
			if(y < map->ySectors-1 && map->sector[x][y+1].distance_to_base > 0 && map->sector[x][y+1].allied_structures < 100 && map->team_sector_map[x][y+1] != my_team)
				directions.push_back(SOUTH);
		}
	}
	
	int xStart = 0;
	int xEnd = 0; 
	int yStart = 0;
	int yEnd = 0;

	// check possible directions
	for(list<Direction>::iterator dir =directions.begin(); dir != directions.end(); ++dir)
	{
		// get area to perform search 
		if(*dir == CENTER)
		{
			xStart = x * map->xSectorSizeMap;
			xEnd = (x+1) * map->xSectorSizeMap; 
			yStart = y * map->ySectorSizeMap;
			yEnd = (y+1) * map->ySectorSizeMap; 
		}
		else if(*dir == WEST)
		{
			xStart = x * map->xSectorSizeMap;
			xEnd = x * map->xSectorSizeMap + map->xSectorSizeMap/4.0f; 
			yStart = y * map->ySectorSizeMap;
			yEnd = (y+1) * map->ySectorSizeMap; 
		}
		else if(*dir == EAST)
		{
			xStart = (x+1) * map->xSectorSizeMap - map->xSectorSizeMap/4.0f;
			xEnd = (x+1) * map->xSectorSizeMap;
			yStart = y * map->ySectorSizeMap;
			yEnd = (y+1) * map->ySectorSizeMap; 
		}
		else if(*dir == NORTH)
		{
			xStart = x * map->xSectorSizeMap;
			xEnd = (x+1) * map->xSectorSizeMap;
			yStart = y * map->ySectorSizeMap;
			yEnd = y * map->ySectorSizeMap + map->ySectorSizeMap/4.0f; 
		}
		else if(*dir == SOUTH)
		{
			xStart = x * map->xSectorSizeMap ;
			xEnd = (x+1) * map->xSectorSizeMap;
			yStart = (y+1) * map->ySectorSizeMap - map->ySectorSizeMap/4.0f;
			yEnd = (y+1) * map->ySectorSizeMap; 
		}

		// 
		my_rating = map->GetDefenceBuildsite(&pos, def, xStart, xEnd, yStart, yEnd, category, terrain_modifier, water);

		if(my_rating > best_rating)
		{
			best_pos = pos;
			best_rating = my_rating;
		}
	}

	return best_pos;
}

float3 AAISector::GetCenterBuildsite(int building, bool water)
{
	int xStart, xEnd, yStart, yEnd;

	GetBuildsiteRectangle(&xStart, &xEnd, &yStart, &yEnd);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -