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

📄 aaiexecute.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		else
		{
			unit = bt->GetSeaAssault(ai->side, power, ground_eff, air_eff, hover_eff, sea_eff, submarine_eff, stat_eff, eff, speed, range, cost, 9, false);

			if(unit && bt->units_dynamic[unit].buildersAvailable <= 0)
			{
				bt->BuildFactoryFor(unit);
				unit = bt->GetSeaAssault(ai->side, power, ground_eff, air_eff, hover_eff, sea_eff, submarine_eff, stat_eff, eff, speed, range, cost, 9, false);
			}
		}
	}
	else if(category == SUBMARINE_ASSAULT)
	{
		if(rand()%cfg->LEARN_RATE == 1)
			unit = bt->GetRandomUnit(bt->units_of_category[SUBMARINE_ASSAULT][ai->side-1]);
		else
		{
			unit = bt->GetSubmarineAssault(ai->side, power, sea_eff, submarine_eff, stat_eff, eff, speed, range, cost, 9, false);

			if(unit && bt->units_dynamic[unit].buildersAvailable <= 0)
			{
				bt->BuildFactoryFor(unit);
				unit = bt->GetSubmarineAssault(ai->side, power, sea_eff, submarine_eff, stat_eff, eff, speed, range, cost, 9, false);
			}
		}
	}


	if(unit)
	{
		if(bt->units_dynamic[unit].buildersAvailable > 0)
		{	
			if(bt->units_static[unit].cost < cfg->MAX_COST_LIGHT_ASSAULT * bt->max_cost[category][ai->side-1])
			{
				if(AddUnitToBuildque(unit, 3, urgent))
					bt->units_dynamic[unit].requested += 3;
			}
			else if(bt->units_static[unit].cost < cfg->MAX_COST_MEDIUM_ASSAULT * bt->max_cost[category][ai->side-1])
			{
				if(AddUnitToBuildque(unit, 2, urgent))
					bt->units_dynamic[unit].requested += 2;
			}
			else
			{
				if(AddUnitToBuildque(unit, 1, urgent))
					bt->units_dynamic[unit].requested += 1;
			}
		}
		else
			bt->BuildFactoryFor(unit);
	}
}

bool AAIExecute::BuildRecon()
{
	if(ai->futureUnits[STATIONARY_RECON])
		return true;

	int radar = 0;
	AAIConstructor *builder;
	float3 pos;
	bool checkWater, checkGround;

	float cost = brain->Affordable();
	float range = 10.0 / (cost + 1);
	
	for(list<AAISector*>::iterator sector = brain->sectors[0].begin(); sector != brain->sectors[0].end(); ++sector)
	{
		if((*sector)->unitsOfType[STATIONARY_RECON] > 0)
		{
			checkWater = false;
			checkGround = false;
		}
		else if((*sector)->water_ratio < 0.15)
		{
			checkWater = false;
			checkGround = true;	
		}
		else if((*sector)->water_ratio < 0.85)
		{
			checkWater = true;
			checkGround = true;
		}
		else
		{
			checkWater = true;
			checkGround = false;
		}

		if(checkGround)
		{
			// find radar
			radar = bt->GetRadar(ai->side, cost, range, false, false);

			if(radar && bt->units_dynamic[radar].buildersAvailable <= 0 && bt->units_dynamic[radar].buildersRequested <= 0)
			{
				bt->BuildBuilderFor(radar);
				radar = bt->GetRadar(ai->side, cost, range, false, true);
			}
		
			if(radar)
			{
				pos = (*sector)->GetHighestBuildsite(radar);

				if(pos.x > 0)
				{
					builder = ut->FindClosestBuilder(radar, pos, true, 10);

					if(builder)
					{
						builder->GiveConstructionOrder(radar, pos, false);
						return true;
					}
					else
					{
						bt->AddBuilder(radar);
						return false;
					}
				}
			}
		}

		if(checkWater)
		{
			// find radar
			radar = bt->GetRadar(ai->side, cost, range, true, false);

			if(radar && bt->units_dynamic[radar].buildersAvailable <= 0 && bt->units_dynamic[radar].buildersRequested <= 0)
			{
				bt->BuildBuilderFor(radar);
				radar = bt->GetRadar(ai->side, cost, range, true, true);
			}
		
			if(radar)
			{
				pos = (*sector)->GetBuildsite(radar, true);

				if(pos.x > 0)
				{
					builder = ut->FindClosestBuilder(radar, pos, true, 10);

					if(builder)
					{
						builder->GiveConstructionOrder(radar, pos, true);
						return true;
					}
					else
					{
						bt->AddBuilder(radar);
						return false;
					}
				}
			}
		}
	}

	return true;
}

