From 1384108f8c32f309852c1d1665a613f2a3e3fcc2 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Wed, 4 Nov 2015 03:33:12 -0500 Subject: Schematics: Add core.place_schematic_on_vmanip API Fix memory leak in minetest.place_schematic Slightly refactor Schematic code --- src/mg_schematic.cpp | 62 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 13 deletions(-) (limited to 'src/mg_schematic.cpp') diff --git a/src/mg_schematic.cpp b/src/mg_schematic.cpp index a5ffb20b8..019ed4dee 100644 --- a/src/mg_schematic.cpp +++ b/src/mg_schematic.cpp @@ -94,7 +94,7 @@ void Schematic::resolveNodeNames() } -void Schematic::blitToVManip(v3s16 p, MMVManip *vm, Rotation rot, bool force_place) +void Schematic::blitToVManip(MMVManip *vm, v3s16 p, Rotation rot, bool force_place) { sanity_check(m_ndef != NULL); @@ -175,20 +175,52 @@ void Schematic::blitToVManip(v3s16 p, MMVManip *vm, Rotation rot, bool force_pla } -void Schematic::placeStructure(Map *map, v3s16 p, u32 flags, +bool Schematic::placeOnVManip(MMVManip *vm, v3s16 p, u32 flags, Rotation rot, bool force_place) { - assert(schemdata != NULL); // Pre-condition + assert(vm != NULL); + assert(schemdata != NULL); sanity_check(m_ndef != NULL); - MMVManip *vm = new MMVManip(map); + //// Determine effective rotation and effective schematic dimensions + if (rot == ROTATE_RAND) + rot = (Rotation)myrand_range(ROTATE_0, ROTATE_270); + + v3s16 s = (rot == ROTATE_90 || rot == ROTATE_270) ? + v3s16(size.Z, size.Y, size.X) : size; + + //// Adjust placement position if necessary + if (flags & DECO_PLACE_CENTER_X) + p.X -= (s.X + 1) / 2; + if (flags & DECO_PLACE_CENTER_Y) + p.Y -= (s.Y + 1) / 2; + if (flags & DECO_PLACE_CENTER_Z) + p.Z -= (s.Z + 1) / 2; + + blitToVManip(vm, p, rot, force_place); + return vm->m_area.contains(VoxelArea(p, p + s - v3s16(1,1,1))); +} + +void Schematic::placeOnMap(Map *map, v3s16 p, u32 flags, + Rotation rot, bool force_place) +{ + std::map lighting_modified_blocks; + std::map modified_blocks; + std::map::iterator it; + + assert(map != NULL); + assert(schemdata != NULL); + sanity_check(m_ndef != NULL); + + //// Determine effective rotation and effective schematic dimensions if (rot == ROTATE_RAND) rot = (Rotation)myrand_range(ROTATE_0, ROTATE_270); v3s16 s = (rot == ROTATE_90 || rot == ROTATE_270) ? - v3s16(size.Z, size.Y, size.X) : size; + v3s16(size.Z, size.Y, size.X) : size; + //// Adjust placement position if necessary if (flags & DECO_PLACE_CENTER_X) p.X -= (s.X + 1) / 2; if (flags & DECO_PLACE_CENTER_Y) @@ -196,25 +228,29 @@ void Schematic::placeStructure(Map *map, v3s16 p, u32 flags, if (flags & DECO_PLACE_CENTER_Z) p.Z -= (s.Z + 1) / 2; + //// Create VManip for effected area, emerge our area, modify area + //// inside VManip, then blit back. v3s16 bp1 = getNodeBlockPos(p); v3s16 bp2 = getNodeBlockPos(p + s - v3s16(1,1,1)); - vm->initialEmerge(bp1, bp2); - blitToVManip(p, vm, rot, force_place); + MMVManip vm(map); + vm.initialEmerge(bp1, bp2); - std::map lighting_modified_blocks; - std::map modified_blocks; - vm->blitBackAll(&modified_blocks); + blitToVManip(&vm, p, rot, force_place); + + vm.blitBackAll(&modified_blocks); + + //// Carry out post-map-modification actions + //// Update lighting // TODO: Optimize this by using Mapgen::calcLighting() instead lighting_modified_blocks.insert(modified_blocks.begin(), modified_blocks.end()); map->updateLighting(lighting_modified_blocks, modified_blocks); + //// Create & dispatch map modification events to observers MapEditEvent event; event.type = MEET_OTHER; - for (std::map::iterator - it = modified_blocks.begin(); - it != modified_blocks.end(); ++it) + for (it = modified_blocks.begin(); it != modified_blocks.end(); ++it) event.modified_blocks.insert(it->first); map->dispatchEvent(&event); -- cgit v1.2.3