LCOV - code coverage report
Current view: top level - src/script/lua_api - l_vmanip.cpp (source / functions) Hit Total Coverage
Test: report Lines: 1 255 0.4 %
Date: 2015-07-11 18:23:49 Functions: 2 26 7.7 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : 
      21             : #include "lua_api/l_vmanip.h"
      22             : #include "lua_api/l_internal.h"
      23             : #include "common/c_content.h"
      24             : #include "common/c_converter.h"
      25             : #include "emerge.h"
      26             : #include "environment.h"
      27             : #include "map.h"
      28             : #include "server.h"
      29             : #include "mapgen.h"
      30             : 
      31             : #define GET_ENV_PTR ServerEnvironment* env =                                   \
      32             :                                 dynamic_cast<ServerEnvironment*>(getEnv(L));                   \
      33             :                                 if (env == NULL) return 0
      34             : 
      35             : // garbage collector
      36           0 : int LuaVoxelManip::gc_object(lua_State *L)
      37             : {
      38           0 :         LuaVoxelManip *o = *(LuaVoxelManip **)(lua_touserdata(L, 1));
      39           0 :         delete o;
      40             : 
      41           0 :         return 0;
      42             : }
      43             : 
      44           0 : int LuaVoxelManip::l_read_from_map(lua_State *L)
      45             : {
      46           0 :         LuaVoxelManip *o = checkobject(L, 1);
      47           0 :         MMVManip *vm = o->vm;
      48             : 
      49           0 :         v3s16 bp1 = getNodeBlockPos(check_v3s16(L, 2));
      50           0 :         v3s16 bp2 = getNodeBlockPos(check_v3s16(L, 3));
      51           0 :         sortBoxVerticies(bp1, bp2);
      52             : 
      53           0 :         vm->initialEmerge(bp1, bp2);
      54             : 
      55           0 :         push_v3s16(L, vm->m_area.MinEdge);
      56           0 :         push_v3s16(L, vm->m_area.MaxEdge);
      57             : 
      58           0 :         return 2;
      59             : }
      60             : 
      61           0 : int LuaVoxelManip::l_get_data(lua_State *L)
      62             : {
      63           0 :         NO_MAP_LOCK_REQUIRED;
      64             : 
      65           0 :         LuaVoxelManip *o = checkobject(L, 1);
      66           0 :         bool use_buffer  = lua_istable(L, 2);
      67             : 
      68           0 :         MMVManip *vm = o->vm;
      69             : 
      70           0 :         u32 volume = vm->m_area.getVolume();
      71             : 
      72           0 :         if (use_buffer)
      73           0 :                 lua_pushvalue(L, 2);
      74             :         else
      75           0 :                 lua_newtable(L);
      76             : 
      77           0 :         for (u32 i = 0; i != volume; i++) {
      78           0 :                 lua_Integer cid = vm->m_data[i].getContent();
      79           0 :                 lua_pushinteger(L, cid);
      80           0 :                 lua_rawseti(L, -2, i + 1);
      81             :         }
      82             : 
      83           0 :         return 1;
      84             : }
      85             : 
      86           0 : int LuaVoxelManip::l_set_data(lua_State *L)
      87             : {
      88           0 :         NO_MAP_LOCK_REQUIRED;
      89             : 
      90           0 :         LuaVoxelManip *o = checkobject(L, 1);
      91           0 :         MMVManip *vm = o->vm;
      92             : 
      93           0 :         if (!lua_istable(L, 2))
      94           0 :                 return 0;
      95             : 
      96           0 :         u32 volume = vm->m_area.getVolume();
      97           0 :         for (u32 i = 0; i != volume; i++) {
      98           0 :                 lua_rawgeti(L, 2, i + 1);
      99           0 :                 content_t c = lua_tointeger(L, -1);
     100             : 
     101           0 :                 vm->m_data[i].setContent(c);
     102             : 
     103           0 :                 lua_pop(L, 1);
     104             :         }
     105             : 
     106           0 :         return 0;
     107             : }
     108             : 
     109           0 : int LuaVoxelManip::l_write_to_map(lua_State *L)
     110             : {
     111           0 :         LuaVoxelManip *o = checkobject(L, 1);
     112           0 :         MMVManip *vm = o->vm;
     113             : 
     114           0 :         vm->blitBackAll(&o->modified_blocks);
     115             : 
     116           0 :         return 0;
     117             : }
     118             : 
     119           0 : int LuaVoxelManip::l_get_node_at(lua_State *L)
     120             : {
     121           0 :         NO_MAP_LOCK_REQUIRED;
     122           0 :         GET_ENV_PTR;
     123             : 
     124           0 :         LuaVoxelManip *o = checkobject(L, 1);
     125           0 :         v3s16 pos        = check_v3s16(L, 2);
     126             : 
     127           0 :         pushnode(L, o->vm->getNodeNoExNoEmerge(pos), env->getGameDef()->ndef());
     128           0 :         return 1;
     129             : }
     130             : 
     131           0 : int LuaVoxelManip::l_set_node_at(lua_State *L)
     132             : {
     133           0 :         NO_MAP_LOCK_REQUIRED;
     134           0 :         GET_ENV_PTR;
     135             : 
     136           0 :         LuaVoxelManip *o = checkobject(L, 1);
     137           0 :         v3s16 pos        = check_v3s16(L, 2);
     138           0 :         MapNode n        = readnode(L, 3, env->getGameDef()->ndef());
     139             : 
     140           0 :         o->vm->setNodeNoEmerge(pos, n);
     141             : 
     142           0 :         return 0;
     143             : }
     144             : 
     145           0 : int LuaVoxelManip::l_update_liquids(lua_State *L)
     146             : {
     147           0 :         GET_ENV_PTR;
     148             : 
     149           0 :         LuaVoxelManip *o = checkobject(L, 1);
     150             : 
     151           0 :         Map *map = &(env->getMap());
     152           0 :         INodeDefManager *ndef = getServer(L)->getNodeDefManager();
     153           0 :         MMVManip *vm = o->vm;
     154             : 
     155           0 :         Mapgen mg;
     156           0 :         mg.vm   = vm;
     157           0 :         mg.ndef = ndef;
     158             : 
     159           0 :         mg.updateLiquid(&map->m_transforming_liquid,
     160           0 :                         vm->m_area.MinEdge, vm->m_area.MaxEdge);
     161             : 
     162           0 :         return 0;
     163             : }
     164             : 
     165           0 : int LuaVoxelManip::l_calc_lighting(lua_State *L)
     166             : {
     167           0 :         NO_MAP_LOCK_REQUIRED;
     168             : 
     169           0 :         LuaVoxelManip *o = checkobject(L, 1);
     170           0 :         if (!o->is_mapgen_vm)
     171           0 :                 return 0;
     172             : 
     173           0 :         INodeDefManager *ndef = getServer(L)->getNodeDefManager();
     174           0 :         EmergeManager *emerge = getServer(L)->getEmergeManager();
     175           0 :         MMVManip *vm = o->vm;
     176             : 
     177           0 :         v3s16 yblock = v3s16(0, 1, 0) * MAP_BLOCKSIZE;
     178           0 :         v3s16 fpmin  = vm->m_area.MinEdge;
     179           0 :         v3s16 fpmax  = vm->m_area.MaxEdge;
     180           0 :         v3s16 pmin   = lua_istable(L, 2) ? check_v3s16(L, 2) : fpmin + yblock;
     181           0 :         v3s16 pmax   = lua_istable(L, 3) ? check_v3s16(L, 3) : fpmax - yblock;
     182             : 
     183           0 :         sortBoxVerticies(pmin, pmax);
     184           0 :         if (!vm->m_area.contains(VoxelArea(pmin, pmax)))
     185           0 :                 throw LuaError("Specified voxel area out of VoxelManipulator bounds");
     186             : 
     187           0 :         Mapgen mg;
     188           0 :         mg.vm          = vm;
     189           0 :         mg.ndef        = ndef;
     190           0 :         mg.water_level = emerge->params.water_level;
     191             : 
     192           0 :         mg.calcLighting(pmin, pmax, fpmin, fpmax);
     193             : 
     194           0 :         return 0;
     195             : }
     196             : 
     197           0 : int LuaVoxelManip::l_set_lighting(lua_State *L)
     198             : {
     199           0 :         NO_MAP_LOCK_REQUIRED;
     200             : 
     201           0 :         LuaVoxelManip *o = checkobject(L, 1);
     202           0 :         if (!o->is_mapgen_vm)
     203           0 :                 return 0;
     204             : 
     205           0 :         if (!lua_istable(L, 2))
     206           0 :                 return 0;
     207             : 
     208             :         u8 light;
     209           0 :         light  = (getintfield_default(L, 2, "day",   0) & 0x0F);
     210           0 :         light |= (getintfield_default(L, 2, "night", 0) & 0x0F) << 4;
     211             : 
     212           0 :         MMVManip *vm = o->vm;
     213             : 
     214           0 :         v3s16 yblock = v3s16(0, 1, 0) * MAP_BLOCKSIZE;
     215           0 :         v3s16 pmin = lua_istable(L, 3) ? check_v3s16(L, 3) : vm->m_area.MinEdge + yblock;
     216           0 :         v3s16 pmax = lua_istable(L, 4) ? check_v3s16(L, 4) : vm->m_area.MaxEdge - yblock;
     217             : 
     218           0 :         sortBoxVerticies(pmin, pmax);
     219           0 :         if (!vm->m_area.contains(VoxelArea(pmin, pmax)))
     220           0 :                 throw LuaError("Specified voxel area out of VoxelManipulator bounds");
     221             : 
     222           0 :         Mapgen mg;
     223           0 :         mg.vm = vm;
     224             : 
     225           0 :         mg.setLighting(light, pmin, pmax);
     226             : 
     227           0 :         return 0;
     228             : }
     229             : 
     230           0 : int LuaVoxelManip::l_get_light_data(lua_State *L)
     231             : {
     232           0 :         NO_MAP_LOCK_REQUIRED;
     233             : 
     234           0 :         LuaVoxelManip *o = checkobject(L, 1);
     235           0 :         MMVManip *vm = o->vm;
     236             : 
     237           0 :         u32 volume = vm->m_area.getVolume();
     238             : 
     239           0 :         lua_newtable(L);
     240           0 :         for (u32 i = 0; i != volume; i++) {
     241           0 :                 lua_Integer light = vm->m_data[i].param1;
     242           0 :                 lua_pushinteger(L, light);
     243           0 :                 lua_rawseti(L, -2, i + 1);
     244             :         }
     245             : 
     246           0 :         return 1;
     247             : }
     248             : 
     249           0 : int LuaVoxelManip::l_set_light_data(lua_State *L)
     250             : {
     251           0 :         NO_MAP_LOCK_REQUIRED;
     252             : 
     253           0 :         LuaVoxelManip *o = checkobject(L, 1);
     254           0 :         MMVManip *vm = o->vm;
     255             : 
     256           0 :         if (!lua_istable(L, 2))
     257           0 :                 return 0;
     258             : 
     259           0 :         u32 volume = vm->m_area.getVolume();
     260           0 :         for (u32 i = 0; i != volume; i++) {
     261           0 :                 lua_rawgeti(L, 2, i + 1);
     262           0 :                 u8 light = lua_tointeger(L, -1);
     263             : 
     264           0 :                 vm->m_data[i].param1 = light;
     265             : 
     266           0 :                 lua_pop(L, 1);
     267             :         }
     268             : 
     269           0 :         return 0;
     270             : }
     271             : 
     272           0 : int LuaVoxelManip::l_get_param2_data(lua_State *L)
     273             : {
     274           0 :         NO_MAP_LOCK_REQUIRED;
     275             : 
     276           0 :         LuaVoxelManip *o = checkobject(L, 1);
     277           0 :         MMVManip *vm = o->vm;
     278             : 
     279           0 :         u32 volume = vm->m_area.getVolume();
     280             : 
     281           0 :         lua_newtable(L);
     282           0 :         for (u32 i = 0; i != volume; i++) {
     283           0 :                 lua_Integer param2 = vm->m_data[i].param2;
     284           0 :                 lua_pushinteger(L, param2);
     285           0 :                 lua_rawseti(L, -2, i + 1);
     286             :         }
     287             : 
     288           0 :         return 1;
     289             : }
     290             : 
     291           0 : int LuaVoxelManip::l_set_param2_data(lua_State *L)
     292             : {
     293           0 :         NO_MAP_LOCK_REQUIRED;
     294             : 
     295           0 :         LuaVoxelManip *o = checkobject(L, 1);
     296           0 :         MMVManip *vm = o->vm;
     297             : 
     298           0 :         if (!lua_istable(L, 2))
     299           0 :                 return 0;
     300             : 
     301           0 :         u32 volume = vm->m_area.getVolume();
     302           0 :         for (u32 i = 0; i != volume; i++) {
     303           0 :                 lua_rawgeti(L, 2, i + 1);
     304           0 :                 u8 param2 = lua_tointeger(L, -1);
     305             : 
     306           0 :                 vm->m_data[i].param2 = param2;
     307             : 
     308           0 :                 lua_pop(L, 1);
     309             :         }
     310             : 
     311           0 :         return 0;
     312             : }
     313             : 
     314           0 : int LuaVoxelManip::l_update_map(lua_State *L)
     315             : {
     316           0 :         LuaVoxelManip *o = checkobject(L, 1);
     317           0 :         if (o->is_mapgen_vm)
     318           0 :                 return 0;
     319             : 
     320           0 :         Environment *env = getEnv(L);
     321           0 :         if (!env)
     322           0 :                 return 0;
     323             : 
     324           0 :         Map *map = &(env->getMap());
     325             : 
     326             :         // TODO: Optimize this by using Mapgen::calcLighting() instead
     327           0 :         std::map<v3s16, MapBlock *> lighting_mblocks;
     328           0 :         std::map<v3s16, MapBlock *> *mblocks = &o->modified_blocks;
     329             : 
     330           0 :         lighting_mblocks.insert(mblocks->begin(), mblocks->end());
     331             : 
     332           0 :         map->updateLighting(lighting_mblocks, *mblocks);
     333             : 
     334           0 :         MapEditEvent event;
     335           0 :         event.type = MEET_OTHER;
     336           0 :         for (std::map<v3s16, MapBlock *>::iterator
     337           0 :                 it = mblocks->begin();
     338           0 :                 it != mblocks->end(); ++it)
     339           0 :                 event.modified_blocks.insert(it->first);
     340             : 
     341           0 :         map->dispatchEvent(&event);
     342             : 
     343           0 :         mblocks->clear();
     344             : 
     345           0 :         return 0;
     346             : }
     347             : 
     348           0 : int LuaVoxelManip::l_was_modified(lua_State *L)
     349             : {
     350           0 :         NO_MAP_LOCK_REQUIRED;
     351             : 
     352           0 :         LuaVoxelManip *o = checkobject(L, 1);
     353           0 :         MMVManip *vm = o->vm;
     354             : 
     355           0 :         lua_pushboolean(L, vm->m_is_dirty);
     356             : 
     357           0 :         return 1;
     358             : }
     359             : 
     360           0 : int LuaVoxelManip::l_get_emerged_area(lua_State *L)
     361             : {
     362           0 :         LuaVoxelManip *o = checkobject(L, 1);
     363             : 
     364           0 :         push_v3s16(L, o->vm->m_area.MinEdge);
     365           0 :         push_v3s16(L, o->vm->m_area.MaxEdge);
     366             : 
     367           0 :         return 2;
     368             : }
     369             : 
     370           0 : LuaVoxelManip::LuaVoxelManip(MMVManip *mmvm, bool is_mg_vm)
     371             : {
     372           0 :         this->vm           = mmvm;
     373           0 :         this->is_mapgen_vm = is_mg_vm;
     374           0 : }
     375             : 
     376           0 : LuaVoxelManip::LuaVoxelManip(Map *map)
     377             : {
     378           0 :         this->vm = new MMVManip(map);
     379           0 :         this->is_mapgen_vm = false;
     380           0 : }
     381             : 
     382           0 : LuaVoxelManip::LuaVoxelManip(Map *map, v3s16 p1, v3s16 p2)
     383             : {
     384           0 :         this->vm = new MMVManip(map);
     385           0 :         this->is_mapgen_vm = false;
     386             : 
     387           0 :         v3s16 bp1 = getNodeBlockPos(p1);
     388           0 :         v3s16 bp2 = getNodeBlockPos(p2);
     389           0 :         sortBoxVerticies(bp1, bp2);
     390           0 :         vm->initialEmerge(bp1, bp2);
     391           0 : }
     392             : 
     393           0 : LuaVoxelManip::~LuaVoxelManip()
     394             : {
     395           0 :         if (!is_mapgen_vm)
     396           0 :                 delete vm;
     397           0 : }
     398             : 
     399             : // LuaVoxelManip()
     400             : // Creates an LuaVoxelManip and leaves it on top of stack
     401           0 : int LuaVoxelManip::create_object(lua_State *L)
     402             : {
     403           0 :         NO_MAP_LOCK_REQUIRED;
     404             : 
     405           0 :         Environment *env = getEnv(L);
     406           0 :         if (!env)
     407           0 :                 return 0;
     408             : 
     409           0 :         Map *map = &(env->getMap());
     410           0 :         LuaVoxelManip *o = (lua_istable(L, 1) && lua_istable(L, 2)) ?
     411           0 :                 new LuaVoxelManip(map, check_v3s16(L, 1), check_v3s16(L, 2)) :
     412           0 :                 new LuaVoxelManip(map);
     413             : 
     414           0 :         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
     415           0 :         luaL_getmetatable(L, className);
     416           0 :         lua_setmetatable(L, -2);
     417           0 :         return 1;
     418             : }
     419             : 
     420           0 : LuaVoxelManip *LuaVoxelManip::checkobject(lua_State *L, int narg)
     421             : {
     422           0 :         NO_MAP_LOCK_REQUIRED;
     423             : 
     424           0 :         luaL_checktype(L, narg, LUA_TUSERDATA);
     425             : 
     426           0 :         void *ud = luaL_checkudata(L, narg, className);
     427           0 :         if (!ud)
     428           0 :                 luaL_typerror(L, narg, className);
     429             : 
     430           0 :         return *(LuaVoxelManip **)ud;  // unbox pointer
     431             : }
     432             : 
     433           0 : void LuaVoxelManip::Register(lua_State *L)
     434             : {
     435           0 :         lua_newtable(L);
     436           0 :         int methodtable = lua_gettop(L);
     437           0 :         luaL_newmetatable(L, className);
     438           0 :         int metatable = lua_gettop(L);
     439             : 
     440           0 :         lua_pushliteral(L, "__metatable");
     441           0 :         lua_pushvalue(L, methodtable);
     442           0 :         lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
     443             : 
     444           0 :         lua_pushliteral(L, "__index");
     445           0 :         lua_pushvalue(L, methodtable);
     446           0 :         lua_settable(L, metatable);
     447             : 
     448           0 :         lua_pushliteral(L, "__gc");
     449           0 :         lua_pushcfunction(L, gc_object);
     450           0 :         lua_settable(L, metatable);
     451             : 
     452           0 :         lua_pop(L, 1);  // drop metatable
     453             : 
     454           0 :         luaL_openlib(L, 0, methods, 0);  // fill methodtable
     455           0 :         lua_pop(L, 1);  // drop methodtable
     456             : 
     457             :         // Can be created from Lua (VoxelManip())
     458           0 :         lua_register(L, className, create_object);
     459           0 : }
     460             : 
     461             : const char LuaVoxelManip::className[] = "VoxelManip";
     462             : const luaL_reg LuaVoxelManip::methods[] = {
     463             :         luamethod(LuaVoxelManip, read_from_map),
     464             :         luamethod(LuaVoxelManip, get_data),
     465             :         luamethod(LuaVoxelManip, set_data),
     466             :         luamethod(LuaVoxelManip, get_node_at),
     467             :         luamethod(LuaVoxelManip, set_node_at),
     468             :         luamethod(LuaVoxelManip, write_to_map),
     469             :         luamethod(LuaVoxelManip, update_map),
     470             :         luamethod(LuaVoxelManip, update_liquids),
     471             :         luamethod(LuaVoxelManip, calc_lighting),
     472             :         luamethod(LuaVoxelManip, set_lighting),
     473             :         luamethod(LuaVoxelManip, get_light_data),
     474             :         luamethod(LuaVoxelManip, set_light_data),
     475             :         luamethod(LuaVoxelManip, get_param2_data),
     476             :         luamethod(LuaVoxelManip, set_param2_data),
     477             :         luamethod(LuaVoxelManip, was_modified),
     478             :         luamethod(LuaVoxelManip, get_emerged_area),
     479             :         {0,0}
     480           3 : };

Generated by: LCOV version 1.11