TreeSeblingBlock.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #include "TreeSeblingBlock.h"
  2. #include "BasicBlocks.h"
  3. #include "Game.h"
  4. #include "NoBlock.h"
  5. #include "RandNoise.h"
  6. #include "TreeTemplate.h"
  7. TreeSeblingBlock::TreeSeblingBlock(int typeId,
  8. Framework::Vec3<int> pos,
  9. int dimensionId,
  10. const BlockType* wood,
  11. const BlockType* leaves)
  12. : Block(typeId, pos, dimensionId, 0),
  13. seblingTicks(0),
  14. seblingTicksMax(10000),
  15. wood(wood),
  16. leaves(leaves)
  17. {
  18. tickSource = 1;
  19. }
  20. bool TreeSeblingBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
  21. {
  22. int lastPercentage = (int)(seblingTicks / (float)seblingTicksMax * 100.f);
  23. seblingTicks += 1;
  24. if ((int)(seblingTicks / (float)seblingTicksMax * 100.f) != lastPercentage)
  25. {
  26. Game::INSTANCE->blockTargetChanged(this);
  27. }
  28. return 0;
  29. }
  30. void TreeSeblingBlock::onPostTick()
  31. {
  32. if ((int)seblingTicks >= seblingTicksMax)
  33. {
  34. Game::INSTANCE->doLater([wood = wood,
  35. leaves = leaves,
  36. pos = getPos(),
  37. dim = getDimensionId()]() {
  38. // the tree sebling object will be deleted during this operation
  39. RandNoise noise((int)time(0));
  40. if (!Game::INSTANCE->zGenerator()->spawnStructure(pos,
  41. dim,
  42. [wood = wood, leaves = leaves](GeneratorTemplate* tmpl) {
  43. TreeTemplate* tree = dynamic_cast<TreeTemplate*>(tmpl);
  44. return tree && tree->getWoodType() == wood
  45. && tree->getLeavesType() == leaves;
  46. }))
  47. {
  48. Game::INSTANCE->zDimension(dim)->placeBlock(
  49. pos, BlockTypeEnum::AIR);
  50. }
  51. });
  52. }
  53. }
  54. Framework::Text TreeSeblingBlock::getTargetUIML()
  55. {
  56. return Text("<targetInfo><text width=\"auto\" height=\"auto\">")
  57. + Game::INSTANCE->zBlockType(typeId)->getName() + "\n" + "Growth: "
  58. + Text((int)(seblingTicks / (float)seblingTicksMax * 100.f))
  59. + "%</text></targetInfo>";
  60. }
  61. TreeSeblingBlockType::TreeSeblingBlockType(Framework::Text itemTypeName,
  62. ModelInfo* model,
  63. Framework::Text woodTypeName,
  64. Framework::Text leavesTypeName,
  65. Framework::Text name,
  66. int mapColor,
  67. float hardness,
  68. Framework::RCArray<Framework::Text> groupNames)
  69. : BlockType(
  70. 0, model, true, 10, false, name, false, mapColor, groupNames, hardness),
  71. itemTypeName(itemTypeName),
  72. transparent(true),
  73. passable(true),
  74. speedModifier(0.5f),
  75. interactable(1),
  76. woodTypeName(woodTypeName),
  77. leavesTypeName(leavesTypeName)
  78. {}
  79. bool TreeSeblingBlockType::initialize(Game* zGame)
  80. {
  81. if (itemTypeName.getLength())
  82. {
  83. itemTypeId = zGame->getItemTypeId(itemTypeName);
  84. }
  85. else
  86. {
  87. itemTypeId = 0;
  88. }
  89. woodTypeId = zGame->getBlockTypeId(woodTypeName);
  90. leavesTypeId = zGame->getBlockTypeId(leavesTypeName);
  91. return itemTypeId >= 0 && BlockType::initialize(zGame);
  92. }
  93. Framework::Text TreeSeblingBlockType::getItemTypeName() const
  94. {
  95. return itemTypeName;
  96. }
  97. Framework::Text TreeSeblingBlockType::getWoodTypeName() const
  98. {
  99. return woodTypeName;
  100. }
  101. Framework::Text TreeSeblingBlockType::getLeavesTypeName() const
  102. {
  103. return leavesTypeName;
  104. }
  105. ItemType* TreeSeblingBlockType::createItemType() const
  106. {
  107. return new BasicBlockItemType(getItemTypeName(),
  108. new ModelInfo(zModel()->getModelPath(),
  109. zModel()->getTexturePaths(),
  110. zModel()->isTransparent(),
  111. zModel()->getSize() / 2.f),
  112. transparent,
  113. passable,
  114. getHardness(),
  115. speedModifier,
  116. getName(),
  117. 0, 50, getGroupNames());
  118. }
  119. void TreeSeblingBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
  120. {
  121. TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
  122. block->transparent = transparent;
  123. block->passable = passable;
  124. block->hp = (float)getInitialMaxHP();
  125. block->maxHP = (float)getInitialMaxHP();
  126. block->hardness = getHardness();
  127. block->speedModifier = speedModifier;
  128. block->interactable = interactable;
  129. BlockType::createSuperBlock(zBlock, zItem);
  130. }
  131. void TreeSeblingBlockType::loadSuperBlock(
  132. Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const
  133. {
  134. TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
  135. zReader->lese((char*)&block->seblingTicks, 4);
  136. zReader->lese((char*)&block->seblingTicksMax, 4);
  137. int id;
  138. zReader->lese((char*)&id, 4);
  139. block->wood = Game::INSTANCE->zBlockType(id);
  140. zReader->lese((char*)&id, 4);
  141. block->leaves = Game::INSTANCE->zBlockType(id);
  142. BlockType::loadSuperBlock(zBlock, zReader, dimensionId);
  143. }
  144. void TreeSeblingBlockType::saveSuperBlock(
  145. Block* zBlock, Framework::StreamWriter* zWriter) const
  146. {
  147. TreeSeblingBlock* block = dynamic_cast<TreeSeblingBlock*>(zBlock);
  148. zWriter->schreibe((char*)&block->seblingTicks, 4);
  149. zWriter->schreibe((char*)&block->seblingTicksMax, 4);
  150. int id = block->wood->getId();
  151. zWriter->schreibe((char*)&id, 4);
  152. id = block->leaves->getId();
  153. zWriter->schreibe((char*)&id, 4);
  154. BlockType::saveSuperBlock(zBlock, zWriter);
  155. }
  156. Item* TreeSeblingBlockType::createItem() const
  157. {
  158. return Game::INSTANCE->zItemType(itemTypeId)->createItem();
  159. }
  160. Block* TreeSeblingBlockType::createBlock(
  161. Framework::Vec3<int> position, int dimensionId) const
  162. {
  163. return new TreeSeblingBlock(getId(),
  164. position,
  165. dimensionId,
  166. Game::INSTANCE->zBlockType(woodTypeId),
  167. Game::INSTANCE->zBlockType(leavesTypeId));
  168. }
  169. TreeSeblingBlockTypeFactory::TreeSeblingBlockTypeFactory()
  170. : SubTypeFactory()
  171. {}
  172. TreeSeblingBlockType* TreeSeblingBlockTypeFactory::fromJson(
  173. Framework::JSON::JSONObject* zJson) const
  174. {
  175. Framework::RCArray<Framework::Text> groupNames;
  176. for (Framework::JSON::JSONValue* value :
  177. *zJson->zValue("groupNames")->asArray())
  178. {
  179. groupNames.add(new Framework::Text(value->asString()->getString()));
  180. }
  181. return new TreeSeblingBlockType(
  182. zJson->zValue("itemType")->asString()->getString(),
  183. Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
  184. zJson->zValue("model")),
  185. zJson->zValue("woodType")->asString()->getString(),
  186. zJson->zValue("leavesType")->asString()->getString(),
  187. zJson->zValue("name")->asString()->getString(),
  188. (int)zJson->zValue("mapColor")->asString()->getString(),
  189. (float)zJson->zValue("hardness")->asNumber()->getNumber(),
  190. groupNames);
  191. }
  192. Framework::JSON::JSONObject* TreeSeblingBlockTypeFactory::toJson(
  193. TreeSeblingBlockType* zObject) const
  194. {
  195. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  196. result->addValue("itemType",
  197. new Framework::JSON::JSONString(zObject->getItemTypeName()));
  198. result->addValue(
  199. "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
  200. result->addValue(
  201. "name", new Framework::JSON::JSONString(zObject->getName()));
  202. result->addValue(
  203. "hardness", new Framework::JSON::JSONNumber(zObject->getHardness()));
  204. result->addValue(
  205. "mapColor", new Framework::JSON::JSONString(zObject->getMapColor()));
  206. result->addValue("woodType",
  207. new Framework::JSON::JSONString(zObject->getWoodTypeName()));
  208. result->addValue("leavesType",
  209. new Framework::JSON::JSONString(zObject->getLeavesTypeName()));
  210. Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
  211. for (Framework::Text* groupName : zObject->getGroupNames())
  212. {
  213. groupNames->addValue(new Framework::JSON::JSONString(*groupName));
  214. }
  215. result->addValue("groupNames", groupNames);
  216. return result;
  217. }
  218. Framework::JSON::Validator::JSONValidator*
  219. TreeSeblingBlockTypeFactory::getValidator(
  220. Framework::JSON::Validator::ObjectValidationBuilder<
  221. Framework::JSON::Validator::JSONValidator>* builder) const
  222. {
  223. return builder->withRequiredString("itemType")
  224. ->finishString()
  225. ->withRequiredAttribute(
  226. "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
  227. ->withRequiredString("name")
  228. ->finishString()
  229. ->withRequiredNumber("hardness")
  230. ->withDefault(1.0)
  231. ->finishNumber()
  232. ->withRequiredString("mapColor")
  233. ->finishString()
  234. ->withRequiredString("woodType")
  235. ->finishString()
  236. ->withRequiredString("leavesType")
  237. ->finishString()
  238. ->withRequiredArray("groupNames")
  239. ->withDefault(new Framework::JSON::JSONArray())
  240. ->addAcceptedStringInArray()
  241. ->finishString()
  242. ->finishArray()
  243. ->finishObject();
  244. }
  245. Framework::Text TreeSeblingBlockTypeFactory::getTypeToken() const
  246. {
  247. return "treeSapling";
  248. }