LCOV - code coverage report
Current view: top level - src/script/lua_api - l_env.cpp (source / functions) Hit Total Coverage
Test: report Lines: 1 534 0.2 %
Date: 2015-07-11 18:23:49 Functions: 2 43 4.7 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       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             : #include "lua_api/l_env.h"
      21             : #include "lua_api/l_internal.h"
      22             : #include "lua_api/l_nodemeta.h"
      23             : #include "lua_api/l_nodetimer.h"
      24             : #include "lua_api/l_noise.h"
      25             : #include "lua_api/l_vmanip.h"
      26             : #include "common/c_converter.h"
      27             : #include "common/c_content.h"
      28             : #include "scripting_game.h"
      29             : #include "environment.h"
      30             : #include "server.h"
      31             : #include "nodedef.h"
      32             : #include "daynightratio.h"
      33             : #include "util/pointedthing.h"
      34             : #include "content_sao.h"
      35             : #include "treegen.h"
      36             : #include "pathfinder.h"
      37             : 
      38             : #define GET_ENV_PTR ServerEnvironment* env =                                   \
      39             :                                 dynamic_cast<ServerEnvironment*>(getEnv(L));                   \
      40             :                                 if (env == NULL) return 0
      41             : 
      42             : ///////////////////////////////////////////////////////////////////////////////
      43             : 
      44             : 
      45           0 : void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
      46             :                 u32 active_object_count, u32 active_object_count_wider)
      47             : {
      48           0 :         GameScripting *scriptIface = env->getScriptIface();
      49           0 :         scriptIface->realityCheck();
      50             : 
      51           0 :         lua_State *L = scriptIface->getStack();
      52           0 :         sanity_check(lua_checkstack(L, 20));
      53           0 :         StackUnroller stack_unroller(L);
      54             : 
      55           0 :         lua_pushcfunction(L, script_error_handler);
      56           0 :         int errorhandler = lua_gettop(L);
      57             : 
      58             :         // Get registered_abms
      59           0 :         lua_getglobal(L, "core");
      60           0 :         lua_getfield(L, -1, "registered_abms");
      61           0 :         luaL_checktype(L, -1, LUA_TTABLE);
      62           0 :         lua_remove(L, -2); // Remove core
      63             : 
      64             :         // Get registered_abms[m_id]
      65           0 :         lua_pushnumber(L, m_id);
      66           0 :         lua_gettable(L, -2);
      67           0 :         if(lua_isnil(L, -1))
      68           0 :                 FATAL_ERROR("");
      69           0 :         lua_remove(L, -2); // Remove registered_abms
      70             : 
      71             :         // Call action
      72           0 :         luaL_checktype(L, -1, LUA_TTABLE);
      73           0 :         lua_getfield(L, -1, "action");
      74           0 :         luaL_checktype(L, -1, LUA_TFUNCTION);
      75           0 :         lua_remove(L, -2); // Remove registered_abms[m_id]
      76           0 :         push_v3s16(L, p);
      77           0 :         pushnode(L, n, env->getGameDef()->ndef());
      78           0 :         lua_pushnumber(L, active_object_count);
      79           0 :         lua_pushnumber(L, active_object_count_wider);
      80           0 :         if(lua_pcall(L, 4, 0, errorhandler))
      81           0 :                 script_error(L);
      82           0 :         lua_pop(L, 1); // Pop error handler
      83           0 : }
      84             : 
      85             : // Exported functions
      86             : 
      87             : // set_node(pos, node)
      88             : // pos = {x=num, y=num, z=num}
      89           0 : int ModApiEnvMod::l_set_node(lua_State *L)
      90             : {
      91           0 :         GET_ENV_PTR;
      92             : 
      93           0 :         INodeDefManager *ndef = env->getGameDef()->ndef();
      94             :         // parameters
      95           0 :         v3s16 pos = read_v3s16(L, 1);
      96           0 :         MapNode n = readnode(L, 2, ndef);
      97             :         // Do it
      98           0 :         bool succeeded = env->setNode(pos, n);
      99           0 :         lua_pushboolean(L, succeeded);
     100           0 :         return 1;
     101             : }
     102             : 
     103           0 : int ModApiEnvMod::l_add_node(lua_State *L)
     104             : {
     105           0 :         return l_set_node(L);
     106             : }
     107             : 
     108             : // remove_node(pos)
     109             : // pos = {x=num, y=num, z=num}
     110           0 : int ModApiEnvMod::l_remove_node(lua_State *L)
     111             : {
     112           0 :         GET_ENV_PTR;
     113             : 
     114             :         // parameters
     115           0 :         v3s16 pos = read_v3s16(L, 1);
     116             :         // Do it
     117           0 :         bool succeeded = env->removeNode(pos);
     118           0 :         lua_pushboolean(L, succeeded);
     119           0 :         return 1;
     120             : }
     121             : 
     122             : // swap_node(pos, node)
     123             : // pos = {x=num, y=num, z=num}
     124           0 : int ModApiEnvMod::l_swap_node(lua_State *L)
     125             : {
     126           0 :         GET_ENV_PTR;
     127             : 
     128           0 :         INodeDefManager *ndef = env->getGameDef()->ndef();
     129             :         // parameters
     130           0 :         v3s16 pos = read_v3s16(L, 1);
     131           0 :         MapNode n = readnode(L, 2, ndef);
     132             :         // Do it
     133           0 :         bool succeeded = env->swapNode(pos, n);
     134           0 :         lua_pushboolean(L, succeeded);
     135           0 :         return 1;
     136             : }
     137             : 
     138             : // get_node(pos)
     139             : // pos = {x=num, y=num, z=num}
     140           0 : int ModApiEnvMod::l_get_node(lua_State *L)
     141             : {
     142           0 :         GET_ENV_PTR;
     143             : 
     144             :         // pos
     145           0 :         v3s16 pos = read_v3s16(L, 1);
     146             :         // Do it
     147           0 :         MapNode n = env->getMap().getNodeNoEx(pos);
     148             :         // Return node
     149           0 :         pushnode(L, n, env->getGameDef()->ndef());
     150           0 :         return 1;
     151             : }
     152             : 
     153             : // get_node_or_nil(pos)
     154             : // pos = {x=num, y=num, z=num}
     155           0 : int ModApiEnvMod::l_get_node_or_nil(lua_State *L)
     156             : {
     157           0 :         GET_ENV_PTR;
     158             : 
     159             :         // pos
     160           0 :         v3s16 pos = read_v3s16(L, 1);
     161             :         // Do it
     162             :         bool pos_ok;
     163           0 :         MapNode n = env->getMap().getNodeNoEx(pos, &pos_ok);
     164           0 :         if (pos_ok) {
     165             :                 // Return node
     166           0 :                 pushnode(L, n, env->getGameDef()->ndef());
     167             :         } else {
     168           0 :                 lua_pushnil(L);
     169             :         }
     170           0 :         return 1;
     171             : }
     172             : 
     173             : // get_node_light(pos, timeofday)
     174             : // pos = {x=num, y=num, z=num}
     175             : // timeofday: nil = current time, 0 = night, 0.5 = day
     176           0 : int ModApiEnvMod::l_get_node_light(lua_State *L)
     177             : {
     178           0 :         GET_ENV_PTR;
     179             : 
     180             :         // Do it
     181           0 :         v3s16 pos = read_v3s16(L, 1);
     182           0 :         u32 time_of_day = env->getTimeOfDay();
     183           0 :         if(lua_isnumber(L, 2))
     184           0 :                 time_of_day = 24000.0 * lua_tonumber(L, 2);
     185           0 :         time_of_day %= 24000;
     186           0 :         u32 dnr = time_to_daynight_ratio(time_of_day, true);
     187             : 
     188             :         bool is_position_ok;
     189           0 :         MapNode n = env->getMap().getNodeNoEx(pos, &is_position_ok);
     190           0 :         if (is_position_ok) {
     191           0 :                 INodeDefManager *ndef = env->getGameDef()->ndef();
     192           0 :                 lua_pushinteger(L, n.getLightBlend(dnr, ndef));
     193             :         } else {
     194           0 :                 lua_pushnil(L);
     195             :         }
     196           0 :         return 1;
     197             : }
     198             : 
     199             : // place_node(pos, node)
     200             : // pos = {x=num, y=num, z=num}
     201           0 : int ModApiEnvMod::l_place_node(lua_State *L)
     202             : {
     203           0 :         GET_ENV_PTR;
     204             : 
     205           0 :         ScriptApiItem *scriptIfaceItem = getScriptApi<ScriptApiItem>(L);
     206           0 :         Server *server = getServer(L);
     207           0 :         INodeDefManager *ndef = server->ndef();
     208           0 :         IItemDefManager *idef = server->idef();
     209             : 
     210           0 :         v3s16 pos = read_v3s16(L, 1);
     211           0 :         MapNode n = readnode(L, 2, ndef);
     212             : 
     213             :         // Don't attempt to load non-loaded area as of now
     214           0 :         MapNode n_old = env->getMap().getNodeNoEx(pos);
     215           0 :         if(n_old.getContent() == CONTENT_IGNORE){
     216           0 :                 lua_pushboolean(L, false);
     217           0 :                 return 1;
     218             :         }
     219             :         // Create item to place
     220           0 :         ItemStack item(ndef->get(n).name, 1, 0, "", idef);
     221             :         // Make pointed position
     222           0 :         PointedThing pointed;
     223           0 :         pointed.type = POINTEDTHING_NODE;
     224           0 :         pointed.node_abovesurface = pos;
     225           0 :         pointed.node_undersurface = pos + v3s16(0,-1,0);
     226             :         // Place it with a NULL placer (appears in Lua as a non-functional
     227             :         // ObjectRef)
     228           0 :         bool success = scriptIfaceItem->item_OnPlace(item, NULL, pointed);
     229           0 :         lua_pushboolean(L, success);
     230           0 :         return 1;
     231             : }
     232             : 
     233             : // dig_node(pos)
     234             : // pos = {x=num, y=num, z=num}
     235           0 : int ModApiEnvMod::l_dig_node(lua_State *L)
     236             : {
     237           0 :         GET_ENV_PTR;
     238             : 
     239           0 :         ScriptApiNode *scriptIfaceNode = getScriptApi<ScriptApiNode>(L);
     240             : 
     241           0 :         v3s16 pos = read_v3s16(L, 1);
     242             : 
     243             :         // Don't attempt to load non-loaded area as of now
     244           0 :         MapNode n = env->getMap().getNodeNoEx(pos);
     245           0 :         if(n.getContent() == CONTENT_IGNORE){
     246           0 :                 lua_pushboolean(L, false);
     247           0 :                 return 1;
     248             :         }
     249             :         // Dig it out with a NULL digger (appears in Lua as a
     250             :         // non-functional ObjectRef)
     251           0 :         bool success = scriptIfaceNode->node_on_dig(pos, n, NULL);
     252           0 :         lua_pushboolean(L, success);
     253           0 :         return 1;
     254             : }
     255             : 
     256             : // punch_node(pos)
     257             : // pos = {x=num, y=num, z=num}
     258           0 : int ModApiEnvMod::l_punch_node(lua_State *L)
     259             : {
     260           0 :         GET_ENV_PTR;
     261             : 
     262           0 :         ScriptApiNode *scriptIfaceNode = getScriptApi<ScriptApiNode>(L);
     263             : 
     264           0 :         v3s16 pos = read_v3s16(L, 1);
     265             : 
     266             :         // Don't attempt to load non-loaded area as of now
     267           0 :         MapNode n = env->getMap().getNodeNoEx(pos);
     268           0 :         if(n.getContent() == CONTENT_IGNORE){
     269           0 :                 lua_pushboolean(L, false);
     270           0 :                 return 1;
     271             :         }
     272             :         // Punch it with a NULL puncher (appears in Lua as a non-functional
     273             :         // ObjectRef)
     274           0 :         bool success = scriptIfaceNode->node_on_punch(pos, n, NULL, PointedThing());
     275           0 :         lua_pushboolean(L, success);
     276           0 :         return 1;
     277             : }
     278             : 
     279             : // get_node_max_level(pos)
     280             : // pos = {x=num, y=num, z=num}
     281           0 : int ModApiEnvMod::l_get_node_max_level(lua_State *L)
     282             : {
     283           0 :         GET_ENV_PTR;
     284             : 
     285           0 :         v3s16 pos = read_v3s16(L, 1);
     286           0 :         MapNode n = env->getMap().getNodeNoEx(pos);
     287           0 :         lua_pushnumber(L, n.getMaxLevel(env->getGameDef()->ndef()));
     288           0 :         return 1;
     289             : }
     290             : 
     291             : // get_node_level(pos)
     292             : // pos = {x=num, y=num, z=num}
     293           0 : int ModApiEnvMod::l_get_node_level(lua_State *L)
     294             : {
     295           0 :         GET_ENV_PTR;
     296             : 
     297           0 :         v3s16 pos = read_v3s16(L, 1);
     298           0 :         MapNode n = env->getMap().getNodeNoEx(pos);
     299           0 :         lua_pushnumber(L, n.getLevel(env->getGameDef()->ndef()));
     300           0 :         return 1;
     301             : }
     302             : 
     303             : // set_node_level(pos, level)
     304             : // pos = {x=num, y=num, z=num}
     305             : // level: 0..63
     306           0 : int ModApiEnvMod::l_set_node_level(lua_State *L)
     307             : {
     308           0 :         GET_ENV_PTR;
     309             : 
     310           0 :         v3s16 pos = read_v3s16(L, 1);
     311           0 :         u8 level = 1;
     312           0 :         if(lua_isnumber(L, 2))
     313           0 :                 level = lua_tonumber(L, 2);
     314           0 :         MapNode n = env->getMap().getNodeNoEx(pos);
     315           0 :         lua_pushnumber(L, n.setLevel(env->getGameDef()->ndef(), level));
     316           0 :         env->setNode(pos, n);
     317           0 :         return 1;
     318             : }
     319             : 
     320             : // add_node_level(pos, level)
     321             : // pos = {x=num, y=num, z=num}
     322             : // level: 0..63
     323           0 : int ModApiEnvMod::l_add_node_level(lua_State *L)
     324             : {
     325           0 :         GET_ENV_PTR;
     326             : 
     327           0 :         v3s16 pos = read_v3s16(L, 1);
     328           0 :         u8 level = 1;
     329           0 :         if(lua_isnumber(L, 2))
     330           0 :                 level = lua_tonumber(L, 2);
     331           0 :         MapNode n = env->getMap().getNodeNoEx(pos);
     332           0 :         lua_pushnumber(L, n.addLevel(env->getGameDef()->ndef(), level));
     333           0 :         env->setNode(pos, n);
     334           0 :         return 1;
     335             : }
     336             : 
     337             : // find_nodes_with_meta(pos1, pos2)
     338           0 : int ModApiEnvMod::l_find_nodes_with_meta(lua_State *L)
     339             : {
     340           0 :         GET_ENV_PTR;
     341             : 
     342           0 :         std::vector<v3s16> positions = env->getMap().findNodesWithMetadata(
     343           0 :                 check_v3s16(L, 1), check_v3s16(L, 2));
     344             : 
     345           0 :         lua_newtable(L);
     346           0 :         for (size_t i = 0; i != positions.size(); i++) {
     347           0 :                 push_v3s16(L, positions[i]);
     348           0 :                 lua_rawseti(L, -2, i + 1);
     349             :         }
     350             : 
     351           0 :         return 1;
     352             : }
     353             : 
     354             : // get_meta(pos)
     355           0 : int ModApiEnvMod::l_get_meta(lua_State *L)
     356             : {
     357           0 :         GET_ENV_PTR;
     358             : 
     359             :         // Do it
     360           0 :         v3s16 p = read_v3s16(L, 1);
     361           0 :         NodeMetaRef::create(L, p, env);
     362           0 :         return 1;
     363             : }
     364             : 
     365             : // get_node_timer(pos)
     366           0 : int ModApiEnvMod::l_get_node_timer(lua_State *L)
     367             : {
     368           0 :         GET_ENV_PTR;
     369             : 
     370             :         // Do it
     371           0 :         v3s16 p = read_v3s16(L, 1);
     372           0 :         NodeTimerRef::create(L, p, env);
     373           0 :         return 1;
     374             : }
     375             : 
     376             : // add_entity(pos, entityname) -> ObjectRef or nil
     377             : // pos = {x=num, y=num, z=num}
     378           0 : int ModApiEnvMod::l_add_entity(lua_State *L)
     379             : {
     380           0 :         GET_ENV_PTR;
     381             : 
     382             :         // pos
     383           0 :         v3f pos = checkFloatPos(L, 1);
     384             :         // content
     385           0 :         const char *name = luaL_checkstring(L, 2);
     386             :         // Do it
     387           0 :         ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
     388           0 :         int objectid = env->addActiveObject(obj);
     389             :         // If failed to add, return nothing (reads as nil)
     390           0 :         if(objectid == 0)
     391           0 :                 return 0;
     392             :         // Return ObjectRef
     393           0 :         getScriptApiBase(L)->objectrefGetOrCreate(L, obj);
     394           0 :         return 1;
     395             : }
     396             : 
     397             : // add_item(pos, itemstack or itemstring or table) -> ObjectRef or nil
     398             : // pos = {x=num, y=num, z=num}
     399           0 : int ModApiEnvMod::l_add_item(lua_State *L)
     400             : {
     401           0 :         GET_ENV_PTR;
     402             : 
     403             :         // pos
     404             :         //v3f pos = checkFloatPos(L, 1);
     405             :         // item
     406           0 :         ItemStack item = read_item(L, 2,getServer(L));
     407           0 :         if(item.empty() || !item.isKnown(getServer(L)->idef()))
     408           0 :                 return 0;
     409             : 
     410           0 :         lua_pushcfunction(L, script_error_handler);
     411           0 :         int errorhandler = lua_gettop(L);
     412             : 
     413             :         // Use spawn_item to spawn a __builtin:item
     414           0 :         lua_getglobal(L, "core");
     415           0 :         lua_getfield(L, -1, "spawn_item");
     416           0 :         lua_remove(L, -2); // Remove core
     417           0 :         if(lua_isnil(L, -1))
     418           0 :                 return 0;
     419           0 :         lua_pushvalue(L, 1);
     420           0 :         lua_pushstring(L, item.getItemString().c_str());
     421           0 :         if(lua_pcall(L, 2, 1, errorhandler))
     422           0 :                 script_error(L);
     423           0 :         lua_remove(L, errorhandler); // Remove error handler
     424           0 :         return 1;
     425             : }
     426             : 
     427             : // get_player_by_name(name)
     428           0 : int ModApiEnvMod::l_get_player_by_name(lua_State *L)
     429             : {
     430           0 :         GET_ENV_PTR;
     431             : 
     432             :         // Do it
     433           0 :         const char *name = luaL_checkstring(L, 1);
     434           0 :         Player *player = env->getPlayer(name);
     435           0 :         if(player == NULL){
     436           0 :                 lua_pushnil(L);
     437           0 :                 return 1;
     438             :         }
     439           0 :         PlayerSAO *sao = player->getPlayerSAO();
     440           0 :         if(sao == NULL){
     441           0 :                 lua_pushnil(L);
     442           0 :                 return 1;
     443             :         }
     444             :         // Put player on stack
     445           0 :         getScriptApiBase(L)->objectrefGetOrCreate(L, sao);
     446           0 :         return 1;
     447             : }
     448             : 
     449             : // get_objects_inside_radius(pos, radius)
     450           0 : int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L)
     451             : {
     452           0 :         GET_ENV_PTR;
     453             : 
     454             :         // Do it
     455           0 :         v3f pos = checkFloatPos(L, 1);
     456           0 :         float radius = luaL_checknumber(L, 2) * BS;
     457           0 :         std::vector<u16> ids;
     458           0 :         env->getObjectsInsideRadius(ids, pos, radius);
     459           0 :         ScriptApiBase *script = getScriptApiBase(L);
     460           0 :         lua_createtable(L, ids.size(), 0);
     461           0 :         std::vector<u16>::const_iterator iter = ids.begin();
     462           0 :         for(u32 i = 0; iter != ids.end(); iter++) {
     463           0 :                 ServerActiveObject *obj = env->getActiveObject(*iter);
     464             :                 // Insert object reference into table
     465           0 :                 script->objectrefGetOrCreate(L, obj);
     466           0 :                 lua_rawseti(L, -2, ++i);
     467             :         }
     468           0 :         return 1;
     469             : }
     470             : 
     471             : // set_timeofday(val)
     472             : // val = 0...1
     473           0 : int ModApiEnvMod::l_set_timeofday(lua_State *L)
     474             : {
     475           0 :         GET_ENV_PTR;
     476             : 
     477             :         // Do it
     478           0 :         float timeofday_f = luaL_checknumber(L, 1);
     479           0 :         sanity_check(timeofday_f >= 0.0 && timeofday_f <= 1.0);
     480           0 :         int timeofday_mh = (int)(timeofday_f * 24000.0);
     481             :         // This should be set directly in the environment but currently
     482             :         // such changes aren't immediately sent to the clients, so call
     483             :         // the server instead.
     484             :         //env->setTimeOfDay(timeofday_mh);
     485           0 :         getServer(L)->setTimeOfDay(timeofday_mh);
     486           0 :         return 0;
     487             : }
     488             : 
     489             : // get_timeofday() -> 0...1
     490           0 : int ModApiEnvMod::l_get_timeofday(lua_State *L)
     491             : {
     492           0 :         GET_ENV_PTR;
     493             : 
     494             :         // Do it
     495           0 :         int timeofday_mh = env->getTimeOfDay();
     496           0 :         float timeofday_f = (float)timeofday_mh / 24000.0;
     497           0 :         lua_pushnumber(L, timeofday_f);
     498           0 :         return 1;
     499             : }
     500             : 
     501             : // get_gametime()
     502           0 : int ModApiEnvMod::l_get_gametime(lua_State *L)
     503             : {
     504           0 :         GET_ENV_PTR;
     505             : 
     506           0 :         int game_time = env->getGameTime();
     507           0 :         lua_pushnumber(L, game_time);
     508           0 :         return 1;
     509             : }
     510             : 
     511             : 
     512             : // find_node_near(pos, radius, nodenames) -> pos or nil
     513             : // nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
     514           0 : int ModApiEnvMod::l_find_node_near(lua_State *L)
     515             : {
     516           0 :         GET_ENV_PTR;
     517             : 
     518           0 :         INodeDefManager *ndef = getServer(L)->ndef();
     519           0 :         v3s16 pos = read_v3s16(L, 1);
     520           0 :         int radius = luaL_checkinteger(L, 2);
     521           0 :         std::set<content_t> filter;
     522           0 :         if(lua_istable(L, 3)){
     523           0 :                 int table = 3;
     524           0 :                 lua_pushnil(L);
     525           0 :                 while(lua_next(L, table) != 0){
     526             :                         // key at index -2 and value at index -1
     527           0 :                         luaL_checktype(L, -1, LUA_TSTRING);
     528           0 :                         ndef->getIds(lua_tostring(L, -1), filter);
     529             :                         // removes value, keeps key for next iteration
     530           0 :                         lua_pop(L, 1);
     531             :                 }
     532           0 :         } else if(lua_isstring(L, 3)){
     533           0 :                 ndef->getIds(lua_tostring(L, 3), filter);
     534             :         }
     535             : 
     536           0 :         for(int d=1; d<=radius; d++){
     537           0 :                 std::vector<v3s16> list = FacePositionCache::getFacePositions(d);
     538           0 :                 for(std::vector<v3s16>::iterator i = list.begin();
     539           0 :                                 i != list.end(); ++i){
     540           0 :                         v3s16 p = pos + (*i);
     541           0 :                         content_t c = env->getMap().getNodeNoEx(p).getContent();
     542           0 :                         if(filter.count(c) != 0){
     543           0 :                                 push_v3s16(L, p);
     544           0 :                                 return 1;
     545             :                         }
     546             :                 }
     547             :         }
     548           0 :         return 0;
     549             : }
     550             : 
     551             : // find_nodes_in_area(minp, maxp, nodenames) -> list of positions
     552             : // nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
     553           0 : int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
     554             : {
     555           0 :         GET_ENV_PTR;
     556             : 
     557           0 :         INodeDefManager *ndef = getServer(L)->ndef();
     558           0 :         v3s16 minp = read_v3s16(L, 1);
     559           0 :         v3s16 maxp = read_v3s16(L, 2);
     560           0 :         std::set<content_t> filter;
     561           0 :         if(lua_istable(L, 3)) {
     562           0 :                 int table = 3;
     563           0 :                 lua_pushnil(L);
     564           0 :                 while(lua_next(L, table) != 0) {
     565             :                         // key at index -2 and value at index -1
     566           0 :                         luaL_checktype(L, -1, LUA_TSTRING);
     567           0 :                         ndef->getIds(lua_tostring(L, -1), filter);
     568             :                         // removes value, keeps key for next iteration
     569           0 :                         lua_pop(L, 1);
     570             :                 }
     571           0 :         } else if(lua_isstring(L, 3)) {
     572           0 :                 ndef->getIds(lua_tostring(L, 3), filter);
     573             :         }
     574             : 
     575           0 :         std::map<content_t, u16> individual_count;
     576             : 
     577           0 :         lua_newtable(L);
     578           0 :         u64 i = 0;
     579           0 :         for (s16 x = minp.X; x <= maxp.X; x++)
     580           0 :                 for (s16 y = minp.Y; y <= maxp.Y; y++)
     581           0 :                         for (s16 z = minp.Z; z <= maxp.Z; z++) {
     582           0 :                                 v3s16 p(x, y, z);
     583           0 :                                 content_t c = env->getMap().getNodeNoEx(p).getContent();
     584           0 :                                 if (filter.count(c) != 0) {
     585           0 :                                         push_v3s16(L, p);
     586           0 :                                         lua_rawseti(L, -2, ++i);
     587           0 :                                         individual_count[c]++;
     588             :                                 }
     589             :         }
     590           0 :         lua_newtable(L);
     591           0 :         for (std::set<content_t>::iterator it = filter.begin();
     592           0 :                         it != filter.end(); ++it) {
     593           0 :                 lua_pushnumber(L, individual_count[*it]);
     594           0 :                 lua_setfield(L, -2, ndef->get(*it).name.c_str());
     595             :         }
     596           0 :         return 2;
     597             : }
     598             : 
     599             : // find_nodes_in_area_under_air(minp, maxp, nodenames) -> list of positions
     600             : // nodenames: e.g. {"ignore", "group:tree"} or "default:dirt"
     601           0 : int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
     602             : {
     603             :         /* Note: A similar but generalized (and therefore slower) version of this
     604             :          * function could be created -- e.g. find_nodes_in_area_under -- which
     605             :          * would accept a node name (or ID?) or list of names that the "above node"
     606             :          * should be.
     607             :          * TODO
     608             :          */
     609             : 
     610           0 :         GET_ENV_PTR;
     611             : 
     612           0 :         INodeDefManager *ndef = getServer(L)->ndef();
     613           0 :         v3s16 minp = read_v3s16(L, 1);
     614           0 :         v3s16 maxp = read_v3s16(L, 2);
     615           0 :         std::set<content_t> filter;
     616             : 
     617           0 :         if (lua_istable(L, 3)) {
     618           0 :                 int table = 3;
     619           0 :                 lua_pushnil(L);
     620           0 :                 while(lua_next(L, table) != 0) {
     621             :                         // key at index -2 and value at index -1
     622           0 :                         luaL_checktype(L, -1, LUA_TSTRING);
     623           0 :                         ndef->getIds(lua_tostring(L, -1), filter);
     624             :                         // removes value, keeps key for next iteration
     625           0 :                         lua_pop(L, 1);
     626             :                 }
     627           0 :         } else if (lua_isstring(L, 3)) {
     628           0 :                 ndef->getIds(lua_tostring(L, 3), filter);
     629             :         }
     630             : 
     631           0 :         lua_newtable(L);
     632           0 :         u64 i = 0;
     633           0 :         for (s16 x = minp.X; x <= maxp.X; x++)
     634           0 :         for (s16 z = minp.Z; z <= maxp.Z; z++) {
     635           0 :                 s16 y = minp.Y;
     636           0 :                 v3s16 p(x, y, z);
     637           0 :                 content_t c = env->getMap().getNodeNoEx(p).getContent();
     638           0 :                 for (; y <= maxp.Y; y++) {
     639           0 :                         v3s16 psurf(x, y + 1, z);
     640           0 :                         content_t csurf = env->getMap().getNodeNoEx(psurf).getContent();
     641           0 :                         if(c != CONTENT_AIR && csurf == CONTENT_AIR &&
     642           0 :                                         filter.count(c) != 0) {
     643           0 :                                 push_v3s16(L, v3s16(x, y, z));
     644           0 :                                 lua_rawseti(L, -2, ++i);
     645             :                         }
     646           0 :                         c = csurf;
     647             :                 }
     648             :         }
     649           0 :         return 1;
     650             : }
     651             : 
     652             : // get_perlin(seeddiff, octaves, persistence, scale)
     653             : // returns world-specific PerlinNoise
     654           0 : int ModApiEnvMod::l_get_perlin(lua_State *L)
     655             : {
     656           0 :         GET_ENV_PTR;
     657             : 
     658           0 :         NoiseParams params;
     659             : 
     660           0 :         if (lua_istable(L, 1)) {
     661           0 :                 read_noiseparams(L, 1, &params);
     662             :         } else {
     663           0 :                 params.seed    = luaL_checkint(L, 1);
     664           0 :                 params.octaves = luaL_checkint(L, 2);
     665           0 :                 params.persist = luaL_checknumber(L, 3);
     666           0 :                 params.spread  = v3f(1, 1, 1) * luaL_checknumber(L, 4);
     667             :         }
     668             : 
     669           0 :         params.seed += (int)env->getServerMap().getSeed();
     670             : 
     671           0 :         LuaPerlinNoise *n = new LuaPerlinNoise(&params);
     672           0 :         *(void **)(lua_newuserdata(L, sizeof(void *))) = n;
     673           0 :         luaL_getmetatable(L, "PerlinNoise");
     674           0 :         lua_setmetatable(L, -2);
     675           0 :         return 1;
     676             : }
     677             : 
     678             : // get_perlin_map(noiseparams, size)
     679             : // returns world-specific PerlinNoiseMap
     680           0 : int ModApiEnvMod::l_get_perlin_map(lua_State *L)
     681             : {
     682           0 :         GET_ENV_PTR;
     683             : 
     684           0 :         NoiseParams np;
     685           0 :         if (!read_noiseparams(L, 1, &np))
     686           0 :                 return 0;
     687           0 :         v3s16 size = read_v3s16(L, 2);
     688             : 
     689           0 :         int seed = (int)(env->getServerMap().getSeed());
     690           0 :         LuaPerlinNoiseMap *n = new LuaPerlinNoiseMap(&np, seed, size);
     691           0 :         *(void **)(lua_newuserdata(L, sizeof(void *))) = n;
     692           0 :         luaL_getmetatable(L, "PerlinNoiseMap");
     693           0 :         lua_setmetatable(L, -2);
     694           0 :         return 1;
     695             : }
     696             : 
     697             : // get_voxel_manip()
     698             : // returns voxel manipulator
     699           0 : int ModApiEnvMod::l_get_voxel_manip(lua_State *L)
     700             : {
     701           0 :         GET_ENV_PTR;
     702             : 
     703           0 :         Map *map = &(env->getMap());
     704           0 :         LuaVoxelManip *o = (lua_istable(L, 1) && lua_istable(L, 2)) ?
     705           0 :                 new LuaVoxelManip(map, read_v3s16(L, 1), read_v3s16(L, 2)) :
     706           0 :                 new LuaVoxelManip(map);
     707             : 
     708           0 :         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
     709           0 :         luaL_getmetatable(L, "VoxelManip");
     710           0 :         lua_setmetatable(L, -2);
     711           0 :         return 1;
     712             : }
     713             : 
     714             : // clear_objects()
     715             : // clear all objects in the environment
     716           0 : int ModApiEnvMod::l_clear_objects(lua_State *L)
     717             : {
     718           0 :         GET_ENV_PTR;
     719             : 
     720           0 :         env->clearAllObjects();
     721           0 :         return 0;
     722             : }
     723             : 
     724             : // line_of_sight(pos1, pos2, stepsize) -> true/false, pos
     725           0 : int ModApiEnvMod::l_line_of_sight(lua_State *L)
     726             : {
     727           0 :         float stepsize = 1.0;
     728             : 
     729           0 :         GET_ENV_PTR;
     730             : 
     731             :         // read position 1 from lua
     732           0 :         v3f pos1 = checkFloatPos(L, 1);
     733             :         // read position 2 from lua
     734           0 :         v3f pos2 = checkFloatPos(L, 2);
     735             :         //read step size from lua
     736           0 :         if (lua_isnumber(L, 3)) {
     737           0 :                 stepsize = lua_tonumber(L, 3);
     738             :         }
     739             : 
     740           0 :         v3s16 p;
     741           0 :         bool success = env->line_of_sight(pos1, pos2, stepsize, &p);
     742           0 :         lua_pushboolean(L, success);
     743           0 :         if (!success) {
     744           0 :                 push_v3s16(L, p);
     745           0 :                 return 2;
     746             :         }
     747           0 :         return 1;
     748             : }
     749             : 
     750             : // delete_area(p1, p2)
     751             : // delete mapblocks in area p1..p2
     752           0 : int ModApiEnvMod::l_delete_area(lua_State *L)
     753             : {
     754           0 :         GET_ENV_PTR;
     755             : 
     756           0 :         v3s16 bpmin = getNodeBlockPos(read_v3s16(L, 1));
     757           0 :         v3s16 bpmax = getNodeBlockPos(read_v3s16(L, 2));
     758           0 :         sortBoxVerticies(bpmin, bpmax);
     759             : 
     760           0 :         ServerMap &map = env->getServerMap();
     761             : 
     762           0 :         MapEditEvent event;
     763           0 :         event.type = MEET_OTHER;
     764             : 
     765           0 :         bool success = true;
     766           0 :         for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
     767           0 :         for (s16 y = bpmin.Y; y <= bpmax.Y; y++)
     768           0 :         for (s16 x = bpmin.X; x <= bpmax.X; x++) {
     769           0 :                 v3s16 bp(x, y, z);
     770           0 :                 if (map.deleteBlock(bp))
     771           0 :                         event.modified_blocks.insert(bp);
     772             :                 else
     773           0 :                         success = false;
     774             :         }
     775             : 
     776           0 :         map.dispatchEvent(&event);
     777           0 :         lua_pushboolean(L, success);
     778           0 :         return 1;
     779             : }
     780             : 
     781             : // find_path(pos1, pos2, searchdistance,
     782             : //     max_jump, max_drop, algorithm) -> table containing path
     783           0 : int ModApiEnvMod::l_find_path(lua_State *L)
     784             : {
     785           0 :         GET_ENV_PTR;
     786             : 
     787           0 :         v3s16 pos1                  = read_v3s16(L, 1);
     788           0 :         v3s16 pos2                  = read_v3s16(L, 2);
     789           0 :         unsigned int searchdistance = luaL_checkint(L, 3);
     790           0 :         unsigned int max_jump       = luaL_checkint(L, 4);
     791           0 :         unsigned int max_drop       = luaL_checkint(L, 5);
     792           0 :         algorithm algo              = A_PLAIN_NP;
     793           0 :         if (!lua_isnil(L, 6)) {
     794           0 :                 std::string algorithm = luaL_checkstring(L,6);
     795             : 
     796           0 :                 if (algorithm == "A*")
     797           0 :                         algo = A_PLAIN;
     798             : 
     799           0 :                 if (algorithm == "Dijkstra")
     800           0 :                         algo = DIJKSTRA;
     801             :         }
     802             : 
     803             :         std::vector<v3s16> path =
     804           0 :                         get_Path(env,pos1,pos2,searchdistance,max_jump,max_drop,algo);
     805             : 
     806           0 :         if (path.size() > 0)
     807             :         {
     808           0 :                 lua_newtable(L);
     809           0 :                 int top = lua_gettop(L);
     810           0 :                 unsigned int index = 1;
     811           0 :                 for (std::vector<v3s16>::iterator i = path.begin(); i != path.end();i++)
     812             :                 {
     813           0 :                         lua_pushnumber(L,index);
     814           0 :                         push_v3s16(L, *i);
     815           0 :                         lua_settable(L, top);
     816           0 :                         index++;
     817             :                 }
     818           0 :                 return 1;
     819             :         }
     820             : 
     821           0 :         return 0;
     822             : }
     823             : 
     824             : // spawn_tree(pos, treedef)
     825           0 : int ModApiEnvMod::l_spawn_tree(lua_State *L)
     826             : {
     827           0 :         GET_ENV_PTR;
     828             : 
     829           0 :         v3s16 p0 = read_v3s16(L, 1);
     830             : 
     831           0 :         treegen::TreeDef tree_def;
     832           0 :         std::string trunk,leaves,fruit;
     833           0 :         INodeDefManager *ndef = env->getGameDef()->ndef();
     834             : 
     835           0 :         if(lua_istable(L, 2))
     836             :         {
     837           0 :                 getstringfield(L, 2, "axiom", tree_def.initial_axiom);
     838           0 :                 getstringfield(L, 2, "rules_a", tree_def.rules_a);
     839           0 :                 getstringfield(L, 2, "rules_b", tree_def.rules_b);
     840           0 :                 getstringfield(L, 2, "rules_c", tree_def.rules_c);
     841           0 :                 getstringfield(L, 2, "rules_d", tree_def.rules_d);
     842           0 :                 getstringfield(L, 2, "trunk", trunk);
     843           0 :                 tree_def.trunknode=ndef->getId(trunk);
     844           0 :                 getstringfield(L, 2, "leaves", leaves);
     845           0 :                 tree_def.leavesnode=ndef->getId(leaves);
     846           0 :                 tree_def.leaves2_chance=0;
     847           0 :                 getstringfield(L, 2, "leaves2", leaves);
     848           0 :                 if (leaves !="")
     849             :                 {
     850           0 :                         tree_def.leaves2node=ndef->getId(leaves);
     851           0 :                         getintfield(L, 2, "leaves2_chance", tree_def.leaves2_chance);
     852             :                 }
     853           0 :                 getintfield(L, 2, "angle", tree_def.angle);
     854           0 :                 getintfield(L, 2, "iterations", tree_def.iterations);
     855           0 :                 if (!getintfield(L, 2, "random_level", tree_def.iterations_random_level))
     856           0 :                         tree_def.iterations_random_level = 0;
     857           0 :                 getstringfield(L, 2, "trunk_type", tree_def.trunk_type);
     858           0 :                 getboolfield(L, 2, "thin_branches", tree_def.thin_branches);
     859           0 :                 tree_def.fruit_chance=0;
     860           0 :                 getstringfield(L, 2, "fruit", fruit);
     861           0 :                 if (fruit != "")
     862             :                 {
     863           0 :                         tree_def.fruitnode=ndef->getId(fruit);
     864           0 :                         getintfield(L, 2, "fruit_chance",tree_def.fruit_chance);
     865             :                 }
     866           0 :                 tree_def.explicit_seed = getintfield(L, 2, "seed", tree_def.seed);
     867             :         }
     868             :         else
     869           0 :                 return 0;
     870             : 
     871             :         treegen::error e;
     872           0 :         if ((e = treegen::spawn_ltree (env, p0, ndef, tree_def)) != treegen::SUCCESS) {
     873           0 :                 if (e == treegen::UNBALANCED_BRACKETS) {
     874           0 :                         luaL_error(L, "spawn_tree(): closing ']' has no matching opening bracket");
     875             :                 } else {
     876           0 :                         luaL_error(L, "spawn_tree(): unknown error");
     877             :                 }
     878             :         }
     879             : 
     880           0 :         return 1;
     881             : }
     882             : 
     883             : // transforming_liquid_add(pos)
     884           0 : int ModApiEnvMod::l_transforming_liquid_add(lua_State *L)
     885             : {
     886           0 :         GET_ENV_PTR;
     887             : 
     888           0 :         v3s16 p0 = read_v3s16(L, 1);
     889           0 :         env->getMap().transforming_liquid_add(p0);
     890           0 :         return 1;
     891             : }
     892             : 
     893             : // forceload_block(blockpos)
     894             : // blockpos = {x=num, y=num, z=num}
     895           0 : int ModApiEnvMod::l_forceload_block(lua_State *L)
     896             : {
     897           0 :         GET_ENV_PTR;
     898             : 
     899           0 :         v3s16 blockpos = read_v3s16(L, 1);
     900           0 :         env->getForceloadedBlocks()->insert(blockpos);
     901           0 :         return 0;
     902             : }
     903             : 
     904             : // forceload_free_block(blockpos)
     905             : // blockpos = {x=num, y=num, z=num}
     906           0 : int ModApiEnvMod::l_forceload_free_block(lua_State *L)
     907             : {
     908           0 :         GET_ENV_PTR;
     909             : 
     910           0 :         v3s16 blockpos = read_v3s16(L, 1);
     911           0 :         env->getForceloadedBlocks()->erase(blockpos);
     912           0 :         return 0;
     913             : }
     914             : 
     915             : // get_us_time()
     916           0 : int ModApiEnvMod::l_get_us_time(lua_State *L)
     917             : {
     918           0 :         lua_pushnumber(L, porting::getTimeUs());
     919           0 :         return 1;
     920             : }
     921             : 
     922           0 : void ModApiEnvMod::Initialize(lua_State *L, int top)
     923             : {
     924           0 :         API_FCT(set_node);
     925           0 :         API_FCT(add_node);
     926           0 :         API_FCT(swap_node);
     927           0 :         API_FCT(add_item);
     928           0 :         API_FCT(remove_node);
     929           0 :         API_FCT(get_node);
     930           0 :         API_FCT(get_node_or_nil);
     931           0 :         API_FCT(get_node_light);
     932           0 :         API_FCT(place_node);
     933           0 :         API_FCT(dig_node);
     934           0 :         API_FCT(punch_node);
     935           0 :         API_FCT(get_node_max_level);
     936           0 :         API_FCT(get_node_level);
     937           0 :         API_FCT(set_node_level);
     938           0 :         API_FCT(add_node_level);
     939           0 :         API_FCT(add_entity);
     940           0 :         API_FCT(find_nodes_with_meta);
     941           0 :         API_FCT(get_meta);
     942           0 :         API_FCT(get_node_timer);
     943           0 :         API_FCT(get_player_by_name);
     944           0 :         API_FCT(get_objects_inside_radius);
     945           0 :         API_FCT(set_timeofday);
     946           0 :         API_FCT(get_timeofday);
     947           0 :         API_FCT(get_gametime);
     948           0 :         API_FCT(find_node_near);
     949           0 :         API_FCT(find_nodes_in_area);
     950           0 :         API_FCT(find_nodes_in_area_under_air);
     951           0 :         API_FCT(delete_area);
     952           0 :         API_FCT(get_perlin);
     953           0 :         API_FCT(get_perlin_map);
     954           0 :         API_FCT(get_voxel_manip);
     955           0 :         API_FCT(clear_objects);
     956           0 :         API_FCT(spawn_tree);
     957           0 :         API_FCT(find_path);
     958           0 :         API_FCT(line_of_sight);
     959           0 :         API_FCT(transforming_liquid_add);
     960           0 :         API_FCT(forceload_block);
     961           0 :         API_FCT(forceload_free_block);
     962           0 :         API_FCT(get_us_time);
     963           3 : }

Generated by: LCOV version 1.11