📄 aaisector.cpp
字号:
return map->GetCenterBuildsite(ai->bt->unitList[building-1], xStart, xEnd, yStart, yEnd, water);
}
float3 AAISector::GetHighestBuildsite(int building)
{
if(building < 1)
{
fprintf(ai->file, "ERROR: Invalid building def id %i passed to AAISector::GetRadarBuildsite()\n", building);
return ZeroVector;
}
int xStart, xEnd, yStart, yEnd;
GetBuildsiteRectangle(&xStart, &xEnd, &yStart, &yEnd);
return map->GetHighestBuildsite(ai->bt->unitList[building-1], xStart, xEnd, yStart, yEnd);
}
float3 AAISector::GetRandomBuildsite(int building, int tries, bool water)
{
if(building < 1)
{
fprintf(ai->file, "ERROR: Invalid building def id %i passed to AAISector::GetRadarBuildsite()\n", building);
return ZeroVector;
}
int xStart, xEnd, yStart, yEnd;
GetBuildsiteRectangle(&xStart, &xEnd, &yStart, &yEnd);
return map->GetRandomBuildsite(ai->bt->unitList[building-1], xStart, xEnd, yStart, yEnd, tries, water);
}
void AAISector::GetBuildsiteRectangle(int *xStart, int *xEnd, int *yStart, int *yEnd)
{
*xStart = x * map->xSectorSizeMap;
*xEnd = *xStart + map->xSectorSizeMap;
if(*xStart == 0)
*xStart = 8;
*yStart = y * map->ySectorSizeMap;
*yEnd = *yStart + map->ySectorSizeMap;
if(*yStart == 0)
*yStart = 8;
// reserve buildspace for def. buildings
if(x > 0 && map->sector[x-1][y].distance_to_base > 0 )
*xStart += map->xSectorSizeMap/8;
if(x < map->xSectors-1 && map->sector[x+1][y].distance_to_base > 0)
*xEnd -= map->xSectorSizeMap/8;
if(y > 0 && map->sector[x][y-1].distance_to_base > 0)
*yStart += map->ySectorSizeMap/8;
if(y < map->ySectors-1 && map->sector[x][y+1].distance_to_base > 0)
*yEnd -= map->ySectorSizeMap/8;
}
// converts unit positions to cell coordinates
void AAISector::Pos2SectorMapPos(float3 *pos, const UnitDef* def)
{
// get cell index of middlepoint
pos->x = ((int) pos->x/SQUARE_SIZE)%ai->map->xSectorSizeMap;
pos->z = ((int) pos->z/SQUARE_SIZE)%ai->map->ySectorSizeMap;
// shift to the leftmost uppermost cell
pos->x -= def->xsize/2;
pos->z -= def->ysize/2;
// check if pos is still in that scetor, otherwise retun 0
if(pos->x < 0 && pos->z < 0)
pos->x = pos->z = 0;
}
void AAISector::SectorMapPos2Pos(float3 *pos, const UnitDef *def)
{
// shift to middlepoint
pos->x += def->xsize/2;
pos->z += def->ysize/2;
// get cell position on complete map
pos->x += x * ai->map->xSectorSizeMap;
pos->z += y * ai->map->ySectorSizeMap;
// back to unit coordinates
pos->x *= SQUARE_SIZE;
pos->z *= SQUARE_SIZE;
}
float AAISector::GetDefencePowerVs(UnitCategory category)
{
float power = 0.5;
for(list<AAIDefence>::iterator i = defences.begin(); i != defences.end(); ++i)
power += ai->bt->GetEfficiencyAgainst(i->def_id, category);
return power;
}
float AAISector::GetDefencePowerVsID(int combat_cat_id)
{
float power = 0.5;
for(list<AAIDefence>::iterator i = defences.begin(); i != defences.end(); ++i)
power += ai->bt->units_static[i->def_id].efficiency[combat_cat_id];
return power;
}
UnitCategory AAISector::GetWeakestCategory()
{
UnitCategory weakest = UNKNOWN;
float importance, most_important = 0;
if(defences.size() > cfg->MAX_DEFENCES)
return UNKNOWN;
float learned = 60000 / (ai->cb->GetCurrentFrame() + 30000) + 0.5;
float current = 2.5 - learned;
if(interior)
{
weakest = AIR_ASSAULT;
}
else
{
for(list<UnitCategory>::iterator cat = ai->bt->assault_categories.begin(); cat != ai->bt->assault_categories.end(); ++cat)
{
importance = GetThreatBy(*cat, learned, current)/GetDefencePowerVs(*cat);
if(importance > most_important)
{
most_important = importance;
weakest = *cat;
}
}
}
return weakest;
}
float AAISector::GetThreatBy(UnitCategory category, float learned, float current)
{
if(category == GROUND_ASSAULT)
return 1.0f + (learned * attacked_by_learned[0] + current * attacked_by_this_game[0] ) / (learned + current);
if(category == AIR_ASSAULT)
return 1.0f + (learned * attacked_by_learned[1] + current * attacked_by_this_game[1] ) / (learned + current);
if(category == HOVER_ASSAULT)
return 1.0f + (learned * attacked_by_learned[2] + current * attacked_by_this_game[2] ) / (learned + current);
if(category == SEA_ASSAULT)
return 1.0f + (learned * attacked_by_learned[3] + current * attacked_by_this_game[3] ) / (learned + current);
if(category == SUBMARINE_ASSAULT)
return 1.0f + (learned * attacked_by_learned[4] + current * attacked_by_this_game[4] ) / (learned + current);
else
return -1;
}
float AAISector::GetThreatByID(int combat_cat_id, float learned, float current)
{
return 1.0f + (learned * attacked_by_learned[combat_cat_id] + current * attacked_by_this_game[combat_cat_id] ) / (learned + current);
}
float AAISector::GetThreatTo(float ground, float air, float hover, float sea, float submarine)
{
return (ground * stat_combat_power[0] + air * stat_combat_power[1] + hover * stat_combat_power[2] + sea * stat_combat_power[3] + submarine * stat_combat_power[4]);
}
float AAISector::GetLostUnits(float ground, float air, float hover, float sea, float submarine)
{
return (ground * lost_units[GROUND_ASSAULT-COMMANDER] + air * lost_units[AIR_ASSAULT-COMMANDER]
+ hover * lost_units[HOVER_ASSAULT-COMMANDER] + sea * lost_units[SEA_ASSAULT-COMMANDER]
+ submarine * lost_units[SUBMARINE_ASSAULT-COMMANDER]);
}
float AAISector::GetOverallThreat(float learned, float current)
{
return (learned * (attacked_by_learned[0] + attacked_by_learned[1] + attacked_by_learned[2] + attacked_by_learned[3])
+ current * (attacked_by_this_game[0] + attacked_by_this_game[1] + attacked_by_this_game[2] + attacked_by_this_game[3]))
/(learned + current);
}
void AAISector::RemoveDefence(int unit_id)
{
for(list<AAIDefence>::iterator i = defences.begin(); i != defences.end(); i++)
{
if(i->unit_id == unit_id)
{
defences.erase(i);
return;
}
}
}
void AAISector::AddDefence(int unit_id, int def_id)
{
AAIDefence def;
def.unit_id = unit_id;
def.def_id = def_id;
defences.push_back(def);
}
float AAISector::GetWaterRatio()
{
float water_ratio = 0;
for(int xPos = x * map->xSectorSizeMap; xPos < (x+1) * map->xSectorSizeMap; ++xPos)
{
for(int yPos = y * map->ySectorSizeMap; yPos < (y+1) * map->ySectorSizeMap; ++yPos)
{
if(map->buildmap[xPos + yPos * map->xMapSize] == 4)
water_ratio +=1;
}
}
return water_ratio / ((float)(map->xSectorSizeMap * map->ySectorSizeMap));
}
float AAISector::GetFlatRatio()
{
// get number of cliffy tiles
float flat_ratio = ai->map->GetCliffyCells(left/SQUARE_SIZE, top/SQUARE_SIZE, ai->map->xSectorSizeMap, ai->map->ySectorSizeMap);
// get number of flat tiles
flat_ratio = (ai->map->xSectorSizeMap * ai->map->ySectorSizeMap) - flat_ratio;
flat_ratio /= (ai->map->xSectorSizeMap * ai->map->ySectorSizeMap);
return flat_ratio;
}
float AAISector::GetMapBorderDist()
{
float result = 2;
if(x == 0 || x == ai->map->xSectors-1)
result -= 0.5;
if(y == 0 || y == ai->map->ySectors-1)
result -= 0.5;
return result;
}
void AAISector::UpdateThreatValues(UnitCategory unit, UnitCategory attacker)
{
// if lost unit is a building, increase attacked_by
if(unit <= METAL_MAKER)
{
float change;
if(this->interior)
change = 0.3f;
else
change = 1;
// determine type of attacker
if(attacker == AIR_ASSAULT)
attacked_by_this_game[1] += change;
else if(attacker == GROUND_ASSAULT)
attacked_by_this_game[0] += change;
else if(attacker == HOVER_ASSAULT)
attacked_by_this_game[2] += change;
else if(attacker == SEA_ASSAULT)
attacked_by_this_game[3] += change;
else if(attacker == SUBMARINE_ASSAULT)
attacked_by_this_game[4] += change;
}
else // unit was lost
{
if(attacker == AIR_ASSAULT)
++combats_this_game[1];
else if(attacker == GROUND_ASSAULT)
++combats_this_game[0];
else if(attacker == HOVER_ASSAULT)
++combats_this_game[2];
else if(attacker == SEA_ASSAULT)
++combats_this_game[3];
else if(attacker == SUBMARINE_ASSAULT)
++combats_this_game[4];
++lost_units[unit-COMMANDER];
}
}
float AAISector::GetAreaCombatPowerVs(int combat_category, float neighbour_importance)
{
float result = mobile_combat_power[combat_category];
// take neighbouring sectors into account (if possible)
if(x > 0)
result += neighbour_importance * ai->map->sector[x-1][y].mobile_combat_power[combat_category];
if(x < map->xSectors-1)
result += neighbour_importance * ai->map->sector[x+1][y].mobile_combat_power[combat_category];
if(y > 0)
result += neighbour_importance * ai->map->sector[x][y-1].mobile_combat_power[combat_category];
if(y < map->ySectors-1)
result += neighbour_importance * ai->map->sector[x][y+1].mobile_combat_power[combat_category];
return result;
}
int AAISector::GetNumberOfBuildings()
{
int result = 0;
for(int i = STATIONARY_DEF; i <= METAL_MAKER; ++i)
result += unitsOfType[i];
return result;
}
bool AAISector::PosInSector(float3 *pos)
{
if(pos->x < left || pos->x > right)
return false;
else if(pos->z < top || pos->z > bottom)
return false;
else
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -