diff --git a/src/items/Inventories.hpp b/src/items/Inventories.hpp index aed3e090..1af4ec8a 100644 --- a/src/items/Inventories.hpp +++ b/src/items/Inventories.hpp @@ -15,7 +15,7 @@ using inventories_map = std::unordered_map>; class Inventories { Level& level; inventories_map map; - PseudoRandom random; + util::PseudoRandom random; public: Inventories(Level& level); ~Inventories(); diff --git a/src/maths/util.hpp b/src/maths/util.hpp index 5e671082..432fe0bb 100644 --- a/src/maths/util.hpp +++ b/src/maths/util.hpp @@ -4,49 +4,63 @@ #include -class PseudoRandom { - unsigned short seed; -public: - PseudoRandom() { - seed = (unsigned short)time(0); - } +namespace util { + class PseudoRandom { + unsigned short seed; + public: + PseudoRandom() { + seed = static_cast(time(0)); + } - int rand() { - seed = (seed + 0x7ed5 + (seed << 6)); - seed = (seed ^ 0xc23c ^ (seed >> 9)); - seed = (seed + 0x1656 + (seed << 3)); - seed = ((seed + 0xa264) ^ (seed << 4)); - seed = (seed + 0xfd70 - (seed << 3)); - seed = (seed ^ 0xba49 ^ (seed >> 8)); + int rand() { + seed = (seed + 0x7ed5 + (seed << 6)); + seed = (seed ^ 0xc23c ^ (seed >> 9)); + seed = (seed + 0x1656 + (seed << 3)); + seed = ((seed + 0xa264) ^ (seed << 4)); + seed = (seed + 0xfd70 - (seed << 3)); + seed = (seed ^ 0xba49 ^ (seed >> 8)); - return (int)seed; - } + return static_cast(seed); + } - int32_t rand32() { - return (rand() << 16) | rand(); - } + int32_t rand32() { + return (rand() << 16) | rand(); + } - uint32_t randU32() { - return (rand() << 16) | rand(); - } + uint32_t randU32() { + return (rand() << 16) | rand(); + } - int64_t rand64() { - uint64_t x = randU32(); - uint64_t y = randU32(); - return (x << 32ULL) | y; - } + int64_t rand64() { + uint64_t x = randU32(); + uint64_t y = randU32(); + return (x << 32ULL) | y; + } - void setSeed(int number) { - seed = - ((unsigned short)(number * 23729) ^ (unsigned short)(number + 16786) - ); - rand(); - } - void setSeed(int number1, int number2) { - seed = - (((unsigned short)(number1 * 23729) | - (unsigned short)(number2 % 16786)) ^ - (unsigned short)(number2 * number1)); - rand(); - } -}; + uint64_t randU64() { + uint64_t x = randU32(); + uint64_t y = randU32(); + return (x << 32ULL) | y; + } + + float randFloat() { + return randU32() / static_cast(UINT32_MAX); + } + + double randDouble() { + return randU64() / static_cast(UINT64_MAX); + } + + void setSeed(int number) { + seed = (static_cast(number * 23729) ^ + static_cast(number + 16786)); + rand(); + } + void setSeed(int number1, int number2) { + seed = ((static_cast(number1 * 23729) | + static_cast(number2 % 16786)) ^ + static_cast(number2 * number1)); + rand(); + } + }; +} diff --git a/src/world/generator/WorldGenerator.cpp b/src/world/generator/WorldGenerator.cpp index 11602236..27c6753c 100644 --- a/src/world/generator/WorldGenerator.cpp +++ b/src/world/generator/WorldGenerator.cpp @@ -173,7 +173,6 @@ void WorldGenerator::generateStructures( } const auto& biomes = prototype.biomes; const auto& heightmap = prototype.heightmap; - const auto& heights = heightmap->getValues(); util::concat(prototype.structures, def.script->placeStructures( {chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed, @@ -189,13 +188,13 @@ void WorldGenerator::generateStructures( offset, placement.structure, placement.rotation, chunkX, chunkZ); } - PseudoRandom structsRand; + util::PseudoRandom structsRand; structsRand.setSeed(chunkX, chunkZ); + auto heights = heightmap->getValues(); for (uint z = 0; z < CHUNK_D; z++) { for (uint x = 0; x < CHUNK_W; x++) { - float rand = (structsRand.randU32() % RAND_MAX) / - static_cast(RAND_MAX); + float rand = structsRand.randFloat(); const Biome* biome = biomes[z * CHUNK_W + x]; size_t structureId = biome->structures.choose(rand, -1); if (structureId == -1) { @@ -273,7 +272,7 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) { std::memset(voxels, 0, sizeof(voxel) * CHUNK_VOL); - PseudoRandom plantsRand; + util::PseudoRandom plantsRand; plantsRand.setSeed(chunkX, chunkZ); const auto& biomes = prototype.biomes.get(); @@ -291,8 +290,7 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) { generate_pole(groundLayers, height, 0, seaLevel, voxels, x, z); if (height+1 > seaLevel) { - float rand = (plantsRand.randU32() % RAND_MAX) / - static_cast(RAND_MAX); + float rand = plantsRand.randFloat(); blockid_t plant = biome->plants.choose(rand); if (plant) { voxels[vox_index(x, height+1, z)].id = plant; @@ -306,7 +304,8 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) { logger.error() << "invalid structure index " << placement.structure; continue; } - auto& structure = *def.structures[placement.structure]->fragments[placement.rotation]; + auto& generatingStructure = def.structures[placement.structure]; + auto& structure = *generatingStructure->fragments[placement.rotation]; auto& structVoxels = structure.getRuntimeVoxels(); const auto& offset = placement.position; const auto& size = structure.getSize();