bool AAIExecute::BuildJammer()
{
	int jammer = 0;

	float cost = brain->Affordable();
	float range = 10.0 / (cost + 1);

	jammer = bt->GetJammer(ai->side, cost, range, false, false);

	if(jammer && bt->units_dynamic[jammer].buildersAvailable <= 0)
	{
		if(bt->units_dynamic[jammer].buildersRequested <= 0)
			bt->BuildBuilderFor(jammer);

		jammer = bt->GetJammer(ai->side, cost, range, false, true);
	}
	
	if(jammer)
	{
		AAIConstructor *builder = ut->FindBuilder(jammer, true, 10);

		if(builder)
		{
			AAISector *best_sector = 0;
			float best_rating = 0, my_rating;
			
			for(list<AAISector*>::iterator sector = brain->sectors[0].begin(); sector != brain->sectors[0].end(); sector++)
			{
				if((*sector)->unitsOfType[STATIONARY_JAMMER] == 0 && ((*sector)->unitsOfType[STATIONARY_CONSTRUCTOR] > 0 || (*sector)->unitsOfType[POWER_PLANT] > 0) )
					my_rating = (*sector)->GetOverallThreat(1, 1);
				else 
					my_rating = 0;

				if(my_rating > best_rating)
				{
					best_rating = my_rating;
					best_sector = *sector;
				}
			}

			// find centered spot in that sector
			if(best_sector)
			{
				float3 pos = best_sector->GetCenterBuildsite(jammer, false);

				if(pos.x > 0)
				{
					builder->GiveConstructionOrder(jammer, pos, false);
					futureRequestedEnergy += (bt->unitList[jammer-1]->energyUpkeep - bt->unitList[jammer-1]->energyMake);
				}
			}
		}
		else
			return false;
	}

	return true;
}

void AAIExecute::DefendMex(int mex, int def_id)
{
	if(ai->activeFactories < cfg->MIN_FACTORIES_FOR_DEFENCES)
		return;

	float3 pos = cb->GetUnitPos(mex);
	float3 base_pos = brain->base_center;

	int x = pos.x/map->xSectorSize;
	int y = pos.z/map->ySectorSize;

	if(x >= 0 && y >= 0 && x < map->xSectors && y < map->ySectors)
	{
		AAISector *sector = &map->sector[x][y];

		if(sector->distance_to_base > 0 && sector->distance_to_base <= cfg->MAX_MEX_DEFENCE_DISTANCE && sector->allied_structures < 500)
		{
			int defence = 0;
			bool water;

			// get defence building dependend on water or land mex
			if(bt->unitList[def_id-1]->minWaterDepth > 0)
			{
				water = true;

				if(cfg->AIR_ONLY_MOD)
					defence = bt->GetDefenceBuilding(ai->side, 2, 1, 1, 1, 0.5, 0, 0, 0, 4, 0.1, 1, true, true);
				else
					defence = bt->GetDefenceBuilding(ai->side, 2, 1, 1, 0, 0, 0, 1.5, 0.5, 4, 0.1, 1, true, true); 
			}
			else 
			{
				if(cfg->AIR_ONLY_MOD)
					defence = bt->GetDefenceBuilding(ai->side, 2, 1, 1, 1, 0.5, 0, 0, 0, 4, 0.1, 1, false, true);
				else
				{
					if(map->mapType == AIR_MAP)
						defence = bt->GetDefenceBuilding(ai->side, 2, 1, 1, 0, 2, 0, 0, 0, 4, 0.1, 1, false, true); 
					else
						defence = bt->GetDefenceBuilding(ai->side, 2, 1, 1, 1.5, 0.5, 0, 0, 0, 4, 0.1, 3, false, true); 
				}
				
				water = false;
			}

			// find closest builder
			if(defence)
			{
				// place defences according to the direction of the main base
				if(pos.x > base_pos.x + 500)
					pos.x += 120;
				else if(pos.x > base_pos.x + 300)
					pos.x += 70;
				else if(pos.x < base_pos.x - 500)
					pos.x -= 120;
				else if(pos.x < base_pos.x - 300)
					pos.x -= 70;

				if(pos.z > base_pos.z + 500)
					pos.z += 70;
				else if(pos.z > base_pos.z + 300)
					pos.z += 120;
				else if(pos.z < base_pos.z - 500)
					pos.z -= 120;
				else if(pos.z < base_pos.z - 300)
					pos.z -= 70;

				// get suitable pos
				pos = cb->ClosestBuildSite(bt->unitList[defence-1], pos, 1400.0, 2);

				if(pos.x > 0)
				{
					AAIConstructor *builder;

					if(brain->sectors[0].size() > 2)
						builder = ut->FindClosestBuilder(defence, pos, false, 10);
					else
						builder = ut->FindClosestBuilder(defence, pos, true, 10);

					if(builder)
						builder->GiveConstructionOrder(defence, pos, water);	
				}
			}
		}
	}
}

