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