diff options
author | kwolekr <kwolekr@minetest.net> | 2015-11-04 03:33:12 -0500 |
---|---|---|
committer | kwolekr <kwolekr@minetest.net> | 2015-11-05 01:18:32 -0500 |
commit | 1384108f8c32f309852c1d1665a613f2a3e3fcc2 (patch) | |
tree | a5a2c9295db4d31ed1e17ec5845a24b54a911ef0 /src/mg_schematic.cpp | |
parent | 732cabee193c101fb59c9f3a6c181b32d77fe37d (diff) | |
download | minetest-1384108f8c32f309852c1d1665a613f2a3e3fcc2.tar.gz minetest-1384108f8c32f309852c1d1665a613f2a3e3fcc2.tar.bz2 minetest-1384108f8c32f309852c1d1665a613f2a3e3fcc2.zip |
Schematics: Add core.place_schematic_on_vmanip API
Fix memory leak in minetest.place_schematic
Slightly refactor Schematic code
Diffstat (limited to 'src/mg_schematic.cpp')
-rw-r--r-- | src/mg_schematic.cpp | 62 |
1 files changed, 49 insertions, 13 deletions
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<v3s16, MapBlock *> lighting_modified_blocks; + std::map<v3s16, MapBlock *> modified_blocks; + std::map<v3s16, MapBlock *>::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<v3s16, MapBlock *> lighting_modified_blocks; - std::map<v3s16, MapBlock *> 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<v3s16, MapBlock *>::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); |