diff --git a/source/glest_game/ai/ai.cpp b/source/glest_game/ai/ai.cpp index a161971c..096522b9 100644 --- a/source/glest_game/ai/ai.cpp +++ b/source/glest_game/ai/ai.cpp @@ -338,12 +338,12 @@ bool Ai::findPosForBuilding(const UnitType* building, const Vec2i &searchPos, Ve const int spacing= 1; - for(int currRadius=0; currRadiusisFreeCells(outPos-Vec2i(spacing), building->getSize()+spacing*2, fLand)){ - return true; + if(aiInterface->isFreeCells(outPos - Vec2i(spacing), building->getSize() + spacing * 2, fLand)) { + return true; } } } diff --git a/source/glest_game/ai/ai_rule.cpp b/source/glest_game/ai/ai_rule.cpp index f5426e56..2e228003 100644 --- a/source/glest_game/ai/ai_rule.cpp +++ b/source/glest_game/ai/ai_rule.cpp @@ -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 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)) { diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index ab14310a..2bb170a9 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -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 &enemies, bool attackersOnly) const { + //all fields + for(int k = 0; k < fieldCount; k++) { + Field f= static_cast(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) { diff --git a/source/glest_game/world/unit_updater.h b/source/glest_game/world/unit_updater.h index edc3daff..f1ad66f2 100644 --- a/source/glest_game/world/unit_updater.h +++ b/source/glest_game/world/unit_updater.h @@ -119,7 +119,7 @@ public: std::pair unitBeingAttacked(const Unit *unit); void unitBeingAttacked(std::pair &result, const Unit *unit, const AttackSkillType *ast,float *currentDistToUnit=NULL); vector enemyUnitsOnRange(const Unit *unit,const AttackSkillType *ast); - + void findEnemiesForCell(const Vec2i pos, int size, int sightRange, const Faction *faction, vector &enemies, bool attackersOnly) const; private: //attack