Add random walk as an alternative to flood fill for oregen (#148)
* Improved oregen * [Lua API] Added biome ore definition property 'gen_type'. Co-authored-by: Quentin Bazin <quent42340@gmail.com>master
parent
95233b78ad
commit
5ba2699c4b
|
@ -183,7 +183,8 @@ ores = {
|
|||
{
|
||||
block = "default:iron_ore",
|
||||
probability = 0.0003,
|
||||
size = 8
|
||||
size = 8,
|
||||
gen_type = "flood_fill"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -193,6 +194,7 @@ Possible attributes:
|
|||
- `block`: Ore block to be used
|
||||
- `probability`: Probability to spawn an ore vein with that block
|
||||
- `size`: Ore vein size
|
||||
- `gen_type`: Algorithm used for generation (possible values: `flood_fill`, `random_walk`)
|
||||
|
||||
### `params`
|
||||
|
||||
|
|
|
@ -57,10 +57,17 @@ mod:biome {
|
|||
-- could decide whether ores at a point very far down should
|
||||
-- still depend on the surface biome, or only on the worldtype.
|
||||
ores = {
|
||||
{
|
||||
block = "default:coal_ore",
|
||||
probability = 0.001,
|
||||
size = 2,
|
||||
gen_type = "flood_fill",
|
||||
},
|
||||
{
|
||||
block = "default:iron_ore",
|
||||
probability = 0.0003,
|
||||
size = 8
|
||||
probability = 0.003,
|
||||
size = 8,
|
||||
gen_type = "random_walk",
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -49,16 +49,22 @@ struct Flora : public gk::ISerializable {
|
|||
};
|
||||
|
||||
struct Ore : public gk::ISerializable {
|
||||
enum Gen {
|
||||
RandomWalk,
|
||||
FloodFill
|
||||
};
|
||||
|
||||
u16 blockID;
|
||||
double probability;
|
||||
double size;
|
||||
u8 genType;
|
||||
|
||||
void serialize(sf::Packet &packet) const override {
|
||||
packet << blockID << probability << size;
|
||||
packet << blockID << probability << size << genType;
|
||||
}
|
||||
|
||||
void deserialize(sf::Packet &packet) override {
|
||||
packet >> blockID >> probability >> size;
|
||||
packet >> blockID >> probability >> size >> genType;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -143,6 +143,13 @@ inline void LuaBiomeLoader::loadOrePlacementEntries(Biome &biome, const sol::tab
|
|||
oreEntry.blockID = Registry::getInstance().getBlockFromStringID(oreDefinition["block"]).id();
|
||||
oreEntry.probability = oreDefinition["probability"];
|
||||
oreEntry.size = oreDefinition["size"];
|
||||
|
||||
std::unordered_map<std::string, PlacementEntry::Ore::Gen> genTypes{
|
||||
{"random_walk", PlacementEntry::Ore::Gen::RandomWalk},
|
||||
{"flood_fill", PlacementEntry::Ore::Gen::FloodFill},
|
||||
};
|
||||
|
||||
oreEntry.genType = genTypes.at(oreDefinition["gen_type"].get<std::string>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,12 +84,12 @@ void TerrainGenerator::fastNoiseGeneration(ServerChunk &chunk) const {
|
|||
else
|
||||
chunk.setBlockRaw(x, y, z, biome.getDeepBlockID());
|
||||
|
||||
// Populate ores.
|
||||
generateOres(chunk, x, y, z, biome, rand);
|
||||
|
||||
// Caves
|
||||
generateCaves(chunk, x, y, z, h);
|
||||
|
||||
// Populate ores.
|
||||
generateOres(chunk, x, y, z, biome, rand);
|
||||
|
||||
// Generate trees, flora and portals
|
||||
if (isGeneratingTopBlock && chunk.getBlock(x, y, z)) {
|
||||
// Try to place a tree
|
||||
|
@ -199,20 +199,39 @@ inline void TerrainGenerator::generateOres(ServerChunk &chunk, int x, int y, int
|
|||
if (!rand.get<bool>(ore.probability))
|
||||
continue;
|
||||
|
||||
oreFloodFill(chunk, x, y, z, biome.getDeepBlockID(), ore.blockID, 2, rand);
|
||||
if (ore.genType == PlacementEntry::Ore::Gen::RandomWalk)
|
||||
randomWalkOrePlace(chunk, x, y, z, rand, ore.blockID, biome.getDeepBlockID(), ore.size);
|
||||
else if (ore.genType == PlacementEntry::Ore::Gen::FloodFill)
|
||||
oreFloodFill(chunk, x, y, z, biome.getDeepBlockID(), ore.blockID, ore.size, rand);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void TerrainGenerator::generateCaves(ServerChunk &chunk, int x, int y, int z, int h) const {
|
||||
float n2 = noise2d(-(x + chunk.x() * CHUNK_WIDTH) / 256.0, (y + chunk.y() * CHUNK_DEPTH) / 256.0, 8, 0.3) * 4;
|
||||
float r2 = noise3d_abs(-(x + chunk.x() * CHUNK_WIDTH) / 512.0f, (z + chunk.z() * CHUNK_HEIGHT) / 512.0f, (y + chunk.y() * CHUNK_DEPTH) / 512.0f, 4, 0.1);
|
||||
float r3 = noise3d_abs(-(x + chunk.x() * CHUNK_WIDTH) / 512.0f, (z + chunk.z() * CHUNK_HEIGHT) / 128.0f, (y + chunk.y() * CHUNK_DEPTH) / 512.0f, 4, 1);
|
||||
float r4 = n2 * 5 + r2 * r3 * 20;
|
||||
if (r4 > 6 && r4 < 8 && h > SEALEVEL) {
|
||||
chunk.setBlockRaw(x, y, z - 1, 0);
|
||||
chunk.setBlockRaw(x, y, z, 0);
|
||||
chunk.setBlockRaw(x, y, z + 1, 0);
|
||||
inline void TerrainGenerator::randomWalkOrePlace(ServerChunk &chunk, int x, int y, int z, Random_t &rand, u16 oreBlock, u16 deepBlock, int size) const {
|
||||
if (size <= 0 || chunk.getBlock(x, y, z) != deepBlock)
|
||||
return;
|
||||
chunk.setBlockRaw(x, y, z, oreBlock);
|
||||
int direction = rand.get(1, 6);
|
||||
switch(direction) {
|
||||
case 1:
|
||||
randomWalkOrePlace(chunk, x + 1, y, z, rand, oreBlock, deepBlock, size - 1);
|
||||
break;
|
||||
case 2:
|
||||
randomWalkOrePlace(chunk, x - 1, y, z, rand, oreBlock, deepBlock, size - 1);
|
||||
break;
|
||||
case 3:
|
||||
randomWalkOrePlace(chunk, x, y + 1, z, rand, oreBlock, deepBlock, size - 1);
|
||||
break;
|
||||
case 4:
|
||||
randomWalkOrePlace(chunk, x, y - 1, z, rand, oreBlock, deepBlock, size - 1);
|
||||
break;
|
||||
case 5:
|
||||
randomWalkOrePlace(chunk, x, y, z + 1, rand, oreBlock, deepBlock, size - 1);
|
||||
break;
|
||||
case 6:
|
||||
randomWalkOrePlace(chunk, x, y, z - 1, rand, oreBlock, deepBlock, size - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,6 +266,18 @@ void TerrainGenerator::oreFloodFill(ServerChunk &chunk, double x, double y, doub
|
|||
oreFloodFill(chunk, x - 1, y - 1, z - 1, toReplace, replaceWith, depth - 1, rand);
|
||||
}
|
||||
|
||||
inline void TerrainGenerator::generateCaves(ServerChunk &chunk, int x, int y, int z, int h) const {
|
||||
float n2 = noise2d(-(x + chunk.x() * CHUNK_WIDTH) / 256.0, (y + chunk.y() * CHUNK_DEPTH) / 256.0, 8, 0.3) * 4;
|
||||
float r2 = noise3d_abs(-(x + chunk.x() * CHUNK_WIDTH) / 512.0f, (z + chunk.z() * CHUNK_HEIGHT) / 512.0f, (y + chunk.y() * CHUNK_DEPTH) / 512.0f, 4, 0.1);
|
||||
float r3 = noise3d_abs(-(x + chunk.x() * CHUNK_WIDTH) / 512.0f, (z + chunk.z() * CHUNK_HEIGHT) / 128.0f, (y + chunk.y() * CHUNK_DEPTH) / 512.0f, 4, 1);
|
||||
float r4 = n2 * 5 + r2 * r3 * 20;
|
||||
if (r4 > 6 && r4 < 8 && h > SEALEVEL) {
|
||||
chunk.setBlockRaw(x, y, z - 1, 0);
|
||||
chunk.setBlockRaw(x, y, z, 0);
|
||||
chunk.setBlockRaw(x, y, z + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
inline float TerrainGenerator::noise2d(double x, double y, int octaves, float persistence) {
|
||||
float sum = 0;
|
||||
float strength = 1.0;
|
||||
|
|
|
@ -57,7 +57,9 @@ class TerrainGenerator {
|
|||
void generateOres(ServerChunk &chunk, int x, int y, int z, const Biome &biome, Random_t &rand) const;
|
||||
void generateCaves(ServerChunk &chunk, int x, int y, int z, int h) const;
|
||||
|
||||
void randomWalkOrePlace(ServerChunk &chunk, int x, int y, int z, Random_t &rand, u16 oreBlock, u16 deepBlock, int size) const;
|
||||
void oreFloodFill(ServerChunk &chunk, double x, double y, double z, u16 toReplace, u16 replaceWith, int depth, Random_t &rand) const;
|
||||
|
||||
static float noise2d(double x, double y, int octaves, float persistence);
|
||||
static float noise3d_abs(double x, double y, double z, int octaves, float persistence);
|
||||
|
||||
|
|
Loading…
Reference in New Issue