PlantConfig.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #include "PlantConfig.h"
  2. #include "Chunk.h"
  3. #include "Dimension.h"
  4. #include "Game.h"
  5. #include "JNoise.h"
  6. PlantConfig::PlantConfig()
  7. : Framework::ReferenceCounter(),
  8. condition(0),
  9. noise(0),
  10. noiseConfig(0),
  11. threshold(0.0),
  12. locations(0),
  13. plantBlockTypeName(""),
  14. plantblockTypeId(0),
  15. plantHeight(0)
  16. {}
  17. PlantConfig::~PlantConfig()
  18. {
  19. if (condition)
  20. {
  21. condition->release();
  22. }
  23. if (noise)
  24. {
  25. noise->release();
  26. }
  27. if (noiseConfig)
  28. {
  29. noiseConfig->release();
  30. }
  31. }
  32. void PlantConfig::initialize(JExpressionMemory* zMemory)
  33. {
  34. condition->compile(zMemory);
  35. if (noise)
  36. {
  37. noise->release();
  38. }
  39. noise = JNoise::parseNoise(noiseConfig, zMemory);
  40. plantblockTypeId = Game::INSTANCE->getBlockTypeId(plantBlockTypeName);
  41. }
  42. double PlantConfig::doesGeneratePlant(int x,
  43. int y,
  44. int z,
  45. int dimensionId,
  46. Chunk* zChunk,
  47. bool underground,
  48. bool underwater,
  49. int seaFluidBlockTypeId)
  50. {
  51. if (underwater && !(locations & PlantLocation::UNDERWATER))
  52. {
  53. return 0.0;
  54. }
  55. if (!underwater && underground && !(locations & PlantLocation::CAVE))
  56. {
  57. return 0.0;
  58. }
  59. if (!underwater && !underground && !(locations & PlantLocation::SURFACE))
  60. {
  61. return 0.0;
  62. }
  63. if (z + plantHeight > WORLD_HEIGHT)
  64. {
  65. return 0.0;
  66. }
  67. for (int i = 0; i < plantHeight; i++)
  68. {
  69. int result = zChunk->getBlockTypeAt(
  70. Dimension::chunkCoordinates({x, y, z + i}));
  71. if (result != BlockTypeEnum::AIR && result != seaFluidBlockTypeId)
  72. {
  73. return 0.0;
  74. }
  75. }
  76. if (!condition->getValue())
  77. {
  78. return 0.0;
  79. }
  80. if (!noise)
  81. {
  82. return 0.0;
  83. }
  84. return noise->getNoise((double)x, (double)y, (double)z) - threshold;
  85. }
  86. void PlantConfig::generatePlantAt(
  87. int x, int y, int z, int dimensionId, Chunk* zChunk)
  88. {
  89. for (int i = 0; i < plantHeight; i++)
  90. {
  91. zChunk->putBlockTypeAt(
  92. Dimension::chunkCoordinates({x, y, z + i}), plantblockTypeId);
  93. }
  94. }
  95. void PlantConfig::setCondition(JBoolExpression* condition)
  96. {
  97. if (this->condition)
  98. {
  99. this->condition->release();
  100. }
  101. this->condition = condition;
  102. }
  103. JBoolExpression* PlantConfig::zCondition() const
  104. {
  105. return condition;
  106. }
  107. void PlantConfig::setNoiseConfig(Framework::JSON::JSONObject* noiseConfig)
  108. {
  109. if (this->noiseConfig)
  110. {
  111. this->noiseConfig->release();
  112. }
  113. this->noiseConfig = noiseConfig;
  114. }
  115. Framework::JSON::JSONObject* PlantConfig::zNoiseConfig() const
  116. {
  117. return noiseConfig;
  118. }
  119. void PlantConfig::setThreshold(double threshold)
  120. {
  121. this->threshold = threshold;
  122. }
  123. double PlantConfig::getThreshold() const
  124. {
  125. return threshold;
  126. }
  127. void PlantConfig::setLocations(int locations)
  128. {
  129. this->locations = locations;
  130. }
  131. int PlantConfig::getLocations() const
  132. {
  133. return locations;
  134. }
  135. void PlantConfig::setPlantBlockTypeName(Framework::Text name)
  136. {
  137. this->plantBlockTypeName = name;
  138. }
  139. Framework::Text PlantConfig::getPlantBlockTypeName() const
  140. {
  141. return plantBlockTypeName;
  142. }
  143. void PlantConfig::setPlantHeight(int height)
  144. {
  145. this->plantHeight = height;
  146. }
  147. int PlantConfig::getPlantHeight() const
  148. {
  149. return plantHeight;
  150. }
  151. PlantConfigFactory::PlantConfigFactory()
  152. : ObjectTypeFactory<PlantConfig>()
  153. {}
  154. PlantConfig* PlantConfigFactory::fromJson(
  155. Framework::JSON::JSONObject* zJson) const
  156. {
  157. PlantConfig* config = new PlantConfig();
  158. config->setCondition(
  159. Game::INSTANCE->zTypeRegistry()->fromJson<JBoolExpression>(
  160. zJson->zValue("condition")));
  161. config->setNoiseConfig(zJson->getValue("noise")->asObject());
  162. config->setThreshold(zJson->zValue("threshold")->asNumber()->getNumber());
  163. config->setLocations(0);
  164. Framework::JSON::JSONArray* zLocationsArray
  165. = zJson->zValue("locations")->asArray();
  166. for (int i = 0; i < zLocationsArray->getLength(); i++)
  167. {
  168. Framework::Text locationStr
  169. = zLocationsArray->zValue(i)->asString()->getString();
  170. if (locationStr.istGleich("CAVE"))
  171. {
  172. config->setLocations(config->getLocations() | PlantLocation::CAVE);
  173. }
  174. else if (locationStr.istGleich("UNDERWATER"))
  175. {
  176. config->setLocations(
  177. config->getLocations() | PlantLocation::UNDERWATER);
  178. }
  179. else if (locationStr.istGleich("SURFACE"))
  180. {
  181. config->setLocations(
  182. config->getLocations() | PlantLocation::SURFACE);
  183. }
  184. }
  185. config->setPlantBlockTypeName(
  186. zJson->zValue("plantBlock")->asString()->getString());
  187. config->setPlantHeight(
  188. (int)zJson->zValue("plantHeight")->asNumber()->getNumber());
  189. return config;
  190. }
  191. Framework::JSON::JSONObject* PlantConfigFactory::toJsonObject(
  192. PlantConfig* zObject) const
  193. {
  194. Framework::JSON::JSONObject* zJson = new Framework::JSON::JSONObject();
  195. zJson->addValue("condition",
  196. Game::INSTANCE->zTypeRegistry()->toJson<JBoolExpression>(
  197. zObject->zCondition()));
  198. zJson->addValue("noise",
  199. dynamic_cast<Framework::JSON::JSONObject*>(
  200. zObject->zNoiseConfig()->getThis()));
  201. zJson->addValue(
  202. "threshold", new Framework::JSON::JSONNumber(zObject->getThreshold()));
  203. Framework::JSON::JSONArray* zLocationsArray
  204. = new Framework::JSON::JSONArray();
  205. int locations = zObject->getLocations();
  206. if (locations & PlantLocation::CAVE)
  207. {
  208. zLocationsArray->addValue(new Framework::JSON::JSONString("CAVE"));
  209. }
  210. if (locations & PlantLocation::UNDERWATER)
  211. {
  212. zLocationsArray->addValue(
  213. new Framework::JSON::JSONString("UNDERWATER"));
  214. }
  215. if (locations & PlantLocation::SURFACE)
  216. {
  217. zLocationsArray->addValue(new Framework::JSON::JSONString("SURFACE"));
  218. }
  219. zJson->addValue("locations", zLocationsArray);
  220. zJson->addValue("plantBlock",
  221. new Framework::JSON::JSONString(zObject->getPlantBlockTypeName()));
  222. zJson->addValue("plantHeight",
  223. new Framework::JSON::JSONNumber(zObject->getPlantHeight()));
  224. return zJson;
  225. }
  226. JSONObjectValidationBuilder* PlantConfigFactory::addToValidator(
  227. JSONObjectValidationBuilder* builder) const
  228. {
  229. return builder
  230. ->withRequiredAttribute("condition",
  231. Game::INSTANCE->zTypeRegistry()->getValidator<JBoolExpression>())
  232. ->withRequiredAttribute("noise", JNoise::getValidator(false))
  233. ->withRequiredNumber("threshold")
  234. ->withDefault(0.5)
  235. ->finishNumber()
  236. ->withRequiredArray("locations")
  237. ->addAcceptedStringInArray()
  238. ->whichIsOneOf({"CAVE", "UNDERWATER", "SURFACE"})
  239. ->finishString()
  240. ->finishArray()
  241. ->withRequiredAttribute("plantBlock",
  242. Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
  243. BlockTypeNameFactory::TYPE_ID))
  244. ->withRequiredNumber("plantHeight")
  245. ->whichIsGreaterOrEqual(1)
  246. ->finishNumber();
  247. }