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 &&
|
return cb->getTile(tileToHit)->topVisitableId() == Obj::BORDER_GATE &&
|
||||||
(dynamic_cast <const CGKeys *>(cb->getTile(tileToHit)->visitableObjects.back()))->wasMyColorVisited (ai->playerID);
|
(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)
|
int howManyTilesWillBeDiscovered(const int3 &pos, int radious, CCallback * cbp)
|
||||||
{ //TODO: do not explore dead-end boundaries
|
{ //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 canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater);
|
||||||
bool isBlockedBorderGate(int3 tileToHit);
|
bool isBlockedBorderGate(int3 tileToHit);
|
||||||
|
bool isBlockVisitObj(const int3 &pos);
|
||||||
|
|
||||||
bool isWeeklyRevisitable (const CGObjectInstance * obj);
|
bool isWeeklyRevisitable (const CGObjectInstance * obj);
|
||||||
bool shouldVisit (HeroPtr h, 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)
|
bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
||||||
{
|
{
|
||||||
|
//TODO: consider if blockVisit objects change something in our checks: AIUtility::isBlockVisitObj()
|
||||||
|
|
||||||
auto afterMovementCheck = [&]() -> void
|
auto afterMovementCheck = [&]() -> void
|
||||||
{
|
{
|
||||||
waitTillFree(); //movement may cause battle or blocking dialog
|
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);
|
int3 ourPos = h->convertPosition(h->pos, false);
|
||||||
std::map<int3, int> dstToRevealedTiles;
|
std::map<int3, int> dstToRevealedTiles;
|
||||||
for(crint3 dir : int3::getDirs())
|
for (crint3 dir : int3::getDirs())
|
||||||
if(cb->isInTheMap(hpos+dir))
|
{
|
||||||
|
int3 tile = hpos + dir;
|
||||||
|
if (cb->isInTheMap(tile))
|
||||||
if (ourPos != dir) //don't stand in place
|
if (ourPos != dir) //don't stand in place
|
||||||
if (isSafeToVisit(h, hpos + dir) && isAccessibleForHero (hpos + dir, h))
|
if (isSafeToVisit(h, tile) && isAccessibleForHero(tile, h))
|
||||||
dstToRevealedTiles[hpos + dir] = howManyTilesWillBeDiscovered(radius, hpos, dir);
|
{
|
||||||
|
if (isBlockVisitObj(tile))
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
dstToRevealedTiles[tile] = howManyTilesWillBeDiscovered(radius, hpos, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dstToRevealedTiles.empty()) //yes, it DID happen!
|
if (dstToRevealedTiles.empty()) //yes, it DID happen!
|
||||||
throw cannotFulfillGoalException("No neighbour will bring new discoveries!");
|
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 (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;
|
bestTile = tile;
|
||||||
bestValue = ourValue;
|
bestValue = ourValue;
|
||||||
}
|
}
|
||||||
@ -2667,7 +2679,7 @@ int3 VCAI::explorationDesperate(HeroPtr h)
|
|||||||
ui64 ourDanger = evaluateDanger(t, h.h);
|
ui64 ourDanger = evaluateDanger(t, h.h);
|
||||||
if (ourDanger < lowestDanger)
|
if (ourDanger < lowestDanger)
|
||||||
{
|
{
|
||||||
if(!isBlockedBorderGate(t))
|
if(!isBlockVisitObj(t))
|
||||||
{
|
{
|
||||||
if (!ourDanger) //at least one safe place found
|
if (!ourDanger) //at least one safe place found
|
||||||
return t;
|
return t;
|
||||||
|
Loading…
Reference in New Issue
Block a user