CGTownInstance.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * CGTownInstance.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include "CObjectHandler.h"
  12. #include "CGMarket.h" // For IMarket interface
  13. #include "CArmedInstance.h"
  14. #include "../CTownHandler.h" // For CTown
  15. class CCastleEvent;
  16. class CGTownInstance;
  17. class CGDwelling;
  18. class DLL_LINKAGE CSpecObjInfo
  19. {
  20. public:
  21. CSpecObjInfo();
  22. virtual ~CSpecObjInfo() = default;
  23. virtual void serializeJson(JsonSerializeFormat & handler) = 0;
  24. const CGDwelling * owner;
  25. };
  26. class DLL_LINKAGE CCreGenAsCastleInfo : public virtual CSpecObjInfo
  27. {
  28. public:
  29. CCreGenAsCastleInfo();
  30. bool asCastle;
  31. ui32 identifier;//h3m internal identifier
  32. std::vector<bool> allowedFactions;
  33. std::string instanceId;//vcmi map instance identifier
  34. void serializeJson(JsonSerializeFormat & handler) override;
  35. };
  36. class DLL_LINKAGE CCreGenLeveledInfo : public virtual CSpecObjInfo
  37. {
  38. public:
  39. CCreGenLeveledInfo();
  40. ui8 minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <1, 7>
  41. void serializeJson(JsonSerializeFormat & handler) override;
  42. };
  43. class DLL_LINKAGE CCreGenLeveledCastleInfo : public CCreGenAsCastleInfo, public CCreGenLeveledInfo
  44. {
  45. public:
  46. CCreGenLeveledCastleInfo() = default;
  47. void serializeJson(JsonSerializeFormat & handler) override;
  48. };
  49. class DLL_LINKAGE CGDwelling : public CArmedInstance
  50. {
  51. public:
  52. typedef std::vector<std::pair<ui32, std::vector<CreatureID> > > TCreaturesSet;
  53. CSpecObjInfo * info; //random dwelling options; not serialized
  54. TCreaturesSet creatures; //creatures[level] -> <vector of alternative ids (base creature and upgrades, creatures amount>
  55. CGDwelling();
  56. virtual ~CGDwelling();
  57. void initRandomObjectInfo();
  58. protected:
  59. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  60. private:
  61. void initObj(CRandomGenerator & rand) override;
  62. void onHeroVisit(const CGHeroInstance * h) const override;
  63. void newTurn(CRandomGenerator & rand) const override;
  64. void setPropertyDer(ui8 what, ui32 val) override;
  65. void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
  66. void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
  67. void updateGuards() const;
  68. void heroAcceptsCreatures(const CGHeroInstance *h) const;
  69. public:
  70. template <typename Handler> void serialize(Handler &h, const int version)
  71. {
  72. h & static_cast<CArmedInstance&>(*this);
  73. h & creatures;
  74. }
  75. };
  76. class DLL_LINKAGE CGTownBuilding : public IObjectInterface
  77. {
  78. ///basic class for town structures handled as map objects
  79. public:
  80. si32 indexOnTV; //identifies its index on towns vector
  81. CGTownInstance *town;
  82. CGTownBuilding() : bType(BuildingSubID::NONE), indexOnTV(0), town(nullptr) {};
  83. STRONG_INLINE
  84. BuildingSubID::EBuildingSubID getBuildingSubtype() const
  85. {
  86. return bType;
  87. }
  88. template <typename Handler> void serialize(Handler &h, const int version)
  89. {
  90. h & bID;
  91. h & indexOnTV;
  92. if(version >= 792)
  93. h & bType;
  94. else if(!h.saving)
  95. bType = BuildingSubID::NONE;
  96. }
  97. protected:
  98. BuildingID bID; //from buildig list
  99. BuildingSubID::EBuildingSubID bType;
  100. };
  101. class DLL_LINKAGE COPWBonus : public CGTownBuilding
  102. {///used for OPW bonusing structures
  103. public:
  104. std::set<si32> visitors;
  105. void setProperty(ui8 what, ui32 val) override;
  106. void onHeroVisit (const CGHeroInstance * h) const override;
  107. COPWBonus (BuildingID index, BuildingSubID::EBuildingSubID subId, CGTownInstance *TOWN);
  108. COPWBonus () {};
  109. template <typename Handler> void serialize(Handler &h, const int version)
  110. {
  111. h & static_cast<CGTownBuilding&>(*this);
  112. h & visitors;
  113. }
  114. };
  115. class DLL_LINKAGE CTownBonus : public CGTownBuilding
  116. {
  117. ///used for one-time bonusing structures
  118. ///feel free to merge inheritance tree
  119. public:
  120. std::set<ObjectInstanceID> visitors;
  121. void setProperty(ui8 what, ui32 val) override;
  122. void onHeroVisit (const CGHeroInstance * h) const override;
  123. CTownBonus (BuildingID index, CGTownInstance *TOWN);
  124. CTownBonus () {};
  125. template <typename Handler> void serialize(Handler &h, const int version)
  126. {
  127. h & static_cast<CGTownBuilding&>(*this);
  128. h & visitors;
  129. }
  130. };
  131. class DLL_LINKAGE CTownAndVisitingHero : public CBonusSystemNode
  132. {
  133. public:
  134. CTownAndVisitingHero();
  135. };
  136. struct DLL_LINKAGE GrowthInfo
  137. {
  138. struct Entry
  139. {
  140. int count;
  141. std::string description;
  142. Entry(const std::string &format, int _count);
  143. Entry(int subID, BuildingID building, int _count);
  144. Entry(int _count, const std::string &fullDescription);
  145. };
  146. std::vector<Entry> entries;
  147. int totalGrowth() const;
  148. };
  149. class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public IMarket
  150. {
  151. public:
  152. enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3};
  153. CTownAndVisitingHero townAndVis;
  154. const CTown * town;
  155. std::string name; // name of town
  156. si32 builded; //how many buildings has been built this turn
  157. si32 destroyed; //how many buildings has been destroyed this turn
  158. ConstTransitivePtr<CGHeroInstance> garrisonHero, visitingHero;
  159. ui32 identifier; //special identifier from h3m (only > RoE maps)
  160. si32 alignment;
  161. std::set<BuildingID> forbiddenBuildings, builtBuildings;
  162. std::vector<CGTownBuilding*> bonusingBuildings;
  163. std::vector<SpellID> possibleSpells, obligatorySpells;
  164. std::vector<std::vector<SpellID> > spells; //spells[level] -> vector of spells, first will be available in guild
  165. std::list<CCastleEvent> events;
  166. std::pair<si32, si32> bonusValue;//var to store town bonuses (rampart = resources from mystic pond);
  167. //////////////////////////////////////////////////////////////////////////
  168. static std::vector<const CArtifact *> merchantArtifacts; //vector of artifacts available at Artifact merchant, NULLs possible (for making empty space when artifact is bought)
  169. static std::vector<int> universitySkills;//skills for university of magic
  170. template <typename Handler> void serialize(Handler &h, const int version)
  171. {
  172. h & static_cast<CGDwelling&>(*this);
  173. h & static_cast<IShipyard&>(*this);
  174. h & static_cast<IMarket&>(*this);
  175. h & name;
  176. h & builded;
  177. h & destroyed;
  178. h & identifier;
  179. h & garrisonHero;
  180. h & visitingHero;
  181. h & alignment;
  182. h & forbiddenBuildings;
  183. h & builtBuildings;
  184. h & bonusValue;
  185. h & possibleSpells;
  186. h & obligatorySpells;
  187. h & spells;
  188. h & events;
  189. h & bonusingBuildings;
  190. for (std::vector<CGTownBuilding*>::iterator i = bonusingBuildings.begin(); i!=bonusingBuildings.end(); i++)
  191. (*i)->town = this;
  192. h & town;
  193. h & townAndVis;
  194. BONUS_TREE_DESERIALIZATION_FIX
  195. vstd::erase_if(builtBuildings, [this](BuildingID building) -> bool
  196. {
  197. if(!town->buildings.count(building) || !town->buildings.at(building))
  198. {
  199. logGlobal->error("#1444-like issue in CGTownInstance::serialize. From town %s at %s removing the bogus builtBuildings item %s", name, pos.toString(), building);
  200. return true;
  201. }
  202. return false;
  203. });
  204. }
  205. //////////////////////////////////////////////////////////////////////////
  206. CBonusSystemNode *whatShouldBeAttached() override;
  207. std::string nodeName() const override;
  208. void updateMoraleBonusFromArmy() override;
  209. void deserializationFix();
  210. void recreateBuildingsBonuses();
  211. bool addBonusIfBuilt(BuildingSubID::EBuildingSubID building, Bonus::BonusType type, int val, int subtype = -1);
  212. bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr &prop, int subtype = -1); //returns true if building is built and bonus has been added
  213. bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, int subtype = -1); //convienence version of above
  214. void setVisitingHero(CGHeroInstance *h);
  215. void setGarrisonedHero(CGHeroInstance *h);
  216. const CArmedInstance *getUpperArmy() const; //garrisoned hero if present or the town itself
  217. //////////////////////////////////////////////////////////////////////////
  218. bool passableFor(PlayerColor color) const override;
  219. //int3 getSightCenter() const override; //"center" tile from which the sight distance is calculated
  220. int getSightRadius() const override; //returns sight distance
  221. int getBoatType() const override; //0 - evil (if a ship can be evil...?), 1 - good, 2 - neutral
  222. void getOutOffsets(std::vector<int3> &offsets) const override; //offsets to obj pos when we boat can be placed. Parameter will be cleared
  223. int getMarketEfficiency() const override; //=market count
  224. bool allowsTrade(EMarketMode::EMarketMode mode) const override;
  225. std::vector<int> availableItemsIds(EMarketMode::EMarketMode mode) const override;
  226. void setType(si32 ID, si32 subID) override;
  227. void updateAppearance();
  228. //////////////////////////////////////////////////////////////////////////
  229. bool needsLastStack() const override;
  230. CGTownInstance::EFortLevel fortLevel() const;
  231. int hallLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
  232. int mageGuildLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
  233. int getHordeLevel(const int & HID) const; //HID - 0 or 1; returns creature level or -1 if that horde structure is not present
  234. int creatureGrowth(const int & level) const;
  235. GrowthInfo getGrowthInfo(int level) const;
  236. bool hasFort() const;
  237. bool hasCapitol() const;
  238. const CGTownBuilding * getBonusingBuilding(BuildingSubID::EBuildingSubID subId) const;
  239. //checks if special building with type buildingID is constructed
  240. bool hasBuilt(BuildingSubID::EBuildingSubID buildingID) const;
  241. //checks if building is constructed and town has same subID
  242. bool hasBuilt(BuildingID buildingID) const;
  243. bool hasBuilt(BuildingID buildingID, int townID) const;
  244. TResources getBuildingCost(BuildingID buildingID) const;
  245. TResources dailyIncome() const; //calculates daily income of this town
  246. int spellsAtLevel(int level, bool checkGuild) const; //levels are counted from 1 (1 - 5)
  247. bool armedGarrison() const; //true if town has creatures in garrison or garrisoned hero
  248. int getTownLevel() const;
  249. CBuilding::TRequired genBuildingRequirements(BuildingID build, bool deep = false) const;
  250. void mergeGarrisonOnSiege() const; // merge garrison into army of visiting hero
  251. void removeCapitols (PlayerColor owner) const;
  252. void clearArmy() const;
  253. void addHeroToStructureVisitors(const CGHeroInstance *h, si64 structureInstanceID) const; //hero must be visiting or garrisoned in town
  254. bool townEnvisagesSpecialBuilding(BuildingSubID::EBuildingSubID bid) const;
  255. const CTown * getTown() const ;
  256. CGTownInstance();
  257. virtual ~CGTownInstance();
  258. ///IObjectInterface overrides
  259. void newTurn(CRandomGenerator & rand) const override;
  260. void onHeroVisit(const CGHeroInstance * h) const override;
  261. void onHeroLeave(const CGHeroInstance * h) const override;
  262. void initObj(CRandomGenerator & rand) override;
  263. void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
  264. std::string getObjectName() const override;
  265. void afterAddToMap(CMap * map) override;
  266. static void reset();
  267. protected:
  268. void setPropertyDer(ui8 what, ui32 val) override;
  269. void serializeJsonOptions(JsonSerializeFormat & handler) override;
  270. private:
  271. int getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<ConstTransitivePtr<CGDwelling> >& dwellings) const;
  272. };