1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Fixed AI getting stuck at blockVisit objects (Tavern, Borderguards/gates etc).

This commit is contained in:
DjWarmonger 2016-11-28 19:29:11 +01:00
parent a1b7c9d8d2
commit 9b5af484b7
3 changed files with 28 additions and 7 deletions

View File

@ -400,11 +400,19 @@ int3 whereToExplore(HeroPtr h)
}
}
bool isBlockedBorderGate(int3 tileToHit)
bool isBlockedBorderGate(int3 tileToHit) //TODO: is that function needed? should be handled by pathfinder
{
return cb->getTile(tileToHit)->topVisitableId() == Obj::BORDER_GATE &&
(dynamic_cast <const CGKeys *>(cb->getTile(tileToHit)->visitableObjects.back()))->wasMyColorVisited (ai->playerID);
}
bool isBlockVisitObj(const int3 &pos)
{
if (auto obj = cb->getTopObj(pos))
if (obj->blockVisit) //we can't stand on that object
return true;
return false;
}
int howManyTilesWillBeDiscovered(const int3 &pos, int radious, CCallback * cbp)
{ //TODO: do not explore dead-end boundaries

View File

@ -145,6 +145,7 @@ void getVisibleNeighbours(const std::vector<int3> &tiles, std::vector<int3> &out
bool canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater);
bool isBlockedBorderGate(int3 tileToHit);
bool isBlockVisitObj(const int3 &pos);
bool isWeeklyRevisitable (const CGObjectInstance * obj);
bool shouldVisit (HeroPtr h, const CGObjectInstance * obj);

View File

@ -1870,6 +1870,8 @@ bool VCAI::isAccessibleForHero(const int3 & pos, HeroPtr h, bool includeAllies /
bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
{
//TODO: consider if blockVisit objects change something in our checks: AIUtility::isBlockVisitObj()
auto afterMovementCheck = [&]() -> void
{
waitTillFree(); //movement may cause battle or blocking dialog
@ -2558,11 +2560,19 @@ int3 VCAI::explorationBestNeighbour(int3 hpos, int radius, HeroPtr h)
{
int3 ourPos = h->convertPosition(h->pos, false);
std::map<int3, int> dstToRevealedTiles;
for(crint3 dir : int3::getDirs())
if(cb->isInTheMap(hpos+dir))
for (crint3 dir : int3::getDirs())
{
int3 tile = hpos + dir;
if (cb->isInTheMap(tile))
if (ourPos != dir) //don't stand in place
if (isSafeToVisit(h, hpos + dir) && isAccessibleForHero (hpos + dir, h))
dstToRevealedTiles[hpos + dir] = howManyTilesWillBeDiscovered(radius, hpos, dir);
if (isSafeToVisit(h, tile) && isAccessibleForHero(tile, h))
{
if (isBlockVisitObj(tile))
continue;
else
dstToRevealedTiles[tile] = howManyTilesWillBeDiscovered(radius, hpos, dir);
}
}
if (dstToRevealedTiles.empty()) //yes, it DID happen!
throw cannotFulfillGoalException("No neighbour will bring new discoveries!");
@ -2619,8 +2629,10 @@ int3 VCAI::explorationNewPoint(HeroPtr h)
if (ourValue > bestValue) //avoid costly checks of tiles that don't reveal much
{
if(isSafeToVisit(h, tile) && !isBlockedBorderGate(tile))
if(isSafeToVisit(h, tile))
{
if (isBlockVisitObj(tile)) //we can't stand on that object
continue;
bestTile = tile;
bestValue = ourValue;
}
@ -2667,7 +2679,7 @@ int3 VCAI::explorationDesperate(HeroPtr h)
ui64 ourDanger = evaluateDanger(t, h.h);
if (ourDanger < lowestDanger)
{
if(!isBlockedBorderGate(t))
if(!isBlockVisitObj(t))
{
if (!ourDanger) //at least one safe place found
return t;