FluidContainer.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. #include "FluidContainer.h"
  2. #include <TextFeld.h>
  3. #include "FluidBlock.h"
  4. #include "Game.h"
  5. FluidContainerItem::FluidContainerItem(int itemTypeId, Framework::Text name)
  6. : Item(itemTypeId, name),
  7. fluidTypeId(0),
  8. fluidAmount(0)
  9. {
  10. placeable = 1;
  11. usable = 1;
  12. eatable = 1;
  13. }
  14. const BlockType* FluidContainerItem::zPlacedBlockType() const
  15. {
  16. return fluidTypeId && fluidAmount >= 1000
  17. ? Game::INSTANCE->zBlockType(fluidTypeId)
  18. : 0;
  19. }
  20. bool FluidContainerItem::canBeStackedWith(const Item* zItem) const
  21. {
  22. const FluidContainerItem* other
  23. = dynamic_cast<const FluidContainerItem*>(zItem);
  24. if (!other) return false;
  25. return Item::canBeStackedWith(zItem) && other->fluidTypeId == fluidTypeId
  26. && other->fluidAmount == fluidAmount;
  27. }
  28. bool FluidContainerItem::canBePlacedAt(
  29. const int dimensionId, Framework::Vec3<int> worldPos) const
  30. {
  31. if (fluidAmount >= 1000)
  32. {
  33. Dimension* dim = Game::INSTANCE->zDimension(dimensionId);
  34. if (dim)
  35. {
  36. const Block* block = dim->zBlockOrDefault(worldPos);
  37. if (block)
  38. {
  39. if (block->zBlockType()->getId() == BlockTypeEnum::AIR)
  40. return true;
  41. if (block->zBlockType()->getId() == fluidTypeId)
  42. {
  43. const FluidBlock* fluidBlock
  44. = dynamic_cast<const FluidBlock*>(block);
  45. return fluidBlock && fluidBlock->getDistanceToSource() > 0;
  46. }
  47. }
  48. }
  49. }
  50. return false;
  51. }
  52. void FluidContainerItem::onPlaced()
  53. {
  54. setAmount(fluidAmount - 1000);
  55. }
  56. Framework::Text FluidContainerItem::getTooltipUIML() const
  57. {
  58. Framework::Text uiml = "<tip><text width=\"auto\" height=\"auto\">";
  59. uiml.append() << getName();
  60. if (fluidTypeId != 0)
  61. {
  62. uiml.append() << "\nFluid: "
  63. << Game::INSTANCE->zBlockType(fluidTypeId)->getName()
  64. << "\nAmount: " << fluidAmount << " L";
  65. }
  66. else
  67. {
  68. uiml.append() << "\nEmpty";
  69. }
  70. uiml.append() << "</text></tip>";
  71. return uiml;
  72. }
  73. bool FluidContainerItem::applyFoodEffects(Entity* zTarget)
  74. {
  75. if (fluidTypeId)
  76. {
  77. const FluidBlockType* fluidType = dynamic_cast<const FluidBlockType*>(
  78. Game::INSTANCE->zBlockType(fluidTypeId));
  79. if (fluidType
  80. && (fluidType->getHungerRecoveryPerL()
  81. || fluidType->getThirstRecoveryPerL()))
  82. {
  83. int drinkable
  84. = fluidType->getThirstRecoveryPerL() > 0
  85. ? (int)((zTarget->getMaxThirst() - zTarget->getThirst())
  86. / fluidType->getThirstRecoveryPerL())
  87. : (int)((zTarget->getMaxHunger() - zTarget->getHunger())
  88. / fluidType->getHungerRecoveryPerL());
  89. if (fluidType->getHungerRecoveryPerL() > 0
  90. && fluidType->getThirstRecoveryPerL() > 0)
  91. {
  92. int drinkable2
  93. = (int)((zTarget->getMaxHunger() - zTarget->getHunger())
  94. / fluidType->getHungerRecoveryPerL());
  95. if (drinkable2 < drinkable) drinkable = drinkable2;
  96. }
  97. if (getAmount() < drinkable) drinkable = getAmount();
  98. if (!drinkable) return false;
  99. setAmount(getAmount() - drinkable);
  100. zTarget->setThirst(
  101. zTarget->getThirst()
  102. + drinkable * fluidType->getThirstRecoveryPerL());
  103. zTarget->setHunger(
  104. zTarget->getHunger()
  105. + drinkable * fluidType->getHungerRecoveryPerL());
  106. return true;
  107. }
  108. }
  109. return false;
  110. }
  111. bool FluidContainerItem::canApplyFoodEffectsFully(Entity* zTarget) const
  112. {
  113. return false;
  114. }
  115. int FluidContainerItem::getAmount() const
  116. {
  117. return fluidAmount;
  118. }
  119. void FluidContainerItem::setAmount(int amount)
  120. {
  121. fluidAmount = amount;
  122. if (!fluidAmount)
  123. {
  124. fluidTypeId = 0;
  125. }
  126. }
  127. int FluidContainerItem::getFluidTypeId() const
  128. {
  129. return fluidTypeId;
  130. }
  131. void FluidContainerItem::setFluidTypeId(int fluidTypeId)
  132. {
  133. this->fluidTypeId = fluidTypeId;
  134. if (!fluidTypeId)
  135. {
  136. fluidAmount = 0;
  137. }
  138. }
  139. FluidContainerItemSkillConfig::FluidContainerItemSkillConfig(
  140. BlockFilter* targetFilter,
  141. float staminaCost,
  142. float staminaCostDevider,
  143. float staminaCostDeviderPerLevel,
  144. int cooldownTicks,
  145. float xpGain)
  146. : targetFilter(targetFilter),
  147. staminaCost(staminaCost),
  148. staminaCostDevider(staminaCostDevider),
  149. staminaCostDeviderPerLevel(staminaCostDeviderPerLevel),
  150. cooldownTicks(cooldownTicks),
  151. xpGain(xpGain)
  152. {}
  153. FluidContainerItemSkillConfig::~FluidContainerItemSkillConfig()
  154. {
  155. if (targetFilter) targetFilter->release();
  156. }
  157. BlockFilter* FluidContainerItemSkillConfig::zTargetFilter() const
  158. {
  159. return targetFilter;
  160. }
  161. float FluidContainerItemSkillConfig::getStaminaCost() const
  162. {
  163. return staminaCost;
  164. }
  165. float FluidContainerItemSkillConfig::getStaminaCostDevider() const
  166. {
  167. return staminaCostDevider;
  168. }
  169. float FluidContainerItemSkillConfig::getStaminaCostDeviderPerLevel() const
  170. {
  171. return staminaCostDeviderPerLevel;
  172. }
  173. int FluidContainerItemSkillConfig::getCooldownTicks() const
  174. {
  175. return cooldownTicks;
  176. }
  177. float FluidContainerItemSkillConfig::getXpGain() const
  178. {
  179. return xpGain;
  180. }
  181. FluidContainerItemSkillConfigFactory::FluidContainerItemSkillConfigFactory()
  182. : TypeFactory()
  183. {}
  184. FluidContainerItemSkillConfig* FluidContainerItemSkillConfigFactory::fromJson(
  185. Framework::JSON::JSONValue* zJson) const
  186. {
  187. return new FluidContainerItemSkillConfig(
  188. Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
  189. zJson->asObject()->zValue("targetFilter")),
  190. (float)zJson->asObject()
  191. ->zValue("staminaCost")
  192. ->asNumber()
  193. ->getNumber(),
  194. (float)zJson->asObject()
  195. ->zValue("staminaCostDevider")
  196. ->asNumber()
  197. ->getNumber(),
  198. (float)zJson->asObject()
  199. ->zValue("staminaCostDeviderPerLevel")
  200. ->asNumber()
  201. ->getNumber(),
  202. (int)zJson->asObject()
  203. ->zValue("cooldownTicks")
  204. ->asNumber()
  205. ->getNumber(),
  206. (float)zJson->asObject()->zValue("xpGain")->asNumber()->getNumber());
  207. }
  208. Framework::JSON::JSONValue* FluidContainerItemSkillConfigFactory::toJson(
  209. FluidContainerItemSkillConfig* zObject) const
  210. {
  211. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  212. result->addValue("targetFilter",
  213. Game::INSTANCE->zTypeRegistry()->toJson(zObject->zTargetFilter()));
  214. result->addValue("staminaCost",
  215. new Framework::JSON::JSONNumber(zObject->getStaminaCost()));
  216. result->addValue("staminaCostDevider",
  217. new Framework::JSON::JSONNumber(zObject->getStaminaCostDevider()));
  218. result->addValue("staminaCostDeviderPerLevel",
  219. new Framework::JSON::JSONNumber(
  220. zObject->getStaminaCostDeviderPerLevel()));
  221. result->addValue("cooldownTicks",
  222. new Framework::JSON::JSONNumber(zObject->getCooldownTicks()));
  223. result->addValue(
  224. "xpGain", new Framework::JSON::JSONNumber(zObject->getXpGain()));
  225. return result;
  226. }
  227. Framework::JSON::Validator::JSONValidator*
  228. FluidContainerItemSkillConfigFactory::getValidator() const
  229. {
  230. return Framework::JSON::Validator::JSONValidator::buildForObject()
  231. ->withRequiredAttribute("targetFilter",
  232. Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
  233. ->withRequiredNumber("staminaCost")
  234. ->whichIsGreaterOrEqual(0.0)
  235. ->withDefault(0.5)
  236. ->finishNumber()
  237. ->withRequiredNumber("staminaCostDevider")
  238. ->whichIsGreaterOrEqual(0.0)
  239. ->withDefault(0.9)
  240. ->finishNumber()
  241. ->withRequiredNumber("staminaCostDeviderPerLevel")
  242. ->whichIsGreaterOrEqual(0.0)
  243. ->withDefault(0.1)
  244. ->finishNumber()
  245. ->withRequiredNumber("cooldownTicks")
  246. ->whichIsGreaterOrEqual(0)
  247. ->withDefault(10)
  248. ->finishNumber()
  249. ->withRequiredNumber("xpGain")
  250. ->whichIsGreaterOrEqual(0.0)
  251. ->withDefault(0.5)
  252. ->finishNumber()
  253. ->finishObject();
  254. }
  255. FluidContainerItemSkill::FluidContainerItemSkill(float xp,
  256. float maxXp,
  257. float level,
  258. int cooldownTicks,
  259. FluidContainerItemSkillConfig* invalidUseConfig,
  260. Framework::RCArray<FluidContainerItemSkillConfig> configs)
  261. : ItemSkill(xp, maxXp, level),
  262. cooldownTicks(cooldownTicks),
  263. invalidUseConfig(invalidUseConfig),
  264. configs(configs)
  265. {}
  266. bool FluidContainerItemSkill::use(
  267. Entity* zActor, Item* zUsedItem, Block* zTarget)
  268. {
  269. if (cooldownTicks)
  270. {
  271. cooldownTicks--;
  272. return false;
  273. }
  274. FluidContainerItem* usedItem = dynamic_cast<FluidContainerItem*>(zUsedItem);
  275. FluidBlock* fluidBlock = dynamic_cast<FluidBlock*>(zTarget);
  276. const FluidContainerItemType* usedItemType
  277. = dynamic_cast<const FluidContainerItemType*>(usedItem->zItemType());
  278. FluidContainerItemSkillConfig* usedConfig = 0;
  279. bool invalid = false;
  280. if (!zTarget->zBlockType()->isFluid() || zTarget->getHP() <= 0)
  281. {
  282. usedConfig = invalidUseConfig;
  283. invalid = true;
  284. }
  285. else if (!usedItem)
  286. {
  287. usedConfig = invalidUseConfig;
  288. invalid = true;
  289. }
  290. else if (!fluidBlock || fluidBlock->getDistanceToSource())
  291. {
  292. usedConfig = invalidUseConfig;
  293. invalid = true;
  294. }
  295. else if (!usedItemType)
  296. {
  297. usedConfig = invalidUseConfig;
  298. invalid = true;
  299. }
  300. else if (usedItem->getAmount() + 1000 <= usedItemType->getMaxFluidAmount())
  301. {
  302. usedConfig = invalidUseConfig;
  303. invalid = true;
  304. }
  305. else if (usedItem->getFluidTypeId()
  306. && usedItem->getFluidTypeId() != fluidBlock->zBlockType()->getId())
  307. {
  308. usedConfig = invalidUseConfig;
  309. invalid = true;
  310. }
  311. if (!usedConfig)
  312. {
  313. for (FluidContainerItemSkillConfig* config : configs)
  314. {
  315. if (config->zTargetFilter()->test(zTarget))
  316. {
  317. usedConfig = config;
  318. break;
  319. }
  320. }
  321. }
  322. if (!usedConfig)
  323. {
  324. usedConfig = invalidUseConfig;
  325. invalid = true;
  326. }
  327. float staminaCost = usedConfig->getStaminaCost();
  328. float staminaCostDevider
  329. = usedConfig->getStaminaCostDevider()
  330. + usedConfig->getStaminaCostDeviderPerLevel() * getLevel();
  331. if (staminaCostDevider)
  332. {
  333. staminaCost /= staminaCostDevider;
  334. }
  335. if (zActor->getStamina() < staminaCost)
  336. {
  337. return false;
  338. }
  339. zActor->setStamina(zActor->getStamina() - staminaCost);
  340. if (!invalid
  341. && usedItem->getAmount() + 1000 <= usedItemType->getMaxFluidAmount())
  342. {
  343. usedItem->setFluidTypeId(fluidBlock->zBlockType()->getId());
  344. usedItem->setAmount(usedItem->getAmount() + 1000);
  345. zTarget->setHP(0);
  346. }
  347. this->cooldownTicks = usedConfig->getCooldownTicks();
  348. setXp(getXp() + usedConfig->getXpGain());
  349. return true;
  350. }
  351. bool FluidContainerItemSkill::use(
  352. Entity* zActor, Item* zUsedItem, Entity* zTarget)
  353. {
  354. // TODO: get milk from cows and something else from other mobs
  355. return false;
  356. }
  357. FluidContainerItemSkillConfig*
  358. FluidContainerItemSkill::zInvalidUseConfig() const
  359. {
  360. return invalidUseConfig;
  361. }
  362. const Framework::RCArray<FluidContainerItemSkillConfig>&
  363. FluidContainerItemSkill::zConfigs() const
  364. {
  365. return configs;
  366. }
  367. FluidContainerItemSkillFactory::FluidContainerItemSkillFactory() {}
  368. FluidContainerItemSkill* FluidContainerItemSkillFactory::fromJson(
  369. Framework::JSON::JSONObject* zJson) const
  370. {
  371. Framework::RCArray<FluidContainerItemSkillConfig> configs;
  372. for (Framework::JSON::JSONValue* configValue :
  373. *zJson->zValue("configs")->asArray())
  374. {
  375. configs.add(Game::INSTANCE->zTypeRegistry()
  376. ->fromJson<FluidContainerItemSkillConfig>(
  377. configValue->asObject()));
  378. }
  379. return new FluidContainerItemSkill(0,
  380. (float)zJson->zValue("maxXp")->asNumber()->getNumber(),
  381. 1,
  382. 0,
  383. new FluidContainerItemSkillConfig(0,
  384. (float)zJson->zValue("invalidUseStaminaCost")
  385. ->asNumber()
  386. ->getNumber(),
  387. (float)zJson->zValue("invalidUseStaminaCostDevider")
  388. ->asNumber()
  389. ->getNumber(),
  390. (float)zJson->zValue("invalidUseStaminaCostDeviderPerLevel")
  391. ->asNumber()
  392. ->getNumber(),
  393. (int)zJson->zValue("invalidUseCooldownTicks")
  394. ->asNumber()
  395. ->getNumber(),
  396. 0),
  397. configs);
  398. }
  399. Framework::JSON::JSONObject* FluidContainerItemSkillFactory::toJson(
  400. FluidContainerItemSkill* zObject) const
  401. {
  402. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  403. result->addValue(
  404. "maxXp", new Framework::JSON::JSONNumber(zObject->getMaxXp()));
  405. result->addValue("invalidUseStaminaCost",
  406. new Framework::JSON::JSONNumber(
  407. zObject->zInvalidUseConfig()->getStaminaCost()));
  408. result->addValue("invalidUseStaminaCostDevider",
  409. new Framework::JSON::JSONNumber(
  410. zObject->zInvalidUseConfig()->getStaminaCostDevider()));
  411. result->addValue("invalidUseStaminaCostDeviderPerLevel",
  412. new Framework::JSON::JSONNumber(
  413. zObject->zInvalidUseConfig()->getStaminaCostDeviderPerLevel()));
  414. result->addValue("invalidUseCooldownTicks",
  415. new Framework::JSON::JSONNumber(
  416. zObject->zInvalidUseConfig()->getCooldownTicks()));
  417. Framework::JSON::JSONArray* configs = new Framework::JSON::JSONArray();
  418. for (FluidContainerItemSkillConfig* config : zObject->zConfigs())
  419. {
  420. configs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(config));
  421. }
  422. result->addValue("configs", configs);
  423. return result;
  424. }
  425. Framework::JSON::Validator::JSONValidator*
  426. FluidContainerItemSkillFactory::getValidator(
  427. Framework::JSON::Validator::ObjectValidationBuilder<
  428. Framework::JSON::Validator::JSONValidator>* builder) const
  429. {
  430. return builder->withRequiredNumber("invalidUseStaminaCost")
  431. ->whichIsGreaterOrEqual(0.0)
  432. ->withDefault(0.5)
  433. ->finishNumber()
  434. ->withRequiredNumber("invalidUseStaminaCostDevider")
  435. ->whichIsGreaterOrEqual(0.0)
  436. ->withDefault(0.9)
  437. ->finishNumber()
  438. ->withRequiredNumber("sinvalidUseStaminaCostDeviderPerLevel")
  439. ->whichIsGreaterOrEqual(0.0)
  440. ->withDefault(0.1)
  441. ->finishNumber()
  442. ->withRequiredNumber("invalidUseCooldownTicks")
  443. ->whichIsGreaterOrEqual(0)
  444. ->withDefault(10)
  445. ->finishNumber()
  446. ->withRequiredNumber("maxXp")
  447. ->whichIsGreaterOrEqual(0)
  448. ->withDefault(10)
  449. ->finishNumber()
  450. ->withRequiredArray("configs")
  451. ->addAcceptedTypeInArray(
  452. Game::INSTANCE->zTypeRegistry()
  453. ->getValidator<FluidContainerItemSkillConfig>())
  454. ->finishArray()
  455. ->finishObject();
  456. }
  457. Framework::Text FluidContainerItemSkillFactory::getTypeToken() const
  458. {
  459. return "fluidGathering";
  460. }
  461. FluidContainerItemType::FluidContainerItemType(Framework::Text name,
  462. ModelInfo* model,
  463. Framework::JSON::JSONObject* itemSkillConfig,
  464. ItemSkillLevelUpRule* levelUpRule,
  465. int maxFluidAmount,
  466. int maxStackSize,
  467. Framework::RCArray<Framework::Text> groups)
  468. : ItemType(name, model, maxStackSize, groups),
  469. itemSkillConfig(itemSkillConfig),
  470. levelUpRule(levelUpRule),
  471. maxFluidAmount(maxFluidAmount)
  472. {}
  473. FluidContainerItemType::~FluidContainerItemType()
  474. {
  475. itemSkillConfig->release();
  476. levelUpRule->release();
  477. }
  478. void FluidContainerItemType::loadSuperItem(
  479. Item* zItem, Framework::StreamReader* zReader) const
  480. {
  481. ItemType::loadSuperItem(zItem, zReader);
  482. FluidContainerItem* item = dynamic_cast<FluidContainerItem*>(zItem);
  483. if (item)
  484. {
  485. zReader->lese((char*)&item->fluidTypeId, 4);
  486. zReader->lese((char*)&item->fluidAmount, 4);
  487. }
  488. else
  489. {
  490. std::cout << "ERROR: FluidContainerItemType::loadSuperItem: "
  491. "zItem is not a FluidContainerItem\n";
  492. }
  493. }
  494. void FluidContainerItemType::saveSuperItem(
  495. const Item* zItem, Framework::StreamWriter* zWriter) const
  496. {
  497. ItemType::saveSuperItem(zItem, zWriter);
  498. const FluidContainerItem* item
  499. = dynamic_cast<const FluidContainerItem*>(zItem);
  500. if (item)
  501. {
  502. zWriter->schreibe((char*)&item->fluidTypeId, 4);
  503. zWriter->schreibe((char*)&item->fluidAmount, 4);
  504. }
  505. else
  506. {
  507. std::cout << "ERROR: FluidContainerItemType::saveSuperItem: "
  508. "zItem is not a FluidContainerItem\n";
  509. }
  510. }
  511. Item* FluidContainerItemType::createItem() const
  512. {
  513. Item* result = new FluidContainerItem(getId(), getName());
  514. return result;
  515. }
  516. ItemSkill* FluidContainerItemType::createDefaultItemSkill() const
  517. {
  518. return Game::INSTANCE->zTypeRegistry()->fromJson<ItemSkill>(
  519. itemSkillConfig);
  520. }
  521. void FluidContainerItemType::levelUpItemSkill(ItemSkill* zSkill) const
  522. {
  523. levelUpRule->applyOn(zSkill);
  524. }
  525. void FluidContainerItemType::setItemAttribute(
  526. Item* zItem, Framework::Text name, Framework::JSON::JSONValue* zValue) const
  527. {
  528. FluidContainerItem* item = dynamic_cast<FluidContainerItem*>(zItem);
  529. if (!item)
  530. {
  531. std::cout << "ERROR: FluidContainerItemType::setItemAttribute: "
  532. "zItem is not a FluidContainerItem\n";
  533. return;
  534. }
  535. if (name.istGleich("fluidType"))
  536. {
  537. if (zValue->getType() == Framework::JSON::JSONType::STRING)
  538. {
  539. int id = ItemType::getTypeId(zValue->asString()->getString());
  540. if (id)
  541. {
  542. item->fluidTypeId = id;
  543. }
  544. else
  545. {
  546. std::cout << "ERROR: FluidContainerItemType::setItemAttribute: "
  547. "'fluidType' is not a valid type name\n";
  548. }
  549. }
  550. else
  551. {
  552. std::cout << "ERROR: FluidContainerItemType::setItemAttribute: "
  553. "'fluidType' is not a string or string\n";
  554. }
  555. }
  556. else if (name.istGleich("fluidAmount"))
  557. {
  558. if (zValue->getType() == Framework::JSON::JSONType::NUMBER)
  559. {
  560. item->fluidAmount = (int)zValue->asNumber()->getNumber();
  561. }
  562. else
  563. {
  564. std::cout << "ERROR: FluidContainerItemType::setItemAttribute: "
  565. "'fluidAmount' is not a number\n";
  566. }
  567. }
  568. else
  569. {
  570. ItemType::setItemAttribute(zItem, name, zValue);
  571. }
  572. }
  573. void FluidContainerItemType::addItemAttributes(
  574. Item* zItem, Framework::JSON::JSONObject* zItemObjet) const
  575. {
  576. FluidContainerItem* item = dynamic_cast<FluidContainerItem*>(zItem);
  577. if (!item)
  578. {
  579. std::cout << "ERROR: FluidContainerItemType::addItemAttributes: "
  580. "zItem is not a FluidContainerItem\n";
  581. return;
  582. }
  583. ItemType::addItemAttributes(zItem, zItemObjet);
  584. if (item->fluidTypeId)
  585. {
  586. zItemObjet->addValue("fluidType",
  587. new Framework::JSON::JSONString(
  588. Game::INSTANCE->zItemType(item->fluidTypeId)->getName()));
  589. zItemObjet->addValue(
  590. "fluidAmount", new Framework::JSON::JSONNumber(item->fluidAmount));
  591. }
  592. }
  593. Framework::JSON::JSONObject* FluidContainerItemType::zItemSkillConfig() const
  594. {
  595. return itemSkillConfig;
  596. }
  597. ItemSkillLevelUpRule* FluidContainerItemType::zLevelUpRule() const
  598. {
  599. return levelUpRule;
  600. }
  601. int FluidContainerItemType::getMaxFluidAmount() const
  602. {
  603. return maxFluidAmount;
  604. }
  605. FluidContainerItemType* FluidContainerItemType::setMaxFluidAmount(
  606. int maxFluidAmount)
  607. {
  608. this->maxFluidAmount = maxFluidAmount;
  609. return this;
  610. }
  611. FluidContainerItemTypeFactory::FluidContainerItemTypeFactory()
  612. : SubTypeFactory()
  613. {}
  614. FluidContainerItemType* FluidContainerItemTypeFactory::fromJson(
  615. Framework::JSON::JSONObject* zJson) const
  616. {
  617. Framework::RCArray<Framework::Text> groups;
  618. for (Framework::JSON::JSONValue* group :
  619. *zJson->zValue("groupNames")->asArray())
  620. {
  621. groups.add(new Framework::Text(group->asString()->getString()));
  622. }
  623. return new FluidContainerItemType(
  624. zJson->zValue("name")->asString()->getString(),
  625. Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
  626. zJson->zValue("model")),
  627. zJson->getValue("itemSkill")->asObject(),
  628. Game::INSTANCE->zTypeRegistry()->fromJson<ItemSkillLevelUpRule>(
  629. zJson->zValue("levelUpRule")),
  630. (int)zJson->zValue("maxFluidAmount")->asNumber()->getNumber(),
  631. (int)zJson->zValue("maxStack")->asNumber()->getNumber(),
  632. groups);
  633. }
  634. Framework::JSON::JSONObject* FluidContainerItemTypeFactory::toJson(
  635. FluidContainerItemType* zObject) const
  636. {
  637. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  638. result->addValue(
  639. "name", new Framework::JSON::JSONString(zObject->getName()));
  640. result->addValue(
  641. "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
  642. result->addValue("levelUpRule",
  643. Game::INSTANCE->zTypeRegistry()->toJson(zObject->zLevelUpRule()));
  644. result->addValue("itemSkill",
  645. dynamic_cast<Framework::JSON::JSONObject*>(
  646. zObject->zItemSkillConfig()->getThis()));
  647. result->addValue("maxFluidAmount",
  648. new Framework::JSON::JSONNumber(zObject->getMaxFluidAmount()));
  649. result->addValue("maxStack",
  650. new Framework::JSON::JSONNumber(zObject->getMaxStackSize()));
  651. Framework::JSON::JSONArray* groups = new Framework::JSON::JSONArray();
  652. for (Framework::Text* group : zObject->getGroups())
  653. {
  654. groups->addValue(new Framework::JSON::JSONString(group->getText()));
  655. }
  656. result->addValue("groupNames", groups);
  657. return result;
  658. }
  659. Framework::JSON::Validator::JSONValidator*
  660. FluidContainerItemTypeFactory::getValidator(
  661. Framework::JSON::Validator::ObjectValidationBuilder<
  662. Framework::JSON::Validator::JSONValidator>* builder) const
  663. {
  664. return builder->withRequiredString("name")
  665. ->finishString()
  666. ->withRequiredAttribute(
  667. "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
  668. ->withRequiredAttribute("levelUpRule",
  669. Game::INSTANCE->zTypeRegistry()
  670. ->getValidator<ItemSkillLevelUpRule>())
  671. ->withRequiredAttribute("itemSkill",
  672. Game::INSTANCE->zTypeRegistry()->getValidator<ItemSkill>())
  673. ->withRequiredNumber("maxFluidAmount")
  674. ->whichIsGreaterThen(0)
  675. ->withDefault(1000.0)
  676. ->finishNumber()
  677. ->withRequiredNumber("maxStack")
  678. ->withDefault(50.0)
  679. ->whichIsGreaterOrEqual(1.0)
  680. ->finishNumber()
  681. ->withRequiredArray("groupNames")
  682. ->addAcceptedStringInArray()
  683. ->finishString()
  684. ->withDefault(new Framework::JSON::JSONArray())
  685. ->finishArray()
  686. ->finishObject();
  687. }
  688. Framework::Text FluidContainerItemTypeFactory::getTypeToken() const
  689. {
  690. return "fluidContainer";
  691. }