Skip to content

Commit b53a60c

Browse files
authoredAug 24, 2019
Mapgen v6: Various mudflow code improvements and bugfixes (#8805)
Calculate 'i' inside 'y' loop to avoid 'i' and 'y' becoming out of step due to the uses of 'continue'. Simplify calculation of 'p2d' when coordinates are inverted. Remove some unnecessary and unreliable 'index out of voxelmanip' checks. Move calculation of '&em' out of loops. For 'Loop further down until not air' code, use y coordinate to detect being out of voxelmanip, instead of checking index which did not detect that. Add and improve comments. Indent the 'for (;; y--) {' loop. Improve format and fix codestyle issues.
1 parent fbc8724 commit b53a60c

File tree

1 file changed

+76
-91
lines changed

1 file changed

+76
-91
lines changed
 

Diff for: ‎src/mapgen/mapgen_v6.cpp

+76-91
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ void MapgenV6::makeChunk(BlockMakeData *data)
538538
updateHeightmap(node_min, node_max);
539539

540540
const s16 max_spread_amount = MAP_BLOCKSIZE;
541-
// Limit dirt flow area by 1 because mud is flown into neighbors.
541+
// Limit dirt flow area by 1 because mud is flowed into neighbors
542542
s16 mudflow_minpos = -max_spread_amount + 1;
543543
s16 mudflow_maxpos = central_area_size.X + max_spread_amount - 2;
544544

@@ -773,6 +773,14 @@ void MapgenV6::addMud()
773773

774774
void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos)
775775
{
776+
const v3s16 &em = vm->m_area.getExtent();
777+
static const v3s16 dirs4[4] = {
778+
v3s16(0, 0, 1), // Back
779+
v3s16(1, 0, 0), // Right
780+
v3s16(0, 0, -1), // Front
781+
v3s16(-1, 0, 0), // Left
782+
};
783+
776784
// Iterate twice
777785
for (s16 k = 0; k < 2; k++) {
778786
for (s16 z = mudflow_minpos; z <= mudflow_maxpos; z++)
@@ -781,120 +789,97 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos)
781789
v2s16 p2d;
782790
// Invert coordinates on second iteration to process columns in
783791
// opposite order, to avoid a directional bias.
784-
if (k == 1) {
785-
p2d = v2s16(node_min.X, node_min.Z) + v2s16(
786-
mudflow_maxpos - (x - mudflow_minpos),
787-
mudflow_maxpos - (z - mudflow_minpos));
788-
} else {
792+
if (k == 1)
793+
p2d = v2s16(node_max.X, node_max.Z) - v2s16(x, z);
794+
else
789795
p2d = v2s16(node_min.X, node_min.Z) + v2s16(x, z);
790-
}
791796

792-
const v3s16 &em = vm->m_area.getExtent();
793-
u32 i = vm->m_area.index(p2d.X, node_max.Y, p2d.Y);
794797
s16 y = node_max.Y;
795798

796799
while (y >= node_min.Y) {
800+
for (;; y--) {
801+
u32 i = vm->m_area.index(p2d.X, y, p2d.Y);
802+
MapNode *n = nullptr;
803+
804+
// Find next mud node in mapchunk column
805+
for (; y >= node_min.Y; y--) {
806+
n = &vm->m_data[i];
807+
if (n->getContent() == c_dirt ||
808+
n->getContent() == c_dirt_with_grass ||
809+
n->getContent() == c_gravel)
810+
break;
797811

798-
for (;; y--) {
799-
MapNode *n = NULL;
800-
// Find mud
801-
for (; y >= node_min.Y; y--) {
802-
n = &vm->m_data[i];
803-
if (n->getContent() == c_dirt ||
804-
n->getContent() == c_dirt_with_grass ||
805-
n->getContent() == c_gravel)
812+
VoxelArea::add_y(em, i, -1);
813+
}
814+
if (y < node_min.Y)
815+
// No mud found in mapchunk column, process the next column
806816
break;
807817

808-
VoxelArea::add_y(em, i, -1);
809-
}
810-
811-
// Stop if out of area
812-
//if(vmanip.m_area.contains(i) == false)
813-
if (y < node_min.Y)
814-
break;
815-
816-
if (n->getContent() == c_dirt ||
817-
n->getContent() == c_dirt_with_grass) {
818-
// Make it exactly mud
819-
n->setContent(c_dirt);
820-
821-
// Don't flow it if the stuff under it is not mud
822-
{
818+
if (n->getContent() == c_dirt || n->getContent() == c_dirt_with_grass) {
819+
// Convert dirt_with_grass to dirt
820+
n->setContent(c_dirt);
821+
// Don't flow mud if the stuff under it is not mud,
822+
// to leave at least 1 node of mud.
823823
u32 i2 = i;
824824
VoxelArea::add_y(em, i2, -1);
825-
// Cancel if out of area
826-
if (!vm->m_area.contains(i2))
827-
continue;
828825
MapNode *n2 = &vm->m_data[i2];
829826
if (n2->getContent() != c_dirt &&
830827
n2->getContent() != c_dirt_with_grass)
828+
// Find next mud node in column
831829
continue;
832830
}
833-
}
834831

835-
static const v3s16 dirs4[4] = {
836-
v3s16(0, 0, 1), // back
837-
v3s16(1, 0, 0), // right
838-
v3s16(0, 0, -1), // front
839-
v3s16(-1, 0, 0), // left
840-
};
841-
842-
// Check that upper is walkable. Cancel
843-
// dropping if upper keeps it in place.
844-
u32 i3 = i;
845-
VoxelArea::add_y(em, i3, 1);
846-
MapNode *n3 = NULL;
847-
848-
if (vm->m_area.contains(i3)) {
849-
n3 = &vm->m_data[i3];
832+
// Check if node above is walkable. If so, cancel
833+
// flowing as if node above keeps it in place.
834+
u32 i3 = i;
835+
VoxelArea::add_y(em, i3, 1);
836+
MapNode *n3 = &vm->m_data[i3];
850837
if (ndef->get(*n3).walkable)
838+
// Find next mud node in column
851839
continue;
852-
}
853840

854-
// Drop mud on side
855-
for (const v3s16 &dirp : dirs4) {
856-
u32 i2 = i;
857-
// Move to side
858-
VoxelArea::add_p(em, i2, dirp);
859-
// Fail if out of area
860-
if (!vm->m_area.contains(i2))
861-
continue;
862-
// Check that side is air
863-
MapNode *n2 = &vm->m_data[i2];
864-
if (ndef->get(*n2).walkable)
865-
continue;
866-
// Check that under side is air
867-
VoxelArea::add_y(em, i2, -1);
868-
if (!vm->m_area.contains(i2))
869-
continue;
870-
n2 = &vm->m_data[i2];
871-
if (ndef->get(*n2).walkable)
872-
continue;
873-
// Loop further down until not air
874-
bool dropped_to_unknown = false;
875-
do {
841+
// Drop mud on one side
842+
for (const v3s16 &dirp : dirs4) {
843+
u32 i2 = i;
844+
// Move to side
845+
VoxelArea::add_p(em, i2, dirp);
846+
// Check that side is air
847+
MapNode *n2 = &vm->m_data[i2];
848+
if (ndef->get(*n2).walkable)
849+
continue;
850+
851+
// Check that under side is air
876852
VoxelArea::add_y(em, i2, -1);
877853
n2 = &vm->m_data[i2];
878-
// if out of known area
879-
if (!vm->m_area.contains(i2) ||
880-
n2->getContent() == CONTENT_IGNORE) {
881-
dropped_to_unknown = true;
882-
break;
883-
}
884-
} while (!ndef->get(*n2).walkable);
885-
// Loop one up so that we're in air
886-
VoxelArea::add_y(em, i2, 1);
887-
888-
// Move mud to new place. Outside mapchunk remove
889-
// any decorations above removed or placed mud.
890-
if (!dropped_to_unknown)
891-
moveMud(i, i2, i3, p2d, em);
854+
if (ndef->get(*n2).walkable)
855+
continue;
892856

893-
// Done
894-
break;
857+
// Loop further down until not air
858+
s16 y2 = y - 1; // y of i2
859+
bool dropped_to_unknown = false;
860+
do {
861+
y2--;
862+
VoxelArea::add_y(em, i2, -1);
863+
n2 = &vm->m_data[i2];
864+
// If out of area or in ungenerated world
865+
if (y2 < full_node_min.Y || n2->getContent() == CONTENT_IGNORE) {
866+
dropped_to_unknown = true;
867+
break;
868+
}
869+
} while (!ndef->get(*n2).walkable);
870+
871+
if (!dropped_to_unknown) {
872+
// Move up one so that we're in air
873+
VoxelArea::add_y(em, i2, 1);
874+
// Move mud to new place, and if outside mapchunk remove
875+
// any decorations above removed or placed mud.
876+
moveMud(i, i2, i3, p2d, em);
877+
}
878+
// Done, find next mud node in column
879+
break;
880+
}
895881
}
896882
}
897-
}
898883
}
899884
}
900885
}

0 commit comments

Comments
 (0)
Please sign in to comment.