mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Introduced 3-value logic for free, blocked and possibly occupied tiles. Refactoring.
This commit is contained in:
		| @@ -21,9 +21,6 @@ | ||||
| #include "../../lib/NetPacks.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; | ||||
|  | ||||
| /* | ||||
|   | ||||
| @@ -450,6 +450,17 @@ namespace EWallState | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| namespace ETileType | ||||
| { | ||||
| 	enum ETileType | ||||
| 	{ | ||||
| 		FREE, | ||||
| 		POSSIBLE, | ||||
| 		BLOCKED, | ||||
| 		USED | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| class Obj | ||||
| { | ||||
| public: | ||||
|   | ||||
| @@ -152,4 +152,7 @@ struct ShashInt3 | ||||
| 		vstd::hash_combine(ret, pos.z); | ||||
| 		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) }; | ||||
| @@ -16,12 +16,12 @@ | ||||
|  | ||||
| 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); | ||||
| } | ||||
|  | ||||
| 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() | ||||
| @@ -46,6 +77,7 @@ std::unique_ptr<CMap> CMapGenerator::generate() | ||||
| 	{ | ||||
| 		editManager->getUndoManager().setUndoRedoLimit(0); | ||||
| 		addHeaderInfo(); | ||||
| 		initTiles(); | ||||
|  | ||||
| 		genZones(); | ||||
| 		map->calculateGuardingGreaturePositions(); //clear map so that all tiles are unguarded | ||||
| @@ -146,7 +178,6 @@ void CMapGenerator::addPlayerInfo() | ||||
|  | ||||
| void CMapGenerator::genZones() | ||||
| { | ||||
| 	map->initTerrain(); | ||||
| 	editManager->clearTerrain(&rand); | ||||
| 	editManager->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions->getWidth(), mapGenOptions->getHeight())); | ||||
| 	editManager->drawTerrain(ETerrainType::GRASS, &rand); | ||||
| @@ -217,3 +248,39 @@ std::map<TRmgTemplateZoneId, CRmgTemplateZone*> CMapGenerator::getZones() const | ||||
| { | ||||
| 	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); | ||||
| } | ||||
|   | ||||
| @@ -14,6 +14,7 @@ | ||||
| #include "../GameConstants.h" | ||||
| #include "../CRandomGenerator.h" | ||||
| #include "CMapGenOptions.h" | ||||
| #include "CRmgTemplateZone.h" | ||||
| #include "../CObjectHandler.h" | ||||
| #include "../int3.h" | ||||
|  | ||||
| @@ -24,14 +25,11 @@ class CMapGenOptions; | ||||
| class CTerrainViewPatternConfig; | ||||
| class CMapEditManager; | ||||
| class JsonNode; | ||||
| class CMapGenerator; | ||||
| class CTileInfo; | ||||
|  | ||||
| typedef std::vector<JsonNode> JsonVector; | ||||
|  | ||||
| class CMapGenerator; | ||||
|  | ||||
| //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) }; | ||||
|  | ||||
| class rmgException : std::exception | ||||
| { | ||||
| 	std::string msg; | ||||
| @@ -68,19 +66,23 @@ public: | ||||
| 	std::map<TRmgTemplateZoneId, CRmgTemplateZone*> getZones() const; | ||||
| 	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: | ||||
| 	std::map<TRmgTemplateZoneId, CRmgTemplateZone*> zones; | ||||
|  | ||||
| 	CTileInfo*** tiles; | ||||
|  | ||||
| 	/// Generation methods | ||||
| 	std::string getMapDescription() const; | ||||
| 	void addPlayerInfo(); | ||||
| 	void addHeaderInfo(); | ||||
| 	void initTiles(); | ||||
| 	void genZones(); | ||||
| 	void fillZones(); | ||||
|  | ||||
| }; | ||||
|  | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
| /* Implementation/Detail classes, Private API */ | ||||
| /* ---------------------------------------------------------------------------- */ | ||||
|  | ||||
| }; | ||||
| @@ -73,47 +73,47 @@ void CRmgTemplateZone::CTownInfo::setCastleDensity(int 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; | ||||
| } | ||||
|  | ||||
| void CRmgTemplateZone::CTileInfo::setNearestObjectDistance(int value) | ||||
| void CTileInfo::setNearestObjectDistance(int value) | ||||
| { | ||||
| 	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; | ||||
| } | ||||
|  | ||||
| ETerrainType CRmgTemplateZone::CTileInfo::getTerrainType() const | ||||
| ETerrainType CTileInfo::getTerrainType() const | ||||
| { | ||||
| 	return terrain; | ||||
| } | ||||
|  | ||||
| void CRmgTemplateZone::CTileInfo::setTerrainType(ETerrainType value) | ||||
| void CTileInfo::setTerrainType(ETerrainType value) | ||||
| { | ||||
| 	terrain = value; | ||||
| } | ||||
| @@ -285,7 +285,7 @@ float3 CRmgTemplateZone::getCenter() const | ||||
| { | ||||
| 	return center; | ||||
| } | ||||
| void CRmgTemplateZone::setCenter(float3 f) | ||||
| void CRmgTemplateZone::setCenter(const float3 &f) | ||||
| { | ||||
| 	//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); | ||||
| @@ -302,7 +302,7 @@ void CRmgTemplateZone::setShape(std::vector<int3> shape) | ||||
| 	this->shape = shape; | ||||
| } | ||||
|  | ||||
| int3 CRmgTemplateZone::getPos() | ||||
| int3 CRmgTemplateZone::getPos() const | ||||
| { | ||||
| 	return pos; | ||||
| } | ||||
| @@ -441,7 +441,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen) | ||||
| 	sel.clearSelection(); | ||||
| 	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(); | ||||
| 			obj->ID = static_cast<Obj>(130); | ||||
| @@ -473,7 +473,7 @@ bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance* | ||||
| 		//avoid borders | ||||
| 		if ((p.x < 3) || (w - p.x < 3) || (p.y < 3) || (h - p.y < 3)) | ||||
| 			continue; | ||||
| 		if (!ti.isOccupied() && !ti.isObstacle()  && (dist >= min_dist) && (dist > best_distance)) | ||||
| 		if (!ti.isBlocked()  && (dist >= min_dist) && (dist > best_distance)) | ||||
| 		{ | ||||
| 			best_distance = dist; | ||||
| 			pos = p; | ||||
| @@ -521,7 +521,7 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object, | ||||
| 	{		 | ||||
| 		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) | ||||
| @@ -547,10 +547,10 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object, | ||||
| 				if (it->first != visitable) | ||||
| 				{ | ||||
| 					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); | ||||
| 						it->second.setObstacle(true); | ||||
| 						it->second.setOccupied(ETileType::BLOCKED); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| @@ -562,7 +562,7 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object, | ||||
| 		return false; | ||||
| 	} | ||||
| 	auto guard_tile = *RandomGeneratorUtil::nextItem(tiles, gen->rand); | ||||
| 	tileinfo[guard_tile].setObstacle(false); | ||||
| 	tileinfo[guard_tile].setOccupied(ETileType::USED); | ||||
| 	auto guard = new CGCreature(); | ||||
| 	guard->ID = Obj::RANDOM_MONSTER; | ||||
| 	guard->subID = 0; | ||||
|   | ||||
| @@ -14,19 +14,44 @@ | ||||
| #include "../GameConstants.h" | ||||
| #include "CMapGenerator.h" | ||||
| #include "float3.h" | ||||
| #include "../int3.h" | ||||
|  | ||||
| class CMapgenerator; | ||||
| class CMapGenerator; | ||||
| class CTileInfo; | ||||
| class int3; | ||||
| class CGObjectInstance; | ||||
|  | ||||
| namespace ETemplateZoneType | ||||
| { | ||||
| enum ETemplateZoneType | ||||
| { | ||||
| 	PLAYER_START, | ||||
| 	CPU_START, | ||||
| 	TREASURE, | ||||
| 	JUNCTION | ||||
| }; | ||||
| 	enum ETemplateZoneType | ||||
| 	{ | ||||
| 		PLAYER_START, | ||||
| 		CPU_START, | ||||
| 		TREASURE, | ||||
| 		JUNCTION | ||||
| 	}; | ||||
| } | ||||
| class DLL_LINKAGE CTileInfo | ||||
| { | ||||
| 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. | ||||
| class DLL_LINKAGE CRmgTemplateZone | ||||
| @@ -49,27 +74,6 @@ public: | ||||
| 	private: | ||||
| 		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(); | ||||
|  | ||||
| @@ -101,8 +105,8 @@ public: | ||||
| 	void setTownTypeLikeZone(boost::optional<TRmgTemplateZoneId> value); | ||||
|  | ||||
| 	float3 getCenter() const; | ||||
| 	void setCenter(float3 f); | ||||
| 	int3 getPos(); | ||||
| 	void setCenter(const float3 &f); | ||||
| 	int3 getPos() const; | ||||
| 	void setPos(const int3 &pos); | ||||
|  | ||||
| 	void addTile (const int3 &pos); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user