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:
parent
a1b7c9d8d2
commit
9b5af484b7
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user