diff options
author | Loic Blot <loic.blot@unix-experience.fr> | 2015-02-22 17:01:03 +0100 |
---|---|---|
committer | Craig Robbins <kde.psych@gmail.com> | 2015-02-27 21:34:33 +1000 |
commit | 0f556d0c7f8c98c7209416577aae4fcc0c1c2b32 (patch) | |
tree | 51db9a8f2f853905a8e0b5e89aeb108baf30d700 /src/script/lua_api | |
parent | 2b189d4507028068694e2d5d2d94ded646d3c604 (diff) | |
download | minetest-0f556d0c7f8c98c7209416577aae4fcc0c1c2b32.tar.gz minetest-0f556d0c7f8c98c7209416577aae4fcc0c1c2b32.tar.bz2 minetest-0f556d0c7f8c98c7209416577aae4fcc0c1c2b32.zip |
Add find_surface_nodes_in_area LUA call which permit to only get the nodes which touch air. This permit to massively improve performance for mods like plantlife
Diffstat (limited to 'src/script/lua_api')
-rw-r--r-- | src/script/lua_api/l_env.cpp | 52 | ||||
-rw-r--r-- | src/script/lua_api/l_env.h | 4 |
2 files changed, 53 insertions, 3 deletions
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 505faa09d..ca1586e39 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -541,17 +541,17 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L) v3s16 minp = read_v3s16(L, 1); v3s16 maxp = read_v3s16(L, 2); std::set<content_t> filter; - if(lua_istable(L, 3)){ + if(lua_istable(L, 3)) { int table = 3; lua_pushnil(L); - while(lua_next(L, table) != 0){ + while(lua_next(L, table) != 0) { // key at index -2 and value at index -1 luaL_checktype(L, -1, LUA_TSTRING); ndef->getIds(lua_tostring(L, -1), filter); // removes value, keeps key for next iteration lua_pop(L, 1); } - } else if(lua_isstring(L, 3)){ + } else if(lua_isstring(L, 3)) { ndef->getIds(lua_tostring(L, 3), filter); } @@ -570,6 +570,51 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L) return 1; } +// find_surface_nodes_in_area(minp, maxp, nodenames) -> list of positions +// nodenames: eg. {"ignore", "group:tree"} or "default:dirt" +int ModApiEnvMod::l_find_surface_nodes_in_area(lua_State *L) +{ + GET_ENV_PTR; + + INodeDefManager *ndef = getServer(L)->ndef(); + v3s16 minp = read_v3s16(L, 1); + v3s16 maxp = read_v3s16(L, 2); + std::set<content_t> filter; + if(lua_istable(L, 3)) { + int table = 3; + lua_pushnil(L); + while(lua_next(L, table) != 0) { + // key at index -2 and value at index -1 + luaL_checktype(L, -1, LUA_TSTRING); + ndef->getIds(lua_tostring(L, -1), filter); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } else if(lua_isstring(L, 3)) { + ndef->getIds(lua_tostring(L, 3), filter); + } + + lua_newtable(L); + u64 i = 0; + for(s16 x = minp.X; x <= maxp.X; x++) + for(s16 z = minp.Z; z <= maxp.Z; z++) { + s16 y = minp.Y; + v3s16 p(x, y, z); + content_t c = env->getMap().getNodeNoEx(p).getContent(); + for(; y <= maxp.Y; y++) { + v3s16 psurf(x, y + 1, z); + content_t csurf = env->getMap().getNodeNoEx(psurf).getContent(); + if(c != CONTENT_AIR && csurf == CONTENT_AIR && + filter.count(c) != 0) { + push_v3s16(L, v3s16(x, y, z)); + lua_rawseti(L, -2, ++i); + } + c = csurf; + } + } + return 1; +} + // get_perlin(seeddiff, octaves, persistence, scale) // returns world-specific PerlinNoise int ModApiEnvMod::l_get_perlin(lua_State *L) @@ -867,6 +912,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top) API_FCT(get_gametime); API_FCT(find_node_near); API_FCT(find_nodes_in_area); + API_FCT(find_surface_nodes_in_area); API_FCT(delete_area); API_FCT(get_perlin); API_FCT(get_perlin_map); diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h index bfaea1c4d..807afe459 100644 --- a/src/script/lua_api/l_env.h +++ b/src/script/lua_api/l_env.h @@ -119,6 +119,10 @@ private: // nodenames: eg. {"ignore", "group:tree"} or "default:dirt" static int l_find_nodes_in_area(lua_State *L); + // find_surface_nodes_in_area(minp, maxp, nodenames) -> list of positions + // nodenames: eg. {"ignore", "group:tree"} or "default:dirt" + static int l_find_surface_nodes_in_area(lua_State *L); + // delete_area(p1, p2) -> true/false static int l_delete_area(lua_State *L); |