Browse Source

Introduced 3-value logic for free, blocked and possibly occupied tiles. Refactoring.

DjWarmonger 11 năm trước cách đây
mục cha
commit
8c24ea0bfb

+ 0 - 3
AI/VCAI/VCAI.h

@@ -21,9 +21,6 @@
 #include "../../lib/NetPacks.h"
 #include "../../lib/NetPacks.h"
 #include "../../lib/CondSh.h"
 #include "../../lib/CondSh.h"
 
 
-static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
-	int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
-
 struct QuestInfo;
 struct QuestInfo;
 
 
 /*
 /*

+ 11 - 0
lib/GameConstants.h

@@ -450,6 +450,17 @@ namespace EWallState
 	};
 	};
 }
 }
 
 
+namespace ETileType
+{
+	enum ETileType
+	{
+		FREE,
+		POSSIBLE,
+		BLOCKED,
+		USED
+	};
+}
+
 class Obj
 class Obj
 {
 {
 public:
 public:

+ 4 - 1
lib/int3.h

@@ -152,4 +152,7 @@ struct ShashInt3
 		vstd::hash_combine(ret, pos.z);
 		vstd::hash_combine(ret, pos.z);
 		return ret;
 		return ret;
 	}
 	}
-};
+};
+
+static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
+	int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };

+ 75 - 8
lib/rmg/CMapGenerator.cpp

@@ -16,12 +16,12 @@
 
 
 void CMapGenerator::foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo)
 void CMapGenerator::foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo)
 {
 {
-	//for(const int3 &dir : dirs)
-	//{
-	//	const int3 n = pos + dir;
-	//	if(map->isInTheMap(n))
-	//		foo(pos+dir);
-	//}
+	for(const int3 &dir : dirs)
+	{
+		const int3 n = pos + dir;
+		if(map->isInTheMap(n))
+			foo(pos+dir);
+	}
 }
 }
 
 
 
 
@@ -31,9 +31,40 @@ CMapGenerator::CMapGenerator(shared_ptr<CMapGenOptions> mapGenOptions, int rando
 	rand.setSeed(randomSeed);
 	rand.setSeed(randomSeed);
 }
 }
 
 
-CMapGenerator::~CMapGenerator()
+void CMapGenerator::initTiles()
 {
 {
+	map->initTerrain();
+
+	int width = map->width;
+	int height = map->height;
+
+	int level = map->twoLevel ? 2 : 1;
+	tiles = new CTileInfo**[width];
+	for (int i = 0; i < width; ++i)
+	{
+		tiles[i] = new CTileInfo*[height];
+		for (int j = 0; j < height; ++j)
+		{
+			tiles[i][j] = new CTileInfo[level];
+		}
+	}
+}
 
 
+CMapGenerator::~CMapGenerator()
+{
+	//FIXME: what if map is not present anymore?
+	if (tiles && map)
+	{
+		for (int i=0; i < map->width; i++)
+		{
+			for(int j=0; j < map->height; j++)
+			{
+				delete [] tiles[i][j];
+			}
+			delete [] tiles[i];
+		}
+		delete [] tiles;
+	}
 }
 }
 
 
 std::unique_ptr<CMap> CMapGenerator::generate()
 std::unique_ptr<CMap> CMapGenerator::generate()
@@ -46,6 +77,7 @@ std::unique_ptr<CMap> CMapGenerator::generate()
 	{
 	{
 		editManager->getUndoManager().setUndoRedoLimit(0);
 		editManager->getUndoManager().setUndoRedoLimit(0);
 		addHeaderInfo();
 		addHeaderInfo();
+		initTiles();
 
 
 		genZones();
 		genZones();
 		map->calculateGuardingGreaturePositions(); //clear map so that all tiles are unguarded
 		map->calculateGuardingGreaturePositions(); //clear map so that all tiles are unguarded
@@ -146,7 +178,6 @@ void CMapGenerator::addPlayerInfo()
 
 
 void CMapGenerator::genZones()
 void CMapGenerator::genZones()
 {
 {
-	map->initTerrain();
 	editManager->clearTerrain(&rand);
 	editManager->clearTerrain(&rand);
 	editManager->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions->getWidth(), mapGenOptions->getHeight()));
 	editManager->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions->getWidth(), mapGenOptions->getHeight()));
 	editManager->drawTerrain(ETerrainType::GRASS, &rand);
 	editManager->drawTerrain(ETerrainType::GRASS, &rand);
@@ -217,3 +248,39 @@ std::map<TRmgTemplateZoneId, CRmgTemplateZone*> CMapGenerator::getZones() const
 {
 {
 	return zones;
 	return zones;
 }
 }
+
+bool CMapGenerator::isBlocked(int3 &tile) const
+{
+	if (!map->isInTheMap(tile))
+		throw  rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
+
+	return tiles[tile.x][tile.y][tile.z].isBlocked();
+}
+bool CMapGenerator::shouldBeBlocked(int3 &tile) const
+{
+	if (!map->isInTheMap(tile))
+		throw  rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
+
+	return tiles[tile.x][tile.y][tile.z].shouldBeBlocked();
+}
+bool CMapGenerator::isPossible(int3 &tile) const
+{
+	if (!map->isInTheMap(tile))
+		throw  rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
+
+	return tiles[tile.x][tile.y][tile.z].isPossible();
+}
+bool CMapGenerator::isFree(int3 &tile) const
+{
+	if (!map->isInTheMap(tile))
+		throw  rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
+
+	return tiles[tile.x][tile.y][tile.z].isFree();
+}
+void CMapGenerator::setOccupied(int3 &tile, ETileType::ETileType state)
+{
+	if (!map->isInTheMap(tile))
+		throw  rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
+
+	tiles[tile.x][tile.y][tile.z].setOccupied(state);
+}

+ 13 - 11
lib/rmg/CMapGenerator.h

@@ -14,6 +14,7 @@
 #include "../GameConstants.h"
 #include "../GameConstants.h"
 #include "../CRandomGenerator.h"
 #include "../CRandomGenerator.h"
 #include "CMapGenOptions.h"
 #include "CMapGenOptions.h"
+#include "CRmgTemplateZone.h"
 #include "../CObjectHandler.h"
 #include "../CObjectHandler.h"
 #include "../int3.h"
 #include "../int3.h"
 
 
@@ -24,13 +25,10 @@ class CMapGenOptions;
 class CTerrainViewPatternConfig;
 class CTerrainViewPatternConfig;
 class CMapEditManager;
 class CMapEditManager;
 class JsonNode;
 class JsonNode;
-
-typedef std::vector<JsonNode> JsonVector;
-
 class CMapGenerator;
 class CMapGenerator;
+class CTileInfo;
 
 
-//static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
-//	int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
+typedef std::vector<JsonNode> JsonVector;
 
 
 class rmgException : std::exception
 class rmgException : std::exception
 {
 {
@@ -68,19 +66,23 @@ public:
 	std::map<TRmgTemplateZoneId, CRmgTemplateZone*> getZones() const;
 	std::map<TRmgTemplateZoneId, CRmgTemplateZone*> getZones() const;
 	void foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo);
 	void foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo);
 
 
+	bool isBlocked(int3 &tile) const;
+	bool shouldBeBlocked(int3 &tile) const;
+	bool isPossible(int3 &tile) const;
+	bool isFree(int3 &tile) const;
+	void setOccupied(int3 &tile, ETileType::ETileType state);
+
 private:
 private:
 	std::map<TRmgTemplateZoneId, CRmgTemplateZone*> zones;
 	std::map<TRmgTemplateZoneId, CRmgTemplateZone*> zones;
 
 
+	CTileInfo*** tiles;
+
 	/// Generation methods
 	/// Generation methods
 	std::string getMapDescription() const;
 	std::string getMapDescription() const;
 	void addPlayerInfo();
 	void addPlayerInfo();
 	void addHeaderInfo();
 	void addHeaderInfo();
+	void initTiles();
 	void genZones();
 	void genZones();
 	void fillZones();
 	void fillZones();
 
 
-};
-
-/* ---------------------------------------------------------------------------- */
-/* Implementation/Detail classes, Private API */
-/* ---------------------------------------------------------------------------- */
-
+};

