#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* PlantConfigFactory::fromJson( Framework::JSON::JSONObject* zJson) const { PlantConfig* config = new PlantConfig(); config->setCondition( Game::INSTANCE->zTypeRegistry()->fromJson( 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( zObject->zCondition())); zJson->addValue("noise", dynamic_cast( 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()) ->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( BlockTypeNameFactory::TYPE_ID)) ->withRequiredNumber("plantHeight") ->whichIsGreaterOrEqual(1) ->finishNumber(); }