- more AI enhancements to better handle repair and build positions

This commit is contained in:
Mark Vejvoda 2011-05-01 07:24:37 +00:00
parent efc6b7ee1d
commit 070b8b76e6
4 changed files with 81 additions and 12 deletions

View File

@ -338,12 +338,12 @@ bool Ai::findPosForBuilding(const UnitType* building, const Vec2i &searchPos, Ve
const int spacing= 1;
for(int currRadius=0; currRadius<maxBuildRadius; ++currRadius){
for(int i=searchPos.x-currRadius; i<searchPos.x+currRadius; ++i){
for(int j=searchPos.y-currRadius; j<searchPos.y+currRadius; ++j){
for(int currRadius = 0; currRadius < maxBuildRadius; ++currRadius) {
for(int i=searchPos.x - currRadius; i < searchPos.x + currRadius; ++i) {
for(int j=searchPos.y - currRadius; j < searchPos.y + currRadius; ++j) {
outPos= Vec2i(i, j);
if(aiInterface->isFreeCells(outPos-Vec2i(spacing), building->getSize()+spacing*2, fLand)){
return true;
if(aiInterface->isFreeCells(outPos - Vec2i(spacing), building->getSize() + spacing * 2, fLand)) {
return true;
}
}
}

View File

@ -92,7 +92,7 @@ AiRuleRepair::AiRuleRepair(Ai *ai):
}
double AiRuleRepair::getMinCastleHpRatio() {
return 0.8;
return 0.6;
}
int AiRuleRepair::getMinUnitsToRepairCastle() {
@ -100,7 +100,7 @@ int AiRuleRepair::getMinUnitsToRepairCastle() {
if(ai->getCountOfClass(ucWorker) <= 4) {
minUnitsRepairingCastle = 1;
}
else if(ai->getCountOfClass(ucWorker) <= 6) {
else if(ai->getCountOfClass(ucWorker) <= 7) {
minUnitsRepairingCastle = 2;
}
else if(ai->getCountOfClass(ucWorker) <= 10) {
@ -263,9 +263,11 @@ void AiRuleRepair::execute() {
*/
//aiInterface->giveCommand(i, rct, damagedUnit->getPos());
aiInterface->giveCommand(i, rct, damagedUnit->getPosWithCellMapSet());
aiInterface->printLog(3, "Repairing order issued");
unitCountAlreadyRepairingDamagedUnit++;
if(unitCountAlreadyRepairingDamagedUnit < minUnitsRepairingCastle) {
aiInterface->giveCommand(i, rct, damagedUnit->getPosWithCellMapSet());
aiInterface->printLog(3, "Repairing order issued");
unitCountAlreadyRepairingDamagedUnit++;
}
if(unitCountAlreadyRepairingDamagedUnit >= minUnitsRepairingCastle) {
return;
@ -1115,7 +1117,44 @@ void AiRuleBuild::buildSpecific(const BuildTask *bt) {
int bIndex = ai->getRandom()->randRange(0, builders.size()-1);
int builderIndex= builders[bIndex];
Vec2i pos;
Vec2i searchPos= bt->getForcePos()? bt->getPos(): ai->getRandomHomePosition();
Vec2i searchPos = bt->getForcePos()? bt->getPos(): ai->getRandomHomePosition();
if(bt->getForcePos() == false) {
const int enemySightDistanceToAvoid = 18;
vector<Unit*> enemies;
ai->getAiInterface()->getWorld()->getUnitUpdater()->findEnemiesForCell(searchPos,bt->getUnitType()->getSize(),enemySightDistanceToAvoid,ai->getAiInterface()->getMyFaction(),enemies,true);
if(enemies.size() > 0) {
for(int i1 = 0; i1 < 25 && enemies.size() > 0; ++i1) {
for(int j1 = 0; j1 < 25 && enemies.size() > 0; ++j1) {
Vec2i tryPos = searchPos + Vec2i(i1,j1);
const int spacing = 1;
if(ai->getAiInterface()->isFreeCells(tryPos - Vec2i(spacing), bt->getUnitType()->getSize() + spacing * 2, fLand)) {
enemies.clear();
ai->getAiInterface()->getWorld()->getUnitUpdater()->findEnemiesForCell(tryPos,bt->getUnitType()->getSize(),enemySightDistanceToAvoid,ai->getAiInterface()->getMyFaction(),enemies,true);
if(enemies.size() <= 0) {
searchPos = tryPos;
}
}
}
}
}
if(enemies.size() > 0) {
for(int i1 = -1; i1 >= -25 && enemies.size() > 0; --i1) {
for(int j1 = -1; j1 >= -25 && enemies.size() > 0; --j1) {
Vec2i tryPos = searchPos + Vec2i(i1,j1);
const int spacing = 1;
if(ai->getAiInterface()->isFreeCells(tryPos - Vec2i(spacing), bt->getUnitType()->getSize() + spacing * 2, fLand)) {
enemies.clear();
ai->getAiInterface()->getWorld()->getUnitUpdater()->findEnemiesForCell(tryPos,bt->getUnitType()->getSize(),enemySightDistanceToAvoid,ai->getAiInterface()->getMyFaction(),enemies,true);
if(enemies.size() <= 0) {
searchPos = tryPos;
}
}
}
}
}
}
//if free pos give command, else retry
if(ai->findPosForBuilding(bt->getUnitType(), searchPos, pos)) {

View File

@ -2025,6 +2025,36 @@ void UnitUpdater::findEnemiesForCell(const AttackSkillType *ast, Cell *cell, con
}
}
void UnitUpdater::findEnemiesForCell(const Vec2i pos, int size, int sightRange, const Faction *faction, vector<Unit*> &enemies, bool attackersOnly) const {
//all fields
for(int k = 0; k < fieldCount; k++) {
Field f= static_cast<Field>(k);
for(int i = pos.x - sightRange; i < pos.x + size + sightRange; ++i) {
for(int j = pos.y - sightRange; j < pos.y + size + sightRange; ++j) {
Vec2i testPos(i,j);
Cell *cell = map->getCell(testPos);
//check field
Unit *possibleEnemy = cell->getUnit(f);
//check enemy
if(possibleEnemy != NULL && possibleEnemy->isAlive()) {
if(faction->getTeam() != possibleEnemy->getTeam()) {
if(attackersOnly == true) {
if(possibleEnemy->getType()->hasCommandClass(ccAttack) || possibleEnemy->getType()->hasCommandClass(ccAttackStopped)) {
enemies.push_back(possibleEnemy);
}
}
else {
enemies.push_back(possibleEnemy);
}
}
}
}
}
}
}
//if the unit has any enemy on range
bool UnitUpdater::unitOnRange(const Unit *unit, int range, Unit **rangedPtr,
const AttackSkillType *ast) {

View File

@ -119,7 +119,7 @@ public:
std::pair<bool,Unit *> unitBeingAttacked(const Unit *unit);
void unitBeingAttacked(std::pair<bool,Unit *> &result, const Unit *unit, const AttackSkillType *ast,float *currentDistToUnit=NULL);
vector<Unit*> enemyUnitsOnRange(const Unit *unit,const AttackSkillType *ast);
void findEnemiesForCell(const Vec2i pos, int size, int sightRange, const Faction *faction, vector<Unit*> &enemies, bool attackersOnly) const;
private:
//attack