add new methods to PseudoRandom & move this class to util::

This commit is contained in:
MihailRis
2024-09-24 22:37:31 +03:00
parent c987bbd34f
commit 36eed38b4c
3 changed files with 62 additions and 49 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ using inventories_map = std::unordered_map<int64_t, std::shared_ptr<Inventory>>;
class Inventories { class Inventories {
Level& level; Level& level;
inventories_map map; inventories_map map;
PseudoRandom random; util::PseudoRandom random;
public: public:
Inventories(Level& level); Inventories(Level& level);
~Inventories(); ~Inventories();
+26 -12
View File
@@ -4,11 +4,12 @@
#include <ctime> #include <ctime>
class PseudoRandom { namespace util {
class PseudoRandom {
unsigned short seed; unsigned short seed;
public: public:
PseudoRandom() { PseudoRandom() {
seed = (unsigned short)time(0); seed = static_cast<unsigned short>(time(0));
} }
int rand() { int rand() {
@@ -19,7 +20,7 @@ public:
seed = (seed + 0xfd70 - (seed << 3)); seed = (seed + 0xfd70 - (seed << 3));
seed = (seed ^ 0xba49 ^ (seed >> 8)); seed = (seed ^ 0xba49 ^ (seed >> 8));
return (int)seed; return static_cast<int>(seed);
} }
int32_t rand32() { int32_t rand32() {
@@ -36,17 +37,30 @@ public:
return (x << 32ULL) | y; return (x << 32ULL) | y;
} }
uint64_t randU64() {
uint64_t x = randU32();
uint64_t y = randU32();
return (x << 32ULL) | y;
}
float randFloat() {
return randU32() / static_cast<float>(UINT32_MAX);
}
double randDouble() {
return randU64() / static_cast<double>(UINT64_MAX);
}
void setSeed(int number) { void setSeed(int number) {
seed = seed = (static_cast<unsigned short>(number * 23729) ^
((unsigned short)(number * 23729) ^ (unsigned short)(number + 16786) static_cast<unsigned short>(number + 16786));
);
rand(); rand();
} }
void setSeed(int number1, int number2) { void setSeed(int number1, int number2) {
seed = seed = ((static_cast<unsigned short>(number1 * 23729) |
(((unsigned short)(number1 * 23729) | static_cast<unsigned short>(number2 % 16786)) ^
(unsigned short)(number2 % 16786)) ^ static_cast<unsigned short>(number2 * number1));
(unsigned short)(number2 * number1));
rand(); rand();
} }
}; };
}
+7 -8
View File
@@ -173,7 +173,6 @@ void WorldGenerator::generateStructures(
} }
const auto& biomes = prototype.biomes; const auto& biomes = prototype.biomes;
const auto& heightmap = prototype.heightmap; const auto& heightmap = prototype.heightmap;
const auto& heights = heightmap->getValues();
util::concat(prototype.structures, def.script->placeStructures( util::concat(prototype.structures, def.script->placeStructures(
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed, {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); offset, placement.structure, placement.rotation, chunkX, chunkZ);
} }
PseudoRandom structsRand; util::PseudoRandom structsRand;
structsRand.setSeed(chunkX, chunkZ); structsRand.setSeed(chunkX, chunkZ);
auto heights = heightmap->getValues();
for (uint z = 0; z < CHUNK_D; z++) { for (uint z = 0; z < CHUNK_D; z++) {
for (uint x = 0; x < CHUNK_W; x++) { for (uint x = 0; x < CHUNK_W; x++) {
float rand = (structsRand.randU32() % RAND_MAX) / float rand = structsRand.randFloat();
static_cast<float>(RAND_MAX);
const Biome* biome = biomes[z * CHUNK_W + x]; const Biome* biome = biomes[z * CHUNK_W + x];
size_t structureId = biome->structures.choose(rand, -1); size_t structureId = biome->structures.choose(rand, -1);
if (structureId == -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); std::memset(voxels, 0, sizeof(voxel) * CHUNK_VOL);
PseudoRandom plantsRand; util::PseudoRandom plantsRand;
plantsRand.setSeed(chunkX, chunkZ); plantsRand.setSeed(chunkX, chunkZ);
const auto& biomes = prototype.biomes.get(); 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); generate_pole(groundLayers, height, 0, seaLevel, voxels, x, z);
if (height+1 > seaLevel) { if (height+1 > seaLevel) {
float rand = (plantsRand.randU32() % RAND_MAX) / float rand = plantsRand.randFloat();
static_cast<float>(RAND_MAX);
blockid_t plant = biome->plants.choose(rand); blockid_t plant = biome->plants.choose(rand);
if (plant) { if (plant) {
voxels[vox_index(x, height+1, z)].id = 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; logger.error() << "invalid structure index " << placement.structure;
continue; 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(); auto& structVoxels = structure.getRuntimeVoxels();
const auto& offset = placement.position; const auto& offset = placement.position;
const auto& size = structure.getSize(); const auto& size = structure.getSize();