Переглянути джерело

Ambient sounds: implement chebyshev distance for getTilesInRange

Arseniy Shestakov 9 роки тому
батько
коміт
e9bfbb70c1
4 змінених файлів з 34 додано та 8 видалено
  1. 1 1
      lib/CPathfinder.cpp
  2. 2 6
      lib/IGameCallback.cpp
  3. 1 1
      lib/IGameCallback.h
  4. 30 0
      lib/int3.h

+ 1 - 1
lib/CPathfinder.cpp

@@ -662,7 +662,7 @@ void CPathfinder::initializePatrol()
 		if(hero->patrol.patrolRadius)
 		{
 			state = PATROL_RADIUS;
-			gs->getTilesInRange(patrolTiles, hero->patrol.initialPos, hero->patrol.patrolRadius, boost::optional<PlayerColor>(), 0, true);
+			gs->getTilesInRange(patrolTiles, hero->patrol.initialPos, hero->patrol.patrolRadius, boost::optional<PlayerColor>(), 0, int3::DIST_MANHATTAN);
 		}
 		else
 			state = PATROL_LOCKED;

+ 2 - 6
lib/IGameCallback.cpp

@@ -52,7 +52,7 @@ void CPrivilagedInfoCallback::getFreeTiles (std::vector<int3> &tiles) const
 	}
 }
 
-void CPrivilagedInfoCallback::getTilesInRange(std::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, boost::optional<PlayerColor> player, int mode, bool patrolDistance) const
+void CPrivilagedInfoCallback::getTilesInRange(std::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, boost::optional<PlayerColor> player, int mode, int3::EDistanceFormula distanceFormula) const
 {
 	if(!!player && *player >= PlayerColor::PLAYER_LIMIT)
 	{
@@ -69,11 +69,7 @@ void CPrivilagedInfoCallback::getTilesInRange(std::unordered_set<int3, ShashInt3
 			for (int yd = std::max<int>(pos.y - radious, 0); yd <= std::min<int>(pos.y + radious, gs->map->height - 1); yd++)
 			{
 				int3 tilePos(xd,yd,pos.z);
-				double distance;
-				if(patrolDistance)
-					distance = pos.mandist2d(tilePos);
-				else
-					distance = pos.dist2d(tilePos) - 0.5;
+				double distance = pos.dist(tilePos, distanceFormula);
 
 				if(distance <= radious)
 				{

+ 1 - 1
lib/IGameCallback.h

@@ -30,7 +30,7 @@ class DLL_LINKAGE CPrivilagedInfoCallback : public CGameInfoCallback
 public:
 	CGameState * gameState();
 	void getFreeTiles (std::vector<int3> &tiles) const; //used for random spawns
-	void getTilesInRange(std::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int mode = 0, bool patrolDistance = false) const;  //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 -  only unrevealed
+	void getTilesInRange(std::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int mode = 0, int3::EDistanceFormula formula = int3::DIST_2D) const; //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 -  only revealed
 	void getAllTiles (std::unordered_set<int3, ShashInt3> &tiles, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int level=-1, int surface=0) const; //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water
 	void pickAllowedArtsSet(std::vector<const CArtifact*> &out, CRandomGenerator & rand); //gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
 	void getAllowedSpells(std::vector<SpellID> &out, ui16 level);

+ 30 - 0
lib/int3.h

@@ -92,6 +92,31 @@ public:
 		return false;
 	}
 
+	enum EDistanceFormula
+	{
+		DIST_2D = 0,
+		DIST_MANHATTAN, // patrol distance
+		DIST_CHEBYSHEV, // ambient sound distance
+		DIST_2DSQ
+	};
+
+	ui32 dist(const int3 & o, EDistanceFormula formula) const
+	{
+		switch(formula)
+		{
+		case DIST_2D:
+			return dist2d(o);
+		case DIST_MANHATTAN:
+			return mandist2d(o);
+		case DIST_CHEBYSHEV:
+			return chebdist2d(o);
+		case DIST_2DSQ:
+			return dist2dSQ(o);
+		default:
+			return 0;
+		}
+	}
+
 	//returns squared distance on Oxy plane (z coord is not used)
 	ui32 dist2dSQ(const int3 & o) const
 	{
@@ -109,6 +134,11 @@ public:
 	{
 		return abs(o.x - x) + abs(o.y - y);
 	}
+	//chebyshev distance used for ambient sounds (z coord is not used)
+	double chebdist2d(const int3 & o) const
+	{
+		return std::max(std::abs(o.x - x), std::abs(o.y - y));
+	}
 
 	bool areNeighbours(const int3 & o) const
 	{