#include "StructureCollection.h" #include "Game.h" #include "JNoise.h" StructureTemplateCollection::StructureTemplateCollection( Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory) : ReferenceCounter() { activeNoise = JNoise::parseNoisse( zConfig->asObject()->zValue("activeNoise"), zMemory); structureNoise = JNoise::parseNoisse( zConfig->asObject()->zValue("structureNoise"), zMemory); threshold = zConfig->asObject()->zValue("threshold")->asNumber()->getNumber(); condition = JExpressionParser::parseBoolExpression( zConfig->asObject()->zValue("condition")); bool first = 1; for (Framework::JSON::JSONValue* value : *zConfig->asObject()->zValue("structures")->asArray()) { GeneratorTemplate* templ = Game::INSTANCE->zTypeRegistry()->createGeneratorTemplate(value); if (first) { minAffected = templ->getMinAffectedOffset(); maxAffected = templ->getMaxAffectedOffset(); first = 0; } else { Framework::Vec3 min = templ->getMinAffectedOffset(); Framework::Vec3 max = templ->getMaxAffectedOffset(); if (minAffected.x > min.x) minAffected.x = min.x; if (minAffected.y > min.y) minAffected.y = min.y; if (minAffected.z > min.z) minAffected.z = min.z; if (maxAffected.x < max.x) maxAffected.x = max.x; if (maxAffected.y < max.y) maxAffected.y = max.y; if (maxAffected.z < max.z) maxAffected.z = max.z; } structures.add(templ); } } StructureTemplateCollection::~StructureTemplateCollection() { activeNoise->release(); structureNoise->release(); condition->release(); } void StructureTemplateCollection::generateStructures(int x, int y, int z, int dimensionId, JExpressionMemory* zMemory, Framework::Vec3 minPos, Framework::Vec3 maxPos, Framework::RCArray* zResult) { int minSearchX = minPos.x - maxAffected.x; int minSearchY = minPos.y - maxAffected.y; int minSearchZ = MAX(minPos.z - maxAffected.z, 0); int maxSearchX = maxPos.x - minAffected.x; int maxSearchY = maxPos.y - minAffected.y; int maxSearchZ = MIN(maxPos.z - minAffected.z, WORLD_HEIGHT - 1); if (x >= minSearchX && x <= maxSearchX && y >= minSearchY && y <= maxSearchY && z >= minSearchZ && z <= maxSearchZ) { if (condition->getValue(zMemory)) { if (activeNoise->getNoise((double)x, (double)y, (double)z) < threshold) { double rValue = structureNoise->getNoise((double)x, (double)y, (double)z); double probSum = 0; for (auto t : structures) { if (rValue - probSum <= t->getPropability()) { zResult->add( t->generateAt(Framework::Vec3(x, y, z), structureNoise, dimensionId)); break; } probSum += t->getPropability(); } } } } } const Framework::RCArray& StructureTemplateCollection::getStructures() const { return structures; } Framework::Vec3 StructureTemplateCollection::getMinAffected() const { return minAffected; } Framework::Vec3 StructureTemplateCollection::getMaxAffected() const { return maxAffected; } Framework::JSON::Validator::JSONValidator* StructureTemplateCollection::getConfigValidator() { return Framework::JSON::Validator::JSONValidator::buildForObject() ->withRequiredAttribute("activeNoise", JNoise::getValidator(false)) ->withRequiredAttribute("structureNoise", JNoise::getValidator(false)) ->withRequiredNumber("threshold") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredAttribute( "condition", JExpressionParser::getBoolValidator()) ->withRequiredArray("structures") ->addAcceptedTypeInArray( Game::INSTANCE->zTypeRegistry()->getGeneratorTemplateValidator()) ->finishArray() ->finishObject(); }