+ 25 - 25
lib/rmg/CRmgTemplateZone.cpp

@@ -73,47 +73,47 @@ void CRmgTemplateZone::CTownInfo::setCastleDensity(int value)
 	castleDensity = value;
 	castleDensity = value;
 }
 }
 
 
-CRmgTemplateZone::CTileInfo::CTileInfo():nearestObjectDistance(INT_MAX), obstacle(false), occupied(false), terrain(ETerrainType::WRONG) 
+CTileInfo::CTileInfo():nearestObjectDistance(INT_MAX), terrain(ETerrainType::WRONG) 
 {
 {
-
+	occupied = ETileType::POSSIBLE; //all tiles are initially possible to place objects or passages
 }
 }
 
 
-int CRmgTemplateZone::CTileInfo::getNearestObjectDistance() const
+int CTileInfo::getNearestObjectDistance() const
 {
 {
 	return nearestObjectDistance;
 	return nearestObjectDistance;
 }
 }
 
 
-void CRmgTemplateZone::CTileInfo::setNearestObjectDistance(int value)
+void CTileInfo::setNearestObjectDistance(int value)
 {
 {
 	nearestObjectDistance = std::max(0, value); //never negative (or unitialized)
 	nearestObjectDistance = std::max(0, value); //never negative (or unitialized)
 }
 }
