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

📄 aaibuildtable.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		// precache usage of jammers
		for(list<int>::iterator i = units_of_category[STATIONARY_JAMMER][s].begin(); i != units_of_category[STATIONARY_JAMMER][s].end(); i++)
		{
			if(unitList[*i-1]->energyUpkeep - unitList[*i-1]->energyMake > 0)
				units_static[*i].efficiency[0] = unitList[*i-1]->energyUpkeep - unitList[*i-1]->energyMake;
		}

		// precache usage of radar
		for(list<int>::iterator i = units_of_category[STATIONARY_RECON][s].begin(); i != units_of_category[STATIONARY_RECON][s].end(); i++)
		{
			if(unitList[*i-1]->energyUpkeep - unitList[*i-1]->energyMake > 0)
				units_static[*i].efficiency[0] = unitList[*i-1]->energyUpkeep - unitList[*i-1]->energyMake;
		}

		// precache extractor efficiency
		min_value[EXTRACTOR][s] = 10000;
		avg_value[EXTRACTOR][s] = 0;
		max_value[EXTRACTOR][s] = 0;	

		for(list<int>::iterator unit = units_of_category[EXTRACTOR][s].begin(); unit != units_of_category[EXTRACTOR][s].end(); ++unit)
		{
			avg_value[EXTRACTOR][s] += unitList[*unit-1]->extractsMetal;

			if(unitList[*unit-1]->extractsMetal > max_value[EXTRACTOR][s])
				max_value[EXTRACTOR][s] = unitList[*unit-1]->extractsMetal;

			if(unitList[*unit-1]->extractsMetal < min_value[EXTRACTOR][s])
				min_value[EXTRACTOR][s] = unitList[*unit-1]->extractsMetal;
		}

		if(units_of_category[EXTRACTOR][s].size() > 0)
			avg_value[EXTRACTOR][s] /= units_of_category[EXTRACTOR][s].size();
		else
		{
			min_value[EXTRACTOR][s] = -1;
			avg_value[EXTRACTOR][s] = -1;
			max_value[EXTRACTOR][s] = -1;
		}

		// precache power plant energy production
		min_value[POWER_PLANT][s] = 10000;
		avg_value[POWER_PLANT][s] = 0;
		max_value[POWER_PLANT][s] = 0;	

		for(list<int>::iterator unit = units_of_category[POWER_PLANT][s].begin(); unit != units_of_category[POWER_PLANT][s].end(); ++unit)
		{
			avg_value[POWER_PLANT][s] += units_static[*unit].efficiency[0];

			if(units_static[*unit].efficiency[0] > max_value[POWER_PLANT][s])
				max_value[POWER_PLANT][s] = units_static[*unit].efficiency[0];

			if(units_static[*unit].efficiency[0] < min_value[POWER_PLANT][s])
				min_value[POWER_PLANT][s] = units_static[*unit].efficiency[0];
		}

		if(units_of_category[POWER_PLANT][s].size() > 0)
			avg_value[POWER_PLANT][s] /= units_of_category[POWER_PLANT][s].size();
		else
		{
			min_value[POWER_PLANT][s] = -1;
			avg_value[POWER_PLANT][s] = -1;
			max_value[POWER_PLANT][s] = -1;
		}

		// precache stationary arty range
		min_value[STATIONARY_ARTY][s] = 100000;
		avg_value[STATIONARY_ARTY][s] = 0;
		max_value[STATIONARY_ARTY][s] = 0;	

		for(list<int>::iterator unit = units_of_category[STATIONARY_ARTY][s].begin(); unit != units_of_category[STATIONARY_ARTY][s].end(); ++unit)
		{
			avg_value[STATIONARY_ARTY][s] += units_static[*unit].efficiency[1];

			if(units_static[*unit].efficiency[1] > max_value[STATIONARY_ARTY][s])
				max_value[STATIONARY_ARTY][s] = units_static[*unit].efficiency[1];

			if(units_static[*unit].efficiency[1] < min_value[STATIONARY_ARTY][s])
				min_value[STATIONARY_ARTY][s] = units_static[*unit].efficiency[1];
		}

		if(units_of_category[STATIONARY_ARTY][s].size() > 0)
			avg_value[STATIONARY_ARTY][s] /= units_of_category[STATIONARY_ARTY][s].size();
		else
		{
			min_value[STATIONARY_ARTY][s] = -1;
			avg_value[STATIONARY_ARTY][s] = -1;
			max_value[STATIONARY_ARTY][s] = -1;
		}

		// precache scout los
		min_value[SCOUT][s] = 100000;
		avg_value[SCOUT][s] = 0;
		max_value[SCOUT][s] = 0;	

		for(list<int>::iterator unit = units_of_category[SCOUT][s].begin(); unit != units_of_category[SCOUT][s].end(); ++unit)
		{
			avg_value[SCOUT][s] += unitList[*unit-1]->losRadius;

			if(unitList[*unit-1]->losRadius > max_value[SCOUT][s])
				max_value[SCOUT][s] = unitList[*unit-1]->losRadius;

			if(unitList[*unit-1]->losRadius < min_value[SCOUT][s])
				min_value[SCOUT][s] = unitList[*unit-1]->losRadius;
		}

		if(units_of_category[SCOUT][s].size() > 0)
			avg_value[SCOUT][s] /= units_of_category[SCOUT][s].size();
		else
		{
			min_value[SCOUT][s] = -1;
			avg_value[SCOUT][s] = -1;
			max_value[SCOUT][s] = -1;
		}

		// precache stationary defences weapon range
		min_value[STATIONARY_DEF][s] = 100000;
		avg_value[STATIONARY_DEF][s] = 0;
		max_value[STATIONARY_DEF][s] = 0;	

		float range;

		if(units_of_category[STATIONARY_DEF][s].size() > 0)
		{
			for(list<int>::iterator unit = units_of_category[STATIONARY_DEF][s].begin(); unit != units_of_category[STATIONARY_DEF][s].end(); ++unit)
			{
				range = units_static[*unit].range;
				
				avg_value[STATIONARY_DEF][s] += range;
	
				if(range > max_value[STATIONARY_DEF][s])
					max_value[STATIONARY_DEF][s] = range;
	
				if(range < min_value[STATIONARY_DEF][s])
					min_value[STATIONARY_DEF][s] = range;
			}

			avg_value[STATIONARY_DEF][s] /= (float)units_of_category[STATIONARY_DEF][s].size();
		}
		else
		{
			min_value[STATIONARY_DEF][s] = -1;
			avg_value[STATIONARY_DEF][s] = -1;
			max_value[STATIONARY_DEF][s] = -1;
		}

		// precache builders' buildspeed
		float buildspeed;

		if(units_of_category[MOBILE_CONSTRUCTOR][s].size() > 0)
		{
			min_value[MOBILE_CONSTRUCTOR][s] = 100000;
			avg_value[MOBILE_CONSTRUCTOR][s] = 0;
			max_value[MOBILE_CONSTRUCTOR][s] = 0;

			for(list<int>::iterator unit = units_of_category[MOBILE_CONSTRUCTOR][s].begin(); unit != units_of_category[MOBILE_CONSTRUCTOR][s].end(); ++unit)
			{
				buildspeed = unitList[*unit-1]->buildSpeed;
				
				avg_value[MOBILE_CONSTRUCTOR][s] += buildspeed;

				if(buildspeed > max_value[MOBILE_CONSTRUCTOR][s])
					max_value[MOBILE_CONSTRUCTOR][s] = buildspeed;
	
				if(buildspeed < min_value[MOBILE_CONSTRUCTOR][s])
					min_value[MOBILE_CONSTRUCTOR][s] = buildspeed;
			}

			avg_value[MOBILE_CONSTRUCTOR][s] /= (float)units_of_category[MOBILE_CONSTRUCTOR][s].size();
		}
		else
		{
			min_value[MOBILE_CONSTRUCTOR][s] = -1;
			avg_value[MOBILE_CONSTRUCTOR][s] = -1;
			max_value[MOBILE_CONSTRUCTOR][s] = -1;
		}

	
		// precache unit speed and weapons range
		int cat;

		for(list<UnitCategory>::iterator category = assault_categories.begin(); category != assault_categories.end(); ++category)
		{
			// precache range
			min_value[*category][s] = 10000;
			avg_value[*category][s] = 0;
			max_value[*category][s] = 0;

			if(units_of_category[*category][s].size() > 0)
			{
				for(list<int>::iterator unit = units_of_category[*category][s].begin(); unit != units_of_category[*category][s].end(); ++unit)
				{
					range = GetMaxRange(*unit);

					avg_value[*category][s] += range;

					if(range > max_value[*category][s])
						max_value[*category][s] = range;

					if(range < min_value[*category][s])
						min_value[*category][s] = range;
				}

				avg_value[*category][s] /= (float)units_of_category[*category][s].size();
			}
			else
			{
				min_value[*category][s] = -1;
				avg_value[*category][s] = -1;
				max_value[*category][s] = -1;
			}

			// precache speed
			cat = GetIDOfAssaultCategory(*category);

			if(cat != -1)
			{
				if(units_of_category[*category][s].size() > 0)
				{
					min_speed[cat][s] = 10000;
					max_speed[cat][s] = 0;
					group_speed[cat][s] = 0;
					avg_speed[cat][s] = 0;	

					for(list<int>::iterator unit = units_of_category[*category][s].begin(); unit != units_of_category[*category][s].end(); ++unit)
					{
						avg_speed[cat][s] += unitList[*unit-1]->speed;

						if(unitList[*unit-1]->speed < min_speed[cat][s])
							min_speed[cat][s] = unitList[*unit-1]->speed;
	
						if(unitList[*unit-1]->speed > max_speed[cat][s])
							max_speed[cat][s] = unitList[*unit-1]->speed;
					}

					avg_speed[cat][s] /= (float)units_of_category[*category][s].size();

					group_speed[cat][s] = (1 + max_speed[cat][s] - min_speed[cat][s]) / ((float)cfg->UNIT_SPEED_SUBGROUPS);
				}
				else
				{
					min_speed[cat][s] = -1;
					max_speed[cat][s] = -1;
					group_speed[cat][s] = -1;
					avg_speed[cat][s] = -1;	
				}
			}
		}
	}
}


