diff --git a/AI/VCAI/AIUtility.cpp b/AI/VCAI/AIUtility.cpp index 42be6f94c..768619da1 100644 --- a/AI/VCAI/AIUtility.cpp +++ b/AI/VCAI/AIUtility.cpp @@ -357,6 +357,26 @@ bool isSafeToVisit(HeroPtr h, crint3 tile) return true; //there's no danger } +bool isObjectRemovable(const CGObjectInstance * obj) +{ + //FIXME: move logic to object property! + switch (obj->ID) + { + case Obj::MONSTER: + case Obj::RESOURCE: + case Obj::CAMPFIRE: + case Obj::TREASURE_CHEST: + case Obj::ARTIFACT: + case Obj::BORDERGUARD: + return true; + break; + default: + return false; + break; + } + +} + bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater) { // TODO: Such information should be provided by pathfinder @@ -422,7 +442,7 @@ bool isBlockedBorderGate(int3 tileToHit) //TODO: is that function needed? should if(cb->getTile(tileToHit)->topVisitableId() != Obj::BORDER_GATE) return false; auto gate = dynamic_cast(cb->getTile(tileToHit)->topVisitableObj()); - return !gate->wasMyColorVisited(ai->playerID); + return !gate->passableFor(ai->playerID); } bool isBlockVisitObj(const int3 & pos) { diff --git a/AI/VCAI/AIUtility.h b/AI/VCAI/AIUtility.h index eacbafbf6..6c2d6414f 100644 --- a/AI/VCAI/AIUtility.h +++ b/AI/VCAI/AIUtility.h @@ -167,6 +167,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj); ui64 evaluateDanger(const CGObjectInstance * obj); ui64 evaluateDanger(crint3 tile, const CGHeroInstance * visitor); bool isSafeToVisit(HeroPtr h, crint3 tile); +bool isObjectRemovable(const CGObjectInstance * obj); //FIXME FIXME: move logic to object property! bool compareMovement(HeroPtr lhs, HeroPtr rhs); bool compareHeroStrength(HeroPtr h1, HeroPtr h2); diff --git a/AI/VCAI/Goals.cpp b/AI/VCAI/Goals.cpp index 824e6d7a5..f0efe253d 100644 --- a/AI/VCAI/Goals.cpp +++ b/AI/VCAI/Goals.cpp @@ -673,6 +673,7 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals() { //FIXME: this way we'll not visit gate and activate quest :? ret.push_back(sptr(Goals::FindObj(Obj::KEYMASTER, cb->getTile(tileToHit)->visitableObjects.back()->subID))); + return ret; //only option } auto topObj = cb->getTopObj(tileToHit); @@ -699,13 +700,16 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals() } else { - //TODO: we should be able to return apriopriate quest here (VCAI::striveToQuest) + //TODO: we should be able to return apriopriate quest here + //ret.push_back(ai->questToGoal()); + //however, visiting obj for firts time will give us quest logAi->debug("Quest guard blocks the way to %s", tile.toString()); continue; //do not access quets guard if we can't complete the quest } + return ret; //try complete quest as the only option } } - if(isSafeToVisit(h, tileToHit)) //this makes sense only if tile is guarded, but there i no quest object + if(isSafeToVisit(h, tileToHit)) //this makes sense only if tile is guarded, but there is no quest object { ret.push_back(sptr(Goals::VisitTile(tileToHit).sethero(h))); } diff --git a/AI/VCAI/SectorMap.cpp b/AI/VCAI/SectorMap.cpp index dfa99a6eb..7840be9ed 100644 --- a/AI/VCAI/SectorMap.cpp +++ b/AI/VCAI/SectorMap.cpp @@ -329,7 +329,7 @@ int3 SectorMap::firstTileToGet(HeroPtr h, crint3 dst) //throw cannotFulfillGoalException("Inter-sector route detection failed: not connected sectors?"); } } - else + else //tiles are in same sector { return findFirstVisitableTile(h, dst); } diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index c621f5529..6c5094672 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -2585,8 +2585,10 @@ int3 VCAI::explorationNewPoint(HeroPtr h) { if(isSafeToVisit(h, tile)) { - if(isBlockVisitObj(tile)) //we can't stand on that object - continue; + auto obj = cb->getTopObj(tile); + if (obj) + if(obj->blockVisit && !isObjectRemovable(obj)) //we can't stand on that object + continue; bestTile = tile; bestValue = ourValue; } @@ -2633,14 +2635,16 @@ int3 VCAI::explorationDesperate(HeroPtr h) ui64 ourDanger = evaluateDanger(t, h.h); if(ourDanger < lowestDanger) { - if(!isBlockVisitObj(t)) - { - if(!ourDanger) //at least one safe place found - return t; + auto obj = cb->getTopObj(t); + if (obj) + if (obj->blockVisit && !isObjectRemovable(obj)) //we can't stand on objct or remove it + continue; - bestTile = t; - lowestDanger = ourDanger; - } + if(!ourDanger) //at least one safe place found + return t; + + bestTile = t; + lowestDanger = ourDanger; } } }