-
-bool CRmgTemplateZone::CTileInfo::isObstacle() const
+bool CTileInfo::shouldBeBlocked() const
 {
 {
-	return obstacle;
+	return occupied == ETileType::BLOCKED;
 }
 }
-
-void CRmgTemplateZone::CTileInfo::setObstacle(bool value)
+bool CTileInfo::isBlocked() const
 {
 {
-	obstacle = value;
+	return occupied == ETileType::BLOCKED || occupied == ETileType::USED;
 }
 }
-
-bool CRmgTemplateZone::CTileInfo::isOccupied() const
+bool CTileInfo::isPossible() const
 {
 {
-	return occupied;
+	return occupied == ETileType::POSSIBLE;
 }
 }
-
-void CRmgTemplateZone::CTileInfo::setOccupied(bool value)
+bool CTileInfo::isFree() const
+{
+	return occupied == ETileType::FREE;
+}
+void CTileInfo::setOccupied(ETileType::ETileType value)
 {
 {
 	occupied = value;
 	occupied = value;
 }
 }
 
 
-ETerrainType CRmgTemplateZone::CTileInfo::getTerrainType() const
+ETerrainType CTileInfo::getTerrainType() const
 {
 {
 	return terrain;
 	return terrain;
 }
 }
 
 
-void CRmgTemplateZone::CTileInfo::setTerrainType(ETerrainType value)
+void CTileInfo::setTerrainType(ETerrainType value)
 {
 {
 	terrain = value;
 	terrain = value;
 }
 }
@@ -285,7 +285,7 @@ float3 CRmgTemplateZone::getCenter() const
 {
 {
 	return center;
 	return center;
 }
 }
-void CRmgTemplateZone::setCenter(float3 f)
+void CRmgTemplateZone::setCenter(const float3 &f)
 {
 {
 	//limit boundaries to (0,1) square
 	//limit boundaries to (0,1) square
 	center = float3 (std::min(std::max(f.x, 0.f), 1.f), std::min(std::max(f.y, 0.f), 1.f), f.z);
 	center = float3 (std::min(std::max(f.x, 0.f), 1.f), std::min(std::max(f.y, 0.f), 1.f), f.z);
@@ -302,7 +302,7 @@ void CRmgTemplateZone::setShape(std::vector<int3> shape)
 	this->shape = shape;
 	this->shape = shape;
 }
 }
 
 
-int3 CRmgTemplateZone::getPos()
+int3 CRmgTemplateZone::getPos() const
 {
 {
 	return pos;
 	return pos;
 }
 }
