/* * Zone.h, 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 * */ #pragma once #include "../GameConstants.h" #include "float3.h" #include "../int3.h" #include "CRmgTemplate.h" #include "RmgArea.h" #include "RmgPath.h" #include "RmgObject.h" #include "modificators/Modificator.h" //uncomment to generate dumps afger every step of map generation //#define RMG_DUMP VCMI_LIB_NAMESPACE_BEGIN class RmgMap; class CMapGenerator; class Modificator; extern const std::function AREA_NO_FILTER; typedef std::list> TModificators; template class ThreadSafeProxy { public: ThreadSafeProxy(T& resource, boost::recursive_mutex& mutex) : resourceRef(resource), lock(mutex) {} T* operator->() { return &resourceRef; } const T* operator->() const { return &resourceRef; } T& operator*() { return resourceRef; } const T& operator*() const { return resourceRef; } T& get() {return resourceRef;} const T& get() const {return resourceRef;} T operator+(const T & other) { return resourceRef + other; } template T operator+(ThreadSafeProxy & other) { return get() + other.get(); } template T operator+(ThreadSafeProxy && other) { return get() + other.get(); } private: T& resourceRef; std::lock_guard lock; }; class Zone : public rmg::ZoneOptions { public: Zone(RmgMap & map, CMapGenerator & generator, vstd::RNG & rand); Zone(const Zone &) = delete; ~Zone(); void setOptions(const rmg::ZoneOptions & options); bool isUnderground() const; float3 getCenter() const; void setCenter(const float3 &f); int3 getPos() const; void setPos(const int3 &pos); ThreadSafeProxy area(); ThreadSafeProxy area() const; ThreadSafeProxy areaPossible(); ThreadSafeProxy areaPossible() const; ThreadSafeProxy freePaths(); ThreadSafeProxy freePaths() const; ThreadSafeProxy areaUsed(); ThreadSafeProxy areaUsed() const; void initFreeTiles(); void clearTiles(); void fractalize(); FactionID getTownType() const; void setTownType(FactionID town); TerrainId getTerrainType() const; void setTerrainType(TerrainId terrain); void connectPath(const rmg::Path & path); rmg::Path searchPath(const rmg::Area & src, bool onlyStraight, const std::function & areafilter = AREA_NO_FILTER) const; rmg::Path searchPath(const int3 & src, bool onlyStraight, const std::function & areafilter = AREA_NO_FILTER) const; rmg::Path searchPath(const rmg::Area & src, bool onlyStraight, const rmg::Area & searchArea) const; TModificators getModificators(); template T* getModificator() { for(auto & m : modificators) if(auto * mm = dynamic_cast(m.get())) return mm; return nullptr; } template void addModificator() { modificators.emplace_back(new T(*this, map, generator)); } void initModificators(); vstd::RNG & getRand(); public: mutable boost::recursive_mutex areaMutex; using Lock = boost::unique_lock; protected: CMapGenerator & generator; std::unique_ptr rand; RmgMap & map; TModificators modificators; bool finished; //placement info int3 pos; float3 center; rmg::Area dArea; //irregular area assigned to zone rmg::Area dAreaPossible; rmg::Area dAreaFree; //core paths of free tiles that all other objects will be linked to rmg::Area dAreaUsed; std::vector possibleQuestArtifactPos; //template info FactionID townType; TerrainId terrainType; }; VCMI_LIB_NAMESPACE_END