summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mapgen/mapgen_v6.cpp167
1 files changed, 76 insertions, 91 deletions
diff --git a/src/mapgen/mapgen_v6.cpp b/src/mapgen/mapgen_v6.cpp
index 28ca8faa2..4e876fc53 100644
--- a/src/mapgen/mapgen_v6.cpp
+++ b/src/mapgen/mapgen_v6.cpp
@@ -538,7 +538,7 @@ void MapgenV6::makeChunk(BlockMakeData *data)
updateHeightmap(node_min, node_max);
const s16 max_spread_amount = MAP_BLOCKSIZE;
- // Limit dirt flow area by 1 because mud is flown into neighbors.
+ // Limit dirt flow area by 1 because mud is flowed into neighbors
s16 mudflow_minpos = -max_spread_amount + 1;
s16 mudflow_maxpos = central_area_size.X + max_spread_amount - 2;
@@ -773,6 +773,14 @@ void MapgenV6::addMud()
void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos)
{
+ const v3s16 &em = vm->m_area.getExtent();
+ static const v3s16 dirs4[4] = {
+ v3s16(0, 0, 1), // Back
+ v3s16(1, 0, 0), // Right
+ v3s16(0, 0, -1), // Front
+ v3s16(-1, 0, 0), // Left
+ };
+
// Iterate twice
for (s16 k = 0; k < 2; k++) {
for (s16 z = mudflow_minpos; z <= mudflow_maxpos; z++)
@@ -781,120 +789,97 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos)
v2s16 p2d;
// Invert coordinates on second iteration to process columns in
// opposite order, to avoid a directional bias.
- if (k == 1) {
- p2d = v2s16(node_min.X, node_min.Z) + v2s16(
- mudflow_maxpos - (x - mudflow_minpos),
- mudflow_maxpos - (z - mudflow_minpos));
- } else {
+ if (k == 1)
+ p2d = v2s16(node_max.X, node_max.Z) - v2s16(x, z);
+ else
p2d = v2s16(node_min.X, node_min.Z) + v2s16(x, z);
- }
- const v3s16 &em = vm->m_area.getExtent();
- u32 i = vm->m_area.index(p2d.X, node_max.Y, p2d.Y);
s16 y = node_max.Y;
while (y >= node_min.Y) {
+ for (;; y--) {
+ u32 i = vm->m_area.index(p2d.X, y, p2d.Y);
+ MapNode *n = nullptr;
+
+ // Find next mud node in mapchunk column
+ for (; y >= node_min.Y; y--) {
+ n = &vm->m_data[i];
+ if (n->getContent() == c_dirt ||
+ n->getContent() == c_dirt_with_grass ||
+ n->getContent() == c_gravel)
+ break;
- for (;; y--) {
- MapNode *n = NULL;
- // Find mud
- for (; y >= node_min.Y; y--) {
- n = &vm->m_data[i];
- if (n->getContent() == c_dirt ||
- n->getContent() == c_dirt_with_grass ||
- n->getContent() == c_gravel)
+ VoxelArea::add_y(em, i, -1);
+ }
+ if (y < node_min.Y)
+ // No mud found in mapchunk column, process the next column
break;
- VoxelArea::add_y(em, i, -1);
- }
-
- // Stop if out of area
- //if(vmanip.m_area.contains(i) == false)
- if (y < node_min.Y)
- break;
-
- if (n->getContent() == c_dirt ||
- n->getContent() == c_dirt_with_grass) {
- // Make it exactly mud
- n->setContent(c_dirt);
-
- // Don't flow it if the stuff under it is not mud
- {
+ if (n->getContent() == c_dirt || n->getContent() == c_dirt_with_grass) {
+ // Convert dirt_with_grass to dirt
+ n->setContent(c_dirt);
+ // Don't flow mud if the stuff under it is not mud,
+ // to leave at least 1 node of mud.
u32 i2 = i;
VoxelArea::add_y(em, i2, -1);
- // Cancel if out of area
- if (!vm->m_area.contains(i2))
- continue;
MapNode *n2 = &vm->m_data[i2];
if (n2->getContent() != c_dirt &&
n2->getContent() != c_dirt_with_grass)
+ // Find next mud node in column
continue;
}
- }
- static const v3s16 dirs4[4] = {
- v3s16(0, 0, 1), // back
- v3s16(1, 0, 0), // right
- v3s16(0, 0, -1), // front
- v3s16(-1, 0, 0), // left
- };
-
- // Check that upper is walkable. Cancel
- // dropping if upper keeps it in place.
- u32 i3 = i;
- VoxelArea::add_y(em, i3, 1);
- MapNode *n3 = NULL;
-
- if (vm->m_area.contains(i3)) {
- n3 = &vm->m_data[i3];
+ // Check if node above is walkable. If so, cancel
+ // flowing as if node above keeps it in place.
+ u32 i3 = i;
+ VoxelArea::add_y(em, i3, 1);
+ MapNode *n3 = &vm->m_data[i3];
if (ndef->get(*n3).walkable)
+ // Find next mud node in column
continue;
- }
- // Drop mud on side
- for (const v3s16 &dirp : dirs4) {
- u32 i2 = i;
- // Move to side
- VoxelArea::add_p(em, i2, dirp);
- // Fail if out of area
- if (!vm->m_area.contains(i2))
- continue;
- // Check that side is air
- MapNode *n2 = &vm->m_data[i2];
- if (ndef->get(*n2).walkable)
- continue;
- // Check that under side is air
- VoxelArea::add_y(em, i2, -1);
- if (!vm->m_area.contains(i2))
- continue;
- n2 = &vm->m_data[i2];
- if (ndef->get(*n2).walkable)
- continue;
- // Loop further down until not air
- bool dropped_to_unknown = false;
- do {
+ // Drop mud on one side
+ for (const v3s16 &dirp : dirs4) {
+ u32 i2 = i;
+ // Move to side
+ VoxelArea::add_p(em, i2, dirp);
+ // Check that side is air
+ MapNode *n2 = &vm->m_data[i2];
+ if (ndef->get(*n2).walkable)
+ continue;
+
+ // Check that under side is air
VoxelArea::add_y(em, i2, -1);
n2 = &vm->m_data[i2];
- // if out of known area
- if (!vm->m_area.contains(i2) ||
- n2->getContent() == CONTENT_IGNORE) {
- dropped_to_unknown = true;
- break;
- }
- } while (!ndef->get(*n2).walkable);
- // Loop one up so that we're in air
- VoxelArea::add_y(em, i2, 1);
-
- // Move mud to new place. Outside mapchunk remove
- // any decorations above removed or placed mud.
- if (!dropped_to_unknown)
- moveMud(i, i2, i3, p2d, em);
+ if (ndef->get(*n2).walkable)
+ continue;
- // Done
- break;
+ // Loop further down until not air
+ s16 y2 = y - 1; // y of i2
+ bool dropped_to_unknown = false;
+ do {
+ y2--;
+ VoxelArea::add_y(em, i2, -1);
+ n2 = &vm->m_data[i2];
+ // If out of area or in ungenerated world
+ if (y2 < full_node_min.Y || n2->getContent() == CONTENT_IGNORE) {
+ dropped_to_unknown = true;
+ break;
+ }
+ } while (!ndef->get(*n2).walkable);
+
+ if (!dropped_to_unknown) {
+ // Move up one so that we're in air
+ VoxelArea::add_y(em, i2, 1);
+ // Move mud to new place, and if outside mapchunk remove
+ // any decorations above removed or placed mud.
+ moveMud(i, i2, i3, p2d, em);
+ }
+ // Done, find next mud node in column
+ break;
+ }
}
}
- }
}
}
}