CObjectClassesHandler.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. void setType(si32 type, si32 subtype);
  90. virtual bool objectFilter(const CGObjectInstance *, const ObjectTemplate &) const;
  91. public:
  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. template<class ObjectType>
  115. class CDefaultObjectTypeHandler : public AObjectTypeHandler
  116. {
  117. CGObjectInstance * create(ObjectTemplate tmpl) const
  118. {
  119. auto obj = new ObjectType();
  120. obj->ID = tmpl.id;
  121. obj->subID = tmpl.subid;
  122. obj->appearance = tmpl;
  123. return obj;
  124. }
  125. virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
  126. {
  127. }
  128. virtual const IObjectInfo * getObjectInfo(ObjectTemplate tmpl) const
  129. {
  130. return nullptr;
  131. }
  132. };
  133. typedef std::shared_ptr<AObjectTypeHandler> TObjectTypeHandler;
  134. class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
  135. {
  136. /// Small internal structure that contains information on specific group of objects
  137. /// (creating separate entity is overcomplicating at least at this point)
  138. struct ObjectContainter
  139. {
  140. si32 id;
  141. std::string name; // human-readable name
  142. std::string handlerName; // ID of handler that controls this object, shoul be determined using hadlerConstructor map
  143. JsonNode base;
  144. std::map<si32, TObjectTypeHandler> objects;
  145. template <typename Handler> void serialize(Handler &h, const int version)
  146. {
  147. h & base & objects;
  148. }
  149. };
  150. /// list of object handlers, each of them handles only one type
  151. std::map<si32, ObjectContainter * > objects;
  152. /// map that is filled during contruction with all known handlers. Not serializeable
  153. std::map<std::string, std::function<TObjectTypeHandler()> > handlerConstructors;
  154. ObjectContainter * loadFromJson(const JsonNode & json);
  155. public:
  156. CObjectClassesHandler();
  157. virtual std::vector<JsonNode> loadLegacyData(size_t dataSize);
  158. virtual void loadObject(std::string scope, std::string name, const JsonNode & data);
  159. virtual void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index);
  160. virtual void afterLoadFinalization(){};
  161. virtual std::vector<bool> getDefaultAllowed() const;
  162. /// returns handler for specified object (ID-based). ObjectHandler keeps ownership
  163. TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const;
  164. std::string getObjectName(si32 type) const;
  165. template <typename Handler> void serialize(Handler &h, const int version)
  166. {
  167. h & objects;
  168. }
  169. };