int AAIBuildTable::GetSide(int unit)
{
	return units_static[cb->GetUnitDef(unit)->id].side;
}

int AAIBuildTable::GetSideByID(int unit_id)
{
	return units_static[unit_id].side;
}

UnitType AAIBuildTable::GetUnitType(int def_id)
{
	if(cfg->AIR_ONLY_MOD)
	{
		return ASSAULT_UNIT;
	}
	else
	{
		if (units_static.empty()) return UNKNOWN_UNIT;
		UnitCategory cat = units_static[def_id].category;
		int side = units_static[def_id].side-1;
		
		if(cat == GROUND_ASSAULT)
		{
			if( units_static[def_id].efficiency[1] / max_eff[side][0][1]  > 6 * units_static[def_id].efficiency[0] / max_eff[side][0][0] )
				return ANTI_AIR_UNIT;
			else
				return ASSAULT_UNIT;
		}
		else if(cat == AIR_ASSAULT)
		{
			float vs_building = units_static[def_id].efficiency[5] / max_eff[side][1][5];
			
			float vs_units = (units_static[def_id].efficiency[0] / max_eff[side][1][0]
							+ units_static[def_id].efficiency[3] / max_eff[side][1][3]) / 2.0f;

			if( units_static[def_id].efficiency[1]  / max_eff[side][1][1] > 2 * (vs_building + vs_units) )
				return ANTI_AIR_UNIT;
			else
			{
				if(vs_building > 4 * vs_units || unitList[def_id-1]->type == string("Bomber"))	
					return BOMBER_UNIT;
				else
					return ASSAULT_UNIT;	
			}
		}
		else if(cat == HOVER_ASSAULT)
		{
			if( units_static[def_id].efficiency[1] / max_eff[side][2][1] > 6 * units_static[def_id].efficiency[0] / max_eff[side][2][0] )
				return ANTI_AIR_UNIT;
			else
				return ASSAULT_UNIT;
		}
		else if(cat == SEA_ASSAULT)
		{
			if( units_static[def_id].efficiency[1] / max_eff[side][3][1] > 6 * units_static[def_id].efficiency[3] / max_eff[side][3][3] )
				return ANTI_AIR_UNIT;
			else
				return ASSAULT_UNIT;
		}
		else if(cat == SUBMARINE_ASSAULT)
		{
			if( units_static[def_id].efficiency[1] / max_eff[side][4][1] > 6 * units_static[def_id].efficiency[3] / max_eff[side][4][3] )
				return ANTI_AIR_UNIT;
			else
				return ASSAULT_UNIT;
		}
		else if(cat >= GROUND_ARTY && cat <= HOVER_ARTY)
		{
			return ARTY_UNIT;
		} else //throw "AAIBuildTable::GetUnitType: invalid unit category";
			return UNKNOWN_UNIT;
	}
}