void AAIExecute::UpdateRessources()
{
	// get current metal/energy surplus
	metalSurplus[counter] = cb->GetMetalIncome() - cb->GetMetalUsage();
	if(metalSurplus[counter] < 0) metalSurplus[counter] = 0;

	energySurplus[counter] = cb->GetEnergyIncome() - cb->GetEnergyUsage();
	if(energySurplus[counter] < 0) energySurplus[counter] = 0;

	// calculate average value
	averageMetalSurplus = 0;
	averageEnergySurplus = 0;

	for(int i = 0; i < 8; i++)
	{
		averageMetalSurplus += metalSurplus[i];
		averageEnergySurplus += energySurplus[i];
	}

	averageEnergySurplus /= 8.0f;
	averageMetalSurplus /= 8.0f;

	// increase counter
	counter = (++counter)%8;
}

void AAIExecute::CheckStationaryArty()
{
	if(cfg->MAX_STAT_ARTY == 0)
		return;

	if(ai->futureUnits[STATIONARY_ARTY] > 0)
		return;

	if(ai->activeUnits[STATIONARY_ARTY] >= cfg->MAX_STAT_ARTY)
		return;

	float temp = 0.05f;

	if(temp > urgency[STATIONARY_ARTY])
		urgency[STATIONARY_ARTY] = temp;
}

void AAIExecute::CheckBuildques()
{
	int req_units = 0;
	int active_factory_types = 0;
	
	for(int i = 0; i < numOfFactories; ++i)
	{
		// sum up builque lengths of active factory types
		if(bt->units_dynamic[factory_table[i]].active > 0)
		{
			req_units += (int) buildques[i].size();
			++active_factory_types;
		}
	}

	if(active_factory_types > 0)
	{
		if( (float)req_units / (float)active_factory_types < (float)cfg->MAX_BUILDQUE_SIZE / 2.5f )
		{
			if(unitProductionRate < 70)
				++unitProductionRate;

			fprintf(ai->file, "Increasing unit production rate to %i\n", unitProductionRate);
		}
		else if( (float)req_units / (float)active_factory_types > (float)cfg->MAX_BUILDQUE_SIZE / 1.5f )
		{
			if(unitProductionRate > 1)
			{
				--unitProductionRate;
				fprintf(ai->file, "Decreasing unit production rate to %i\n", unitProductionRate);
			}
		}
	}
}

