BlockType.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. #pragma once
  2. #include <Array.h>
  3. #include <Either.h>
  4. #include <Vec3.h>
  5. #include <Writer.h>
  6. #include <XML.h>
  7. #include "Area.h"
  8. #include "DropConfig.h"
  9. #include "InteractionConfig.h"
  10. #include "ModelInfo.h"
  11. class Item;
  12. class Block;
  13. class Game;
  14. class ItemType;
  15. class BlockTypeEnum
  16. {
  17. public:
  18. static const int NO_BLOCK = 0;
  19. static const int AIR = 1;
  20. };
  21. class BlockType : public virtual Framework::ReferenceCounter
  22. {
  23. private:
  24. int id;
  25. ModelInfo* model;
  26. int initialMaxHP;
  27. bool needsClientInstance;
  28. bool lightSource;
  29. Framework::Text name;
  30. bool needModelSubscription;
  31. int initialMapColor;
  32. Framework::RCArray<Framework::Text> groupNames;
  33. float hardness;
  34. Framework::RCArray<DropConfig> dropConfigs;
  35. bool damagableByHand;
  36. Framework::RCArray<InteractionConfig> interactionConfigs;
  37. const ItemType* itemType;
  38. Direction defaultFrontDirection;
  39. protected:
  40. Block* defaultBlock;
  41. BlockType();
  42. virtual ~BlockType();
  43. virtual void loadSuperBlock(
  44. Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const;
  45. virtual void saveSuperBlock(
  46. Block* zBlock, Framework::StreamWriter* zWriter) const;
  47. virtual void createSuperBlock(Block* zBlock, Item* zItem) const;
  48. virtual void createSuperItem(Block* zBlock, Item* zItem) const;
  49. virtual Block* createBlock(
  50. Framework::Vec3<int> position, int dimensionId) const
  51. = 0;
  52. virtual Item* createItem() const = 0;
  53. virtual ItemType* createItemTypeInternal() const = 0;
  54. public:
  55. virtual bool initialize(Game* zGame);
  56. virtual BlockType* initializeDefault();
  57. void addDropConfig(DropConfig* config);
  58. const Framework::RCArray<DropConfig>& getDropConfigs() const;
  59. const Block* zDefault() const;
  60. ItemType* createItemType();
  61. virtual int getItemTypeId() const;
  62. void writeTypeInfo(Framework::StreamWriter* zWriter) const;
  63. virtual Framework::XML::Element* getTargetUIML() const;
  64. virtual Block* loadBlock(Framework::Vec3<int> position,
  65. Framework::StreamReader* zReader,
  66. int dimensionId) const;
  67. virtual void saveBlock(
  68. Block* zBlock, Framework::StreamWriter* zWriter) const;
  69. virtual Item* getItemFromBlock(Block* zBlock) const;
  70. virtual Block* createBlockAt(
  71. Framework::Vec3<int> position, int dimensionId, Item* zUsedItem) const;
  72. int getId() const;
  73. virtual bool isFluid() const;
  74. virtual unsigned char getFlowDistance() const;
  75. void setTypeId(int id);
  76. void setModel(ModelInfo* model);
  77. ModelInfo* zModel() const;
  78. void setInitialMaxHP(int initialMaxHP);
  79. int getInitialMaxHP() const;
  80. void setNeedsClientInstance(bool needsClientInstance);
  81. bool doesNeedClientInstance() const;
  82. void setLightSource(bool lightSource);
  83. bool isLightSource() const;
  84. void setName(Framework::Text name);
  85. const char* getName() const;
  86. void setNeedModelSubscription(bool needModelSubscription);
  87. const bool doesNeedModelSubscription() const;
  88. void setMapColor(int mapColor);
  89. int getMapColor() const;
  90. void setGroupNames(Framework::RCArray<Framework::Text> groupNames);
  91. const Framework::RCArray<Framework::Text>& getGroupNames() const;
  92. void setHardness(float hardness);
  93. float getHardness() const;
  94. void setDamagableByHand(bool damagableByHand);
  95. bool isDamagableByHand() const;
  96. void addInteractionConfig(InteractionConfig* config);
  97. const Framework::RCArray<InteractionConfig>& getInteractionConfigs() const;
  98. void setDefaultFrontDirection(Direction defaultFrontDirection);
  99. Direction getDefaultFrontDirection() const;
  100. static int getTypeId(const char* name);
  101. static Framework::Text getTypeName(int id);
  102. };
  103. const Block* getDefaultBlock(Framework::Either<Block*, int> b);
  104. template<typename S> class BlockTypeFactoryBase
  105. : public SubTypeFactory<BlockType, S>
  106. {
  107. public:
  108. BlockTypeFactoryBase()
  109. : SubTypeFactory<BlockType, S>()
  110. {}
  111. virtual S* fromJson(Framework::JSON::JSONObject* zJson) const override
  112. {
  113. S* result = createValue(zJson);
  114. BlockType* zType = dynamic_cast<BlockType*>(result);
  115. zType->setModel(Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
  116. zJson->zValue("model")->asObject()));
  117. zType->setInitialMaxHP(
  118. (int)zJson->zValue("maxHp")->asNumber()->getNumber());
  119. zType->setNeedsClientInstance(
  120. zJson->zValue("needsClientInstance")->asBool()->getBool());
  121. zType->setLightSource(
  122. zJson->zValue("lightSource")->asBool()->getBool());
  123. zType->setName(zJson->zValue("name")->asString()->getString());
  124. zType->setNeedModelSubscription(
  125. zJson->zValue("needModelSubscription")->asBool()->getBool());
  126. zType->setMapColor(
  127. (int)zJson->zValue("mapColor")->asString()->getString());
  128. Framework::RCArray<Framework::Text> groupNames;
  129. for (Framework::JSON::JSONValue* value :
  130. *zJson->zValue("groupNames")->asArray())
  131. {
  132. groupNames.add(new Framework::Text(value->asString()->getString()));
  133. }
  134. zType->setGroupNames(groupNames);
  135. zType->setHardness(
  136. (float)zJson->zValue("hardness")->asNumber()->getNumber());
  137. for (Framework::JSON::JSONValue* value :
  138. *zJson->zValue("drops")->asArray())
  139. {
  140. zType->addDropConfig(
  141. Game::INSTANCE->zTypeRegistry()->fromJson<DropConfig>(value));
  142. }
  143. zType->setDamagableByHand(
  144. zJson->zValue("damagableByHand")->asBool()->getBool());
  145. for (Framework::JSON::JSONValue* value :
  146. *zJson->zValue("interactions")->asArray())
  147. {
  148. zType->addInteractionConfig(
  149. Game::INSTANCE->zTypeRegistry()->fromJson<InteractionConfig>(
  150. value));
  151. }
  152. Framework::Text frontDirection
  153. = zJson->zValue("defaultFrontDirection")->asString()->getString();
  154. if (frontDirection.isEqual("NORTH"))
  155. {
  156. zType->setDefaultFrontDirection(Direction::NORTH);
  157. }
  158. else if (frontDirection.isEqual("EAST"))
  159. {
  160. zType->setDefaultFrontDirection(Direction::EAST);
  161. }
  162. else if (frontDirection.isEqual("SOUTH"))
  163. {
  164. zType->setDefaultFrontDirection(Direction::SOUTH);
  165. }
  166. else if (frontDirection.isEqual("WEST"))
  167. {
  168. zType->setDefaultFrontDirection(Direction::WEST);
  169. }
  170. else if (frontDirection.isEqual("TOP"))
  171. {
  172. zType->setDefaultFrontDirection(Direction::TOP);
  173. }
  174. else if (frontDirection.isEqual("BOTTOM"))
  175. {
  176. zType->setDefaultFrontDirection(Direction::BOTTOM);
  177. }
  178. return result;
  179. }
  180. virtual Framework::JSON::JSONObject* toJsonObject(S* zObject) const override
  181. {
  182. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  183. BlockType* zType = dynamic_cast<BlockType*>(zObject);
  184. result->addValue("model",
  185. Game::INSTANCE->zTypeRegistry()->toJson<ModelInfo>(
  186. zType->zModel()));
  187. result->addValue("maxHp",
  188. new Framework::JSON::JSONNumber((double)zType->getInitialMaxHP()));
  189. result->addValue("needsClientInstance",
  190. new Framework::JSON::JSONBool(zType->doesNeedClientInstance()));
  191. result->addValue("lightSource",
  192. new Framework::JSON::JSONBool(zType->isLightSource()));
  193. result->addValue(
  194. "name", new Framework::JSON::JSONString(zType->getName()));
  195. result->addValue("needModelSubscription",
  196. new Framework::JSON::JSONBool(zType->doesNeedModelSubscription()));
  197. result->addValue("mapColor",
  198. new Framework::JSON::JSONString(
  199. Framework::Text(zType->getMapColor())));
  200. Framework::JSON::JSONArray* groupNames
  201. = new Framework::JSON::JSONArray();
  202. for (Framework::Text* groupName : zType->getGroupNames())
  203. {
  204. groupNames->addValue(new Framework::JSON::JSONString(*groupName));
  205. }
  206. result->addValue("groupNames", groupNames);
  207. Framework::JSON::JSONArray* drops = new Framework::JSON::JSONArray();
  208. for (DropConfig* drop : zType->getDropConfigs())
  209. {
  210. drops->addValue(
  211. Game::INSTANCE->zTypeRegistry()->toJson<DropConfig>(drop));
  212. }
  213. result->addValue("drops", drops);
  214. result->addValue(
  215. "hardness", new Framework::JSON::JSONNumber(zType->getHardness()));
  216. result->addValue("damagableByHand",
  217. new Framework::JSON::JSONBool(zType->isDamagableByHand()));
  218. Framework::JSON::JSONArray* interactions
  219. = new Framework::JSON::JSONArray();
  220. for (InteractionConfig* interaction : zType->getInteractionConfigs())
  221. {
  222. interactions->addValue(
  223. Game::INSTANCE->zTypeRegistry()->toJson<InteractionConfig>(
  224. interaction));
  225. }
  226. result->addValue("interactions", interactions);
  227. switch (zType->getDefaultFrontDirection())
  228. {
  229. case Direction::NORTH:
  230. result->addValue("defaultFrontDirection",
  231. new Framework::JSON::JSONString("NORTH"));
  232. break;
  233. case Direction::EAST:
  234. result->addValue("defaultFrontDirection",
  235. new Framework::JSON::JSONString("EAST"));
  236. break;
  237. case Direction::SOUTH:
  238. result->addValue("defaultFrontDirection",
  239. new Framework::JSON::JSONString("SOUTH"));
  240. break;
  241. case Direction::WEST:
  242. result->addValue("defaultFrontDirection",
  243. new Framework::JSON::JSONString("WEST"));
  244. break;
  245. case Direction::TOP:
  246. result->addValue("defaultFrontDirection",
  247. new Framework::JSON::JSONString("TOP"));
  248. break;
  249. case Direction::BOTTOM:
  250. result->addValue("defaultFrontDirection",
  251. new Framework::JSON::JSONString("BOTTOM"));
  252. break;
  253. }
  254. return result;
  255. }
  256. virtual JSONObjectValidationBuilder* addToValidator(
  257. JSONObjectValidationBuilder* builder) const override
  258. {
  259. Framework::JSON::JSONArray* defaultDrops
  260. = new Framework::JSON::JSONArray();
  261. Framework::JSON::JSONObject* defaultBlockItemDrop
  262. = new Framework::JSON::JSONObject();
  263. defaultBlockItemDrop->addValue(
  264. "type", new Framework::JSON::JSONString("blockItem"));
  265. Framework::JSON::JSONObject* defaultDropCondition
  266. = new Framework::JSON::JSONObject();
  267. defaultDropCondition->addValue(
  268. "type", new Framework::JSON::JSONString("allways"));
  269. defaultBlockItemDrop->addValue("condition", defaultDropCondition);
  270. defaultDrops->addValue(defaultBlockItemDrop);
  271. return builder
  272. ->withRequiredAttribute("model",
  273. Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
  274. ->withRequiredNumber("maxHp")
  275. ->withDefault(100.0)
  276. ->finishNumber()
  277. ->withRequiredBool("needsClientInstance")
  278. ->withDefault(true)
  279. ->finishBool()
  280. ->withRequiredBool("lightSource")
  281. ->withDefault(false)
  282. ->finishBool()
  283. ->withRequiredString("name")
  284. ->finishString()
  285. ->withRequiredBool("needModelSubscription")
  286. ->withDefault(true)
  287. ->finishBool()
  288. ->withRequiredString("mapColor")
  289. ->finishString()
  290. ->withRequiredArray("groupNames")
  291. ->withDefault(new Framework::JSON::JSONArray())
  292. ->addAcceptedStringInArray()
  293. ->finishString()
  294. ->finishArray()
  295. ->withRequiredNumber("hardness")
  296. ->withDefault(1.0)
  297. ->finishNumber()
  298. ->withRequiredAttribute("drops",
  299. Framework::Validator::DataValidator::buildForArray()
  300. ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
  301. ->getValidator<DropConfig>())
  302. ->withDefault(defaultDrops)
  303. ->finishArray())
  304. ->withRequiredBool("damagableByHand")
  305. ->withDefault(false)
  306. ->finishBool()
  307. ->withRequiredArray("interactions")
  308. ->withDefault(new Framework::JSON::JSONArray())
  309. ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
  310. ->getValidator<InteractionConfig>())
  311. ->finishArray()
  312. ->withRequiredString("defaultFrontDirection")
  313. ->whichIsOneOf({"NORTH", "EAST", "SOUTH", "WEST", "TOP", "BOTTOM"})
  314. ->withDefault("NORTH")
  315. ->finishString();
  316. }
  317. protected:
  318. virtual S* createValue(Framework::JSON::JSONObject* zJson) const = 0;
  319. };