From 922e6ff57ec9f07d2ff04cf010821c1ddd00831e Mon Sep 17 00:00:00 2001 From: Paramat Date: Fri, 25 Jan 2019 19:01:00 +0000 Subject: [PATCH] blitToVManip: Check out-of-bounds using node position not index (#8127) Previously, when using 'place on vmanip' to add a schematic to a lua voxelmanip, if part of the schematic was outside the voxelmanip volume, the outside part would often appear in a strange place elsewhere inside the voxelmanip instead of being trimmed off. This was due to the out-of-bounds check checking the index. A position outside the voxelmanip can have an index that satisfies '0 <= index <= voxelmanip volume', causing the node to be placed at a strange position inside the voxelmanip. Use 'vm->m_area.contains(pos)' instead. Move index calculation to later in the code to optimise. --- src/mapgen/mg_schematic.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mapgen/mg_schematic.cpp b/src/mapgen/mg_schematic.cpp index ba619b2e..36f1dd76 100644 --- a/src/mapgen/mg_schematic.cpp +++ b/src/mapgen/mg_schematic.cpp @@ -137,8 +137,8 @@ void Schematic::blitToVManip(MMVManip *vm, v3s16 p, Rotation rot, bool force_pla for (s16 z = 0; z != sz; z++) { u32 i = z * i_step_z + y * ystride + i_start; for (s16 x = 0; x != sx; x++, i += i_step_x) { - u32 vi = vm->m_area.index(p.X + x, y_map, p.Z + z); - if (!vm->m_area.contains(vi)) + v3s16 pos(p.X + x, y_map, p.Z + z); + if (!vm->m_area.contains(pos)) continue; if (schemdata[i].getContent() == CONTENT_IGNORE) @@ -150,6 +150,7 @@ void Schematic::blitToVManip(MMVManip *vm, v3s16 p, Rotation rot, bool force_pla if (placement_prob == MTSCHEM_PROB_NEVER) continue; + u32 vi = vm->m_area.index(pos); if (!force_place && !force_place_node) { content_t c = vm->m_data[vi].getContent(); if (c != CONTENT_AIR && c != CONTENT_IGNORE)