mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Wood & ore mines will be placed close to zone center.
This commit is contained in:
		| @@ -605,6 +605,10 @@ void CRmgTemplateZone::addRequiredObject(CGObjectInstance * obj, si32 strength) | ||||
| { | ||||
| 	requiredObjects.push_back(std::make_pair(obj, strength)); | ||||
| } | ||||
| void CRmgTemplateZone::addCloseObject(CGObjectInstance * obj, si32 strength) | ||||
| { | ||||
| 	closeObjects.push_back(std::make_pair(obj, strength)); | ||||
| } | ||||
|  | ||||
| bool CRmgTemplateZone::addMonster(CMapGenerator* gen, int3 &pos, si32 strength, bool clearSurroundingTiles, bool zoneGuard) | ||||
| { | ||||
| @@ -1109,11 +1113,8 @@ bool CRmgTemplateZone::placeMines (CMapGenerator* gen) | ||||
| 	static const Res::ERes woodOre[] = {Res::ERes::WOOD, Res::ERes::ORE}; | ||||
| 	static const Res::ERes preciousResources[] = {Res::ERes::GEMS, Res::ERes::CRYSTAL, Res::ERes::MERCURY, Res::ERes::SULFUR}; | ||||
|  | ||||
|  | ||||
| 	//TODO: factory / copy constructor? | ||||
| 	for (const auto & res : woodOre) | ||||
| 	{ | ||||
| 		//TODO: these 2 should be close to town (within 12 tiles radius) | ||||
| 		for (int i = 0; i < mines[res]; i++) | ||||
| 		{ | ||||
| 			auto mine = new CGMine(); | ||||
| @@ -1121,7 +1122,7 @@ bool CRmgTemplateZone::placeMines (CMapGenerator* gen) | ||||
| 			mine->subID = static_cast<si32>(res); | ||||
| 			mine->producedResource = res; | ||||
| 			mine->producedQuantity = mine->defaultResProduction(); | ||||
| 			addRequiredObject(mine, 1500); | ||||
| 			addCloseObject(mine, 1500); | ||||
| 		} | ||||
| 	} | ||||
| 	for (const auto & res : preciousResources) | ||||
| @@ -1166,6 +1167,49 @@ bool CRmgTemplateZone::createRequiredObjects(CMapGenerator* gen) | ||||
| 		guardObject (gen, obj.first, obj.second, (obj.first->ID == Obj::MONOLITH_TWO_WAY), true); | ||||
| 		//paths to required objects constitute main paths of zone. otherwise they just may lead to middle and create dead zones | ||||
| 	} | ||||
|  | ||||
| 	for (const auto &obj : closeObjects) | ||||
| 	{ | ||||
| 		std::vector<int3> tiles(possibleTiles.begin(), possibleTiles.end()); //new tiles vector after each object has been placed | ||||
| 		 | ||||
| 		// smallest distance to zone center, greatest distance to nearest object | ||||
| 		auto isCloser = [this, gen](const int3 & lhs, const int3 & rhs) -> bool | ||||
| 		{ | ||||
| 			return (this->pos.dist2dSQ(lhs) * 0.5f - gen->getNearestObjectDistance(lhs)) < (this->pos.dist2dSQ(rhs) * 0.5f - gen->getNearestObjectDistance(rhs)); | ||||
| 		}; | ||||
|  | ||||
| 		boost::sort (tiles, isCloser); | ||||
|  | ||||
| 		setTemplateForObject(gen, obj.first); | ||||
| 		auto tilesBlockedByObject = obj.first->getBlockedOffsets(); | ||||
| 		bool result = false; | ||||
|  | ||||
| 		for (auto tile : tiles) | ||||
| 		{ | ||||
| 			//object must be accessible from at least one surounding tile | ||||
| 			if (!isAccessibleFromAnywhere(gen, obj.first->appearance, tile, tilesBlockedByObject)) | ||||
| 				continue; | ||||
|  | ||||
| 			//avoid borders | ||||
| 			if (gen->isPossible(tile)) | ||||
| 			{ | ||||
| 				if (areAllTilesAvailable(gen, obj.first, tile, tilesBlockedByObject)) | ||||
| 				{ | ||||
| 					placeObject(gen, obj.first, tile); | ||||
| 					guardObject(gen, obj.first, obj.second, (obj.first->ID == Obj::MONOLITH_TWO_WAY), true); | ||||
| 					result = true; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if (!result) | ||||
| 		{ | ||||
| 			logGlobal->errorStream() << boost::format("Failed to fill zone %d due to lack of space") % id; | ||||
| 			//TODO CLEANUP! | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| @@ -1441,17 +1485,36 @@ bool CRmgTemplateZone::isAccessibleFromAnywhere (CMapGenerator* gen, ObjectTempl | ||||
| 	return accessible; | ||||
| } | ||||
|  | ||||
| bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos) | ||||
| void CRmgTemplateZone::setTemplateForObject(CMapGenerator* gen, CGObjectInstance* obj) | ||||
| { | ||||
| 	//we need object apperance to deduce free tiles | ||||
| 	if (obj->appearance.id == Obj::NO_OBJ) | ||||
| 	{ | ||||
| 		auto templates = VLC->objtypeh->getHandlerFor(obj->ID, obj->subID)->getTemplates(gen->map->getTile(getPos()).terType); | ||||
| 		if (templates.empty()) | ||||
| 			throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") %obj->ID %obj->subID %pos)); | ||||
| 	 | ||||
| 			throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") % obj->ID %obj->subID %pos)); | ||||
|  | ||||
| 		obj->appearance = templates.front(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool CRmgTemplateZone::areAllTilesAvailable(CMapGenerator* gen, CGObjectInstance* obj, int3& tile, std::set<int3>& tilesBlockedByObject) const | ||||
| { | ||||
| 	for (auto blockingTile : tilesBlockedByObject) | ||||
| 	{ | ||||
| 		int3 t = tile + blockingTile; | ||||
| 		if (!gen->map->isInTheMap(t) || !gen->isPossible(t)) | ||||
| 		{ | ||||
| 			//if at least one tile is not possible, object can't be placed here | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos) | ||||
| { | ||||
| 	//we need object apperance to deduce free tile | ||||
| 	setTemplateForObject(gen, obj); | ||||
|  | ||||
| 	//si32 min_dist = sqrt(tileinfo.size()/density); | ||||
| 	int best_distance = 0; | ||||
| @@ -1474,17 +1537,7 @@ bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance* | ||||
| 		//avoid borders | ||||
| 		if (gen->isPossible(tile) && (dist >= min_dist) && (dist > best_distance)) | ||||
| 		{ | ||||
| 			bool allTilesAvailable = true; | ||||
| 			for (auto blockingTile : tilesBlockedByObject) | ||||
| 			{ | ||||
| 				int3 t = tile + blockingTile; | ||||
| 				if (!gen->map->isInTheMap(t) || !gen->isPossible(t)) | ||||
| 				{ | ||||
| 					allTilesAvailable = false; //if at least one tile is not possible, object can't be placed here | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (allTilesAvailable) | ||||
| 			if (areAllTilesAvailable(gen, obj, tile, tilesBlockedByObject)) | ||||
| 			{ | ||||
| 				best_distance = dist; | ||||
| 				pos = tile; | ||||
|   | ||||
| @@ -150,6 +150,7 @@ public: | ||||
| 	void discardDistantTiles (CMapGenerator* gen, float distance); | ||||
|  | ||||
| 	void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0); | ||||
| 	void addCloseObject(CGObjectInstance * obj, si32 guardStrength = 0); | ||||
| 	bool addMonster(CMapGenerator* gen, int3 &pos, si32 strength, bool clearSurroundingTiles = true, bool zoneGuard = false); | ||||
| 	bool createTreasurePile(CMapGenerator* gen, int3 &pos, float minDistance, const CTreasureInfo& treasureInfo); | ||||
| 	bool fill (CMapGenerator* gen); | ||||
| @@ -198,6 +199,7 @@ private: | ||||
|  | ||||
| 	//content info | ||||
| 	std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects; | ||||
| 	std::vector<std::pair<CGObjectInstance*, ui32>> closeObjects; | ||||
| 	std::vector<CGObjectInstance*> objects; | ||||
|  | ||||
| 	//placement info | ||||
| @@ -214,6 +216,8 @@ private: | ||||
| 	bool findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos); | ||||
| 	bool findPlaceForTreasurePile(CMapGenerator* gen, float min_dist, int3 &pos); | ||||
| 	bool canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos); | ||||
| 	void setTemplateForObject(CMapGenerator* gen, CGObjectInstance* obj); | ||||
| 	bool areAllTilesAvailable(CMapGenerator* gen, CGObjectInstance* obj, int3& tile, std::set<int3>& tilesBlockedByObject) const; | ||||
| 	void checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos); | ||||
| 	void placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, bool updateDistance = true); | ||||
| 	bool guardObject(CMapGenerator* gen, CGObjectInstance* object, si32 str, bool zoneGuard = false, bool addToFreePaths = false); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user