bool AAIBuildTable::MemberOf(int unit_id, list<int> unit_list)
{
	// test all units in list
	for(list<int>::iterator i = unit_list.begin(); i != unit_list.end(); i++)
	{
		if(*i == unit_id)
			return true;
	}

	// unitid not found
	return false;
}

int AAIBuildTable::GetPowerPlant(int side, float cost, float urgency, float power, float current_energy, bool water, bool geo, bool canBuild)
{
	UnitTypeStatic *unit;

	int best_unit = 0;  

	float best_ranking = -10000, my_ranking;

	float max_buildtime = this->max_buildtime[POWER_PLANT][side-1] * 256.0f;

	float max_power = this->max_value[POWER_PLANT][side-1];

	//debug
	//fprintf(ai->file, "Selecting power plant:     power %f    cost %f    urgency %f   energy %f \n", power, cost, urgency, current_energy);

	for(list<int>::iterator pplant = units_of_category[POWER_PLANT][side-1].begin(); pplant != units_of_category[POWER_PLANT][side-1].end(); ++pplant)
	{
		unit = &units_static[*pplant];

		if(canBuild && units_dynamic[*pplant].buildersAvailable <= 0)
			my_ranking = -10000;
		else if(!geo && unitList[*pplant-1]->needGeo)
			my_ranking = -10000;
		else if( (!water && unitList[*pplant-1]->minWaterDepth <= 0) || (water && unitList[*pplant-1]->minWaterDepth > 0) )
		{
			my_ranking = cost * unit->efficiency[1] / max_pplant_eff[side-1] + power * unit->efficiency[0] / max_power
						- urgency * (unitList[*pplant-1]->buildTime / max_buildtime);

			//
			if(unit->cost >= max_cost[POWER_PLANT][side-1])
				my_ranking -= (cost + urgency + power)/2.0f;

			//fprintf(ai->file, "%-20s: %f\n", unitList[*pplant-1]->humanName.c_str(), my_ranking);
		}
		else
			my_ranking = -10000;

		if(my_ranking > best_ranking)
		{
				best_ranking = my_ranking;
				best_unit = *pplant;
		}
	}

	// 0 if no unit found (list was probably empty)
	return best_unit;
}

int AAIBuildTable::GetMex(int side, float cost, float effiency, bool armed, bool water, bool canBuild)
{
	int best_unit = 0; 
	float best_ranking = -10000, my_ranking;

	side -= 1;

	for(list<int>::iterator i = units_of_category[EXTRACTOR][side].begin(); i != units_of_category[EXTRACTOR][side].end(); i++)
	{
		if(canBuild && units_dynamic[*i].buildersAvailable <= 0)
			my_ranking = -10000;
		// check if under water or ground || water = true and building under water
		else if( ( (!water) && unitList[*i-1]->minWaterDepth <= 0 ) || ( water && unitList[*i-1]->minWaterDepth > 0 ) )

⌨️ 快捷键说明

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