| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 | /* * Functions.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */#include "StdInc.h"#include "Functions.h"#include "CMapGenerator.h"#include "ObjectManager.h"#include "RoadPlacer.h"#include "TreasurePlacer.h"#include "ConnectionsPlacer.h"#include "TownPlacer.h"#include "WaterProxy.h"#include "WaterRoutes.h"#include "RmgMap.h"#include "TileInfo.h"#include "RmgPath.h"#include "../CTownHandler.h"#include "../mapping/CMapEditManager.h"#include "../mapping/CMap.h"#include "../mapObjects/CommonConstructors.h"#include "../mapObjects/MapObjects.h" //needed to resolve templates for CommonConstructors.h#include "../VCMI_Lib.h"VCMI_LIB_NAMESPACE_BEGINvoid createModificators(RmgMap & map){	for(auto & z : map.getZones())	{		auto & zone = *z.second;		switch(zone.getType())		{			case ETemplateZoneType::WATER:				zone.addModificator<ObjectManager>();				zone.addModificator<TreasurePlacer>();				zone.addModificator<WaterProxy>();				zone.addModificator<WaterRoutes>();				break;							default:				zone.addModificator<TownPlacer>();				zone.addModificator<ObjectManager>();				zone.addModificator<ConnectionsPlacer>();				zone.addModificator<TreasurePlacer>();				zone.addModificator<RoadPlacer>();				break;		}			}}rmg::Tileset collectDistantTiles(const Zone& zone, int distance){	uint32_t distanceSq = distance * distance;	auto subarea = zone.getArea().getSubarea([&zone, distanceSq](const int3 & t)	{		return t.dist2dSQ(zone.getPos()) > distanceSq;	});	return subarea.getTiles();}void createBorder(RmgMap & gen, Zone & zone){	rmg::Area borderArea(zone.getArea().getBorder());	rmg::Area borderOutsideArea(zone.getArea().getBorderOutside());	auto blockBorder = borderArea.getSubarea([&gen, &borderOutsideArea](const int3 & t)	{		auto tile = borderOutsideArea.nearest(t);		return gen.isOnMap(tile) && gen.getZones()[gen.getZoneID(tile)]->getType() != ETemplateZoneType::WATER;	});		for(auto & tile : blockBorder.getTilesVector())	{		if(gen.isPossible(tile))		{			gen.setOccupied(tile, ETileType::BLOCKED);			zone.areaPossible().erase(tile);		}				gen.foreachDirectNeighbour(tile, [&gen, &zone](int3 &nearbyPos)		{			if(gen.isPossible(nearbyPos) && gen.getZoneID(nearbyPos) == zone.getId())			{				gen.setOccupied(nearbyPos, ETileType::BLOCKED);				zone.areaPossible().erase(nearbyPos);			}		});	}}void paintZoneTerrain(const Zone & zone, CRandomGenerator & generator, RmgMap & map, TerrainId terrain){	auto v = zone.getArea().getTilesVector();	map.getEditManager()->getTerrainSelection().setSelection(v);	map.getEditManager()->drawTerrain(terrain, &generator);}int chooseRandomAppearance(CRandomGenerator & generator, si32 ObjID, TerrainId terrain){	auto factories = VLC->objtypeh->knownSubObjects(ObjID);	vstd::erase_if(factories, [ObjID, &terrain](si32 f)	{		return VLC->objtypeh->getHandlerFor(ObjID, f)->getTemplates(terrain).empty();	});		return *RandomGeneratorUtil::nextItem(factories, generator);}void initTerrainType(Zone & zone, CMapGenerator & gen){	if(zone.getType()==ETemplateZoneType::WATER)	{		//collect all water terrain types		std::vector<TerrainId> waterTerrains;		for(const auto & terrain : VLC->terrainTypeHandler->terrains())			if(terrain.isWater())				waterTerrains.push_back(terrain.id);				zone.setTerrainType(*RandomGeneratorUtil::nextItem(waterTerrains, gen.rand));	}	else	{		if(zone.isMatchTerrainToTown() && zone.getTownType() != ETownType::NEUTRAL)		{			zone.setTerrainType((*VLC->townh)[zone.getTownType()]->nativeTerrain);		}		else		{			zone.setTerrainType(*RandomGeneratorUtil::nextItem(zone.getTerrainTypes(), gen.rand));		}				//Now, replace disallowed terrains on surface and in the underground		const auto & terrainType = VLC->terrainTypeHandler->terrains()[zone.getTerrainType()];		if(zone.isUnderground())		{			if(!terrainType.isUnderground())			{				zone.setTerrainType(Terrain::SUBTERRANEAN);			}		}		else		{			if (!terrainType.isSurface())			{				zone.setTerrainType(Terrain::DIRT);			}		}	}}void createObstaclesCommon2(RmgMap & map, CRandomGenerator & generator){	if(map.map().twoLevel)	{		//finally mark rock tiles as occupied, spawn no obstacles there		for(int x = 0; x < map.map().width; x++)		{			for(int y = 0; y < map.map().height; y++)			{				int3 tile(x, y, 1);				if(!map.map().getTile(tile).terType->isPassable())				{					map.setOccupied(tile, ETileType::USED);				}			}		}	}}VCMI_LIB_NAMESPACE_END
 |