ItemFilter.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. #include "ItemFilter.h"
  2. #include "Game.h"
  3. #include "Item.h"
  4. #include "ItemSlot.h"
  5. #include "ItemStack.h"
  6. #include "ItemType.h"
  7. ItemFilter::ItemFilter()
  8. : ReferenceCounter()
  9. {}
  10. bool ItemFilter::matchItem(const Item* zItem) const
  11. {
  12. return 1;
  13. }
  14. bool ItemFilter::matchSourceSlot(ItemSlot* zSlot) const
  15. {
  16. return zSlot->zStack() ? matchItem(zSlot->zStack()->zItem()) : 0;
  17. }
  18. bool ItemFilter::matchTargetSlot(ItemSlot* zSlot) const
  19. {
  20. return 1;
  21. }
  22. CombinedItemFilter::CombinedItemFilter(
  23. Framework::RCArray<ItemFilter> filters, std::function<bool(bool, bool)> op)
  24. : ItemFilter(),
  25. filters(filters),
  26. op(op)
  27. {}
  28. bool CombinedItemFilter::matchItem(const Item* zItem) const
  29. {
  30. bool result = false;
  31. for (int i = 0; i < filters.getEintragAnzahl(); i++)
  32. {
  33. if (i == 0)
  34. result = filters.z(i)->matchItem(zItem);
  35. else
  36. result = op(result, filters.z(i)->matchItem(zItem));
  37. }
  38. return result;
  39. }
  40. bool CombinedItemFilter::matchSourceSlot(ItemSlot* zSlot) const
  41. {
  42. bool result = false;
  43. for (int i = 0; i < filters.getEintragAnzahl(); i++)
  44. {
  45. if (i == 0)
  46. result = filters.z(i)->matchSourceSlot(zSlot);
  47. else
  48. result = op(result, filters.z(i)->matchSourceSlot(zSlot));
  49. }
  50. return result;
  51. }
  52. bool CombinedItemFilter::matchTargetSlot(ItemSlot* zSlot) const
  53. {
  54. bool result = false;
  55. for (int i = 0; i < filters.getEintragAnzahl(); i++)
  56. {
  57. if (i == 0)
  58. result = filters.z(i)->matchTargetSlot(zSlot);
  59. else
  60. result = op(result, filters.z(i)->matchTargetSlot(zSlot));
  61. }
  62. return result;
  63. }
  64. Framework::Text CombinedItemFilter::getLogicUIML() const
  65. {
  66. if (filters.getEintragAnzahl() == 0)
  67. {
  68. return "";
  69. }
  70. if (filters.getEintragAnzahl() == 1)
  71. {
  72. return filters.z(0)->getLogicUIML();
  73. }
  74. else
  75. {
  76. Framework::Text result = "<operator result_0_0=\"";
  77. result.append() << (int)op(0, 0) << "\" result_0_1=\"" << (int)op(0, 1)
  78. << "\" result_1_0=\"" << (int)op(1, 0)
  79. << "\" result_1_1=\"" << (int)op(1, 1) << "\">";
  80. int openCount = 1;
  81. for (int i = 0; i < filters.getEintragAnzahl() - 1; i++)
  82. {
  83. if (i < filters.getEintragAnzahl() - 2)
  84. {
  85. result.append()
  86. << filters.z(i)->getLogicUIML() << "<operator result_0_0=\""
  87. << (int)op(0, 0) << "\" result_0_1=\"" << (int)op(0, 1)
  88. << "\" result_1_0=\"" << (int)op(1, 0) << "\" result_1_1=\""
  89. << (int)op(1, 1) << "\">";
  90. }
  91. else
  92. {
  93. filters.z(i)->getLogicUIML();
  94. filters.z(i + 1)->getLogicUIML();
  95. }
  96. }
  97. return result;
  98. }
  99. }
  100. const Framework::RCArray<ItemFilter>& CombinedItemFilter::getFilters() const
  101. {
  102. return filters;
  103. }
  104. std::function<bool(bool, bool)> CombinedItemFilter::getOp() const
  105. {
  106. return op;
  107. }
  108. CombinedItemFilterFactory::CombinedItemFilterFactory()
  109. : SubTypeFactory()
  110. {}
  111. CombinedItemFilter* CombinedItemFilterFactory::fromJson(
  112. Framework::JSON::JSONObject* zJson) const
  113. {
  114. std::function<bool(bool, bool)> func;
  115. Framework::Text op = zJson->zValue("operator")->asString()->getString();
  116. if (op.istGleich("or"))
  117. {
  118. func = [](bool a, bool b) { return a || b; };
  119. }
  120. else if (op.istGleich("and"))
  121. {
  122. func = [](bool a, bool b) { return a && b; };
  123. }
  124. else if (op.istGleich("xor"))
  125. {
  126. func = [](bool a, bool b) { return (!a || !b) && (a || b); };
  127. }
  128. else if (op.istGleich("nor"))
  129. {
  130. func = [](bool a, bool b) { return !(a || b); };
  131. }
  132. else if (op.istGleich("nand"))
  133. {
  134. func = [](bool a, bool b) { return !(a && b); };
  135. }
  136. else if (op.istGleich("left"))
  137. {
  138. func = [](bool a, bool b) { return a; };
  139. }
  140. else if (op.istGleich("right"))
  141. {
  142. func = [](bool a, bool b) { return b; };
  143. }
  144. else if (op.istGleich("onlyLeft"))
  145. {
  146. func = [](bool a, bool b) { return a && !b; };
  147. }
  148. else if (op.istGleich("onlyRight"))
  149. {
  150. func = [](bool a, bool b) { return !a && b; };
  151. }
  152. else if (op.istGleich("notLeft"))
  153. {
  154. func = [](bool a, bool b) { return !a; };
  155. }
  156. else if (op.istGleich("notRight"))
  157. {
  158. func = [](bool a, bool b) { return !b; };
  159. }
  160. else if (op.istGleich("eq"))
  161. {
  162. func = [](bool a, bool b) { return a == b; };
  163. }
  164. else if (op.istGleich("leftOrEq"))
  165. {
  166. func = [](bool a, bool b) { return a || (a == b); };
  167. }
  168. else if (op.istGleich("rightOrEq"))
  169. {
  170. func = [](bool a, bool b) { return b || (a == b); };
  171. }
  172. else if (op.istGleich("true"))
  173. {
  174. func = [](bool a, bool b) { return true; };
  175. }
  176. else
  177. {
  178. func = [](bool a, bool b) { return false; };
  179. }
  180. Framework::RCArray<ItemFilter> filters;
  181. for (Framework::JSON::JSONValue* value :
  182. *zJson->zValue("filters")->asArray())
  183. {
  184. filters.add(
  185. Game::INSTANCE->zTypeRegistry()->fromJson<ItemFilter>(value));
  186. }
  187. return new CombinedItemFilter(filters, func);
  188. }
  189. Framework::JSON::JSONObject* CombinedItemFilterFactory::toJson(
  190. CombinedItemFilter* zObject) const
  191. {
  192. Framework::Text op;
  193. std::function<bool(bool, bool)> func = zObject->getOp();
  194. if (func(0, 0))
  195. {
  196. if (func(0, 1))
  197. {
  198. if (func(1, 0))
  199. {
  200. if (func(1, 1))
  201. {
  202. op = "true";
  203. }
  204. else
  205. {
  206. op = "nand";
  207. }
  208. }
  209. else
  210. {
  211. if (func(1, 1))
  212. {
  213. op = "rightOrEq";
  214. }
  215. else
  216. {
  217. op = "notLeft";
  218. }
  219. }
  220. }
  221. else
  222. {
  223. if (func(1, 0))
  224. {
  225. if (func(1, 1))
  226. {
  227. op = "leftOrEq";
  228. }
  229. else
  230. {
  231. op = "notRight";
  232. }
  233. }
  234. else
  235. {
  236. if (func(1, 1))
  237. {
  238. op = "eq";
  239. }
  240. else
  241. {
  242. op = "nor";
  243. }
  244. }
  245. }
  246. }
  247. else
  248. {
  249. if (func(0, 1))
  250. {
  251. if (func(1, 0))
  252. {
  253. if (func(1, 1))
  254. {
  255. op = "or";
  256. }
  257. else
  258. {
  259. op = "xor";
  260. }
  261. }
  262. else
  263. {
  264. if (func(1, 1))
  265. {
  266. op = "right";
  267. }
  268. else
  269. {
  270. op = "onlyRight";
  271. }
  272. }
  273. }
  274. else
  275. {
  276. if (func(1, 0))
  277. {
  278. if (func(1, 1))
  279. {
  280. op = "left";
  281. }
  282. else
  283. {
  284. op = "onlyLeft";
  285. }
  286. }
  287. else
  288. {
  289. if (func(1, 1))
  290. {
  291. op = "and";
  292. }
  293. else
  294. {
  295. op = "false";
  296. }
  297. }
  298. }
  299. }
  300. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  301. result->addValue("operator", new Framework::JSON::JSONString(op));
  302. Framework::JSON::JSONArray* filters = new Framework::JSON::JSONArray();
  303. for (ItemFilter* filter : zObject->getFilters())
  304. {
  305. filters->addValue(Game::INSTANCE->zTypeRegistry()->toJson(filter));
  306. }
  307. result->addValue("filters", filters);
  308. return result;
  309. }
  310. Framework::JSON::Validator::JSONValidator*
  311. CombinedItemFilterFactory::getValidator(
  312. Framework::JSON::Validator::ObjectValidationBuilder<
  313. Framework::JSON::Validator::JSONValidator>* builder) const
  314. {
  315. return builder->withRequiredString("operator")
  316. ->whichIsOneOf({"or",
  317. "and",
  318. "xor",
  319. "nor",
  320. "nand",
  321. "left",
  322. "right",
  323. "onlyLeft",
  324. "onlyRight",
  325. "notLeft",
  326. "notRight",
  327. "eq",
  328. "leftOrEq",
  329. "rightOrEq",
  330. "true",
  331. "false"})
  332. ->finishString()
  333. ->withRequiredArray("filters")
  334. ->addAcceptedTypeInArray(
  335. Game::INSTANCE->zTypeRegistry()->getValidator<ItemFilter>())
  336. ->finishArray()
  337. ->finishObject();
  338. }
  339. Framework::Text CombinedItemFilterFactory::getTypeToken() const
  340. {
  341. return "operator";
  342. }
  343. AnyItemFilter::AnyItemFilter()
  344. : ItemFilter()
  345. {}
  346. bool AnyItemFilter::matchItem(const Item* zItem) const
  347. {
  348. return true;
  349. }
  350. Framework::Text AnyItemFilter::getLogicUIML() const
  351. {
  352. return "<anyItem/>";
  353. }
  354. AnyItemFilterFactory::AnyItemFilterFactory()
  355. : SubTypeFactory()
  356. {}
  357. AnyItemFilter* AnyItemFilterFactory::fromJson(
  358. Framework::JSON::JSONObject* zJson) const
  359. {
  360. return new AnyItemFilter();
  361. }
  362. Framework::JSON::JSONObject* AnyItemFilterFactory::toJson(
  363. AnyItemFilter* zObject) const
  364. {
  365. return new Framework::JSON::JSONObject();
  366. }
  367. Framework::JSON::Validator::JSONValidator* AnyItemFilterFactory::getValidator(
  368. Framework::JSON::Validator::ObjectValidationBuilder<
  369. Framework::JSON::Validator::JSONValidator>* builder) const
  370. {
  371. return builder->finishObject();
  372. }
  373. Framework::Text AnyItemFilterFactory::getTypeToken() const
  374. {
  375. return "anyItem";
  376. }
  377. TypeItemFilter::TypeItemFilter(const ItemType* zType)
  378. : ItemFilter(),
  379. type(zType)
  380. {}
  381. bool TypeItemFilter::matchItem(const Item* zItem) const
  382. {
  383. return zItem->zItemType() == type;
  384. }
  385. Framework::Text TypeItemFilter::getLogicUIML() const
  386. {
  387. Framework::Text result = "<attribute name=\"Type\" operator=\"=\" value=\"";
  388. result.append() << type->getId() << "\"/>";
  389. return result;
  390. }
  391. const ItemType* TypeItemFilter::zType() const
  392. {
  393. return type;
  394. }
  395. TypeItemFilterFactory::TypeItemFilterFactory()
  396. : SubTypeFactory()
  397. {}
  398. TypeItemFilter* TypeItemFilterFactory::fromJson(
  399. Framework::JSON::JSONObject* zJson) const
  400. {
  401. return new TypeItemFilter(
  402. Game::INSTANCE->zItemType(Game::INSTANCE->getItemTypeId(
  403. zJson->zValue("itemType")->asString()->getString())));
  404. }
  405. Framework::JSON::JSONObject* TypeItemFilterFactory::toJson(
  406. TypeItemFilter* zObject) const
  407. {
  408. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  409. result->addValue("itemType",
  410. new Framework::JSON::JSONString(zObject->zType()->getName()));
  411. return result;
  412. }
  413. Framework::JSON::Validator::JSONValidator* TypeItemFilterFactory::getValidator(
  414. Framework::JSON::Validator::ObjectValidationBuilder<
  415. Framework::JSON::Validator::JSONValidator>* builder) const
  416. {
  417. Framework::RCArray<Text> types;
  418. for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++)
  419. {
  420. if (Game::INSTANCE->zItemType(i))
  421. {
  422. types.add(
  423. new Framework::Text(Game::INSTANCE->zItemType(i)->getName()));
  424. }
  425. }
  426. return builder->withRequiredString("itemType")
  427. ->whichIsOneOf(types)
  428. ->finishString()
  429. ->finishObject();
  430. }
  431. Framework::Text TypeItemFilterFactory::getTypeToken() const
  432. {
  433. return "type";
  434. }
  435. SpecificSlotFilter::SpecificSlotFilter(int sourceSlotId, int targetSlotId)
  436. : ItemFilter(),
  437. sourceSlotId(sourceSlotId),
  438. targetSlotId(targetSlotId)
  439. {}
  440. bool SpecificSlotFilter::matchSourceSlot(ItemSlot* zSlot) const
  441. {
  442. return sourceSlotId == zSlot->getId();
  443. }
  444. bool SpecificSlotFilter::matchTargetSlot(ItemSlot* zSlot) const
  445. {
  446. return targetSlotId == zSlot->getId();
  447. }
  448. Framework::Text SpecificSlotFilter::getLogicUIML() const
  449. {
  450. return "<anyItem/>";
  451. }
  452. SourceSlotBlacklistFilter::SourceSlotBlacklistFilter()
  453. : ItemFilter()
  454. {}
  455. void SourceSlotBlacklistFilter::addBlackListSlotId(int id)
  456. {
  457. blackList.add(id);
  458. }
  459. bool SourceSlotBlacklistFilter::matchSourceSlot(ItemSlot* zSlot) const
  460. {
  461. for (int black : blackList)
  462. {
  463. if (black == zSlot->getId()) return 0;
  464. }
  465. return 1;
  466. }
  467. bool SourceSlotBlacklistFilter::matchTargetSlot(ItemSlot* zSlot) const
  468. {
  469. return 1;
  470. }
  471. Framework::Text SourceSlotBlacklistFilter::getLogicUIML() const
  472. {
  473. return "<anyItem/>";
  474. }
  475. TargetSlotBlacklistFilter::TargetSlotBlacklistFilter()
  476. : ItemFilter()
  477. {}
  478. void TargetSlotBlacklistFilter::addBlackListSlotId(int id)
  479. {
  480. blackList.add(id);
  481. }
  482. bool TargetSlotBlacklistFilter::matchSourceSlot(ItemSlot* zSlot) const
  483. {
  484. return 1;
  485. }
  486. bool TargetSlotBlacklistFilter::matchTargetSlot(ItemSlot* zSlot) const
  487. {
  488. for (int black : blackList)
  489. {
  490. if (black == zSlot->getId()) return 0;
  491. }
  492. return 1;
  493. }
  494. Framework::Text TargetSlotBlacklistFilter::getLogicUIML() const
  495. {
  496. return "<anyItem/>";
  497. }
  498. GroupItemFilter::GroupItemFilter(Framework::RCArray<Framework::Text> groups)
  499. : ItemFilter(),
  500. groups(groups)
  501. {}
  502. bool GroupItemFilter::matchItem(const Item* zItem) const
  503. {
  504. for (Framework::Text* group : groups)
  505. {
  506. for (Framework::Text* typeGroup : zItem->zItemType()->getGroups())
  507. {
  508. if (typeGroup->istGleich(group)) return true;
  509. }
  510. }
  511. return false;
  512. }
  513. Framework::Text GroupItemFilter::getLogicUIML() const
  514. {
  515. Framework::RCArray<ItemFilter> filters;
  516. for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++)
  517. {
  518. if (Game::INSTANCE->zItemType(i))
  519. {
  520. bool found = false;
  521. for (Framework::Text* group : groups)
  522. {
  523. for (Framework::Text* typeGroup :
  524. Game::INSTANCE->zItemType(i)->getGroups())
  525. {
  526. if (typeGroup->istGleich(group))
  527. {
  528. found = true;
  529. break;
  530. }
  531. }
  532. if (found) break;
  533. }
  534. if (found)
  535. filters.add(new TypeItemFilter(Game::INSTANCE->zItemType(i)));
  536. }
  537. }
  538. return CombinedItemFilter(filters, [](bool a, bool b) {
  539. return a || b;
  540. }).getLogicUIML();
  541. }
  542. const Framework::RCArray<Framework::Text>& GroupItemFilter::getGroups() const
  543. {
  544. return groups;
  545. }
  546. GroupItemFilterFactory::GroupItemFilterFactory()
  547. : SubTypeFactory()
  548. {}
  549. GroupItemFilter* GroupItemFilterFactory::fromJson(
  550. Framework::JSON::JSONObject* zJson) const
  551. {
  552. Framework::RCArray<Framework::Text> groups;
  553. for (Framework::JSON::JSONValue* group :
  554. *zJson->zValue("groupNames")->asArray())
  555. {
  556. groups.add(new Framework::Text(group->asString()->getString()));
  557. }
  558. return new GroupItemFilter(groups);
  559. }
  560. Framework::JSON::JSONObject* GroupItemFilterFactory::toJson(
  561. GroupItemFilter* zObject) const
  562. {
  563. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  564. Framework::JSON::JSONArray* groups = new Framework::JSON::JSONArray();
  565. for (Framework::Text* group : zObject->getGroups())
  566. {
  567. groups->addValue(new Framework::JSON::JSONString(group->getText()));
  568. }
  569. result->addValue("groupNames", groups);
  570. return result;
  571. }
  572. Framework::JSON::Validator::JSONValidator* GroupItemFilterFactory::getValidator(
  573. Framework::JSON::Validator::ObjectValidationBuilder<
  574. Framework::JSON::Validator::JSONValidator>* builder) const
  575. {
  576. return builder->withRequiredArray("groupNames")
  577. ->addAcceptedStringInArray()
  578. ->finishString()
  579. ->finishArray()
  580. ->finishObject();
  581. }
  582. Framework::Text GroupItemFilterFactory::getTypeToken() const
  583. {
  584. return "groups";
  585. }