Recipie.cpp 17 KB

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