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

VCAI::wander: only use nearby objects from SectorMap when possible

Now AI only check full object list if there is no suitable objects found in current sector and sectors around it.
This optimization drastically increase wandering performance on maps with tons of objects when AI see most of it.
This commit is contained in:
Arseniy Shestakov 2016-08-12 09:05:11 +03:00
parent aabf4808da
commit 7bdcd209e6
2 changed files with 36 additions and 3 deletions

View File

@ -1464,10 +1464,26 @@ void VCAI::wander(HeroPtr h)
return false;
});
vstd::copy_if(visitableObjs, std::back_inserter(dests), [&](ObjectIdRef obj) -> bool
int pass = 0;
while(!dests.size() && pass < 3)
{
return isGoodForVisit(obj, h, *sm);
});
if(pass < 2) // optimization - first check objects in current sector; then in sectors around
{
auto objs = sm->getNearbyObjs(h, pass);
vstd::copy_if(objs, std::back_inserter(dests), [&](ObjectIdRef obj) -> bool
{
return isGoodForVisit(obj, h, *sm);
});
}
else // we only check full objects list if for some reason there are no objects in closest sectors
{
vstd::copy_if(visitableObjs, std::back_inserter(dests), [&](ObjectIdRef obj) -> bool
{
return isGoodForVisit(obj, h, *sm);
});
}
pass++;
}
vstd::erase_if(dests, [&](ObjectIdRef obj) -> bool
{
@ -3435,3 +3451,19 @@ TerrainTile* SectorMap::getTile(crint3 pos) const
//still we cached this array to avoid any checks
return visibleTiles->operator[](pos.x)[pos.y][pos.z];
}
std::vector<const CGObjectInstance *> SectorMap::getNearbyObjs(HeroPtr h, bool sectorsAround)
{
const Sector *heroSector = &infoOnSectors[retreiveTile(h->visitablePos())];
if(sectorsAround)
{
std::vector<const CGObjectInstance *> ret;
for(auto embarkPoint : heroSector->embarkmentPoints)
{
const Sector *embarkSector = &infoOnSectors[retreiveTile(embarkPoint)];
range::copy(embarkSector->visitableObjs, std::back_inserter(ret));
}
return ret;
}
return heroSector->visitableObjs;
}

View File

@ -106,6 +106,7 @@ struct SectorMap
bool markIfBlocked(ui8 &sec, crint3 pos);
unsigned char &retreiveTile(crint3 pos);
TerrainTile* getTile(crint3 pos) const;
std::vector<const CGObjectInstance *> getNearbyObjs(HeroPtr h, bool sectorsAround);
void makeParentBFS(crint3 source);