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:
parent
aabf4808da
commit
7bdcd209e6
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user