@@ -441,7 +441,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
 	sel.clearSelection();
 	sel.clearSelection();
 	for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
 	for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
 	{
 	{
-		if (it->second.isObstacle())
+		if (it->second.shouldBeBlocked()) //fill tiles that should be blocked with obstacles
 		{
 		{
 			auto obj = new CGObjectInstance();
 			auto obj = new CGObjectInstance();
 			obj->ID = static_cast<Obj>(130);
 			obj->ID = static_cast<Obj>(130);
@@ -473,7 +473,7 @@ bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance*
 		//avoid borders
 		//avoid borders
 		if ((p.x < 3) || (w - p.x < 3) || (p.y < 3) || (h - p.y < 3))
 		if ((p.x < 3) || (w - p.x < 3) || (p.y < 3) || (h - p.y < 3))
 			continue;
 			continue;
-		if (!ti.isOccupied() && !ti.isObstacle()  && (dist >= min_dist) && (dist > best_distance))
+		if (!ti.isBlocked()  && (dist >= min_dist) && (dist > best_distance))
 		{
 		{
 			best_distance = dist;
 			best_distance = dist;
 			pos = p;
 			pos = p;
@@ -521,7 +521,7 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
 	{		
 	{		
 		if (tileinfo.find(pos + p) != tileinfo.end())
 		if (tileinfo.find(pos + p) != tileinfo.end())
 		{
 		{
-			tileinfo[pos + p].setOccupied(true);
+			tileinfo[pos + p].setOccupied(ETileType::USED);
 		}
 		}
 	}
 	}
 	for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
 	for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
@@ -547,10 +547,10 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
 				if (it->first != visitable)
 				if (it->first != visitable)
 				{
 				{
 					logGlobal->traceStream() << boost::format("Block at %d %d") % it->first.x % it->first.y;
 					logGlobal->traceStream() << boost::format("Block at %d %d") % it->first.x % it->first.y;
-					if (!it->second.isOccupied() &&  !it->second.isObstacle())
+					if (it->second.isPossible())
 					{
 					{
 						tiles.push_back(it->first);
 						tiles.push_back(it->first);
-						it->second.setObstacle(true);
+						it->second.setOccupied(ETileType::BLOCKED);
 					}
 					}
 				}
 				}
 			}
 			}
@@ -562,7 +562,7 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
 		return false;
 		return false;
 	}
 	}
 	auto guard_tile = *RandomGeneratorUtil::nextItem(tiles, gen->rand);
 	auto guard_tile = *RandomGeneratorUtil::nextItem(tiles, gen->rand);
-	tileinfo[guard_tile].setObstacle(false);
+	tileinfo[guard_tile].setOccupied(ETileType::USED);
 	auto guard = new CGCreature();
 	auto guard = new CGCreature();
 	guard->ID = Obj::RANDOM_MONSTER;
 	guard->ID = Obj::RANDOM_MONSTER;
 	guard->subID = 0;
 	guard->subID = 0;

+ 34 - 30
lib/rmg/CRmgTemplateZone.h

@@ -14,19 +14,44 @@
 #include "../GameConstants.h"
 #include "../GameConstants.h"
 #include "CMapGenerator.h"
 #include "CMapGenerator.h"
 #include "float3.h"
 #include "float3.h"
+#include "../int3.h"
 
 
-class CMapgenerator;
+class CMapGenerator;
+class CTileInfo;
+class int3;
+class CGObjectInstance;
 
 
 namespace ETemplateZoneType
 namespace ETemplateZoneType
 {
 {
-enum ETemplateZoneType
+	enum ETemplateZoneType
+	{
+		PLAYER_START,
+		CPU_START,
+		TREASURE,
+		JUNCTION
+	};
+}
+class DLL_LINKAGE CTileInfo
 {
 {
-	PLAYER_START,
-	CPU_START,
-	TREASURE,
-	JUNCTION
+public:
+
+	CTileInfo();
+
+	int getNearestObjectDistance() const;
+	void setNearestObjectDistance(int value);
+	bool isBlocked() const;
+	bool shouldBeBlocked() const;
+	bool isPossible() const;
+	bool isFree() const;
+	void setOccupied(ETileType::ETileType value);
+	ETerrainType getTerrainType() const;
+	void setTerrainType(ETerrainType value);
+
+private:
+	int nearestObjectDistance;
+	ETileType::ETileType occupied;
+	ETerrainType terrain;
 };
 };
-}
 
 
 /// The CRmgTemplateZone describes a zone in a template.
 /// The CRmgTemplateZone describes a zone in a template.
 class DLL_LINKAGE CRmgTemplateZone
 class DLL_LINKAGE CRmgTemplateZone
@@ -49,27 +74,6 @@ public:
 	private:
 	private:
 		int townCount, castleCount, townDensity, castleDensity;
 		int townCount, castleCount, townDensity, castleDensity;
 	};
 	};
-	
-	class DLL_LINKAGE CTileInfo
-	{
-	public:
-		CTileInfo();
-
-		int getNearestObjectDistance() const;
-		void setNearestObjectDistance(int value);
-		bool isObstacle() const;
-		void setObstacle(bool value);
-		bool isOccupied() const;
-		void setOccupied(bool value);
-		ETerrainType getTerrainType() const;
-		void setTerrainType(ETerrainType value);
-
-	private:
-		int nearestObjectDistance;
-		bool obstacle;
-		bool occupied;
-		ETerrainType terrain;
-	};
 
 
 	CRmgTemplateZone();
 	CRmgTemplateZone();
 
 
@@ -101,8 +105,8 @@ public:
 	void setTownTypeLikeZone(boost::optional<TRmgTemplateZoneId> value);
 	void setTownTypeLikeZone(boost::optional<TRmgTemplateZoneId> value);
 
 
 	float3 getCenter() const;
 	float3 getCenter() const;
-	void setCenter(float3 f);
-	int3 getPos();
+	void setCenter(const float3 &f);
+	int3 getPos() const;
 	void setPos(const int3 &pos);
 	void setPos(const int3 &pos);
 
 
 	void addTile (const int3 &pos);
 	void addTile (const int3 &pos);