void AAIExecute::CheckDefences()
{
	if(ai->activeFactories < cfg->MIN_FACTORIES_FOR_DEFENCES || ai->futureUnits[STATIONARY_DEF] > 2)
		return;

	int t = brain->GetGamePeriod();

	int max_dist = 1;

	double rating, highest_rating = 0;

	AAISector *first = 0, *second = 0;
	UnitCategory cat1 = UNKNOWN, cat2 = UNKNOWN;

	for(int dist = 0; dist <= max_dist; ++dist)
	{
		for(list<AAISector*>::iterator sector = brain->sectors[dist].begin(); sector != brain->sectors[dist].end(); ++sector)
		{
			// stop building further defences if maximum has been reached / sector contains allied buildings / is occupied by another aai instance
			if((*sector)->defences.size() < cfg->MAX_DEFENCES && (*sector)->allied_structures < 100 && map->team_sector_map[(*sector)->x][(*sector)->y] != cb->GetMyAllyTeam())
			{
				if((*sector)->failed_defences > 1)
				{
					(*sector)->failed_defences = 0;
				}
				else
				{
					for(list<int>::iterator cat = map->map_categories_id.begin(); cat!= map->map_categories_id.end(); ++cat)
					{
						// anti air defences may be built anywhere
						if(cfg->AIR_ONLY_MOD || *cat == AIR_ASSAULT)
							rating = (1.0f + sqrt((*sector)->own_structures)) * (1.0f + bt->attacked_by_category[1][*cat][t]) * (*sector)->GetThreatByID(*cat, learned, current) / ( (*sector)->GetDefencePowerVsID(*cat) );
						// dont build anti ground/hover/sea defences in interior sectors
						else if(!(*sector)->interior)
							rating = (1.0f + sqrt((*sector)->own_structures)) * (1.0f + bt->attacked_by_category[1][*cat][t]) * (*sector)->GetThreatByID(*cat, learned, current) / ( (*sector)->GetDefencePowerVsID(*cat));		
						else
							rating = 0;
								
						if(rating > highest_rating)
						{
							// dont block empty sectors with too much aa
							if(bt->GetAssaultCategoryOfID(*cat) != AIR_ASSAULT || ((*sector)->unitsOfType[POWER_PLANT] > 0 || (*sector)->unitsOfType[STATIONARY_CONSTRUCTOR] > 0 ) )
							{
								second = first;
								cat2 = cat1;

								first = *sector;
								cat1 = bt->GetAssaultCategoryOfID(*cat);

								highest_rating = rating;
							}
						}
					}
				}
			}
		}
	}

	if(first)
	{
		// if no builder available retry later
		BuildOrderStatus status = BuildStationaryDefenceVS(cat1, first);

		if(status == BUILDORDER_NOBUILDER)
		{
			float temp = 0.3 + 6.0 / ( (float) first->defences.size() + 1.0f); 

			if(urgency[STATIONARY_DEF] < temp)
				urgency[STATIONARY_DEF] = temp;

			next_defence = first;
			def_category = cat1;
		}
		else if(status == BUILDORDER_NOBUILDPOS)
		{
			++first->failed_defences;
		}
	}
	
	if(second)
		BuildStationaryDefenceVS(cat2, second);
}

void AAIExecute::CheckRessources()
{
	// prevent float rounding errors
	if(futureAvailableEnergy < 0)
		futureAvailableEnergy = 0;

	// determine how much metal/energy is needed based on net surplus
	float temp = GetMetalUrgency();
	if(urgency[EXTRACTOR] < temp) // && urgency[EXTRACTOR] > 0.05) 
		urgency[EXTRACTOR] = temp;

	temp = GetEnergyUrgency();
	if(urgency[POWER_PLANT] < temp) // && urgency[POWER_PLANT] > 0.05)
		urgency[POWER_PLANT] = temp;

	// build storages if needed
	if(ai->activeUnits[STORAGE] + ai->futureUnits[STORAGE] < cfg->MAX_STORAGE 
		&& ai->activeFactories >= cfg->MIN_FACTORIES_FOR_STORAGE)
	{
		float temp = max(GetMetalStorageUrgency(), GetEnergyStorageUrgency());
		
		if(temp > urgency[STORAGE])
			urgency[STORAGE] = temp;
	}

	// energy low
	if(averageEnergySurplus < 1.5 * cfg->METAL_ENERGY_RATIO)
	{
		// try to accelerate power plant construction
		if(ai->futureUnits[POWER_PLANT] > 0)
			AssistConstructionOfCategory(POWER_PLANT, 10);

		// try to disbale some metal makers
		if((ai->activeUnits[METAL_MAKER] - disabledMMakers) > 0)
		{
			for(set<int>::iterator maker = ut->metal_makers.begin(); maker != ut->metal_makers.end(); maker++)
			{
				if(cb->IsUnitActivated(*maker))
				{
					Command c;
					c.id = CMD_ONOFF;
					c.params.push_back(0);
					cb->Giv

⌨️ 快捷键说明

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