X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fscript%2Flua_api%2Fl_vmanip.cpp;h=0d8123acd437eaea75b8e8c08398df5a5667fcef;hb=3c63c3044d5e4ca36c2649c530f31622581d90fd;hp=6743f40f9c97911c0cbac2ea85d879e2b85ef39b;hpb=8aa930f28e69f3518831500022988ca2a4b6985d;p=dragonfireclient.git diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp index 6743f40f9..0d8123acd 100644 --- a/src/script/lua_api/l_vmanip.cpp +++ b/src/script/lua_api/l_vmanip.cpp @@ -18,85 +18,141 @@ with this program; if not, write to the Free Software Foundation, Inc., */ -#include "lua_api/l_base.h" #include "lua_api/l_vmanip.h" - -/////// - -#include "cpp_api/scriptapi.h" +#include "lua_api/l_internal.h" +#include "common/c_content.h" #include "common/c_converter.h" -#include "server.h" #include "emerge.h" -#include "common/c_internal.h" +#include "environment.h" +#include "map.h" +#include "server.h" +#include "mapgen.h" // garbage collector int LuaVoxelManip::gc_object(lua_State *L) { LuaVoxelManip *o = *(LuaVoxelManip **)(lua_touserdata(L, 1)); - if (o->do_gc) - delete o; - + delete o; + return 0; } -int LuaVoxelManip::l_read_chunk(lua_State *L) +int LuaVoxelManip::l_read_from_map(lua_State *L) { + MAP_LOCK_REQUIRED; + LuaVoxelManip *o = checkobject(L, 1); - - v3s16 bp1 = getNodeBlockPos(read_v3s16(L, 2)); - v3s16 bp2 = getNodeBlockPos(read_v3s16(L, 3)); + MMVManip *vm = o->vm; + + v3s16 bp1 = getNodeBlockPos(check_v3s16(L, 2)); + v3s16 bp2 = getNodeBlockPos(check_v3s16(L, 3)); sortBoxVerticies(bp1, bp2); - ManualMapVoxelManipulator *vm = o->vm; + vm->initialEmerge(bp1, bp2); - - v3s16 emerged_p1 = vm->m_area.MinEdge; - v3s16 emerged_p2 = vm->m_area.MaxEdge; - - int volume = vm->m_area.getVolume(); - - lua_newtable(L); - for (int i = 0; i != volume; i++) { - lua_Number cid = vm->m_data[i].getContent(); - lua_pushnumber(L, cid); + + push_v3s16(L, vm->m_area.MinEdge); + push_v3s16(L, vm->m_area.MaxEdge); + + return 2; +} + +int LuaVoxelManip::l_get_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + bool use_buffer = lua_istable(L, 2); + + MMVManip *vm = o->vm; + + u32 volume = vm->m_area.getVolume(); + + if (use_buffer) + lua_pushvalue(L, 2); + else + lua_newtable(L); + + for (u32 i = 0; i != volume; i++) { + lua_Integer cid = vm->m_data[i].getContent(); + lua_pushinteger(L, cid); lua_rawseti(L, -2, i + 1); } - - push_v3s16(L, emerged_p1); - push_v3s16(L, emerged_p2); - - return 3; + + return 1; } -int LuaVoxelManip::l_write_chunk(lua_State *L) +int LuaVoxelManip::l_set_data(lua_State *L) { + NO_MAP_LOCK_REQUIRED; + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + if (!lua_istable(L, 2)) return 0; - - ManualMapVoxelManipulator *vm = o->vm; - - int volume = vm->m_area.getVolume(); - for (int i = 0; i != volume; i++) { + + u32 volume = vm->m_area.getVolume(); + for (u32 i = 0; i != volume; i++) { lua_rawgeti(L, 2, i + 1); - content_t c = lua_tonumber(L, -1); - + content_t c = lua_tointeger(L, -1); + vm->m_data[i].setContent(c); lua_pop(L, 1); } + return 0; +} + +int LuaVoxelManip::l_write_to_map(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + vm->blitBackAll(&o->modified_blocks); - + + return 0; +} + +int LuaVoxelManip::l_get_node_at(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + INodeDefManager *ndef = getServer(L)->getNodeDefManager(); + + LuaVoxelManip *o = checkobject(L, 1); + v3s16 pos = check_v3s16(L, 2); + + pushnode(L, o->vm->getNodeNoExNoEmerge(pos), ndef); + return 1; +} + +int LuaVoxelManip::l_set_node_at(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + INodeDefManager *ndef = getServer(L)->getNodeDefManager(); + + LuaVoxelManip *o = checkobject(L, 1); + v3s16 pos = check_v3s16(L, 2); + MapNode n = readnode(L, 3, ndef); + + o->vm->setNodeNoEmerge(pos, n); + return 0; } int LuaVoxelManip::l_update_liquids(lua_State *L) { + GET_ENV_PTR; + LuaVoxelManip *o = checkobject(L, 1); - - ManualMapVoxelManipulator *vm = o->vm; - INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager(); - Map *map = &(get_scriptapi(L)->getEnv()->getMap()); + + Map *map = &(env->getMap()); + INodeDefManager *ndef = getServer(L)->getNodeDefManager(); + MMVManip *vm = o->vm; Mapgen mg; mg.vm = vm; @@ -111,22 +167,32 @@ int LuaVoxelManip::l_update_liquids(lua_State *L) int LuaVoxelManip::l_calc_lighting(lua_State *L) { NO_MAP_LOCK_REQUIRED; - + LuaVoxelManip *o = checkobject(L, 1); - v3s16 p1 = read_v3s16(L, 2); - v3s16 p2 = read_v3s16(L, 3); - sortBoxVerticies(p1, p2); - - ManualMapVoxelManipulator *vm = o->vm; - INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager(); - EmergeManager *emerge = STACK_TO_SERVER(L)->getEmergeManager(); - + if (!o->is_mapgen_vm) + return 0; + + INodeDefManager *ndef = getServer(L)->getNodeDefManager(); + EmergeManager *emerge = getServer(L)->getEmergeManager(); + MMVManip *vm = o->vm; + + v3s16 yblock = v3s16(0, 1, 0) * MAP_BLOCKSIZE; + v3s16 fpmin = vm->m_area.MinEdge; + v3s16 fpmax = vm->m_area.MaxEdge; + v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) : fpmin + yblock; + v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) : fpmax - yblock; + bool propagate_shadow = lua_isboolean(L, 4) ? lua_toboolean(L, 4) : true; + + sortBoxVerticies(pmin, pmax); + if (!vm->m_area.contains(VoxelArea(pmin, pmax))) + throw LuaError("Specified voxel area out of VoxelManipulator bounds"); + Mapgen mg; mg.vm = vm; mg.ndef = ndef; - mg.water_level = emerge->params->water_level; - - mg.calcLighting(p1, p2); + mg.water_level = emerge->mgparams->water_level; + + mg.calcLighting(pmin, pmax, fpmin, fpmax, propagate_shadow); return 0; } @@ -134,40 +200,136 @@ int LuaVoxelManip::l_calc_lighting(lua_State *L) int LuaVoxelManip::l_set_lighting(lua_State *L) { NO_MAP_LOCK_REQUIRED; - + LuaVoxelManip *o = checkobject(L, 1); - v3s16 p1 = read_v3s16(L, 2); - v3s16 p2 = read_v3s16(L, 3); - sortBoxVerticies(p1, p2); - - u8 light; - if (!lua_istable(L, 4)) + if (!o->is_mapgen_vm) + return 0; + + if (!lua_istable(L, 2)) return 0; - light = getintfield_default(L, 4, "day", 0); - light |= getintfield_default(L, 4, "night", 0); - - ManualMapVoxelManipulator *vm = o->vm; - + u8 light; + light = (getintfield_default(L, 2, "day", 0) & 0x0F); + light |= (getintfield_default(L, 2, "night", 0) & 0x0F) << 4; + + MMVManip *vm = o->vm; + + v3s16 yblock = v3s16(0, 1, 0) * MAP_BLOCKSIZE; + v3s16 pmin = lua_istable(L, 3) ? check_v3s16(L, 3) : vm->m_area.MinEdge + yblock; + v3s16 pmax = lua_istable(L, 4) ? check_v3s16(L, 4) : vm->m_area.MaxEdge - yblock; + + sortBoxVerticies(pmin, pmax); + if (!vm->m_area.contains(VoxelArea(pmin, pmax))) + throw LuaError("Specified voxel area out of VoxelManipulator bounds"); + Mapgen mg; mg.vm = vm; - - mg.setLighting(p1, p2, light); + + mg.setLighting(light, pmin, pmax); + + return 0; +} + +int LuaVoxelManip::l_get_light_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + + u32 volume = vm->m_area.getVolume(); + + lua_newtable(L); + for (u32 i = 0; i != volume; i++) { + lua_Integer light = vm->m_data[i].param1; + lua_pushinteger(L, light); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +int LuaVoxelManip::l_set_light_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + + if (!lua_istable(L, 2)) + return 0; + + u32 volume = vm->m_area.getVolume(); + for (u32 i = 0; i != volume; i++) { + lua_rawgeti(L, 2, i + 1); + u8 light = lua_tointeger(L, -1); + + vm->m_data[i].param1 = light; + + lua_pop(L, 1); + } + + return 0; +} + +int LuaVoxelManip::l_get_param2_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + + u32 volume = vm->m_area.getVolume(); + + lua_newtable(L); + for (u32 i = 0; i != volume; i++) { + lua_Integer param2 = vm->m_data[i].param2; + lua_pushinteger(L, param2); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +int LuaVoxelManip::l_set_param2_data(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + + if (!lua_istable(L, 2)) + return 0; + + u32 volume = vm->m_area.getVolume(); + for (u32 i = 0; i != volume; i++) { + lua_rawgeti(L, 2, i + 1); + u8 param2 = lua_tointeger(L, -1); + + vm->m_data[i].param2 = param2; + + lua_pop(L, 1); + } return 0; } int LuaVoxelManip::l_update_map(lua_State *L) { + GET_ENV_PTR; + LuaVoxelManip *o = checkobject(L, 1); - + if (o->is_mapgen_vm) + return 0; + + Map *map = &(env->getMap()); + // TODO: Optimize this by using Mapgen::calcLighting() instead std::map lighting_mblocks; std::map *mblocks = &o->modified_blocks; - + lighting_mblocks.insert(mblocks->begin(), mblocks->end()); - - Map *map = &(get_scriptapi(L)->getEnv()->getMap()); + map->updateLighting(lighting_mblocks, *mblocks); MapEditEvent event; @@ -176,39 +338,78 @@ int LuaVoxelManip::l_update_map(lua_State *L) it = mblocks->begin(); it != mblocks->end(); ++it) event.modified_blocks.insert(it->first); - + map->dispatchEvent(&event); mblocks->clear(); - return 0; + return 0; } -LuaVoxelManip::LuaVoxelManip(ManualMapVoxelManipulator *mmvm, bool dogc) +int LuaVoxelManip::l_was_modified(lua_State *L) { - this->vm = mmvm; - this->do_gc = dogc; + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + MMVManip *vm = o->vm; + + lua_pushboolean(L, vm->m_is_dirty); + + return 1; +} + +int LuaVoxelManip::l_get_emerged_area(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaVoxelManip *o = checkobject(L, 1); + + push_v3s16(L, o->vm->m_area.MinEdge); + push_v3s16(L, o->vm->m_area.MaxEdge); + + return 2; +} + +LuaVoxelManip::LuaVoxelManip(MMVManip *mmvm, bool is_mg_vm) +{ + this->vm = mmvm; + this->is_mapgen_vm = is_mg_vm; } LuaVoxelManip::LuaVoxelManip(Map *map) { - vm = new ManualMapVoxelManipulator(map); + this->vm = new MMVManip(map); + this->is_mapgen_vm = false; +} + +LuaVoxelManip::LuaVoxelManip(Map *map, v3s16 p1, v3s16 p2) +{ + this->vm = new MMVManip(map); + this->is_mapgen_vm = false; + + v3s16 bp1 = getNodeBlockPos(p1); + v3s16 bp2 = getNodeBlockPos(p2); + sortBoxVerticies(bp1, bp2); + vm->initialEmerge(bp1, bp2); } LuaVoxelManip::~LuaVoxelManip() { - delete vm; + if (!is_mapgen_vm) + delete vm; } // LuaVoxelManip() // Creates an LuaVoxelManip and leaves it on top of stack int LuaVoxelManip::create_object(lua_State *L) { - NO_MAP_LOCK_REQUIRED; - - Map *map = &(get_scriptapi(L)->getEnv()->getMap()); - LuaVoxelManip *o = new LuaVoxelManip(map); - + GET_ENV_PTR; + + Map *map = &(env->getMap()); + LuaVoxelManip *o = (lua_istable(L, 1) && lua_istable(L, 2)) ? + new LuaVoxelManip(map, check_v3s16(L, 1), check_v3s16(L, 2)) : + new LuaVoxelManip(map); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; luaL_getmetatable(L, className); lua_setmetatable(L, -2); @@ -218,13 +419,13 @@ int LuaVoxelManip::create_object(lua_State *L) LuaVoxelManip *LuaVoxelManip::checkobject(lua_State *L, int narg) { NO_MAP_LOCK_REQUIRED; - + luaL_checktype(L, narg, LUA_TUSERDATA); void *ud = luaL_checkudata(L, narg, className); if (!ud) luaL_typerror(L, narg, className); - + return *(LuaVoxelManip **)ud; // unbox pointer } @@ -252,19 +453,27 @@ void LuaVoxelManip::Register(lua_State *L) luaL_openlib(L, 0, methods, 0); // fill methodtable lua_pop(L, 1); // drop methodtable - // Can be created from Lua (VoxelManip() + // Can be created from Lua (VoxelManip()) lua_register(L, className, create_object); } const char LuaVoxelManip::className[] = "VoxelManip"; const luaL_reg LuaVoxelManip::methods[] = { - luamethod(LuaVoxelManip, read_chunk), - luamethod(LuaVoxelManip, write_chunk), + luamethod(LuaVoxelManip, read_from_map), + luamethod(LuaVoxelManip, get_data), + luamethod(LuaVoxelManip, set_data), + luamethod(LuaVoxelManip, get_node_at), + luamethod(LuaVoxelManip, set_node_at), + luamethod(LuaVoxelManip, write_to_map), luamethod(LuaVoxelManip, update_map), luamethod(LuaVoxelManip, update_liquids), luamethod(LuaVoxelManip, calc_lighting), luamethod(LuaVoxelManip, set_lighting), + luamethod(LuaVoxelManip, get_light_data), + luamethod(LuaVoxelManip, set_light_data), + luamethod(LuaVoxelManip, get_param2_data), + luamethod(LuaVoxelManip, set_param2_data), + luamethod(LuaVoxelManip, was_modified), + luamethod(LuaVoxelManip, get_emerged_area), {0,0} }; - -REGISTER_LUA_REF(LuaVoxelManip);