CObjectClassesHandler.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #pragma once
  2. #include "GameConstants.h"
  3. #include "../lib/ConstTransitivePtr.h"
  4. #include "IHandlerBase.h"
  5. /*
  6. * CObjectClassesHandler.h, part of VCMI engine
  7. *
  8. * Authors: listed in file AUTHORS in main folder
  9. *
  10. * License: GNU General Public License v2.0 or later
  11. * Full text of license available in license.txt file, in main folder
  12. *
  13. */
  14. class CBinaryReader;
  15. class CLegacyConfigParser;
  16. class JsonNode;
  17. class CRandomGenerator;
  18. class DLL_LINKAGE ObjectTemplate
  19. {
  20. enum EBlockMapBits
  21. {
  22. VISIBLE = 1,
  23. VISITABLE = 2,
  24. BLOCKED = 4
  25. };
  26. /// tiles that are covered by this object, uses EBlockMapBits enum as flags
  27. std::vector<std::vector<ui8>> usedTiles;
  28. /// directions from which object can be entered, format same as for moveDir in CGHeroInstance(but 0 - 7)
  29. ui8 visitDir;
  30. /// list of terrains on which this object can be placed
  31. std::set<ETerrainType> allowedTerrains;
  32. public:
  33. /// H3 ID/subID of this object
  34. Obj id;
  35. si32 subid;
  36. /// print priority, objects with higher priority will be print first, below everything else
  37. si32 printPriority;
  38. /// animation file that should be used to display object
  39. std::string animationFile;
  40. /// string ID, equals to def base name for h3m files (lower case, no extension) or specified in mod data
  41. std::string stringID;
  42. ui32 getWidth() const;
  43. ui32 getHeight() const;
  44. void setSize(ui32 width, ui32 height);
  45. bool isVisitable() const;
  46. // Checks object used tiles
  47. // Position is relative to bottom-right corner of the object, can not be negative
  48. bool isWithin(si32 X, si32 Y) const;
  49. bool isVisitableAt(si32 X, si32 Y) const;
  50. bool isVisibleAt(si32 X, si32 Y) const;
  51. bool isBlockedAt(si32 X, si32 Y) const;
  52. // Checks if object is visitable from certain direction. X and Y must be between -1..+1
  53. bool isVisitableFrom(si8 X, si8 Y) const;
  54. // Checks if object can be placed on specific terrain
  55. bool canBePlacedAt(ETerrainType terrain) const;
  56. ObjectTemplate();
  57. void readTxt(CLegacyConfigParser & parser);
  58. void readMsk();
  59. void readMap(CBinaryReader & reader);
  60. void readJson(const JsonNode & node);
  61. template <typename Handler> void serialize(Handler &h, const int version)
  62. {
  63. h & usedTiles & allowedTerrains & animationFile & stringID;
  64. h & id & subid & printPriority & visitDir;
  65. }
  66. };
  67. class IObjectInfo
  68. {
  69. public:
  70. virtual bool givesResources() const = 0;
  71. virtual bool givesExperience() const = 0;
  72. virtual bool givesMana() const = 0;
  73. virtual bool givesMovement() const = 0;
  74. virtual bool givesPrimarySkills() const = 0;
  75. virtual bool givesSecondarySkills() const = 0;
  76. virtual bool givesArtifacts() const = 0;
  77. virtual bool givesCreatures() const = 0;
  78. virtual bool givesSpells() const = 0;
  79. virtual bool givesBonuses() const = 0;
  80. };
  81. class CGObjectInstance;
  82. class AObjectTypeHandler
  83. {
  84. si32 type;
  85. si32 subtype;
  86. JsonNode base; /// describes base template
  87. std::vector<ObjectTemplate> templates;
  88. protected:
  89. virtual bool objectFilter(const CGObjectInstance *, const ObjectTemplate &) const;
  90. public:
  91. void setType(si32 type, si32 subtype);
  92. /// loads templates from Json structure using fields "base" and "templates"
  93. virtual void init(const JsonNode & input);
  94. void addTemplate(const ObjectTemplate & templ);
  95. /// returns all templates, without any filters
  96. std::vector<ObjectTemplate> getTemplates() const;
  97. /// returns all templates that can be placed on specific terrain type
  98. std::vector<ObjectTemplate> getTemplates(si32 terrainType) const;
  99. /// returns preferred template for this object, if present (e.g. one of 3 possible templates for town - village, fort and castle)
  100. /// note that appearance will not be changed - this must be done separately (either by assignment or via pack from server)
  101. boost::optional<ObjectTemplate> getOverride(si32 terrainType, const CGObjectInstance * object) const;
  102. /// Creates object and set up core properties (like ID/subID). Object is NOT initialized
  103. /// to allow creating objects before game start (e.g. map loading)
  104. virtual CGObjectInstance * create(ObjectTemplate tmpl) const = 0;
  105. /// Configures object properties. Should be re-entrable, resetting state of the object if necessarily
  106. virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const = 0;
  107. /// Returns object configuration, if available. Othervice returns NULL
  108. virtual const IObjectInfo * getObjectInfo(ObjectTemplate tmpl) const = 0;
  109. template <typename Handler> void serialize(Handler &h, const int version)
  110. {
  111. h & type & subtype & templates;
  112. }
  113. };
  114. /// Class that is used for objects that do not have dedicated handler
  115. template<class ObjectType>
  116. class CDefaultObjectTypeHandler : public AObjectTypeHandler
  117. {
  118. CGObjectInstance * create(ObjectTemplate tmpl) const
  119. {
  120. auto obj = new ObjectType();
  121. obj->ID = tmpl.id;
  122. obj->subID = tmpl.subid;
  123. obj->appearance = tmpl;
  124. return obj;
  125. }
  126. virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
  127. {
  128. }
  129. virtual const IObjectInfo * getObjectInfo(ObjectTemplate tmpl) const
  130. {
  131. return nullptr;
  132. }
  133. };
  134. typedef std::shared_ptr<AObjectTypeHandler> TObjectTypeHandler;
  135. class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
  136. {
  137. /// Small internal structure that contains information on specific group of objects
  138. /// (creating separate entity is overcomplicating at least at this point)
  139. struct ObjectContainter
  140. {
  141. si32 id;
  142. std::string name; // human-readable name
  143. std::string handlerName; // ID of handler that controls this object, shoul be determined using hadlerConstructor map
  144. JsonNode base;
  145. std::map<si32, TObjectTypeHandler> objects;
  146. template <typename Handler> void serialize(Handler &h, const int version)
  147. {
  148. h & base & objects;
  149. }
  150. };
  151. typedef std::multimap<std::pair<si32, si32>, ObjectTemplate> TTemplatesContainer;
  152. /// list of object handlers, each of them handles only one type
  153. std::map<si32, ObjectContainter * > objects;
  154. /// map that is filled during contruction with all known handlers. Not serializeable
  155. std::map<std::string, std::function<TObjectTypeHandler()> > handlerConstructors;
  156. /// container with H3 templates, used only during loading
  157. TTemplatesContainer legacyTemplates;
  158. void loadObjectEntry(const JsonNode & entry, ObjectContainter * obj);
  159. ObjectContainter * loadFromJson(const JsonNode & json);
  160. public:
  161. CObjectClassesHandler();
  162. virtual std::vector<JsonNode> loadLegacyData(size_t dataSize);
  163. virtual void loadObject(std::string scope, std::string name, const JsonNode & data);
  164. virtual void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index);
  165. void createObject(std::string name, JsonNode config, si32 ID, boost::optional<si32> subID = boost::optional<si32>());
  166. virtual void afterLoadFinalization();
  167. virtual std::vector<bool> getDefaultAllowed() const;
  168. /// returns handler for specified object (ID-based). ObjectHandler keeps ownership
  169. TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const;
  170. std::string getObjectName(si32 type) const;
  171. template <typename Handler> void serialize(Handler &h, const int version)
  172. {
  173. h & objects;
  174. }
  175. };