123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- /*
- * RmgMap.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 "RmgMap.h"
- #include "TileInfo.h"
- #include "CMapGenOptions.h"
- #include "Zone.h"
- #include "../mapping/CMapEditManager.h"
- #include "../mapping/CMap.h"
- #include "../CTownHandler.h"
- #include "modificators/ObjectManager.h"
- #include "modificators/RoadPlacer.h"
- #include "modificators/TreasurePlacer.h"
- #include "modificators/PrisonHeroPlacer.h"
- #include "modificators/QuestArtifactPlacer.h"
- #include "modificators/ConnectionsPlacer.h"
- #include "modificators/TownPlacer.h"
- #include "modificators/MinePlacer.h"
- #include "modificators/ObjectDistributor.h"
- #include "modificators/WaterAdopter.h"
- #include "modificators/WaterProxy.h"
- #include "modificators/WaterRoutes.h"
- #include "modificators/RockPlacer.h"
- #include "modificators/RockFiller.h"
- #include "modificators/ObstaclePlacer.h"
- #include "modificators/RiverPlacer.h"
- #include "modificators/TerrainPainter.h"
- #include "Functions.h"
- #include "CMapGenerator.h"
- VCMI_LIB_NAMESPACE_BEGIN
- RmgMap::RmgMap(const CMapGenOptions& mapGenOptions, IGameCallback * cb) :
- mapGenOptions(mapGenOptions), zonesTotal(0)
- {
- mapInstance = std::make_unique<CMap>(cb);
- mapProxy = std::make_shared<MapProxy>(*this);
- getEditManager()->getUndoManager().setUndoRedoLimit(0);
- }
- int RmgMap::getDecorationsPercentage() const
- {
- return 15; // arbitrary value to generate more readable map
- }
- void RmgMap::foreach_neighbour(const int3 & pos, const std::function<void(int3 & pos)> & foo) const
- {
- for(const int3 &dir : int3::getDirs())
- {
- int3 n = pos + dir;
- /*important notice: perform any translation before this function is called,
- so the actual mapInstance->position is checked*/
- if(mapInstance->isInTheMap(n))
- foo(n);
- }
- }
- void RmgMap::foreachDirectNeighbour(const int3 & pos, const std::function<void(int3 & pos)> & foo) const
- {
- for(const int3 &dir : rmg::dirs4)
- {
- int3 n = pos + dir;
- if(mapInstance->isInTheMap(n))
- foo(n);
- }
- }
- void RmgMap::foreachDiagonalNeighbour(const int3 & pos, const std::function<void(int3 & pos)> & foo) const
- {
- for (const int3 &dir : rmg::dirsDiagonal)
- {
- int3 n = pos + dir;
- if (mapInstance->isInTheMap(n))
- foo(n);
- }
- }
- void RmgMap::initTiles(CMapGenerator & generator, CRandomGenerator & rand)
- {
- mapInstance->initTerrain();
-
- tiles.resize(boost::extents[mapInstance->width][mapInstance->height][mapInstance->levels()]);
- zoneColouring.resize(boost::extents[mapInstance->width][mapInstance->height][mapInstance->levels()]);
-
- //init native town count with 0
- for (auto faction : VLC->townh->getAllowedFactions())
- zonesPerFaction[faction] = 0;
-
- getEditManager()->clearTerrain(&rand);
- getEditManager()->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions.getWidth(), mapGenOptions.getHeight()));
- getEditManager()->drawTerrain(ETerrainId::GRASS, getDecorationsPercentage(), &rand);
- const auto * tmpl = mapGenOptions.getMapTemplate();
- zones.clear();
- for(const auto & option : tmpl->getZones())
- {
- auto zone = std::make_shared<Zone>(*this, generator, rand);
- zone->setOptions(*option.second);
- zones[zone->getId()] = zone;
- }
-
- switch(mapGenOptions.getWaterContent())
- {
- case EWaterContent::NORMAL:
- case EWaterContent::ISLANDS:
- TRmgTemplateZoneId waterId = zones.size() + 1;
- rmg::ZoneOptions options;
- options.setId(waterId);
- options.setType(ETemplateZoneType::WATER);
- auto zone = std::make_shared<Zone>(*this, generator, rand);
- zone->setOptions(options);
- //std::set<FactionID> allowedMonsterFactions({FactionID::CASTLE, FactionID::INFERNO}); // example of filling allowed monster factions
- //zone->setMonsterTypes(allowedMonsterFactions); // can be set here, probably from template json, along with the treasure ranges and densities
- zone->monsterStrength = EMonsterStrength::ZONE_NONE; // can be set to other value, probably from a new field in the template json
- zones[zone->getId()] = zone;
- break;
- }
- }
- void RmgMap::addModificators()
- {
- bool hasObjectDistributor = false;
- bool hasHeroPlacer = false;
- bool hasRockFiller = false;
- for(auto & z : getZones())
- {
- auto zone = z.second;
-
- zone->addModificator<ObjectManager>();
- if (!hasObjectDistributor)
- {
- zone->addModificator<ObjectDistributor>();
- hasObjectDistributor = true;
- }
- if (!hasHeroPlacer)
- {
- zone->addModificator<PrisonHeroPlacer>();
- hasHeroPlacer = true;
- }
- zone->addModificator<TreasurePlacer>();
- zone->addModificator<ObstaclePlacer>();
- zone->addModificator<TerrainPainter>();
-
- if(zone->getType() == ETemplateZoneType::WATER)
- {
- for(auto & z1 : getZones())
- {
- z1.second->addModificator<WaterAdopter>();
- z1.second->getModificator<WaterAdopter>()->setWaterZone(zone->getId());
- }
- zone->addModificator<WaterProxy>();
- zone->addModificator<WaterRoutes>();
- }
- else
- {
- zone->addModificator<TownPlacer>();
- zone->addModificator<MinePlacer>();
- zone->addModificator<QuestArtifactPlacer>();
- zone->addModificator<ConnectionsPlacer>();
- zone->addModificator<RoadPlacer>();
- zone->addModificator<RiverPlacer>();
- }
-
- if(zone->isUnderground())
- {
- zone->addModificator<RockPlacer>();
- if (!hasRockFiller)
- {
- zone->addModificator<RockFiller>();
- hasRockFiller = true;
- }
- }
-
- }
- }
- int RmgMap::levels() const
- {
- return mapInstance->levels();
- }
- int RmgMap::width() const
- {
- return mapInstance->width;
- }
- int RmgMap::height() const
- {
- return mapInstance->height;
- }
- PlayerInfo & RmgMap::getPlayer(int playerId)
- {
- return mapInstance->players.at(playerId);
- }
- std::shared_ptr<MapProxy> RmgMap::getMapProxy() const
- {
- return mapProxy;
- }
- CMap& RmgMap::getMap(const CMapGenerator*) const
- {
- return *mapInstance;
- }
- CMapEditManager* RmgMap::getEditManager() const
- {
- return mapInstance->getEditManager();
- }
- bool RmgMap::isOnMap(const int3 & tile) const
- {
- return mapInstance->isInTheMap(tile);
- }
- const CMapGenOptions& RmgMap::getMapGenOptions() const
- {
- return mapGenOptions;
- }
- void RmgMap::assertOnMap(const int3& tile) const
- {
- if (!mapInstance->isInTheMap(tile))
- throw rmgException(boost::str(boost::format("Tile %s is outside the map") % tile.toString()));
- }
- RmgMap::Zones & RmgMap::getZones()
- {
- return zones;
- }
- RmgMap::Zones RmgMap::getZonesOnLevel(int level) const
- {
- Zones zonesOnLevel;
- for(const auto& zonePair : zones)
- {
- if(zonePair.second->isUnderground() == (bool)level)
- {
- zonesOnLevel.insert(zonePair);
- }
- }
- return zonesOnLevel;
- }
- bool RmgMap::isBlocked(const int3 &tile) const
- {
- assertOnMap(tile);
-
- return tiles[tile.x][tile.y][tile.z].isBlocked();
- }
- bool RmgMap::shouldBeBlocked(const int3 &tile) const
- {
- assertOnMap(tile);
-
- return tiles[tile.x][tile.y][tile.z].shouldBeBlocked();
- }
- bool RmgMap::isPossible(const int3 &tile) const
- {
- assertOnMap(tile);
-
- return tiles[tile.x][tile.y][tile.z].isPossible();
- }
- bool RmgMap::isFree(const int3 &tile) const
- {
- assertOnMap(tile);
-
- return tiles[tile.x][tile.y][tile.z].isFree();
- }
- bool RmgMap::isUsed(const int3 &tile) const
- {
- assertOnMap(tile);
-
- return tiles[tile.x][tile.y][tile.z].isUsed();
- }
- bool RmgMap::isRoad(const int3& tile) const
- {
- assertOnMap(tile);
-
- return tiles[tile.x][tile.y][tile.z].isRoad();
- }
- void RmgMap::setOccupied(const int3 &tile, ETileType state)
- {
- assertOnMap(tile);
-
- tiles[tile.x][tile.y][tile.z].setOccupied(state);
- }
- void RmgMap::setRoad(const int3& tile, RoadId roadType)
- {
- assertOnMap(tile);
-
- tiles[tile.x][tile.y][tile.z].setRoadType(roadType);
- }
- TileInfo RmgMap::getTileInfo(const int3& tile) const
- {
- assertOnMap(tile);
-
- return tiles[tile.x][tile.y][tile.z];
- }
- TerrainTile & RmgMap::getTile(const int3& tile) const
- {
- return mapInstance->getTile(tile);
- }
- TRmgTemplateZoneId RmgMap::getZoneID(const int3& tile) const
- {
- assertOnMap(tile);
-
- return zoneColouring[tile.x][tile.y][tile.z];
- }
- void RmgMap::setZoneID(const int3& tile, TRmgTemplateZoneId zid)
- {
- assertOnMap(tile);
-
- zoneColouring[tile.x][tile.y][tile.z] = zid;
- }
- void RmgMap::setNearestObjectDistance(const int3 &tile, float value)
- {
- assertOnMap(tile);
-
- tiles[tile.x][tile.y][tile.z].setNearestObjectDistance(value);
- }
- float RmgMap::getNearestObjectDistance(const int3 &tile) const
- {
- assertOnMap(tile);
-
- return tiles[tile.x][tile.y][tile.z].getNearestObjectDistance();
- }
- void RmgMap::registerZone(FactionID faction)
- {
- //FIXME: Protect with lock guard?
- zonesPerFaction[faction]++;
- zonesTotal++;
- }
- ui32 RmgMap::getZoneCount(FactionID faction)
- {
- return zonesPerFaction[faction];
- }
- ui32 RmgMap::getTotalZoneCount() const
- {
- return zonesTotal;
- }
- bool RmgMap::isAllowedSpell(const SpellID & sid) const
- {
- assert(sid.getNum() >= 0);
- return mapInstance->allowedSpells.count(sid);
- }
- void RmgMap::dump(bool zoneId) const
- {
- static int id = 0;
- std::ofstream out(boost::str(boost::format("zone_%d.txt") % id++));
- int levels = mapInstance->levels();
- int width = mapInstance->width;
- int height = mapInstance->height;
- for (int k = 0; k < levels; k++)
- {
- for(int j = 0; j < height; j++)
- {
- for (int i = 0; i < width; i++)
- {
- if(zoneId)
- {
- out << getZoneID(int3(i, j, k));
- }
- else
- {
- char t = '?';
- switch (getTileInfo(int3(i, j, k)).getTileType())
- {
- case ETileType::FREE:
- t = ' '; break;
- case ETileType::BLOCKED:
- t = '#'; break;
- case ETileType::POSSIBLE:
- t = '-'; break;
- case ETileType::USED:
- t = 'O'; break;
- }
- out << t;
- }
- }
- out << std::endl;
- }
- out << std::endl;
- }
- out << std::endl;
- }
- VCMI_LIB_NAMESPACE_END
|