RecipieLoader.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. #include "RecipieLoader.h"
  2. #include <Datei.h>
  3. #include <iostream>
  4. #include <stdexcept>
  5. #include "Game.h"
  6. #include "ItemType.h"
  7. using namespace Framework::JSON;
  8. using namespace Validator;
  9. RecipieLoader::RecipieLoader()
  10. : Framework::ReferenceCounter(),
  11. validator(0)
  12. {}
  13. RecipieLoader::~RecipieLoader()
  14. {
  15. if (validator) validator->release();
  16. }
  17. void RecipieLoader::loadRecipies(const char* path)
  18. {
  19. std::cout << "loading recipies from '" << path << "'" << std::endl;
  20. Framework::Datei d;
  21. d.setDatei(path);
  22. if (d.istOrdner())
  23. {
  24. Framework::RCArray<Framework::Text>* files = d.getDateiListe();
  25. for (Framework::Text* f : *files)
  26. loadRecipies(Framework::Text(path) + "/" + *f);
  27. files->release();
  28. }
  29. else
  30. {
  31. JSONValue* json = loadJSONFromFile(path);
  32. JSONValidator* validator = zRecipieValidator();
  33. Framework::RCArray<JSONValidationResult> invalidParts;
  34. JSONValue* valid = validator->getValidParts(json, &invalidParts);
  35. for (JSONValidationResult* invalidPart : invalidParts)
  36. {
  37. invalidPart->printInvalidInfo();
  38. }
  39. json->release();
  40. int count = 0;
  41. if (valid)
  42. {
  43. for (JSONValue* recipie : *valid->asArray())
  44. loadRecipie(recipie->asObject());
  45. count = valid->asArray()->getLength();
  46. valid->release();
  47. }
  48. std::cout << count << " recipies were loaded.\n";
  49. }
  50. }
  51. void RecipieLoader::loadRecipie(JSONObject* zRecipie)
  52. {
  53. Framework::Text group = zRecipie->zValue("group")->asString()->getString();
  54. if (zRecipie->zValue("type")->asString()->getString().istGleich("shaped"))
  55. {
  56. int width = (int)zRecipie->zValue("width")->asNumber()->getNumber();
  57. int height = (int)zRecipie->zValue("height")->asNumber()->getNumber();
  58. ShapedRecipie* recipie = new ShapedRecipie(width, height);
  59. for (JSONValue* input : *zRecipie->zValue("inputs")->asArray())
  60. {
  61. int x
  62. = (int)input->asObject()->zValue("x")->asNumber()->getNumber();
  63. int y
  64. = (int)input->asObject()->zValue("y")->asNumber()->getNumber();
  65. ItemFilter* filter
  66. = loadFilter(input->asObject()->zValue("filter")->asObject());
  67. CombinedItemModifier* resultingModifier
  68. = new CombinedItemModifier();
  69. for (JSONValue* modifier :
  70. *input->asObject()->zValue("modifiers")->asArray())
  71. resultingModifier->addModifier(
  72. loadModifier(modifier->asObject()));
  73. recipie->setIngredient(x, y, filter, resultingModifier);
  74. }
  75. int outputCount = (int)zRecipie->asObject()
  76. ->zValue("outputCount")
  77. ->asNumber()
  78. ->getNumber();
  79. Framework::Text outputType = zRecipie->asObject()
  80. ->zValue("output")
  81. ->asObject()
  82. ->zValue("itemType")
  83. ->asString()
  84. ->getString();
  85. Item* item = 0;
  86. for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++)
  87. {
  88. if (Game::INSTANCE->zItemType(i)
  89. && Game::INSTANCE->zItemType(i)->getName().istGleich(
  90. outputType))
  91. {
  92. item = Game::INSTANCE->zItemType(i)->createItem();
  93. break;
  94. }
  95. }
  96. recipie->addOutput(item, outputCount);
  97. if (!zRecipieList(group)) registerRecipieList(group);
  98. zRecipieList(group)->addRecipie(recipie);
  99. }
  100. else if (zRecipie->zValue("type")->asString()->getString().istGleich(
  101. "unordered"))
  102. {
  103. UnshapedRecipie* recipie = new UnshapedRecipie();
  104. for (JSONValue* input : *zRecipie->zValue("inputs")->asArray())
  105. {
  106. int count = (int)input->asObject()
  107. ->zValue("count")
  108. ->asNumber()
  109. ->getNumber();
  110. ItemFilter* filter
  111. = loadFilter(input->asObject()->zValue("filter")->asObject());
  112. CombinedItemModifier* resultingModifier
  113. = new CombinedItemModifier();
  114. for (JSONValue* modifier :
  115. *input->asObject()->zValue("modifiers")->asArray())
  116. resultingModifier->addModifier(
  117. loadModifier(modifier->asObject()));
  118. recipie->addIngredient(filter, count, resultingModifier);
  119. }
  120. for (JSONValue* output : *zRecipie->zValue("outputs")->asArray())
  121. {
  122. int count = (int)output->asObject()
  123. ->zValue("count")
  124. ->asNumber()
  125. ->getNumber();
  126. Framework::Text outputType = output->asObject()
  127. ->zValue("item")
  128. ->asObject()
  129. ->zValue("itemType")
  130. ->asString()
  131. ->getString();
  132. Item* item = 0;
  133. for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++)
  134. {
  135. if (Game::INSTANCE->zItemType(i)
  136. && Game::INSTANCE->zItemType(i)->getName().istGleich(
  137. outputType))
  138. {
  139. item = Game::INSTANCE->zItemType(i)->createItem();
  140. break;
  141. }
  142. }
  143. recipie->addOutput(item, count);
  144. }
  145. if (!zRecipieList(group)) registerRecipieList(group);
  146. zRecipieList(group)->addRecipie(recipie);
  147. }
  148. }
  149. ItemFilter* RecipieLoader::loadFilter(JSONObject* zFilter)
  150. {
  151. if (zFilter->hasValue("itemType"))
  152. {
  153. Framework::Text type
  154. = zFilter->zValue("itemType")->asString()->getString();
  155. return new TypeItemFilter(
  156. Game::INSTANCE->zItemType(ItemType::getTypeId(type)));
  157. }
  158. else if (zFilter->hasValue("operator"))
  159. {
  160. Framework::Text op
  161. = zFilter->zValue("operator")->asString()->getString();
  162. ItemFilter* left = loadFilter(zFilter->zValue("left")->asObject());
  163. ItemFilter* right = loadFilter(zFilter->zValue("right")->asObject());
  164. if (op.istGleich("&&"))
  165. {
  166. return new CombinedItemFilter(
  167. left, right, [](bool a, bool b) { return a && b; });
  168. }
  169. else if (op.istGleich("||"))
  170. {
  171. return new CombinedItemFilter(
  172. left, right, [](bool a, bool b) { return a || b; });
  173. }
  174. else if (op.istGleich("=="))
  175. {
  176. return new CombinedItemFilter(
  177. left, right, [](bool a, bool b) { return a == b; });
  178. }
  179. else if (op.istGleich("!="))
  180. {
  181. return new CombinedItemFilter(
  182. left, right, [](bool a, bool b) { return a != b; });
  183. }
  184. else
  185. {
  186. left->release();
  187. right->release();
  188. }
  189. }
  190. return 0;
  191. }
  192. RecipieList* RecipieLoader::zRecipieList(const char* name) const
  193. {
  194. for (RecipieList* l : lists)
  195. {
  196. if (l->getName().istGleich(name)) return l;
  197. }
  198. return 0;
  199. }
  200. void RecipieLoader::registerRecipieList(const char* name)
  201. {
  202. if (zRecipieList(name))
  203. throw new std::invalid_argument("the recipie list already exists");
  204. lists.add(new RecipieList(name));
  205. }
  206. Framework::Text RecipieLoader::getCrafingUIML(const ItemType* zTargetType)
  207. {
  208. Framework::Text result = "<dialog id=\"crafting_";
  209. result.append() << zTargetType->getId() << "\"><craftingRecipies>";
  210. for (RecipieList* list : lists)
  211. {
  212. Framework::RCArray<Recipie> recipies;
  213. list->findRecipies(zTargetType, recipies);
  214. if (recipies.getEintragAnzahl() > 0)
  215. {
  216. result.append()
  217. << "<craftingRecipieGroup name=\"" << list->getName();
  218. if (list->getName().istGleich("inventory"))
  219. {
  220. result.append()
  221. << "\" itemIcon=\""
  222. << Game::INSTANCE->getItemTypeId("Crafting Table");
  223. }
  224. result += "\">";
  225. for (Recipie* recipie : recipies)
  226. {
  227. result += recipie->getRecipieUIML();
  228. }
  229. result += "</craftingRecipieGroup>";
  230. }
  231. }
  232. result += "</craftingRecipies></dialog>";
  233. return result;
  234. }
  235. ItemModifier* RecipieLoader::loadModifier(
  236. Framework::JSON::JSONObject* zModifier)
  237. {
  238. return new AttributeItemModifier(
  239. zModifier->zValue("attribute")->asString()->getString(),
  240. zModifier->zValue("value")->asString()->getString());
  241. }
  242. JSONValidator* RecipieLoader::zRecipieValidator()
  243. {
  244. if (validator) return validator;
  245. Framework::RCArray<Framework::Text> itemTypes;
  246. for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++)
  247. {
  248. if (Game::INSTANCE->zItemType(i))
  249. {
  250. itemTypes.add(new Framework::Text(
  251. Game::INSTANCE->zItemType(i)->getName().getText()));
  252. }
  253. }
  254. JSONValidator* typeFilterValidator
  255. = JSONValidator::buildForObject()
  256. ->setObjectReferenceId("typeFilter")
  257. ->withRequiredString("itemType")
  258. ->whichIsOneOf(itemTypes)
  259. ->finishString()
  260. ->finishObject();
  261. Framework::RCArray<Framework::Text> operators;
  262. operators.add(new Framework::Text("=="));
  263. operators.add(new Framework::Text("!="));
  264. operators.add(new Framework::Text("&&"));
  265. operators.add(new Framework::Text("||"));
  266. JSONValidator* operatorFilterValidator
  267. = JSONValidator::buildForObject()
  268. ->setObjectReferenceId("operatorFilter")
  269. ->withRequiredString("operator")
  270. ->whichIsOneOf(operators)
  271. ->finishString()
  272. ->withRequiredAttribute(
  273. "left", JSONValidator::buildForObjectReference("typeFilter"))
  274. ->withRequiredAttribute("left",
  275. JSONValidator::buildForObjectReference("operatorFilter"))
  276. ->withRequiredAttribute(
  277. "right", JSONValidator::buildForObjectReference("typeFilter"))
  278. ->withRequiredAttribute("right",
  279. JSONValidator::buildForObjectReference("operatorFilter"))
  280. ->finishObject();
  281. JSONValidator* outputValidator = JSONValidator::buildForObject()
  282. ->withRequiredString("itemType")
  283. ->whichIsOneOf(itemTypes)
  284. ->finishString()
  285. ->finishObject();
  286. validator
  287. = JSONValidator::buildForArray()
  288. ->typeSpecifiedByAttribute("type")
  289. ->removeInvalidEntries()
  290. ->addAcceptedTypeInArray(
  291. JSONValidator::buildForObject()
  292. ->withRequiredString("type")
  293. ->withExactMatch("shaped")
  294. ->finishString()
  295. ->withRequiredString("group")
  296. ->finishString()
  297. ->withRequiredNumber("width")
  298. ->whichIsGreaterThen(0)
  299. ->finishNumber()
  300. ->withRequiredNumber("height")
  301. ->whichIsGreaterThen(0)
  302. ->finishNumber()
  303. ->withRequiredAttribute("inputs",
  304. JSONValidator::buildForArray()
  305. ->withDefault(new JSONArray())
  306. ->addAcceptedTypeInArray(
  307. JSONValidator::buildForObject()
  308. ->withRequiredNumber("x")
  309. ->whichIsGreaterOrEqual(0)
  310. ->finishNumber()
  311. ->withRequiredNumber("y")
  312. ->whichIsGreaterOrEqual(0)
  313. ->finishNumber()
  314. ->withRequiredAttribute("filter",
  315. dynamic_cast<JSONValidator*>(
  316. typeFilterValidator->getThis()))
  317. ->withRequiredAttribute("filter",
  318. dynamic_cast<JSONValidator*>(
  319. operatorFilterValidator
  320. ->getThis()))
  321. ->withRequiredAttribute("modifiers",
  322. JSONValidator::buildForArray()
  323. ->withDefault(Parser::getValue(
  324. "[{\"attribute\": \"hp\", "
  325. "\"value\": \"=0\"}]")
  326. ->asArray())
  327. ->addAcceptedTypeInArray(
  328. JSONValidator::
  329. buildForObject()
  330. ->withRequiredString(
  331. "attribute")
  332. ->finishString()
  333. ->withRequiredString(
  334. "value")
  335. ->finishString()
  336. ->finishObject())
  337. ->finishArray())
  338. ->finishObject())
  339. ->finishArray())
  340. ->withRequiredAttribute("output",
  341. dynamic_cast<JSONValidator*>(
  342. outputValidator->getThis()))
  343. ->withRequiredNumber("outputCount")
  344. ->withDefault(1)
  345. ->whichIsGreaterThen(0)
  346. ->finishNumber()
  347. ->finishObject())
  348. ->addAcceptedTypeInArray(
  349. JSONValidator::buildForObject()
  350. ->withRequiredString("type")
  351. ->withExactMatch("unordered")
  352. ->finishString()
  353. ->withRequiredString("group")
  354. ->finishString()
  355. ->withRequiredAttribute("inputs",
  356. JSONValidator::buildForArray()
  357. ->withDefault(new JSONArray())
  358. ->addAcceptedTypeInArray(
  359. JSONValidator::buildForObject()
  360. ->withRequiredNumber("count")
  361. ->withDefault(1)
  362. ->whichIsGreaterThen(0)
  363. ->finishNumber()
  364. ->withRequiredAttribute("filter",
  365. dynamic_cast<JSONValidator*>(
  366. typeFilterValidator->getThis()))
  367. ->withRequiredAttribute("filter",
  368. dynamic_cast<JSONValidator*>(
  369. operatorFilterValidator
  370. ->getThis()))
  371. ->withRequiredAttribute("modifiers",
  372. JSONValidator::buildForArray()
  373. ->withDefault(Parser::getValue(
  374. "[{\"attribute\": \"hp\", "
  375. "\"value\": \"=0\"}]")
  376. ->asArray())
  377. ->addAcceptedTypeInArray(
  378. JSONValidator::
  379. buildForObject()
  380. ->withRequiredString(
  381. "attribute")
  382. ->finishString()
  383. ->withRequiredString(
  384. "value")
  385. ->finishString()
  386. ->finishObject())
  387. ->finishArray())
  388. ->finishObject())
  389. ->finishArray())
  390. ->withRequiredAttribute("output",
  391. JSONValidator::buildForArray()
  392. ->addAcceptedTypeInArray(
  393. JSONValidator::buildForObject()
  394. ->withRequiredAttribute("item",
  395. dynamic_cast<JSONValidator*>(
  396. outputValidator->getThis()))
  397. ->withRequiredNumber("count")
  398. ->withDefault(1)
  399. ->whichIsGreaterThen(0)
  400. ->finishNumber()
  401. ->finishObject())
  402. ->finishArray())
  403. ->finishObject())
  404. ->finishArray();
  405. typeFilterValidator->release();
  406. operatorFilterValidator->release();
  407. outputValidator->release();
  408. return validator;
  409. }