#pragma once #include <Array.h> #include <Either.h> #include <ReferenceCounter.h> #include "BiomGenerator.h" #include "CaveGenerator.h" #include "Chunk.h" #include "JNoise.h" #include "JsonExpression.h" class DimensionGenerator; class WorldHeightLayer : public virtual Framework::ReferenceCounter { private: Framework::JSON::JSONObject* noiseConfig; Noise* noise; Framework::Text name; JFloatExpression* value; public: WorldHeightLayer(); ~WorldHeightLayer(); void initialize(JExpressionMemory* zMemory); void calculateValue(JExpressionMemory* zMemory); void setNoiseConfig(Framework::JSON::JSONObject* noiseConfig); Framework::JSON::JSONObject* zNoiseConfig() const; void setName(Framework::Text name); Framework::Text getName() const; void setValue(JFloatExpression* value); JFloatExpression* zValue() const; }; class WorldHeightLayerFactory : public ObjectTypeFactory<WorldHeightLayer> { public: WorldHeightLayerFactory(); WorldHeightLayer* fromJson( Framework::JSON::JSONObject* zJson) const override; Framework::JSON::JSONObject* toJsonObject( WorldHeightLayer* zObject) const override; JSONObjectValidationBuilder* addToValidator( JSONObjectValidationBuilder* builder) const override; }; class DimensionGenerator : public virtual Framework::ReferenceCounter { private: JExpressionMemory* jExpressionMemory; JFloatExpression* seedExpression; Framework::RCArray<WorldHeightLayer> heightLayers; Framework::Text name; int dimensionId; protected: DimensionGenerator(); ~DimensionGenerator(); JExpressionMemory* zMemory() const; void calculateHeightLayers(); public: Dimension* createDimension(); virtual void initialize(int worldSeed); virtual Chunk* generateChunk(int centerX, int centerY) = 0; virtual Framework::Either<Block*, int> generateBlock( Framework::Vec3<int> location) = 0; virtual bool spawnStructure(Framework::Vec3<int> location, std::function<bool(GeneratorTemplate* tmpl)> filter) = 0; virtual void generateEntities(Chunk* zChunk) = 0; int getDimensionId() const; void addHeightLayer(WorldHeightLayer* layer); const Framework::RCArray<WorldHeightLayer>& getHeightLayers() const; void setName(Framework::Text name); Framework::Text getName() const; void setId(int id); int getId() const; void setSeed(JFloatExpression* seed); JFloatExpression* zSeed() const; }; template<typename S> class DimensionGeneratorFactory : public SubTypeFactory<DimensionGenerator, S> { public: DimensionGeneratorFactory() : SubTypeFactory<DimensionGenerator, S>() {} S* fromJson(Framework::JSON::JSONObject* zJson) const override { S* result = createValue(zJson); DimensionGenerator* zGenerator = dynamic_cast<DimensionGenerator*>(result); zGenerator->setName(zJson->zValue("name")->asString()->getString()); zGenerator->setId((int)zJson->zValue("id")->asNumber()->getNumber()); zGenerator->setSeed( Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>( zJson->zValue("dimensionSeed"))); for (Framework::JSON::JSONValue* layer : *zJson->zValue("heightLayers")->asArray()) { zGenerator->addHeightLayer( Game::INSTANCE->zTypeRegistry()->fromJson<WorldHeightLayer>( layer)); } return result; } Framework::JSON::JSONObject* toJsonObject(S* zObject) const override { Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject(); DimensionGenerator* zGenerator = dynamic_cast<DimensionGenerator*>(zObject); result->addValue( "name", new Framework::JSON::JSONString(zGenerator->getName())); result->addValue( "id", new Framework::JSON::JSONNumber(zGenerator->getId())); result->addValue("dimensionSeed", Game::INSTANCE->zTypeRegistry()->toJson<JFloatExpression>( zGenerator->zSeed())); Framework::JSON::JSONArray* hightLayers = new Framework::JSON::JSONArray(); for (WorldHeightLayer* layer : zGenerator->getHeightLayers()) { hightLayers->addValue( Game::INSTANCE->zTypeRegistry()->toJson(layer)); } result->addValue("heightLayers", hightLayers); return result; } JSONObjectValidationBuilder* addToValidator( JSONObjectValidationBuilder* builder) const override { return builder ->withRequiredAttribute("dimensionSeed", Game::INSTANCE->zTypeRegistry() ->getValidator<JFloatExpression>()) ->withRequiredArray("heightLayers") ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry() ->getValidator<WorldHeightLayer>()) ->finishArray() ->withRequiredString("name") ->finishString() ->withRequiredNumber("id") ->finishNumber(); } protected: virtual S* createValue(Framework::JSON::JSONObject* zJson) const = 0; }; class BiomGenerator; class BiomedCavedDimensionGenerator : public DimensionGenerator { private: Framework::RCArray<BiomGenerator> biomGenerators; CaveGenerator* caveGenerator; Framework::JSON::JSONObject* noiseConfig; Noise* biomNoise; Framework::Vec3<int> minStructureOffset; Framework::Vec3<int> maxStructureOffset; BiomGenerator* zBiomGenerator(); protected: Framework::RCArray<GeneratedStructure>* getGeneratedStructoresForArea( Framework::Vec3<int> minPos, Framework::Vec3<int> maxPos); public: BiomedCavedDimensionGenerator(); ~BiomedCavedDimensionGenerator(); virtual void initialize(int worldSeed) override; Chunk* generateChunk(int centerX, int centerY); void generateEntities(Chunk* zChunk); Framework::Either<Block*, int> generateBlock(Framework::Vec3<int> location); bool spawnStructure(Framework::Vec3<int> location, std::function<bool(GeneratorTemplate* tmpl)> filter); void addBiomGenerator(BiomGenerator* biomGenerator); const Framework::RCArray<BiomGenerator>& getBiomGenerators() const; void setBiomNoiseConfig(Framework::JSON::JSONObject* biomNoiseConfig); Framework::JSON::JSONObject* zBiomNoiseConfig() const; }; class BiomedCavedDimensionGeneratorFactory : public DimensionGeneratorFactory<BiomedCavedDimensionGenerator> { public: BiomedCavedDimensionGeneratorFactory(); BiomedCavedDimensionGenerator* createValue( Framework::JSON::JSONObject* zJson) const override; BiomedCavedDimensionGenerator* fromJson( Framework::JSON::JSONObject* zJson) const override; Framework::JSON::JSONObject* toJsonObject( BiomedCavedDimensionGenerator* zObject) const override; JSONObjectValidationBuilder* addToValidator( JSONObjectValidationBuilder* builder) const override; const char* getTypeToken() const override; };