|
|
@@ -0,0 +1,269 @@
|
|
|
+#include "PlantConfig.h"
|
|
|
+
|
|
|
+#include "Chunk.h"
|
|
|
+#include "Dimension.h"
|
|
|
+#include "Game.h"
|
|
|
+#include "JNoise.h"
|
|
|
+
|
|
|
+PlantConfig::PlantConfig()
|
|
|
+ : Framework::ReferenceCounter(),
|
|
|
+ condition(0),
|
|
|
+ noise(0),
|
|
|
+ noiseConfig(0),
|
|
|
+ threshold(0.0),
|
|
|
+ locations(0),
|
|
|
+ plantBlockTypeName(""),
|
|
|
+ plantblockTypeId(0),
|
|
|
+ plantHeight(0)
|
|
|
+{}
|
|
|
+
|
|
|
+PlantConfig::~PlantConfig()
|
|
|
+{
|
|
|
+ if (condition)
|
|
|
+ {
|
|
|
+ condition->release();
|
|
|
+ }
|
|
|
+ if (noise)
|
|
|
+ {
|
|
|
+ noise->release();
|
|
|
+ }
|
|
|
+ if (noiseConfig)
|
|
|
+ {
|
|
|
+ noiseConfig->release();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PlantConfig::initialize(JExpressionMemory* zMemory)
|
|
|
+{
|
|
|
+ condition->compile(zMemory);
|
|
|
+ if (noise)
|
|
|
+ {
|
|
|
+ noise->release();
|
|
|
+ }
|
|
|
+ noise = JNoise::parseNoise(noiseConfig, zMemory);
|
|
|
+ plantblockTypeId = Game::INSTANCE->getBlockTypeId(plantBlockTypeName);
|
|
|
+}
|
|
|
+
|
|
|
+double PlantConfig::doesGeneratePlant(int x,
|
|
|
+ int y,
|
|
|
+ int z,
|
|
|
+ int dimensionId,
|
|
|
+ Chunk* zChunk,
|
|
|
+ bool underground,
|
|
|
+ bool underwater,
|
|
|
+ int seaFluidBlockTypeId)
|
|
|
+{
|
|
|
+ if (underwater && !(locations & PlantLocation::UNDERWATER))
|
|
|
+ {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ if (!underwater && underground && !(locations & PlantLocation::CAVE))
|
|
|
+ {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ if (!underwater && !underground && !(locations & PlantLocation::SURFACE))
|
|
|
+ {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ if (z + plantHeight > WORLD_HEIGHT)
|
|
|
+ {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ for (int i = 0; i < plantHeight; i++)
|
|
|
+ {
|
|
|
+ int result = zChunk->getBlockTypeAt(
|
|
|
+ Dimension::chunkCoordinates({x, y, z + i}));
|
|
|
+ if (result != BlockTypeEnum::AIR && result != seaFluidBlockTypeId)
|
|
|
+ {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!condition->getValue())
|
|
|
+ {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ if (!noise)
|
|
|
+ {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ return noise->getNoise((double)x, (double)y, (double)z) - threshold;
|
|
|
+}
|
|
|
+
|
|
|
+void PlantConfig::generatePlantAt(
|
|
|
+ int x, int y, int z, int dimensionId, Chunk* zChunk)
|
|
|
+{
|
|
|
+ for (int i = 0; i < plantHeight; i++)
|
|
|
+ {
|
|
|
+ zChunk->putBlockTypeAt(
|
|
|
+ Dimension::chunkCoordinates({x, y, z + i}), plantblockTypeId);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PlantConfig::setCondition(JBoolExpression* condition)
|
|
|
+{
|
|
|
+ if (this->condition)
|
|
|
+ {
|
|
|
+ this->condition->release();
|
|
|
+ }
|
|
|
+ this->condition = condition;
|
|
|
+}
|
|
|
+
|
|
|
+JBoolExpression* PlantConfig::zCondition() const
|
|
|
+{
|
|
|
+ return condition;
|
|
|
+}
|
|
|
+
|
|
|
+void PlantConfig::setNoiseConfig(Framework::JSON::JSONObject* noiseConfig)
|
|
|
+{
|
|
|
+ if (this->noiseConfig)
|
|
|
+ {
|
|
|
+ this->noiseConfig->release();
|
|
|
+ }
|
|
|
+ this->noiseConfig = noiseConfig;
|
|
|
+}
|
|
|
+
|
|
|
+Framework::JSON::JSONObject* PlantConfig::zNoiseConfig() const
|
|
|
+{
|
|
|
+ return noiseConfig;
|
|
|
+}
|
|
|
+
|
|
|
+void PlantConfig::setThreshold(double threshold)
|
|
|
+{
|
|
|
+ this->threshold = threshold;
|
|
|
+}
|
|
|
+
|
|
|
+double PlantConfig::getThreshold() const
|
|
|
+{
|
|
|
+ return threshold;
|
|
|
+}
|
|
|
+
|
|
|
+void PlantConfig::setLocations(int locations)
|
|
|
+{
|
|
|
+ this->locations = locations;
|
|
|
+}
|
|
|
+
|
|
|
+int PlantConfig::getLocations() const
|
|
|
+{
|
|
|
+ return locations;
|
|
|
+}
|
|
|
+
|
|
|
+void PlantConfig::setPlantBlockTypeName(Framework::Text name)
|
|
|
+{
|
|
|
+ this->plantBlockTypeName = name;
|
|
|
+}
|
|
|
+
|
|
|
+Framework::Text PlantConfig::getPlantBlockTypeName() const
|
|
|
+{
|
|
|
+ return plantBlockTypeName;
|
|
|
+}
|
|
|
+
|
|
|
+void PlantConfig::setPlantHeight(int height)
|
|
|
+{
|
|
|
+ this->plantHeight = height;
|
|
|
+}
|
|
|
+
|
|
|
+int PlantConfig::getPlantHeight() const
|
|
|
+{
|
|
|
+ return plantHeight;
|
|
|
+}
|
|
|
+
|
|
|
+PlantConfigFactory::PlantConfigFactory()
|
|
|
+ : ObjectTypeFactory<PlantConfig>()
|
|
|
+{}
|
|
|
+
|
|
|
+PlantConfig* PlantConfigFactory::fromJson(
|
|
|
+ Framework::JSON::JSONObject* zJson) const
|
|
|
+{
|
|
|
+ PlantConfig* config = new PlantConfig();
|
|
|
+ config->setCondition(
|
|
|
+ Game::INSTANCE->zTypeRegistry()->fromJson<JBoolExpression>(
|
|
|
+ zJson->zValue("condition")));
|
|
|
+ config->setNoiseConfig(zJson->getValue("noise")->asObject());
|
|
|
+ config->setThreshold(zJson->zValue("threshold")->asNumber()->getNumber());
|
|
|
+ config->setLocations(0);
|
|
|
+ Framework::JSON::JSONArray* zLocationsArray
|
|
|
+ = zJson->zValue("locations")->asArray();
|
|
|
+ for (int i = 0; i < zLocationsArray->getLength(); i++)
|
|
|
+ {
|
|
|
+ Framework::Text locationStr
|
|
|
+ = zLocationsArray->zValue(i)->asString()->getString();
|
|
|
+ if (locationStr.istGleich("CAVE"))
|
|
|
+ {
|
|
|
+ config->setLocations(config->getLocations() | PlantLocation::CAVE);
|
|
|
+ }
|
|
|
+ else if (locationStr.istGleich("UNDERWATER"))
|
|
|
+ {
|
|
|
+ config->setLocations(
|
|
|
+ config->getLocations() | PlantLocation::UNDERWATER);
|
|
|
+ }
|
|
|
+ else if (locationStr.istGleich("SURFACE"))
|
|
|
+ {
|
|
|
+ config->setLocations(
|
|
|
+ config->getLocations() | PlantLocation::SURFACE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ config->setPlantBlockTypeName(
|
|
|
+ zJson->zValue("plantBlock")->asString()->getString());
|
|
|
+ config->setPlantHeight(
|
|
|
+ (int)zJson->zValue("plantHeight")->asNumber()->getNumber());
|
|
|
+ return config;
|
|
|
+}
|
|
|
+
|
|
|
+Framework::JSON::JSONObject* PlantConfigFactory::toJsonObject(
|
|
|
+ PlantConfig* zObject) const
|
|
|
+{
|
|
|
+ Framework::JSON::JSONObject* zJson = new Framework::JSON::JSONObject();
|
|
|
+ zJson->addValue("condition",
|
|
|
+ Game::INSTANCE->zTypeRegistry()->toJson<JBoolExpression>(
|
|
|
+ zObject->zCondition()));
|
|
|
+ zJson->addValue("noise",
|
|
|
+ dynamic_cast<Framework::JSON::JSONObject*>(
|
|
|
+ zObject->zNoiseConfig()->getThis()));
|
|
|
+ zJson->addValue(
|
|
|
+ "threshold", new Framework::JSON::JSONNumber(zObject->getThreshold()));
|
|
|
+ Framework::JSON::JSONArray* zLocationsArray
|
|
|
+ = new Framework::JSON::JSONArray();
|
|
|
+ int locations = zObject->getLocations();
|
|
|
+ if (locations & PlantLocation::CAVE)
|
|
|
+ {
|
|
|
+ zLocationsArray->addValue(new Framework::JSON::JSONString("CAVE"));
|
|
|
+ }
|
|
|
+ if (locations & PlantLocation::UNDERWATER)
|
|
|
+ {
|
|
|
+ zLocationsArray->addValue(
|
|
|
+ new Framework::JSON::JSONString("UNDERWATER"));
|
|
|
+ }
|
|
|
+ if (locations & PlantLocation::SURFACE)
|
|
|
+ {
|
|
|
+ zLocationsArray->addValue(new Framework::JSON::JSONString("SURFACE"));
|
|
|
+ }
|
|
|
+ zJson->addValue("locations", zLocationsArray);
|
|
|
+ zJson->addValue("plantBlock",
|
|
|
+ new Framework::JSON::JSONString(zObject->getPlantBlockTypeName()));
|
|
|
+ zJson->addValue("plantHeight",
|
|
|
+ new Framework::JSON::JSONNumber(zObject->getPlantHeight()));
|
|
|
+ return zJson;
|
|
|
+}
|
|
|
+
|
|
|
+JSONObjectValidationBuilder* PlantConfigFactory::addToValidator(
|
|
|
+ JSONObjectValidationBuilder* builder) const
|
|
|
+{
|
|
|
+ return builder
|
|
|
+ ->withRequiredAttribute("condition",
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<JBoolExpression>())
|
|
|
+ ->withRequiredAttribute("noise", JNoise::getValidator(false))
|
|
|
+ ->withRequiredNumber("threshold")
|
|
|
+ ->withDefault(0.5)
|
|
|
+ ->finishNumber()
|
|
|
+ ->withRequiredArray("locations")
|
|
|
+ ->addAcceptedStringInArray()
|
|
|
+ ->whichIsOneOf({"CAVE", "UNDERWATER", "SURFACE"})
|
|
|
+ ->finishString()
|
|
|
+ ->finishArray()
|
|
|
+ ->withRequiredAttribute("plantBlock",
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
|
|
|
+ BlockTypeNameFactory::TYPE_ID))
|
|
|
+ ->withRequiredNumber("plantHeight")
|
|
|
+ ->whichIsGreaterOrEqual(1)
|
|
|
+ ->finishNumber();
|
|
|
+}
|