mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Create random obstacles that match terrain.
This commit is contained in:
		| @@ -15,7 +15,7 @@ SPELLS: | ||||
| * New configuration format: http://wiki.vcmi.eu/index.php?title=Spell_Format | ||||
|  | ||||
| RANDOM MAP GENERATOR | ||||
| * Towns form mods cna be used | ||||
| * Towns from mods can be used | ||||
| * Reading connections, terrains, towns and mines from template | ||||
| * Zone placement | ||||
| * Zone borders and connections, fractalized paths inside zones | ||||
|   | ||||
| @@ -178,16 +178,7 @@ std::set<int3> CGObjectInstance::getBlockedPos() const | ||||
|  | ||||
| std::set<int3> CGObjectInstance::getBlockedOffsets() const | ||||
| { | ||||
| 	std::set<int3> ret; | ||||
| 	for(int w=0; w<getWidth(); ++w) | ||||
| 	{ | ||||
| 		for(int h=0; h<getHeight(); ++h) | ||||
| 		{ | ||||
| 			if (appearance.isBlockedAt(w, h)) | ||||
| 				ret.insert(int3(-w, -h, 0)); | ||||
| 		} | ||||
| 	} | ||||
| 	return ret; | ||||
| 	return appearance.getBlockedOffsets(); | ||||
| } | ||||
|  | ||||
| void CGObjectInstance::setType(si32 ID, si32 subID) | ||||
|   | ||||
| @@ -308,6 +308,33 @@ bool ObjectTemplate::isBlockedAt(si32 X, si32 Y) const | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| std::set<int3> ObjectTemplate::getBlockedOffsets() const | ||||
| { | ||||
| 	std::set<int3> ret; | ||||
| 	for(int w = 0; w < getWidth(); ++w) | ||||
| 	{ | ||||
| 		for(int h = 0; h < getHeight(); ++h) | ||||
| 		{ | ||||
| 			if (isBlockedAt(w, h)) | ||||
| 				ret.insert(int3(-w, -h, 0)); | ||||
| 		} | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| int3 ObjectTemplate::getBlockMapOffset() const | ||||
| { | ||||
| 	for(int w = 0; w < getWidth(); ++w) | ||||
| 	{ | ||||
| 		for(int h = 0; h < getHeight(); ++h) | ||||
| 		{ | ||||
| 			if (isBlockedAt(w, h)) | ||||
| 				return int3(-w, -h, 0); | ||||
| 		} | ||||
| 	} | ||||
| 	return int3(-1,-1,-1); | ||||
| } | ||||
|  | ||||
| bool ObjectTemplate::isVisitableFrom(si8 X, si8 Y) const | ||||
| { | ||||
| 	// visitDir uses format | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
| class CBinaryReader; | ||||
| class CLegacyConfigParser; | ||||
| class JsonNode; | ||||
| class int3; | ||||
|  | ||||
| class DLL_LINKAGE ObjectTemplate | ||||
| { | ||||
| @@ -56,6 +57,8 @@ public: | ||||
| 	bool isVisitableAt(si32 X, si32 Y) const; | ||||
| 	bool isVisibleAt(si32 X, si32 Y) const; | ||||
| 	bool isBlockedAt(si32 X, si32 Y) const; | ||||
| 	std::set<int3> getBlockedOffsets() const; | ||||
| 	int3 getBlockMapOffset() const; //bottom-right corner when firts blocked tile is | ||||
|  | ||||
| 	// Checks if object is visitable from certain direction. X and Y must be between -1..+1 | ||||
| 	bool isVisitableFrom(si8 X, si8 Y) const; | ||||
|   | ||||
| @@ -962,20 +962,49 @@ void CRmgTemplateZone::createTreasures(CMapGenerator* gen) | ||||
|  | ||||
| void CRmgTemplateZone::createObstacles(CMapGenerator* gen) | ||||
| { | ||||
| 	//get all possible obstacles for this terrain | ||||
| 	for (auto primaryID : VLC->objtypeh->knownObjects())  | ||||
| 	{  | ||||
| 		for (auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID))  | ||||
| 		{  | ||||
| 			auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);  | ||||
| 			if (handler->isStaticObject()) | ||||
| 			{ | ||||
| 				for (auto temp : handler->getTemplates()) | ||||
| 				{ | ||||
| 					if (temp.canBePlacedAt(terrainType) && temp.getBlockMapOffset().valid()) | ||||
| 						possibleObstacles.push_back(temp); | ||||
| 				} | ||||
| 			} | ||||
| 		}  | ||||
| 	} | ||||
|  | ||||
| 	auto sel = gen->editManager->getTerrainSelection(); | ||||
| 	sel.clearSelection(); | ||||
|  | ||||
| 	auto tryToPlaceObstacleHere = [this, gen](int3& tile)-> bool | ||||
| 	{ | ||||
| 		auto temp = *RandomGeneratorUtil::nextItem(possibleObstacles, gen->rand); | ||||
| 		int3 obstaclePos = tile + temp.getBlockMapOffset(); | ||||
| 		if (canObstacleBePlacedHere(gen, temp, obstaclePos)) //can be placed here | ||||
| 		{ | ||||
| 			auto obj = VLC->objtypeh->getHandlerFor(temp.id, temp.subid)->create(temp); | ||||
| 			placeObject(gen, obj, obstaclePos); | ||||
| 			return true; | ||||
| 		} | ||||
| 		return false; | ||||
| 	}; | ||||
|  | ||||
| 	for (auto tile : tileinfo) | ||||
| 	{ | ||||
| 		//test code - block all the map to show paths clearly | ||||
| 		//if (gen->isPossible(tile)) | ||||
| 		//	gen->setOccupied(tile, ETileType::BLOCKED); | ||||
|  | ||||
| 		if (gen->shouldBeBlocked(tile)) //fill tiles that should be blocked with obstacles | ||||
| 		{ | ||||
| 			auto obj = new CGObjectInstance(); | ||||
| 			obj->ID = static_cast<Obj>(57); | ||||
| 			obj->subID = 0; | ||||
| 			placeObject(gen, obj, tile); | ||||
| 			while (!tryToPlaceObstacleHere(tile)); | ||||
| 		} | ||||
| 		else if (gen->isPossible(tile)) | ||||
| 		{ | ||||
| 			//try to place random obstacle once - if not possible, leave it clear | ||||
| 			tryToPlaceObstacleHere(tile); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -1031,6 +1060,23 @@ bool CRmgTemplateZone::findPlaceForTreasurePile(CMapGenerator* gen, si32 min_dis | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| bool CRmgTemplateZone::canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos) | ||||
| { | ||||
| 	auto tilesBlockedByObject = temp.getBlockedOffsets(); | ||||
|  | ||||
| 	bool allTilesAvailable = true; | ||||
| 	for (auto blockingTile : tilesBlockedByObject) | ||||
| 	{ | ||||
| 		int3 t = pos + blockingTile; | ||||
| 		if (!gen->map->isInTheMap(t) || !(gen->isPossible(t) || gen->shouldBeBlocked(t))) | ||||
| 		{ | ||||
| 			allTilesAvailable = false; //if at least one tile is not possible, object can't be placed here | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	return allTilesAvailable; | ||||
| } | ||||
|  | ||||
| bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos) | ||||
| { | ||||
| 	//we need object apperance to deduce free tiles | ||||
|   | ||||
| @@ -21,6 +21,7 @@ class CMapGenerator; | ||||
| class CTileInfo; | ||||
| class int3; | ||||
| class CGObjectInstance; | ||||
| class ObjectTemplate; | ||||
|  | ||||
| namespace ETemplateZoneType | ||||
| { | ||||
| @@ -173,6 +174,7 @@ private: | ||||
| 	ui16 totalDensity; | ||||
| 	std::vector<CTreasureInfo> treasureInfo; | ||||
| 	std::vector<ObjectInfo> possibleObjects; | ||||
| 	std::vector<ObjectTemplate> possibleObstacles; | ||||
|  | ||||
| 	//content info | ||||
| 	std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects; | ||||
| @@ -189,6 +191,7 @@ private: | ||||
| 	void addAllPossibleObjects (CMapGenerator* gen); //add objects, including zone-specific, to possibleObjects | ||||
| 	bool findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos); | ||||
| 	bool findPlaceForTreasurePile(CMapGenerator* gen, si32 min_dist, int3 &pos); | ||||
| 	bool canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos); | ||||
| 	void checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos); | ||||
| 	void placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos); | ||||
| 	bool guardObject(CMapGenerator* gen, CGObjectInstance* object, si32 str); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user