Bläddra i källkod

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.
Arseniy Shestakov 9 år sedan
förälder
incheckning
7bdcd209e6
2 ändrade filer med 36 tillägg och 3 borttagningar
  1. 35 3
      AI/VCAI/VCAI.cpp
  2. 1 0
      AI/VCAI/VCAI.h

+ 35 - 3
AI/VCAI/VCAI.cpp

@@ -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;
+}

+ 1 - 0
AI/VCAI/VCAI.h

@@ -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);