📄 aaiexecute.cpp
字号:
{
if(bt->units_static[(*task)->def_id].cost > 0.7 * bt->avg_cost[STATIONARY_DEF][ai->side-1])
return BUILDORDER_SUCCESFUL;
}
}
}
double gr_eff = 0, air_eff = 0, hover_eff = 0, sea_eff = 0, submarine_eff = 0;
bool checkWater, checkGround;
int building;
float3 pos;
AAIConstructor *builder;
float terrain = 3.0f;
if(dest->distance_to_base > 0)
terrain = 15.0f;
if(dest->water_ratio < 0.15)
{
checkWater = false;
checkGround = true;
}
else if(dest->water_ratio < 0.85)
{
checkWater = true;
checkGround = true;
}
else
{
checkWater = true;
checkGround = false;
}
double urgency = 0.25 + 10.0 / (dest->defences.size() + dest->GetDefencePowerVs(category) + 1.0);
double power = 0.5 + 2.0 / urgency;
double eff = 0.5 + brain->Affordable()/6.0;
double range = 0.5;
double cost = 0.5 + brain->Affordable()/6.0;
if(dest->defences.size() > 3)
{
int t = rand()%500;
if(t < 70)
{
range = 2.5;
terrain = 30.0f;
}
else if(t < 200)
{
range = 1;
terrain = 25.0f;
}
t = rand()%500;
if(t < 200)
power += 1.5;
}
if(category == GROUND_ASSAULT)
gr_eff = 2;
else if(category == AIR_ASSAULT)
air_eff = 2;
else if(category == HOVER_ASSAULT)
{
gr_eff = 1;
sea_eff = 1;
hover_eff = 4;
}
else if(category == SEA_ASSAULT)
{
sea_eff = 4;
submarine_eff = 1;
}
else if(category == SUBMARINE_ASSAULT)
{
sea_eff = 1;
submarine_eff = 4;
}
if(checkGround)
{
if(rand()%cfg->LEARN_RATE == 1 && dest->defences.size() > 3)
building = bt->GetRandomDefence(ai->side, category);
else
building = bt->GetDefenceBuilding(ai->side, eff, power, cost, gr_eff, air_eff, hover_eff, sea_eff, submarine_eff, urgency, range, 8, false, false);
if(building && bt->units_dynamic[building].buildersAvailable <= 0 && bt->units_dynamic[building].buildersRequested <= 0)
{
bt->BuildBuilderFor(building);
building = bt->GetDefenceBuilding(ai->side, eff, power, cost, gr_eff, air_eff, hover_eff, sea_eff, submarine_eff, urgency, range, 8, false, true);
}
// stop building of weak defences if urgency is too low (wait for better defences)
if(urgency < 2.5)
{
int id = bt->GetIDOfAssaultCategory(category);
if(bt->units_static[building].efficiency[id] < bt->avg_eff[ai->side-1][5][id] / 2.0f)
building = 0;
}
else if(urgency < 0.75)
{
int id = bt->GetIDOfAssaultCategory(category);
if(bt->units_static[building].efficiency[id] < bt->avg_eff[ai->side-1][5][id])
building = 0;
}
if(building)
{
pos = dest->GetDefenceBuildsite(building, category, terrain, false);
if(pos.x > 0)
{
builder = ut->FindClosestBuilder(building, pos, true, 10);
if(builder)
{
builder->GiveConstructionOrder(building, pos, false);
// add defence to map
map->AddDefence(&pos, building);
return BUILDORDER_SUCCESFUL;
}
else
{
bt->AddBuilder(building);
return BUILDORDER_NOBUILDER;
}
}
else
return BUILDORDER_NOBUILDPOS;
}
}
if(checkWater)
{
if(rand()%cfg->LEARN_RATE == 1 && dest->defences.size() > 3)
building = bt->GetRandomDefence(ai->side, category);
else
building = bt->GetDefenceBuilding(ai->side, eff, power, cost, gr_eff, air_eff, hover_eff, sea_eff, submarine_eff, urgency, 1, 8, true, false);
if(building && bt->units_dynamic[building].buildersAvailable <= 0 && bt->units_dynamic[building].buildersRequested <= 0)
{
bt->BuildBuilderFor(building);
building = bt->GetDefenceBuilding(ai->side, eff, power, cost, gr_eff, air_eff, hover_eff, sea_eff, submarine_eff, urgency, 1, 8, true, true);
}
// stop building of weak defences if urgency is too low (wait for better defences)
if(urgency < 2.5)
{
int id = bt->GetIDOfAssaultCategory(category);
if(bt->units_static[building].efficiency[id] < bt->avg_eff[ai->side-1][5][id] / 2.0f)
building = 0;
}
else if(urgency < 0.75)
{
int id = bt->GetIDOfAssaultCategory(category);
if(bt->units_static[building].efficiency[id] < bt->avg_eff[ai->side-1][5][id])
building = 0;
}
if(building)
{
pos = dest->GetDefenceBuildsite(building, category, terrain, true);
if(pos.x > 0)
{
builder = ut->FindClosestBuilder(building, pos, true, 10);
if(builder)
{
builder->GiveConstructionOrder(building, pos, true);
// add defence to map
map->AddDefence(&pos, building);
return BUILDORDER_SUCCESFUL;
}
else
{
bt->AddBuilder(building);
return BUILDORDER_NOBUILDER;
}
}
else
return BUILDORDER_NOBUILDPOS;
}
}
return BUILDORDER_FAILED;
}
bool AAIExecute::BuildArty()
{
if(ai->futureUnits[STATIONARY_ARTY])
return true;
AAIConstructor *builder;
float3 pos;
int arty = 0;
bool checkWater, checkGround;
brain->sectors[0].sort(suitable_for_arty);
for(list<AAISector*>::iterator sector = brain->sectors[0].begin(); sector != brain->sectors[0].end(); ++sector)
{
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)
{
arty = bt->GetStationaryArty(ai->side, 1, 2, 2, false, false);
if(arty)
{
if(bt->units_dynamic[arty].buildersAvailable <= 0)
{
if(bt->units_dynamic[arty].buildersRequested <= 0)
bt->BuildBuilderFor(arty);
return true;
}
pos = (*sector)->GetHighestBuildsite(arty);
if(pos.x > 0)
{
builder = ut->FindClosestBuilder(arty, pos, true, 10);
if(builder)
{
builder->GiveConstructionOrder(arty, pos, false);
return true;
}
else
{
bt->AddBuilder(arty);
return false;
}
}
}
}
if(checkWater)
{
arty = bt->GetStationaryArty(ai->side, 1, 2, 2, true, false);
if(arty)
{
if(bt->units_dynamic[arty].buildersAvailable <= 0)
{
if(bt->units_dynamic[arty].buildersRequested <= 0)
bt->BuildBuilderFor(arty);
return true;
}
pos = (*sector)->GetBuildsite(arty, true);
if(pos.x > 0)
{
builder = ut->FindClosestBuilder(arty, pos, true, 10);
if(builder)
{
builder->GiveConstructionOrder(arty, pos, true);
return true;
}
else
{
bt->AddBuilder(arty);
return false;
}
}
}
}
}
return true;
}
bool AAIExecute::BuildFactory()
{
if(ai->futureUnits[STATIONARY_CONSTRUCTOR] > 0)
return true;
AAIConstructor *builder = 0, *temp_builder;
float3 pos = ZeroVector;
float best_rating = 0, my_rating;
int building = 0;
// go through list of factories, build cheapest requested factory first
for(list<int>::iterator fac = bt->units_of_category[STATIONARY_CONSTRUCTOR][ai->side-1].begin(); fac != bt->units_of_category[STATIONARY_CONSTRUCTOR][ai->side-1].end(); ++fac)
{
if(bt->units_dynamic[*fac].requested > 0)
{
my_rating = bt->GetFactoryRating(*fac) / pow( (float) (1 + bt->units_dynamic[*fac].active), 2.0f);
my_rating *= (1 + sqrt(2.0 + (float) GetBuildqueOfFactory(*fac)->size()));
if(ai->activeFactories < 1)
my_rating /= bt->units_static[*fac].cost;
// skip factories that could not be built
if(bt->units_static[*fac].efficiency[4] > 2)
{
my_rating = 0;
bt->units_static[*fac].efficiency[4] = 0;
}
if(my_rating > best_rating)
{
// only check building if a suitable builder is available
temp_builder = ut->FindBuilder(*fac, true, 10);
if(temp_builder)
{
best_rating = my_rating;
builder = temp_builder;
building = *fac;
}
}
}
}
if(building)
{
bool water;
// land
if(bt->CanPlacedLand(building))
{
water = false;
brain->sectors[0].sort(suitable_for_ground_factory);
// find buildpos
for(list<AAISector*>::iterator sector = brain->sectors[0].begin(); sector != brain->sectors[0].end(); ++sector)
{
pos = (*sector)->GetRandomBuildsite(building, 20, false);
if(pos.x > 0)
break;
}
if(pos.x == 0)
{
for(list<AAISector*>::iterator sector = brain->sectors[0].begin(); sector != brain->sectors[0].end(); ++sector)
{
pos = (*sector)->GetBuildsite(building, false);
if(pos.x > 0)
break;
}
}
}
// try to build on water if land has not been possible
if(pos.x == 0 && bt->CanPlacedWater(building))
{
water = true;
brain->sectors[0].sort(suitable_for_sea_factory);
// find buildpos
for(list<AAISector*>::iterator sector = brain->sectors[0].begin(); sector != brain->sectors[0].end(); ++sector)
{
pos = (*sector)->GetRandomBuildsite(building, 20, true);
if(pos.x > 0)
break;
}
if(pos.x == 0)
{
for(list<AAISector*>::iterator sector = brain->sectors[0].begin(); sector != brain->sectors[0].end(); ++sector)
{
pos = (*sector)->GetBuildsite(building, true);
if(pos.x > 0)
break;
}
}
}
if(pos.x > 0)
{
builder = ut->FindClosestBuilder(building, pos, true, 10);
if(builder)
{
// give build order
builder->GiveConstructionOrder(building, pos, water);
// add average ressource usage
futureRequestedMetal += bt->units_static[building].efficiency[0];
futureRequestedEnergy += bt->units_static[building].efficiency[1];
}
else
{
if(bt->units_dynamic[building].buildersRequested <= 0 && bt->units_dynamic[building].buildersAvailable <= 0)
bt->BuildBuilderFor(building);
return false;
}
}
else
{
bool expanded = false;
// no suitable buildsite found
if(bt->CanPlacedLand(building))
{
expanded = brain->ExpandBase(LAND_SECTOR);
fprintf(ai->file, "Base expanded by BuildFactory()\n");
}
if(!expanded && bt->CanPlacedWater(building))
{
brain->ExpandBase(WATER_SECTOR);
fprintf(ai->file, "Base expanded by BuildFactory() (water sector)\n");
}
// could not build due to lack of suitable buildpos
++bt->units_static[building].efficiency[4];
return true;
}
}
return true;
}
void AAIExecute::BuildUnit(UnitCategory category, float speed, float cost, float range, float power, float ground_eff, float air_eff, float hover_eff, float sea_eff, float submarine_eff, float stat_eff, float eff, bool urgent)
{
int unit = 0;
if(category == GROUND_ASSAULT)
{
// choose random unit (to learn more)
if(rand()%cfg->LEARN_RATE == 1)
unit = bt->GetRandomUnit(bt->units_of_category[GROUND_ASSAULT][ai->side-1]);
else
{
unit = bt->GetGroundAssault(ai->side, power, ground_eff, air_eff, hover_eff, sea_eff, stat_eff, eff, speed, range, cost, 15, false);
if(unit && bt->units_dynamic[unit].buildersAvailable <= 0)
{
bt->BuildFactoryFor(unit);
unit = bt->GetGroundAssault(ai->side, power, ground_eff, air_eff, hover_eff, sea_eff, stat_eff, eff, speed, range, cost, 15, true);
}
}
}
else if(category == AIR_ASSAULT)
{
if(rand()%cfg->LEARN_RATE == 1)
unit = bt->GetRandomUnit(bt->units_of_category[AIR_ASSAULT][ai->side-1]);
else
{
unit = bt->GetAirAssault(ai->side, power, ground_eff, air_eff, hover_eff, sea_eff, stat_eff, eff, speed, range, cost, 9, false);
if(unit && bt->units_dynamic[unit].buildersAvailable <= 0)
{
bt->BuildFactoryFor(unit);
unit = bt->GetAirAssault(ai->side, power, ground_eff, air_eff, hover_eff, sea_eff, stat_eff, eff, speed, range, cost, 9, true);
}
}
}
else if(category == HOVER_ASSAULT)
{
if(rand()%cfg->LEARN_RATE == 1)
unit = bt->GetRandomUnit(bt->units_of_category[HOVER_ASSAULT][ai->side-1]);
else
{
unit = bt->GetHoverAssault(ai->side, power, ground_eff, air_eff, hover_eff, sea_eff, stat_eff, eff, speed, range, cost, 9, false);
if(unit && bt->units_dynamic[unit].buildersAvailable <= 0)
{
bt->BuildFactoryFor(unit);
unit = bt->GetHoverAssault(ai->side, power, ground_eff, air_eff, hover_eff, sea_eff, stat_eff, eff, speed, range, cost, 9, true);
}
}
}
else if(category == SEA_ASSAULT)
{
if(rand()%cfg->LEARN_RATE == 1)
unit = bt->GetRandomUnit(bt->units_of_category[SEA_ASSAULT][ai->side-1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -