Recipie.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. #include "Recipie.h"
  2. #include <Logging.h>
  3. #include "CraftingStorage.h"
  4. #include "Game.h"
  5. #include "Item.h"
  6. RecipieInput::RecipieInput()
  7. : ReferenceCounter(),
  8. filter(0),
  9. modifier(0),
  10. amount(0)
  11. {}
  12. RecipieInput::~RecipieInput()
  13. {
  14. if (filter) filter->release();
  15. if (modifier) modifier->release();
  16. }
  17. void RecipieInput::setFilter(ItemFilter* filter)
  18. {
  19. if (filter) filter->release();
  20. filter = filter;
  21. }
  22. ItemFilter* RecipieInput::zFilter() const
  23. {
  24. return filter;
  25. }
  26. void RecipieInput::setModifier(ItemModifier* modifier)
  27. {
  28. if (modifier) modifier->release();
  29. modifier = modifier;
  30. }
  31. ItemModifier* RecipieInput::zModifier() const
  32. {
  33. return modifier;
  34. }
  35. void RecipieInput::setAmount(int amount)
  36. {
  37. this->amount = amount;
  38. }
  39. int RecipieInput::getAmount() const
  40. {
  41. return amount;
  42. }
  43. RecipieInputFactory::RecipieInputFactory()
  44. : TypeFactory()
  45. {}
  46. RecipieInput* RecipieInputFactory::createValue(
  47. Framework::JSON::JSONObject* zJson) const
  48. {
  49. return new RecipieInput();
  50. }
  51. void RecipieInputFactory::fromJson(
  52. RecipieInput* zResult, Framework::JSON::JSONObject* zJson) const
  53. {
  54. zResult->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<ItemFilter>(
  55. zJson->asObject()->zValue("filter")));
  56. zResult->setModifier(
  57. Game::INSTANCE->zTypeRegistry()->fromJson<ItemModifier>(
  58. zJson->asObject()->zValue("modifier")));
  59. zResult->setAmount(
  60. (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber());
  61. }
  62. void RecipieInputFactory::toJson(
  63. RecipieInput* zObject, Framework::JSON::JSONObject* zResult) const
  64. {
  65. zResult->addValue(
  66. "filter", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
  67. zResult->addValue("modifier",
  68. Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModifier()));
  69. zResult->addValue("amount",
  70. new Framework::JSON::JSONNumber((double)zObject->getAmount()));
  71. }
  72. JSONObjectValidationBuilder* RecipieInputFactory::addToValidator(
  73. JSONObjectValidationBuilder* builder) const
  74. {
  75. Framework::JSON::JSONObject* defaultModifier
  76. = new Framework::JSON::JSONObject();
  77. defaultModifier->addValue(
  78. "type", new Framework::JSON::JSONString("consume"));
  79. return builder
  80. ->withRequiredAttribute("filter",
  81. Game::INSTANCE->zTypeRegistry()->getValidator<ItemFilter>())
  82. ->withRequiredAttribute("modifier",
  83. Game::INSTANCE->zTypeRegistry()->getValidator<ItemModifier>())
  84. ->withRequiredObject("modifier")
  85. ->withRequiredString("type")
  86. ->withExactMatch("consume")
  87. ->finishString()
  88. ->withDefault(defaultModifier)
  89. ->finishObject()
  90. ->withRequiredNumber("amount")
  91. ->whichIsGreaterOrEqual(1.0)
  92. ->withDefault(1.0)
  93. ->finishNumber();
  94. }
  95. RecipieOutput::RecipieOutput()
  96. : ReferenceCounter(),
  97. itemTypeId(0),
  98. amount(0),
  99. modifier(0)
  100. {}
  101. RecipieOutput::~RecipieOutput()
  102. {
  103. modifier->release();
  104. }
  105. void RecipieOutput::setItemTypeId(int itemTypeId)
  106. {
  107. this->itemTypeId = itemTypeId;
  108. }
  109. int RecipieOutput::getItemTypeId() const
  110. {
  111. return itemTypeId;
  112. }
  113. void RecipieOutput::setAmount(int amount)
  114. {
  115. this->amount = amount;
  116. }
  117. int RecipieOutput::getAmount() const
  118. {
  119. return amount;
  120. }
  121. void RecipieOutput::setModifier(ItemModifier* modifier)
  122. {
  123. if (this->modifier) this->modifier->release();
  124. this->modifier = modifier;
  125. }
  126. ItemModifier* RecipieOutput::zModifier() const
  127. {
  128. return modifier;
  129. }
  130. Item* RecipieOutput::createItem() const
  131. {
  132. Item* result = Game::INSTANCE->zItemType(itemTypeId)->createItem();
  133. if (result)
  134. {
  135. modifier->applyOn(result);
  136. }
  137. return result;
  138. }
  139. RecipieOutputFactory::RecipieOutputFactory()
  140. : TypeFactory()
  141. {}
  142. RecipieOutput* RecipieOutputFactory::createValue(
  143. Framework::JSON::JSONObject* zJson) const
  144. {
  145. return new RecipieOutput();
  146. }
  147. void RecipieOutputFactory::fromJson(
  148. RecipieOutput* zResult, Framework::JSON::JSONObject* zJson) const
  149. {
  150. zResult->setItemTypeId(Game::INSTANCE->getItemTypeId(
  151. zJson->asObject()->zValue("itemType")->asString()->getString()));
  152. zResult->setAmount(
  153. (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber());
  154. zResult->setModifier(
  155. Game::INSTANCE->zTypeRegistry()->fromJson<ItemModifier>(
  156. zJson->asObject()->zValue("modifier")));
  157. }
  158. void RecipieOutputFactory::toJson(
  159. RecipieOutput* zObject, Framework::JSON::JSONObject* zResult) const
  160. {
  161. zResult->addValue("itemType",
  162. new Framework::JSON::JSONString(
  163. Game::INSTANCE->zItemType(zObject->getItemTypeId())->getName()));
  164. zResult->addValue("amount",
  165. new Framework::JSON::JSONNumber((double)zObject->getAmount()));
  166. zResult->addValue("modifier",
  167. Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModifier()));
  168. }
  169. JSONObjectValidationBuilder* RecipieOutputFactory::addToValidator(
  170. JSONObjectValidationBuilder* builder) const
  171. {
  172. Framework::JSON::JSONObject* defaultModifier
  173. = new Framework::JSON::JSONObject();
  174. defaultModifier->addValue(
  175. "type", new Framework::JSON::JSONString("doNothing"));
  176. Framework::RCArray<Framework::Text> itemTypes;
  177. for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++)
  178. {
  179. if (Game::INSTANCE->zItemType(i))
  180. {
  181. itemTypes.add(
  182. new Framework::Text(Game::INSTANCE->zItemType(i)->getName()));
  183. }
  184. }
  185. return builder->withRequiredString("itemType")
  186. ->whichIsOneOf(itemTypes)
  187. ->finishString()
  188. ->withRequiredAttribute("modifier",
  189. Game::INSTANCE->zTypeRegistry()->getValidator<ItemModifier>())
  190. ->withRequiredObject("modifier")
  191. ->withRequiredString("type")
  192. ->withExactMatch("doNothing")
  193. ->finishString()
  194. ->withDefault(defaultModifier)
  195. ->finishObject()
  196. ->withRequiredNumber("amount")
  197. ->whichIsGreaterOrEqual(1.0)
  198. ->withDefault(1.0)
  199. ->finishNumber();
  200. }
  201. Recipie::Recipie()
  202. : ReferenceCounter()
  203. {}
  204. void Recipie::addOutput(RecipieOutput* outputs)
  205. {
  206. this->outputs.add(outputs);
  207. }
  208. Framework::Array<ItemInfo> Recipie::getOutput() const
  209. {
  210. Framework::Array<ItemInfo> result;
  211. for (const RecipieOutput* output : outputs)
  212. {
  213. Item* item = output->createItem();
  214. if (item)
  215. {
  216. result.add({item->zItemType()->getId(),
  217. output->getAmount(),
  218. item->getHp(),
  219. item->getMaxHp(),
  220. item->getDurability(),
  221. item->getMaxDurability()});
  222. item->release();
  223. }
  224. }
  225. return result;
  226. }
  227. bool Recipie::createsOutput(int itemTypeId)
  228. {
  229. for (RecipieOutput* output : outputs)
  230. {
  231. if (output->getItemTypeId() == itemTypeId)
  232. {
  233. return 1;
  234. }
  235. }
  236. return 0;
  237. }
  238. void Recipie::setGroupName(Framework::Text groupName)
  239. {
  240. this->groupName = groupName;
  241. }
  242. const Framework::RCArray<RecipieOutput>& Recipie::getOutputs() const
  243. {
  244. return outputs;
  245. }
  246. Framework::Text Recipie::getGroupName() const
  247. {
  248. return groupName;
  249. }
  250. UnshapedRecipie::UnshapedRecipie()
  251. : Recipie()
  252. {}
  253. bool UnshapedRecipie::testApplicability(CraftingStorage* zStorage)
  254. {
  255. for (RecipieOutput* output : outputs)
  256. {
  257. Item* item = output->createItem();
  258. if (item)
  259. {
  260. if (!zStorage->hasFreeSpace(item, output->getAmount()))
  261. {
  262. item->release();
  263. return 0;
  264. }
  265. item->release();
  266. }
  267. }
  268. return zStorage->isAllAvailable(inputs);
  269. }
  270. void UnshapedRecipie::apply(CraftingStorage* zStorage)
  271. {
  272. zStorage->consume(inputs);
  273. for (RecipieOutput* output : outputs)
  274. {
  275. Item* item = output->createItem();
  276. if (item)
  277. {
  278. ItemStack* stack = new ItemStack(item, output->getAmount());
  279. zStorage->addCraftingResult(stack);
  280. stack->release();
  281. }
  282. }
  283. }
  284. Framework::Text UnshapedRecipie::getRecipieUIML()
  285. {
  286. Framework::Text result = "<recipie type=\"unshaped\"><ingredients>";
  287. for (RecipieInput* input : inputs)
  288. {
  289. result.append() << "<ingredient amount=\"" << input->getAmount()
  290. << "\">";
  291. if (input->zFilter())
  292. {
  293. result.append()
  294. << "<logic>" << input->zFilter()->getLogicUIML() << "</logic>";
  295. }
  296. result += "</ingredient>";
  297. // TODO: add modifiers
  298. }
  299. result += "</ingredients><outputs>";
  300. for (RecipieOutput* output : outputs)
  301. {
  302. Item* item = output->createItem();
  303. if (item)
  304. {
  305. result.append()
  306. << "<output amount=\"" << output->getAmount()
  307. << "\" itemType=\"" << item->zItemType()->getId() << "\" hp=\""
  308. << item->getHp() << "\" durability=\"" << item->getDurability()
  309. << "\" maxHp=\"" << item->getMaxHp() << "\" maxDurability=\""
  310. << item->getMaxDurability() << "\">" << item->getTooltipUIML()
  311. << "</output>";
  312. item->release();
  313. }
  314. }
  315. result += "</outputs></recipie>";
  316. return result;
  317. }
  318. void UnshapedRecipie::addInput(RecipieInput* input)
  319. {
  320. inputs.add(input);
  321. }
  322. const Framework::RCArray<RecipieInput>& UnshapedRecipie::getInputs() const
  323. {
  324. return inputs;
  325. }
  326. UnshapedRecipieFactory::UnshapedRecipieFactory()
  327. : RecipieFactory()
  328. {}
  329. UnshapedRecipie* UnshapedRecipieFactory::createValue(
  330. Framework::JSON::JSONObject* zJson) const
  331. {
  332. return new UnshapedRecipie();
  333. }
  334. void UnshapedRecipieFactory::fromJson(
  335. UnshapedRecipie* zResult, Framework::JSON::JSONObject* zJson) const
  336. {
  337. for (Framework::JSON::JSONValue* input :
  338. *zJson->zValue("inputs")->asArray())
  339. {
  340. zResult->addInput(
  341. Game::INSTANCE->zTypeRegistry()->fromJson<RecipieInput>(input));
  342. }
  343. RecipieFactory::fromJson(zResult, zJson);
  344. }
  345. void UnshapedRecipieFactory::toJson(
  346. UnshapedRecipie* zObject, Framework::JSON::JSONObject* zResult) const
  347. {
  348. Framework::JSON::JSONArray* inputs = new Framework::JSON::JSONArray();
  349. for (RecipieInput* input : zObject->getInputs())
  350. {
  351. inputs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(input));
  352. }
  353. zResult->addValue("inputs", inputs);
  354. RecipieFactory::toJson(zObject, zResult);
  355. }
  356. JSONObjectValidationBuilder* UnshapedRecipieFactory::addToValidator(
  357. JSONObjectValidationBuilder* builder) const
  358. {
  359. return RecipieFactory::addToValidator(
  360. builder->withRequiredArray("inputs")
  361. ->addAcceptedTypeInArray(
  362. Game::INSTANCE->zTypeRegistry()->getValidator<RecipieInput>())
  363. ->finishArray());
  364. }
  365. Framework::Text UnshapedRecipieFactory::getTypeToken() const
  366. {
  367. return "unshaped";
  368. }
  369. ShapedRecipie::ShapedRecipie()
  370. : Recipie(),
  371. width(0),
  372. height(0)
  373. {}
  374. bool ShapedRecipie::testApplicability(CraftingStorage* zStorage)
  375. {
  376. ShapedCraftingStorage* zShapedStorage
  377. = dynamic_cast<ShapedCraftingStorage*>(zStorage);
  378. if (!zShapedStorage) return 0;
  379. for (RecipieOutput* output : outputs)
  380. {
  381. Item* item = output->createItem();
  382. if (item)
  383. {
  384. if (!zShapedStorage->hasFreeSpace(item, output->getAmount()))
  385. {
  386. item->release();
  387. return 0;
  388. }
  389. item->release();
  390. }
  391. }
  392. return zShapedStorage->isAllAvailable(inputs, width, height);
  393. }
  394. void ShapedRecipie::apply(CraftingStorage* zStorage)
  395. {
  396. ShapedCraftingStorage* zShapedStorage
  397. = dynamic_cast<ShapedCraftingStorage*>(zStorage);
  398. zShapedStorage->consume(inputs, width, height);
  399. for (RecipieOutput* output : outputs)
  400. {
  401. Item* item = output->createItem();
  402. if (item)
  403. {
  404. ItemStack* stack = new ItemStack(item, output->getAmount());
  405. zStorage->addCraftingResult(stack);
  406. stack->release();
  407. }
  408. }
  409. }
  410. Framework::Text ShapedRecipie::getRecipieUIML()
  411. {
  412. Framework::Text result = "<recipie type=\"shaped\" width=\"";
  413. result.append() << width << "\" height=\"" << height << "\"><ingredients>";
  414. for (RecipieInput* input : inputs)
  415. {
  416. result.append() << "<ingredient amount=\"" << input->getAmount()
  417. << "\">";
  418. if (input->zFilter())
  419. {
  420. result.append()
  421. << "<logic>" << input->zFilter()->getLogicUIML() << "</logic>";
  422. }
  423. result += "</ingredient>";
  424. // TODO: add modifiers
  425. }
  426. result += "</ingredients><outputs>";
  427. for (RecipieOutput* output : outputs)
  428. {
  429. Item* item = output->createItem();
  430. if (item)
  431. {
  432. result.append()
  433. << "<output amount=\"" << output->getAmount()
  434. << "\" itemType=\"" << item->zItemType()->getId() << "\" hp=\""
  435. << item->getHp() << "\" durability=\"" << item->getDurability()
  436. << "\" maxHp=\"" << item->getMaxHp() << "\" maxDurability=\""
  437. << item->getMaxDurability() << "\">" << item->getTooltipUIML()
  438. << "</output>";
  439. item->release();
  440. }
  441. }
  442. result += "</outputs></recipie>";
  443. return result;
  444. }
  445. void ShapedRecipie::setWidth(int width)
  446. {
  447. this->width = width;
  448. }
  449. int ShapedRecipie::getWidth() const
  450. {
  451. return width;
  452. }
  453. void ShapedRecipie::setHeight(int height)
  454. {
  455. this->height = height;
  456. }
  457. int ShapedRecipie::getHeight() const
  458. {
  459. return height;
  460. }
  461. void ShapedRecipie::addInput(RecipieInput* input)
  462. {
  463. inputs.add(input);
  464. }
  465. void ShapedRecipie::setInput(int index, RecipieInput* input)
  466. {
  467. inputs.set(input, index);
  468. }
  469. const Framework::RCArray<RecipieInput>& ShapedRecipie::getInputs() const
  470. {
  471. return inputs;
  472. }
  473. ShapedRecipieFactory::ShapedRecipieFactory()
  474. : RecipieFactory()
  475. {}
  476. ShapedRecipie* ShapedRecipieFactory::createValue(
  477. Framework::JSON::JSONObject* zJson) const
  478. {
  479. return new ShapedRecipie();
  480. }
  481. void ShapedRecipieFactory::fromJson(
  482. ShapedRecipie* zResult, Framework::JSON::JSONObject* zJson) const
  483. {
  484. int width = (int)zJson->zValue("width")->asNumber()->getNumber();
  485. int height = (int)zJson->zValue("height")->asNumber()->getNumber();
  486. for (int i = 0; i < width * height; i++)
  487. {
  488. zResult->addInput(new RecipieInput());
  489. }
  490. for (Framework::JSON::JSONValue* input :
  491. *zJson->zValue("inputs")->asArray())
  492. {
  493. int x = (int)input->asObject()->zValue("x")->asNumber()->getNumber();
  494. int y = (int)input->asObject()->zValue("y")->asNumber()->getNumber();
  495. if (x >= width || y >= height)
  496. {
  497. Framework::Logging::warning()
  498. << "Invalid input position in shaped recipie with width="
  499. << width << ", height=" << height << ", x=" << x << ", y=" << y;
  500. return;
  501. }
  502. zResult->setInput(y * width + x,
  503. Game::INSTANCE->zTypeRegistry()->fromJson<RecipieInput>(
  504. input->asObject()->zValue("input")));
  505. }
  506. zResult->setWidth((int)zJson->zValue("width")->asNumber()->getNumber());
  507. zResult->setHeight((int)zJson->zValue("height")->asNumber()->getNumber());
  508. RecipieFactory::fromJson(zResult, zJson);
  509. }
  510. void ShapedRecipieFactory::toJson(
  511. ShapedRecipie* zObject, Framework::JSON::JSONObject* zResult) const
  512. {
  513. zResult->addValue(
  514. "width", new Framework::JSON::JSONNumber(zObject->getWidth()));
  515. zResult->addValue(
  516. "height", new Framework::JSON::JSONNumber(zObject->getHeight()));
  517. Framework::JSON::JSONArray* inputs = new Framework::JSON::JSONArray();
  518. for (int i = 0; i < zObject->getWidth() * zObject->getHeight(); i++)
  519. {
  520. Framework::JSON::JSONObject* input = new Framework::JSON::JSONObject();
  521. input->addValue(
  522. "x", new Framework::JSON::JSONNumber(i % zObject->getHeight()));
  523. input->addValue(
  524. "y", new Framework::JSON::JSONNumber(i / zObject->getHeight()));
  525. input->addValue("input",
  526. Game::INSTANCE->zTypeRegistry()->toJson(zObject->getInputs().z(i)));
  527. inputs->addValue(input);
  528. }
  529. zResult->addValue("inputs", inputs);
  530. RecipieFactory::toJson(zObject, zResult);
  531. }
  532. JSONObjectValidationBuilder* ShapedRecipieFactory::addToValidator(
  533. JSONObjectValidationBuilder* builder) const
  534. {
  535. return RecipieFactory::addToValidator(
  536. builder->withRequiredArray("inputs")
  537. ->addAcceptedObjectInArray()
  538. ->withRequiredNumber("x")
  539. ->whichIsGreaterOrEqual(0.0)
  540. ->finishNumber()
  541. ->withRequiredNumber("y")
  542. ->whichIsGreaterOrEqual(0.0)
  543. ->finishNumber()
  544. ->withRequiredAttribute("input",
  545. Game::INSTANCE->zTypeRegistry()->getValidator<RecipieInput>())
  546. ->finishObject()
  547. ->finishArray()
  548. ->withRequiredNumber("width")
  549. ->whichIsGreaterOrEqual(1.0)
  550. ->finishNumber()
  551. ->withRequiredNumber("height")
  552. ->whichIsGreaterOrEqual(1.0)
  553. ->finishNumber());
  554. }
  555. Framework::Text ShapedRecipieFactory::getTypeToken() const
  556. {
  557. return "shaped";
  558. }