📄 aaibuildtable.cpp
字号:
// 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 + -