LCOV - code coverage report
Current view: top level - src/script/lua_api - l_object.cpp (source / functions) Hit Total Coverage
Test: report Lines: 1 988 0.1 %
Date: 2015-07-11 18:23:49 Functions: 2 85 2.4 %

          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_object.h"
      21             : #include "lua_api/l_internal.h"
      22             : #include "lua_api/l_inventory.h"
      23             : #include "lua_api/l_item.h"
      24             : #include "common/c_converter.h"
      25             : #include "common/c_content.h"
      26             : #include "log.h"
      27             : #include "tool.h"
      28             : #include "serverobject.h"
      29             : #include "content_sao.h"
      30             : #include "server.h"
      31             : #include "hud.h"
      32             : #include "scripting_game.h"
      33             : 
      34             : #define GET_ENV_PTR ServerEnvironment* env =                                   \
      35             :                                 dynamic_cast<ServerEnvironment*>(getEnv(L));                   \
      36             :                                 if (env == NULL) return 0
      37             : 
      38             : struct EnumString es_HudElementType[] =
      39             : {
      40             :         {HUD_ELEM_IMAGE,     "image"},
      41             :         {HUD_ELEM_TEXT,      "text"},
      42             :         {HUD_ELEM_STATBAR,   "statbar"},
      43             :         {HUD_ELEM_INVENTORY, "inventory"},
      44             :         {HUD_ELEM_WAYPOINT,  "waypoint"},
      45             : {0, NULL},
      46             : };
      47             : 
      48             : struct EnumString es_HudElementStat[] =
      49             : {
      50             :         {HUD_STAT_POS,    "position"},
      51             :         {HUD_STAT_POS,    "pos"}, /* Deprecated, only for compatibility's sake */
      52             :         {HUD_STAT_NAME,   "name"},
      53             :         {HUD_STAT_SCALE,  "scale"},
      54             :         {HUD_STAT_TEXT,   "text"},
      55             :         {HUD_STAT_NUMBER, "number"},
      56             :         {HUD_STAT_ITEM,   "item"},
      57             :         {HUD_STAT_DIR,    "direction"},
      58             :         {HUD_STAT_ALIGN,  "alignment"},
      59             :         {HUD_STAT_OFFSET, "offset"},
      60             :         {HUD_STAT_WORLD_POS, "world_pos"},
      61             :         {0, NULL},
      62             : };
      63             : 
      64             : struct EnumString es_HudBuiltinElement[] =
      65             : {
      66             :         {HUD_FLAG_HOTBAR_VISIBLE,    "hotbar"},
      67             :         {HUD_FLAG_HEALTHBAR_VISIBLE, "healthbar"},
      68             :         {HUD_FLAG_CROSSHAIR_VISIBLE, "crosshair"},
      69             :         {HUD_FLAG_WIELDITEM_VISIBLE, "wielditem"},
      70             :         {HUD_FLAG_BREATHBAR_VISIBLE, "breathbar"},
      71             :         {0, NULL},
      72             : };
      73             : 
      74             : /*
      75             :         ObjectRef
      76             : */
      77             : 
      78             : 
      79           0 : ObjectRef* ObjectRef::checkobject(lua_State *L, int narg)
      80             : {
      81           0 :         luaL_checktype(L, narg, LUA_TUSERDATA);
      82           0 :         void *ud = luaL_checkudata(L, narg, className);
      83           0 :         if(!ud) luaL_typerror(L, narg, className);
      84           0 :         return *(ObjectRef**)ud;  // unbox pointer
      85             : }
      86             : 
      87           0 : ServerActiveObject* ObjectRef::getobject(ObjectRef *ref)
      88             : {
      89           0 :         ServerActiveObject *co = ref->m_object;
      90           0 :         return co;
      91             : }
      92             : 
      93           0 : LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref)
      94             : {
      95           0 :         ServerActiveObject *obj = getobject(ref);
      96           0 :         if(obj == NULL)
      97           0 :                 return NULL;
      98           0 :         if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
      99           0 :                 return NULL;
     100           0 :         return (LuaEntitySAO*)obj;
     101             : }
     102             : 
     103           0 : PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
     104             : {
     105           0 :         ServerActiveObject *obj = getobject(ref);
     106           0 :         if(obj == NULL)
     107           0 :                 return NULL;
     108           0 :         if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
     109           0 :                 return NULL;
     110           0 :         return (PlayerSAO*)obj;
     111             : }
     112             : 
     113           0 : Player* ObjectRef::getplayer(ObjectRef *ref)
     114             : {
     115           0 :         PlayerSAO *playersao = getplayersao(ref);
     116           0 :         if(playersao == NULL)
     117           0 :                 return NULL;
     118           0 :         return playersao->getPlayer();
     119             : }
     120             : 
     121             : // Exported functions
     122             : 
     123             : // garbage collector
     124           0 : int ObjectRef::gc_object(lua_State *L) {
     125           0 :         ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
     126             :         //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
     127           0 :         delete o;
     128           0 :         return 0;
     129             : }
     130             : 
     131             : // remove(self)
     132           0 : int ObjectRef::l_remove(lua_State *L)
     133             : {
     134           0 :         NO_MAP_LOCK_REQUIRED;
     135           0 :         ObjectRef *ref = checkobject(L, 1);
     136           0 :         ServerActiveObject *co = getobject(ref);
     137           0 :         if(co == NULL) return 0;
     138           0 :         if(co->getType() == ACTIVEOBJECT_TYPE_PLAYER) return 0;
     139           0 :         verbosestream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
     140           0 :         co->m_removed = true;
     141           0 :         return 0;
     142             : }
     143             : 
     144             : // getpos(self)
     145             : // returns: {x=num, y=num, z=num}
     146           0 : int ObjectRef::l_getpos(lua_State *L)
     147             : {
     148           0 :         NO_MAP_LOCK_REQUIRED;
     149           0 :         ObjectRef *ref = checkobject(L, 1);
     150           0 :         ServerActiveObject *co = getobject(ref);
     151           0 :         if(co == NULL) return 0;
     152           0 :         v3f pos = co->getBasePosition() / BS;
     153           0 :         lua_newtable(L);
     154           0 :         lua_pushnumber(L, pos.X);
     155           0 :         lua_setfield(L, -2, "x");
     156           0 :         lua_pushnumber(L, pos.Y);
     157           0 :         lua_setfield(L, -2, "y");
     158           0 :         lua_pushnumber(L, pos.Z);
     159           0 :         lua_setfield(L, -2, "z");
     160           0 :         return 1;
     161             : }
     162             : 
     163             : // setpos(self, pos)
     164           0 : int ObjectRef::l_setpos(lua_State *L)
     165             : {
     166           0 :         NO_MAP_LOCK_REQUIRED;
     167           0 :         ObjectRef *ref = checkobject(L, 1);
     168             :         //LuaEntitySAO *co = getluaobject(ref);
     169           0 :         ServerActiveObject *co = getobject(ref);
     170           0 :         if(co == NULL) return 0;
     171             :         // pos
     172           0 :         v3f pos = checkFloatPos(L, 2);
     173             :         // Do it
     174           0 :         co->setPos(pos);
     175           0 :         return 0;
     176             : }
     177             : 
     178             : // moveto(self, pos, continuous=false)
     179           0 : int ObjectRef::l_moveto(lua_State *L)
     180             : {
     181           0 :         NO_MAP_LOCK_REQUIRED;
     182           0 :         ObjectRef *ref = checkobject(L, 1);
     183             :         //LuaEntitySAO *co = getluaobject(ref);
     184           0 :         ServerActiveObject *co = getobject(ref);
     185           0 :         if(co == NULL) return 0;
     186             :         // pos
     187           0 :         v3f pos = checkFloatPos(L, 2);
     188             :         // continuous
     189           0 :         bool continuous = lua_toboolean(L, 3);
     190             :         // Do it
     191           0 :         co->moveTo(pos, continuous);
     192           0 :         return 0;
     193             : }
     194             : 
     195             : // punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
     196           0 : int ObjectRef::l_punch(lua_State *L)
     197             : {
     198           0 :         NO_MAP_LOCK_REQUIRED;
     199           0 :         ObjectRef *ref = checkobject(L, 1);
     200           0 :         ObjectRef *puncher_ref = checkobject(L, 2);
     201           0 :         ServerActiveObject *co = getobject(ref);
     202           0 :         ServerActiveObject *puncher = getobject(puncher_ref);
     203           0 :         if(co == NULL) return 0;
     204           0 :         if(puncher == NULL) return 0;
     205           0 :         v3f dir;
     206           0 :         if(lua_type(L, 5) != LUA_TTABLE)
     207           0 :                 dir = co->getBasePosition() - puncher->getBasePosition();
     208             :         else
     209           0 :                 dir = read_v3f(L, 5);
     210           0 :         float time_from_last_punch = 1000000;
     211           0 :         if(lua_isnumber(L, 3))
     212           0 :                 time_from_last_punch = lua_tonumber(L, 3);
     213           0 :         ToolCapabilities toolcap = read_tool_capabilities(L, 4);
     214           0 :         dir.normalize();
     215             : 
     216           0 :         s16 src_original_hp = co->getHP();
     217           0 :         s16 dst_origin_hp = puncher->getHP();
     218             : 
     219             :         // Do it
     220           0 :         co->punch(dir, &toolcap, puncher, time_from_last_punch);
     221             : 
     222             :         // If the punched is a player, and its HP changed
     223           0 :         if (src_original_hp != co->getHP() &&
     224           0 :                         co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
     225           0 :                 getServer(L)->SendPlayerHPOrDie(((PlayerSAO*)co)->getPeerID(),
     226           0 :                                 co->getHP() == 0);
     227             :         }
     228             : 
     229             :         // If the puncher is a player, and its HP changed
     230           0 :         if (dst_origin_hp != puncher->getHP() &&
     231           0 :                         puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
     232           0 :                 getServer(L)->SendPlayerHPOrDie(((PlayerSAO*)puncher)->getPeerID(),
     233           0 :                                 puncher->getHP() == 0);
     234             :         }
     235           0 :         return 0;
     236             : }
     237             : 
     238             : // right_click(self, clicker); clicker = an another ObjectRef
     239           0 : int ObjectRef::l_right_click(lua_State *L)
     240             : {
     241           0 :         NO_MAP_LOCK_REQUIRED;
     242           0 :         ObjectRef *ref = checkobject(L, 1);
     243           0 :         ObjectRef *ref2 = checkobject(L, 2);
     244           0 :         ServerActiveObject *co = getobject(ref);
     245           0 :         ServerActiveObject *co2 = getobject(ref2);
     246           0 :         if(co == NULL) return 0;
     247           0 :         if(co2 == NULL) return 0;
     248             :         // Do it
     249           0 :         co->rightClick(co2);
     250           0 :         return 0;
     251             : }
     252             : 
     253             : // set_hp(self, hp)
     254             : // hp = number of hitpoints (2 * number of hearts)
     255             : // returns: nil
     256           0 : int ObjectRef::l_set_hp(lua_State *L)
     257             : {
     258           0 :         NO_MAP_LOCK_REQUIRED;
     259           0 :         ObjectRef *ref = checkobject(L, 1);
     260           0 :         luaL_checknumber(L, 2);
     261           0 :         ServerActiveObject *co = getobject(ref);
     262           0 :         if(co == NULL) return 0;
     263           0 :         int hp = lua_tonumber(L, 2);
     264             :         /*infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
     265             :                         <<" hp="<<hp<<std::endl;*/
     266             :         // Do it
     267           0 :         co->setHP(hp);
     268           0 :         if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
     269           0 :                 getServer(L)->SendPlayerHPOrDie(((PlayerSAO*)co)->getPeerID(), co->getHP() == 0);
     270             :         }
     271             :         // Return
     272           0 :         return 0;
     273             : }
     274             : 
     275             : // get_hp(self)
     276             : // returns: number of hitpoints (2 * number of hearts)
     277             : // 0 if not applicable to this type of object
     278           0 : int ObjectRef::l_get_hp(lua_State *L)
     279             : {
     280           0 :         NO_MAP_LOCK_REQUIRED;
     281           0 :         ObjectRef *ref = checkobject(L, 1);
     282           0 :         ServerActiveObject *co = getobject(ref);
     283           0 :         if(co == NULL){
     284             :                 // Default hp is 1
     285           0 :                 lua_pushnumber(L, 1);
     286           0 :                 return 1;
     287             :         }
     288           0 :         int hp = co->getHP();
     289             :         /*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
     290             :                         <<" hp="<<hp<<std::endl;*/
     291             :         // Return
     292           0 :         lua_pushnumber(L, hp);
     293           0 :         return 1;
     294             : }
     295             : 
     296             : // get_inventory(self)
     297           0 : int ObjectRef::l_get_inventory(lua_State *L)
     298             : {
     299           0 :         NO_MAP_LOCK_REQUIRED;
     300           0 :         ObjectRef *ref = checkobject(L, 1);
     301           0 :         ServerActiveObject *co = getobject(ref);
     302           0 :         if(co == NULL) return 0;
     303             :         // Do it
     304           0 :         InventoryLocation loc = co->getInventoryLocation();
     305           0 :         if(getServer(L)->getInventory(loc) != NULL)
     306           0 :                 InvRef::create(L, loc);
     307             :         else
     308           0 :                 lua_pushnil(L); // An object may have no inventory (nil)
     309           0 :         return 1;
     310             : }
     311             : 
     312             : // get_wield_list(self)
     313           0 : int ObjectRef::l_get_wield_list(lua_State *L)
     314             : {
     315           0 :         NO_MAP_LOCK_REQUIRED;
     316           0 :         ObjectRef *ref = checkobject(L, 1);
     317           0 :         ServerActiveObject *co = getobject(ref);
     318           0 :         if(co == NULL) return 0;
     319             :         // Do it
     320           0 :         lua_pushstring(L, co->getWieldList().c_str());
     321           0 :         return 1;
     322             : }
     323             : 
     324             : // get_wield_index(self)
     325           0 : int ObjectRef::l_get_wield_index(lua_State *L)
     326             : {
     327           0 :         NO_MAP_LOCK_REQUIRED;
     328           0 :         ObjectRef *ref = checkobject(L, 1);
     329           0 :         ServerActiveObject *co = getobject(ref);
     330           0 :         if(co == NULL) return 0;
     331             :         // Do it
     332           0 :         lua_pushinteger(L, co->getWieldIndex() + 1);
     333           0 :         return 1;
     334             : }
     335             : 
     336             : // get_wielded_item(self)
     337           0 : int ObjectRef::l_get_wielded_item(lua_State *L)
     338             : {
     339           0 :         NO_MAP_LOCK_REQUIRED;
     340           0 :         ObjectRef *ref = checkobject(L, 1);
     341           0 :         ServerActiveObject *co = getobject(ref);
     342           0 :         if(co == NULL){
     343             :                 // Empty ItemStack
     344           0 :                 LuaItemStack::create(L, ItemStack());
     345           0 :                 return 1;
     346             :         }
     347             :         // Do it
     348           0 :         LuaItemStack::create(L, co->getWieldedItem());
     349           0 :         return 1;
     350             : }
     351             : 
     352             : // set_wielded_item(self, itemstack or itemstring or table or nil)
     353           0 : int ObjectRef::l_set_wielded_item(lua_State *L)
     354             : {
     355           0 :         NO_MAP_LOCK_REQUIRED;
     356           0 :         ObjectRef *ref = checkobject(L, 1);
     357           0 :         ServerActiveObject *co = getobject(ref);
     358           0 :         if(co == NULL) return 0;
     359             :         // Do it
     360           0 :         ItemStack item = read_item(L, 2, getServer(L));
     361           0 :         bool success = co->setWieldedItem(item);
     362           0 :         if (success && co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
     363           0 :                 getServer(L)->SendInventory(((PlayerSAO*)co));
     364             :         }
     365           0 :         lua_pushboolean(L, success);
     366           0 :         return 1;
     367             : }
     368             : 
     369             : // set_armor_groups(self, groups)
     370           0 : int ObjectRef::l_set_armor_groups(lua_State *L)
     371             : {
     372           0 :         NO_MAP_LOCK_REQUIRED;
     373           0 :         ObjectRef *ref = checkobject(L, 1);
     374           0 :         ServerActiveObject *co = getobject(ref);
     375           0 :         if(co == NULL) return 0;
     376             :         // Do it
     377           0 :         ItemGroupList groups;
     378           0 :         read_groups(L, 2, groups);
     379           0 :         co->setArmorGroups(groups);
     380           0 :         return 0;
     381             : }
     382             : 
     383             : // get_armor_groups(self)
     384           0 : int ObjectRef::l_get_armor_groups(lua_State *L)
     385             : {
     386           0 :         NO_MAP_LOCK_REQUIRED;
     387           0 :         ObjectRef *ref = checkobject(L, 1);
     388           0 :         ServerActiveObject *co = getobject(ref);
     389           0 :         if (co == NULL)
     390           0 :                 return 0;
     391             :         // Do it
     392           0 :         ItemGroupList groups = co->getArmorGroups();
     393           0 :         push_groups(L, groups);
     394           0 :         return 1;
     395             : }
     396             : 
     397             : // set_physics_override(self, physics_override_speed, physics_override_jump,
     398             : //                      physics_override_gravity, sneak, sneak_glitch)
     399           0 : int ObjectRef::l_set_physics_override(lua_State *L)
     400             : {
     401           0 :         ObjectRef *ref = checkobject(L, 1);
     402           0 :         PlayerSAO *co = (PlayerSAO *) getobject(ref);
     403           0 :         if(co == NULL) return 0;
     404             :         // Do it
     405           0 :         if (lua_istable(L, 2)) {
     406           0 :                 co->m_physics_override_speed = getfloatfield_default(L, 2, "speed", co->m_physics_override_speed);
     407           0 :                 co->m_physics_override_jump = getfloatfield_default(L, 2, "jump", co->m_physics_override_jump);
     408           0 :                 co->m_physics_override_gravity = getfloatfield_default(L, 2, "gravity", co->m_physics_override_gravity);
     409           0 :                 co->m_physics_override_sneak = getboolfield_default(L, 2, "sneak", co->m_physics_override_sneak);
     410           0 :                 co->m_physics_override_sneak_glitch = getboolfield_default(L, 2, "sneak_glitch", co->m_physics_override_sneak_glitch);
     411           0 :                 co->m_physics_override_sent = false;
     412             :         } else {
     413             :                 // old, non-table format
     414           0 :                 if(!lua_isnil(L, 2)){
     415           0 :                         co->m_physics_override_speed = lua_tonumber(L, 2);
     416           0 :                         co->m_physics_override_sent = false;
     417             :                 }
     418           0 :                 if(!lua_isnil(L, 3)){
     419           0 :                         co->m_physics_override_jump = lua_tonumber(L, 3);
     420           0 :                         co->m_physics_override_sent = false;
     421             :                 }
     422           0 :                 if(!lua_isnil(L, 4)){
     423           0 :                         co->m_physics_override_gravity = lua_tonumber(L, 4);
     424           0 :                         co->m_physics_override_sent = false;
     425             :                 }
     426             :         }
     427           0 :         return 0;
     428             : }
     429             : 
     430             : // get_physics_override(self)
     431           0 : int ObjectRef::l_get_physics_override(lua_State *L)
     432             : {
     433           0 :         ObjectRef *ref = checkobject(L, 1);
     434           0 :         PlayerSAO *co = (PlayerSAO *)getobject(ref);
     435           0 :         if (co == NULL)
     436           0 :                 return 0;
     437             :         // Do it
     438           0 :         lua_newtable(L);
     439           0 :         lua_pushnumber(L, co->m_physics_override_speed);
     440           0 :         lua_setfield(L, -2, "speed");
     441           0 :         lua_pushnumber(L, co->m_physics_override_jump);
     442           0 :         lua_setfield(L, -2, "jump");
     443           0 :         lua_pushnumber(L, co->m_physics_override_gravity);
     444           0 :         lua_setfield(L, -2, "gravity");
     445           0 :         lua_pushboolean(L, co->m_physics_override_sneak);
     446           0 :         lua_setfield(L, -2, "sneak");
     447           0 :         lua_pushboolean(L, co->m_physics_override_sneak_glitch);
     448           0 :         lua_setfield(L, -2, "sneak_glitch");
     449           0 :         return 1;
     450             : }
     451             : 
     452             : // set_animation(self, frame_range, frame_speed, frame_blend, frame_loop)
     453           0 : int ObjectRef::l_set_animation(lua_State *L)
     454             : {
     455           0 :         NO_MAP_LOCK_REQUIRED;
     456           0 :         ObjectRef *ref = checkobject(L, 1);
     457           0 :         ServerActiveObject *co = getobject(ref);
     458           0 :         if(co == NULL) return 0;
     459             :         // Do it
     460           0 :         v2f frames = v2f(1, 1);
     461           0 :         if(!lua_isnil(L, 2))
     462           0 :                 frames = read_v2f(L, 2);
     463           0 :         float frame_speed = 15;
     464           0 :         if(!lua_isnil(L, 3))
     465           0 :                 frame_speed = lua_tonumber(L, 3);
     466           0 :         float frame_blend = 0;
     467           0 :         if(!lua_isnil(L, 4))
     468           0 :                 frame_blend = lua_tonumber(L, 4);
     469           0 :         bool frame_loop = true;
     470           0 :         if(lua_isboolean(L, 5))
     471           0 :                 frame_loop = lua_toboolean(L, 5);
     472           0 :         co->setAnimation(frames, frame_speed, frame_blend, frame_loop);
     473           0 :         return 0;
     474             : }
     475             : 
     476             : // get_animation(self)
     477           0 : int ObjectRef::l_get_animation(lua_State *L)
     478             : {
     479           0 :         NO_MAP_LOCK_REQUIRED;
     480           0 :         ObjectRef *ref = checkobject(L, 1);
     481           0 :         ServerActiveObject *co = getobject(ref);
     482           0 :         if (co == NULL)
     483           0 :                 return 0;
     484             :         // Do it
     485           0 :         v2f frames = v2f(1,1);
     486           0 :         float frame_speed = 15;
     487           0 :         float frame_blend = 0;
     488           0 :         bool frame_loop = true;
     489           0 :         co->getAnimation(&frames, &frame_speed, &frame_blend, &frame_loop);
     490             : 
     491           0 :         push_v2f(L, frames);
     492           0 :         lua_pushnumber(L, frame_speed);
     493           0 :         lua_pushnumber(L, frame_blend);
     494           0 :         lua_pushboolean(L, frame_loop);
     495           0 :         return 4;
     496             : }
     497             : 
     498             : // set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed)
     499           0 : int ObjectRef::l_set_local_animation(lua_State *L)
     500             : {
     501             :         //NO_MAP_LOCK_REQUIRED;
     502           0 :         ObjectRef *ref = checkobject(L, 1);
     503           0 :         Player *player = getplayer(ref);
     504           0 :         if (player == NULL)
     505           0 :                 return 0;
     506             :         // Do it
     507           0 :         v2s32 frames[4];
     508           0 :         for (int i=0;i<4;i++) {
     509           0 :                 if(!lua_isnil(L, 2+1))
     510           0 :                         frames[i] = read_v2s32(L, 2+i);
     511             :         }
     512           0 :         float frame_speed = 30;
     513           0 :         if(!lua_isnil(L, 6))
     514           0 :                 frame_speed = lua_tonumber(L, 6);
     515             : 
     516           0 :         if (!getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed))
     517           0 :                 return 0;
     518             : 
     519           0 :         lua_pushboolean(L, true);
     520           0 :         return 0;
     521             : }
     522             : 
     523             : // get_local_animation(self)
     524           0 : int ObjectRef::l_get_local_animation(lua_State *L)
     525             : {
     526             :         //NO_MAP_LOCK_REQUIRED
     527           0 :         ObjectRef *ref = checkobject(L, 1);
     528           0 :         Player *player = getplayer(ref);
     529           0 :         if (player == NULL)
     530           0 :                 return 0;
     531             : 
     532           0 :         v2s32 frames[4];
     533             :         float frame_speed;
     534           0 :         player->getLocalAnimations(frames, &frame_speed);
     535             : 
     536           0 :         for (int i = 0; i < 4; i++) {
     537           0 :                 push_v2s32(L, frames[i]);
     538             :         }
     539             : 
     540           0 :         lua_pushnumber(L, frame_speed);
     541           0 :         return 5;
     542             : }
     543             : 
     544             : // set_eye_offset(self, v3f first pv, v3f third pv)
     545           0 : int ObjectRef::l_set_eye_offset(lua_State *L)
     546             : {
     547             :         //NO_MAP_LOCK_REQUIRED;
     548           0 :         ObjectRef *ref = checkobject(L, 1);
     549           0 :         Player *player = getplayer(ref);
     550           0 :         if (player == NULL)
     551           0 :                 return 0;
     552             :         // Do it
     553           0 :         v3f offset_first = v3f(0, 0, 0);
     554           0 :         v3f offset_third = v3f(0, 0, 0);
     555             : 
     556           0 :         if(!lua_isnil(L, 2))
     557           0 :                 offset_first = read_v3f(L, 2);
     558           0 :         if(!lua_isnil(L, 3))
     559           0 :                 offset_third = read_v3f(L, 3);
     560             : 
     561             :         // Prevent abuse of offset values (keep player always visible)
     562           0 :         offset_third.X = rangelim(offset_third.X,-10,10);
     563           0 :         offset_third.Z = rangelim(offset_third.Z,-5,5);
     564             :         /* TODO: if possible: improve the camera colision detetion to allow Y <= -1.5) */
     565           0 :         offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS
     566             : 
     567           0 :         if (!getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third))
     568           0 :                 return 0;
     569             : 
     570           0 :         lua_pushboolean(L, true);
     571           0 :         return 0;
     572             : }
     573             : 
     574             : // get_eye_offset(self)
     575           0 : int ObjectRef::l_get_eye_offset(lua_State *L)
     576             : {
     577             :         //NO_MAP_LOCK_REQUIRED;
     578           0 :         ObjectRef *ref = checkobject(L, 1);
     579           0 :         Player *player = getplayer(ref);
     580           0 :         if (player == NULL)
     581           0 :                 return 0;
     582             :         // Do it
     583           0 :         push_v3f(L, player->eye_offset_first);
     584           0 :         push_v3f(L, player->eye_offset_third);
     585           0 :         return 2;
     586             : }
     587             : 
     588             : // set_bone_position(self, std::string bone, v3f position, v3f rotation)
     589           0 : int ObjectRef::l_set_bone_position(lua_State *L)
     590             : {
     591           0 :         NO_MAP_LOCK_REQUIRED;
     592           0 :         ObjectRef *ref = checkobject(L, 1);
     593           0 :         ServerActiveObject *co = getobject(ref);
     594           0 :         if(co == NULL) return 0;
     595             :         // Do it
     596           0 :         std::string bone = "";
     597           0 :         if(!lua_isnil(L, 2))
     598           0 :                 bone = lua_tostring(L, 2);
     599           0 :         v3f position = v3f(0, 0, 0);
     600           0 :         if(!lua_isnil(L, 3))
     601           0 :                 position = read_v3f(L, 3);
     602           0 :         v3f rotation = v3f(0, 0, 0);
     603           0 :         if(!lua_isnil(L, 4))
     604           0 :                 rotation = read_v3f(L, 4);
     605           0 :         co->setBonePosition(bone, position, rotation);
     606           0 :         return 0;
     607             : }
     608             : 
     609             : // get_bone_position(self, bone)
     610           0 : int ObjectRef::l_get_bone_position(lua_State *L)
     611             : {
     612           0 :         NO_MAP_LOCK_REQUIRED;
     613           0 :         ObjectRef *ref = checkobject(L, 1);
     614           0 :         ServerActiveObject *co = getobject(ref);
     615           0 :         if (co == NULL)
     616           0 :                 return 0;
     617             :         // Do it
     618           0 :         std::string bone = "";
     619           0 :         if(!lua_isnil(L, 2))
     620           0 :                 bone = lua_tostring(L, 2);
     621             : 
     622           0 :         v3f position = v3f(0, 0, 0);
     623           0 :         v3f rotation = v3f(0, 0, 0);
     624           0 :         co->getBonePosition(bone, &position, &rotation);
     625             : 
     626           0 :         push_v3f(L, position);
     627           0 :         push_v3f(L, rotation);
     628           0 :         return 2;
     629             : }
     630             : 
     631             : // set_attach(self, parent, bone, position, rotation)
     632           0 : int ObjectRef::l_set_attach(lua_State *L)
     633             : {
     634           0 :         NO_MAP_LOCK_REQUIRED;
     635           0 :         ObjectRef *ref = checkobject(L, 1);
     636           0 :         ObjectRef *parent_ref = checkobject(L, 2);
     637           0 :         ServerActiveObject *co = getobject(ref);
     638           0 :         ServerActiveObject *parent = getobject(parent_ref);
     639           0 :         if(co == NULL) return 0;
     640           0 :         if(parent == NULL) return 0;
     641             :         // Do it
     642           0 :         std::string bone = "";
     643           0 :         if(!lua_isnil(L, 3))
     644           0 :                 bone = lua_tostring(L, 3);
     645           0 :         v3f position = v3f(0, 0, 0);
     646           0 :         if(!lua_isnil(L, 4))
     647           0 :                 position = read_v3f(L, 4);
     648           0 :         v3f rotation = v3f(0, 0, 0);
     649           0 :         if(!lua_isnil(L, 5))
     650           0 :                 rotation = read_v3f(L, 5);
     651           0 :         co->setAttachment(parent->getId(), bone, position, rotation);
     652           0 :         return 0;
     653             : }
     654             : 
     655             : // get_attach(self)
     656           0 : int ObjectRef::l_get_attach(lua_State *L)
     657             : {
     658           0 :         NO_MAP_LOCK_REQUIRED;
     659           0 :         GET_ENV_PTR;
     660             : 
     661           0 :         ObjectRef *ref = checkobject(L, 1);
     662           0 :         ServerActiveObject *co = getobject(ref);
     663           0 :         if (co == NULL)
     664           0 :                 return 0;
     665             : 
     666             :         // Do it
     667           0 :         int parent_id = 0;
     668           0 :         std::string bone = "";
     669           0 :         v3f position = v3f(0, 0, 0);
     670           0 :         v3f rotation = v3f(0, 0, 0);
     671           0 :         co->getAttachment(&parent_id, &bone, &position, &rotation);
     672           0 :         if (!parent_id)
     673           0 :                 return 0;
     674           0 :         ServerActiveObject *parent = env->getActiveObject(parent_id);
     675             : 
     676           0 :         getScriptApiBase(L)->objectrefGetOrCreate(L, parent);
     677           0 :         lua_pushlstring(L, bone.c_str(), bone.size());
     678           0 :         push_v3f(L, position);
     679           0 :         push_v3f(L, rotation);
     680           0 :         return 4;
     681             : }
     682             : 
     683             : // set_detach(self)
     684           0 : int ObjectRef::l_set_detach(lua_State *L)
     685             : {
     686           0 :         NO_MAP_LOCK_REQUIRED;
     687           0 :         ObjectRef *ref = checkobject(L, 1);
     688           0 :         ServerActiveObject *co = getobject(ref);
     689           0 :         if(co == NULL) return 0;
     690             :         // Do it
     691           0 :         co->setAttachment(0, "", v3f(0,0,0), v3f(0,0,0));
     692           0 :         return 0;
     693             : }
     694             : 
     695             : // set_properties(self, properties)
     696           0 : int ObjectRef::l_set_properties(lua_State *L)
     697             : {
     698           0 :         NO_MAP_LOCK_REQUIRED;
     699           0 :         ObjectRef *ref = checkobject(L, 1);
     700           0 :         ServerActiveObject *co = getobject(ref);
     701           0 :         if(co == NULL) return 0;
     702           0 :         ObjectProperties *prop = co->accessObjectProperties();
     703           0 :         if(!prop)
     704           0 :                 return 0;
     705           0 :         read_object_properties(L, 2, prop);
     706           0 :         co->notifyObjectPropertiesModified();
     707           0 :         return 0;
     708             : }
     709             : 
     710             : // get_properties(self)
     711           0 : int ObjectRef::l_get_properties(lua_State *L)
     712             : {
     713           0 :         NO_MAP_LOCK_REQUIRED;
     714           0 :         ObjectRef *ref = checkobject(L, 1);
     715           0 :         ServerActiveObject *co = getobject(ref);
     716           0 :         if (co == NULL)
     717           0 :                 return 0;
     718           0 :         ObjectProperties *prop = co->accessObjectProperties();
     719           0 :         if (!prop)
     720           0 :                 return 0;
     721           0 :         push_object_properties(L, prop);
     722           0 :         return 1;
     723             : }
     724             : 
     725             : // is_player(self)
     726           0 : int ObjectRef::l_is_player(lua_State *L)
     727             : {
     728           0 :         NO_MAP_LOCK_REQUIRED;
     729           0 :         ObjectRef *ref = checkobject(L, 1);
     730           0 :         Player *player = getplayer(ref);
     731           0 :         lua_pushboolean(L, (player != NULL));
     732           0 :         return 1;
     733             : }
     734             : 
     735             : /* LuaEntitySAO-only */
     736             : 
     737             : // setvelocity(self, {x=num, y=num, z=num})
     738           0 : int ObjectRef::l_setvelocity(lua_State *L)
     739             : {
     740           0 :         NO_MAP_LOCK_REQUIRED;
     741           0 :         ObjectRef *ref = checkobject(L, 1);
     742           0 :         LuaEntitySAO *co = getluaobject(ref);
     743           0 :         if(co == NULL) return 0;
     744           0 :         v3f pos = checkFloatPos(L, 2);
     745             :         // Do it
     746           0 :         co->setVelocity(pos);
     747           0 :         return 0;
     748             : }
     749             : 
     750             : // getvelocity(self)
     751           0 : int ObjectRef::l_getvelocity(lua_State *L)
     752             : {
     753           0 :         NO_MAP_LOCK_REQUIRED;
     754           0 :         ObjectRef *ref = checkobject(L, 1);
     755           0 :         LuaEntitySAO *co = getluaobject(ref);
     756           0 :         if(co == NULL) return 0;
     757             :         // Do it
     758           0 :         v3f v = co->getVelocity();
     759           0 :         pushFloatPos(L, v);
     760           0 :         return 1;
     761             : }
     762             : 
     763             : // setacceleration(self, {x=num, y=num, z=num})
     764           0 : int ObjectRef::l_setacceleration(lua_State *L)
     765             : {
     766           0 :         NO_MAP_LOCK_REQUIRED;
     767           0 :         ObjectRef *ref = checkobject(L, 1);
     768           0 :         LuaEntitySAO *co = getluaobject(ref);
     769           0 :         if(co == NULL) return 0;
     770             :         // pos
     771           0 :         v3f pos = checkFloatPos(L, 2);
     772             :         // Do it
     773           0 :         co->setAcceleration(pos);
     774           0 :         return 0;
     775             : }
     776             : 
     777             : // getacceleration(self)
     778           0 : int ObjectRef::l_getacceleration(lua_State *L)
     779             : {
     780           0 :         NO_MAP_LOCK_REQUIRED;
     781           0 :         ObjectRef *ref = checkobject(L, 1);
     782           0 :         LuaEntitySAO *co = getluaobject(ref);
     783           0 :         if(co == NULL) return 0;
     784             :         // Do it
     785           0 :         v3f v = co->getAcceleration();
     786           0 :         pushFloatPos(L, v);
     787           0 :         return 1;
     788             : }
     789             : 
     790             : // setyaw(self, radians)
     791           0 : int ObjectRef::l_setyaw(lua_State *L)
     792             : {
     793           0 :         NO_MAP_LOCK_REQUIRED;
     794           0 :         ObjectRef *ref = checkobject(L, 1);
     795           0 :         LuaEntitySAO *co = getluaobject(ref);
     796           0 :         if(co == NULL) return 0;
     797           0 :         float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
     798             :         // Do it
     799           0 :         co->setYaw(yaw);
     800           0 :         return 0;
     801             : }
     802             : 
     803             : // getyaw(self)
     804           0 : int ObjectRef::l_getyaw(lua_State *L)
     805             : {
     806           0 :         NO_MAP_LOCK_REQUIRED;
     807           0 :         ObjectRef *ref = checkobject(L, 1);
     808           0 :         LuaEntitySAO *co = getluaobject(ref);
     809           0 :         if(co == NULL) return 0;
     810             :         // Do it
     811           0 :         float yaw = co->getYaw() * core::DEGTORAD;
     812           0 :         lua_pushnumber(L, yaw);
     813           0 :         return 1;
     814             : }
     815             : 
     816             : // settexturemod(self, mod)
     817           0 : int ObjectRef::l_settexturemod(lua_State *L)
     818             : {
     819           0 :         NO_MAP_LOCK_REQUIRED;
     820           0 :         ObjectRef *ref = checkobject(L, 1);
     821           0 :         LuaEntitySAO *co = getluaobject(ref);
     822           0 :         if(co == NULL) return 0;
     823             :         // Do it
     824           0 :         std::string mod = luaL_checkstring(L, 2);
     825           0 :         co->setTextureMod(mod);
     826           0 :         return 0;
     827             : }
     828             : 
     829             : // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
     830             : //           select_horiz_by_yawpitch=false)
     831           0 : int ObjectRef::l_setsprite(lua_State *L)
     832             : {
     833           0 :         NO_MAP_LOCK_REQUIRED;
     834           0 :         ObjectRef *ref = checkobject(L, 1);
     835           0 :         LuaEntitySAO *co = getluaobject(ref);
     836           0 :         if(co == NULL) return 0;
     837             :         // Do it
     838           0 :         v2s16 p(0,0);
     839           0 :         if(!lua_isnil(L, 2))
     840           0 :                 p = read_v2s16(L, 2);
     841           0 :         int num_frames = 1;
     842           0 :         if(!lua_isnil(L, 3))
     843           0 :                 num_frames = lua_tonumber(L, 3);
     844           0 :         float framelength = 0.2;
     845           0 :         if(!lua_isnil(L, 4))
     846           0 :                 framelength = lua_tonumber(L, 4);
     847           0 :         bool select_horiz_by_yawpitch = false;
     848           0 :         if(!lua_isnil(L, 5))
     849           0 :                 select_horiz_by_yawpitch = lua_toboolean(L, 5);
     850           0 :         co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
     851           0 :         return 0;
     852             : }
     853             : 
     854             : // DEPRECATED
     855             : // get_entity_name(self)
     856           0 : int ObjectRef::l_get_entity_name(lua_State *L)
     857             : {
     858           0 :         NO_MAP_LOCK_REQUIRED;
     859           0 :         ObjectRef *ref = checkobject(L, 1);
     860           0 :         LuaEntitySAO *co = getluaobject(ref);
     861           0 :         log_deprecated(L,"Deprecated call to \"get_entity_name");
     862           0 :         if(co == NULL) return 0;
     863             :         // Do it
     864           0 :         std::string name = co->getName();
     865           0 :         lua_pushstring(L, name.c_str());
     866           0 :         return 1;
     867             : }
     868             : 
     869             : // get_luaentity(self)
     870           0 : int ObjectRef::l_get_luaentity(lua_State *L)
     871             : {
     872           0 :         NO_MAP_LOCK_REQUIRED;
     873           0 :         ObjectRef *ref = checkobject(L, 1);
     874           0 :         LuaEntitySAO *co = getluaobject(ref);
     875           0 :         if(co == NULL) return 0;
     876             :         // Do it
     877           0 :         luaentity_get(L, co->getId());
     878           0 :         return 1;
     879             : }
     880             : 
     881             : /* Player-only */
     882             : 
     883             : // is_player_connected(self)
     884           0 : int ObjectRef::l_is_player_connected(lua_State *L)
     885             : {
     886           0 :         NO_MAP_LOCK_REQUIRED;
     887           0 :         ObjectRef *ref = checkobject(L, 1);
     888           0 :         Player *player = getplayer(ref);
     889           0 :         lua_pushboolean(L, (player != NULL && player->peer_id != 0));
     890           0 :         return 1;
     891             : }
     892             : 
     893             : // get_player_name(self)
     894           0 : int ObjectRef::l_get_player_name(lua_State *L)
     895             : {
     896           0 :         NO_MAP_LOCK_REQUIRED;
     897           0 :         ObjectRef *ref = checkobject(L, 1);
     898           0 :         Player *player = getplayer(ref);
     899           0 :         if(player == NULL){
     900           0 :                 lua_pushlstring(L, "", 0);
     901           0 :                 return 1;
     902             :         }
     903             :         // Do it
     904           0 :         lua_pushstring(L, player->getName());
     905           0 :         return 1;
     906             : }
     907             : 
     908             : // get_look_dir(self)
     909           0 : int ObjectRef::l_get_look_dir(lua_State *L)
     910             : {
     911           0 :         NO_MAP_LOCK_REQUIRED;
     912           0 :         ObjectRef *ref = checkobject(L, 1);
     913           0 :         Player *player = getplayer(ref);
     914           0 :         if(player == NULL) return 0;
     915             :         // Do it
     916           0 :         float pitch = player->getRadPitch();
     917           0 :         float yaw = player->getRadYaw();
     918           0 :         v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
     919           0 :         push_v3f(L, v);
     920           0 :         return 1;
     921             : }
     922             : 
     923             : // get_look_pitch(self)
     924           0 : int ObjectRef::l_get_look_pitch(lua_State *L)
     925             : {
     926           0 :         NO_MAP_LOCK_REQUIRED;
     927           0 :         ObjectRef *ref = checkobject(L, 1);
     928           0 :         Player *player = getplayer(ref);
     929           0 :         if(player == NULL) return 0;
     930             :         // Do it
     931           0 :         lua_pushnumber(L, player->getRadPitch());
     932           0 :         return 1;
     933             : }
     934             : 
     935             : // get_look_yaw(self)
     936           0 : int ObjectRef::l_get_look_yaw(lua_State *L)
     937             : {
     938           0 :         NO_MAP_LOCK_REQUIRED;
     939           0 :         ObjectRef *ref = checkobject(L, 1);
     940           0 :         Player *player = getplayer(ref);
     941           0 :         if(player == NULL) return 0;
     942             :         // Do it
     943           0 :         lua_pushnumber(L, player->getRadYaw());
     944           0 :         return 1;
     945             : }
     946             : 
     947             : // set_look_pitch(self, radians)
     948           0 : int ObjectRef::l_set_look_pitch(lua_State *L)
     949             : {
     950           0 :         NO_MAP_LOCK_REQUIRED;
     951           0 :         ObjectRef *ref = checkobject(L, 1);
     952           0 :         PlayerSAO* co = getplayersao(ref);
     953           0 :         if(co == NULL) return 0;
     954           0 :         float pitch = luaL_checknumber(L, 2) * core::RADTODEG;
     955             :         // Do it
     956           0 :         co->setPitch(pitch);
     957           0 :         return 1;
     958             : }
     959             : 
     960             : // set_look_yaw(self, radians)
     961           0 : int ObjectRef::l_set_look_yaw(lua_State *L)
     962             : {
     963           0 :         NO_MAP_LOCK_REQUIRED;
     964           0 :         ObjectRef *ref = checkobject(L, 1);
     965           0 :         PlayerSAO* co = getplayersao(ref);
     966           0 :         if(co == NULL) return 0;
     967           0 :         float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
     968             :         // Do it
     969           0 :         co->setYaw(yaw);
     970           0 :         return 1;
     971             : }
     972             : 
     973             : // set_breath(self, breath)
     974           0 : int ObjectRef::l_set_breath(lua_State *L)
     975             : {
     976           0 :         NO_MAP_LOCK_REQUIRED;
     977           0 :         ObjectRef *ref = checkobject(L, 1);
     978           0 :         PlayerSAO* co = getplayersao(ref);
     979           0 :         if(co == NULL) return 0;
     980           0 :         u16 breath = luaL_checknumber(L, 2);
     981             :         // Do it
     982           0 :         co->setBreath(breath);
     983             : 
     984             :         // If the object is a player sent the breath to client
     985           0 :         if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
     986           0 :                         getServer(L)->SendPlayerBreath(((PlayerSAO*)co)->getPeerID());
     987             : 
     988           0 :         return 0;
     989             : }
     990             : 
     991             : // get_breath(self)
     992           0 : int ObjectRef::l_get_breath(lua_State *L)
     993             : {
     994           0 :         NO_MAP_LOCK_REQUIRED;
     995           0 :         ObjectRef *ref = checkobject(L, 1);
     996           0 :         PlayerSAO* co = getplayersao(ref);
     997           0 :         if(co == NULL) return 0;
     998             :         // Do it
     999           0 :         u16 breath = co->getBreath();
    1000           0 :         lua_pushinteger (L, breath);
    1001           0 :         return 1;
    1002             : }
    1003             : 
    1004             : // set_inventory_formspec(self, formspec)
    1005           0 : int ObjectRef::l_set_inventory_formspec(lua_State *L)
    1006             : {
    1007           0 :         NO_MAP_LOCK_REQUIRED;
    1008           0 :         ObjectRef *ref = checkobject(L, 1);
    1009           0 :         Player *player = getplayer(ref);
    1010           0 :         if(player == NULL) return 0;
    1011           0 :         std::string formspec = luaL_checkstring(L, 2);
    1012             : 
    1013           0 :         player->inventory_formspec = formspec;
    1014           0 :         getServer(L)->reportInventoryFormspecModified(player->getName());
    1015           0 :         lua_pushboolean(L, true);
    1016           0 :         return 1;
    1017             : }
    1018             : 
    1019             : // get_inventory_formspec(self) -> formspec
    1020           0 : int ObjectRef::l_get_inventory_formspec(lua_State *L)
    1021             : {
    1022           0 :         NO_MAP_LOCK_REQUIRED;
    1023           0 :         ObjectRef *ref = checkobject(L, 1);
    1024           0 :         Player *player = getplayer(ref);
    1025           0 :         if(player == NULL) return 0;
    1026             : 
    1027           0 :         std::string formspec = player->inventory_formspec;
    1028           0 :         lua_pushlstring(L, formspec.c_str(), formspec.size());
    1029           0 :         return 1;
    1030             : }
    1031             : 
    1032             : // get_player_control(self)
    1033           0 : int ObjectRef::l_get_player_control(lua_State *L)
    1034             : {
    1035           0 :         NO_MAP_LOCK_REQUIRED;
    1036           0 :         ObjectRef *ref = checkobject(L, 1);
    1037           0 :         Player *player = getplayer(ref);
    1038           0 :         if(player == NULL){
    1039           0 :                 lua_pushlstring(L, "", 0);
    1040           0 :                 return 1;
    1041             :         }
    1042             :         // Do it
    1043           0 :         PlayerControl control = player->getPlayerControl();
    1044           0 :         lua_newtable(L);
    1045           0 :         lua_pushboolean(L, control.up);
    1046           0 :         lua_setfield(L, -2, "up");
    1047           0 :         lua_pushboolean(L, control.down);
    1048           0 :         lua_setfield(L, -2, "down");
    1049           0 :         lua_pushboolean(L, control.left);
    1050           0 :         lua_setfield(L, -2, "left");
    1051           0 :         lua_pushboolean(L, control.right);
    1052           0 :         lua_setfield(L, -2, "right");
    1053           0 :         lua_pushboolean(L, control.jump);
    1054           0 :         lua_setfield(L, -2, "jump");
    1055           0 :         lua_pushboolean(L, control.aux1);
    1056           0 :         lua_setfield(L, -2, "aux1");
    1057           0 :         lua_pushboolean(L, control.sneak);
    1058           0 :         lua_setfield(L, -2, "sneak");
    1059           0 :         lua_pushboolean(L, control.LMB);
    1060           0 :         lua_setfield(L, -2, "LMB");
    1061           0 :         lua_pushboolean(L, control.RMB);
    1062           0 :         lua_setfield(L, -2, "RMB");
    1063           0 :         return 1;
    1064             : }
    1065             : 
    1066             : // get_player_control_bits(self)
    1067           0 : int ObjectRef::l_get_player_control_bits(lua_State *L)
    1068             : {
    1069           0 :         NO_MAP_LOCK_REQUIRED;
    1070           0 :         ObjectRef *ref = checkobject(L, 1);
    1071           0 :         Player *player = getplayer(ref);
    1072           0 :         if(player == NULL){
    1073           0 :                 lua_pushlstring(L, "", 0);
    1074           0 :                 return 1;
    1075             :         }
    1076             :         // Do it
    1077           0 :         lua_pushnumber(L, player->keyPressed);
    1078           0 :         return 1;
    1079             : }
    1080             : 
    1081             : // hud_add(self, form)
    1082           0 : int ObjectRef::l_hud_add(lua_State *L)
    1083             : {
    1084           0 :         ObjectRef *ref = checkobject(L, 1);
    1085           0 :         Player *player = getplayer(ref);
    1086           0 :         if (player == NULL)
    1087           0 :                 return 0;
    1088             : 
    1089           0 :         HudElement *elem = new HudElement;
    1090             : 
    1091           0 :         elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type",
    1092           0 :                                                                 es_HudElementType, HUD_ELEM_TEXT);
    1093             : 
    1094           0 :         lua_getfield(L, 2, "position");
    1095           0 :         elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
    1096           0 :         lua_pop(L, 1);
    1097             : 
    1098           0 :         lua_getfield(L, 2, "scale");
    1099           0 :         elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
    1100           0 :         lua_pop(L, 1);
    1101             : 
    1102           0 :         lua_getfield(L, 2, "size");
    1103           0 :         elem->size = lua_istable(L, -1) ? read_v2s32(L, -1) : v2s32();
    1104           0 :         lua_pop(L, 1);
    1105             : 
    1106           0 :         elem->name   = getstringfield_default(L, 2, "name", "");
    1107           0 :         elem->text   = getstringfield_default(L, 2, "text", "");
    1108           0 :         elem->number = getintfield_default(L, 2, "number", 0);
    1109           0 :         elem->item   = getintfield_default(L, 2, "item", 0);
    1110           0 :         elem->dir    = getintfield_default(L, 2, "direction", 0);
    1111             : 
    1112             :         // Deprecated, only for compatibility's sake
    1113           0 :         if (elem->dir == 0)
    1114           0 :                 elem->dir = getintfield_default(L, 2, "dir", 0);
    1115             : 
    1116           0 :         lua_getfield(L, 2, "alignment");
    1117           0 :         elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
    1118           0 :         lua_pop(L, 1);
    1119             : 
    1120           0 :         lua_getfield(L, 2, "offset");
    1121           0 :         elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
    1122           0 :         lua_pop(L, 1);
    1123             : 
    1124           0 :         lua_getfield(L, 2, "world_pos");
    1125           0 :         elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
    1126           0 :         lua_pop(L, 1);
    1127             : 
    1128             :         /* check for known deprecated element usage */
    1129           0 :         if ((elem->type  == HUD_ELEM_STATBAR) && (elem->size == v2s32())) {
    1130           0 :                 log_deprecated(L,"Deprecated usage of statbar without size!");
    1131             :         }
    1132             : 
    1133           0 :         u32 id = getServer(L)->hudAdd(player, elem);
    1134           0 :         if (id == (u32)-1) {
    1135           0 :                 delete elem;
    1136           0 :                 return 0;
    1137             :         }
    1138             : 
    1139           0 :         lua_pushnumber(L, id);
    1140           0 :         return 1;
    1141             : }
    1142             : 
    1143             : // hud_remove(self, id)
    1144           0 : int ObjectRef::l_hud_remove(lua_State *L)
    1145             : {
    1146           0 :         ObjectRef *ref = checkobject(L, 1);
    1147           0 :         Player *player = getplayer(ref);
    1148           0 :         if (player == NULL)
    1149           0 :                 return 0;
    1150             : 
    1151           0 :         u32 id = -1;
    1152           0 :         if (!lua_isnil(L, 2))
    1153           0 :                 id = lua_tonumber(L, 2);
    1154             : 
    1155           0 :         if (!getServer(L)->hudRemove(player, id))
    1156           0 :                 return 0;
    1157             : 
    1158           0 :         lua_pushboolean(L, true);
    1159           0 :         return 1;
    1160             : }
    1161             : 
    1162             : // hud_change(self, id, stat, data)
    1163           0 : int ObjectRef::l_hud_change(lua_State *L)
    1164             : {
    1165           0 :         ObjectRef *ref = checkobject(L, 1);
    1166           0 :         Player *player = getplayer(ref);
    1167           0 :         if (player == NULL)
    1168           0 :                 return 0;
    1169             : 
    1170           0 :         u32 id = lua_isnumber(L, 2) ? lua_tonumber(L, 2) : -1;
    1171             : 
    1172           0 :         HudElement *e = player->getHud(id);
    1173           0 :         if (!e)
    1174           0 :                 return 0;
    1175             : 
    1176           0 :         HudElementStat stat = HUD_STAT_NUMBER;
    1177           0 :         if (lua_isstring(L, 3)) {
    1178             :                 int statint;
    1179           0 :                 std::string statstr = lua_tostring(L, 3);
    1180           0 :                 stat = string_to_enum(es_HudElementStat, statint, statstr) ?
    1181           0 :                                 (HudElementStat)statint : HUD_STAT_NUMBER;
    1182             :         }
    1183             : 
    1184           0 :         void *value = NULL;
    1185           0 :         switch (stat) {
    1186             :                 case HUD_STAT_POS:
    1187           0 :                         e->pos = read_v2f(L, 4);
    1188           0 :                         value = &e->pos;
    1189           0 :                         break;
    1190             :                 case HUD_STAT_NAME:
    1191           0 :                         e->name = luaL_checkstring(L, 4);
    1192           0 :                         value = &e->name;
    1193           0 :                         break;
    1194             :                 case HUD_STAT_SCALE:
    1195           0 :                         e->scale = read_v2f(L, 4);
    1196           0 :                         value = &e->scale;
    1197           0 :                         break;
    1198             :                 case HUD_STAT_TEXT:
    1199           0 :                         e->text = luaL_checkstring(L, 4);
    1200           0 :                         value = &e->text;
    1201           0 :                         break;
    1202             :                 case HUD_STAT_NUMBER:
    1203           0 :                         e->number = luaL_checknumber(L, 4);
    1204           0 :                         value = &e->number;
    1205           0 :                         break;
    1206             :                 case HUD_STAT_ITEM:
    1207           0 :                         e->item = luaL_checknumber(L, 4);
    1208           0 :                         value = &e->item;
    1209           0 :                         break;
    1210             :                 case HUD_STAT_DIR:
    1211           0 :                         e->dir = luaL_checknumber(L, 4);
    1212           0 :                         value = &e->dir;
    1213           0 :                         break;
    1214             :                 case HUD_STAT_ALIGN:
    1215           0 :                         e->align = read_v2f(L, 4);
    1216           0 :                         value = &e->align;
    1217           0 :                         break;
    1218             :                 case HUD_STAT_OFFSET:
    1219           0 :                         e->offset = read_v2f(L, 4);
    1220           0 :                         value = &e->offset;
    1221           0 :                         break;
    1222             :                 case HUD_STAT_WORLD_POS:
    1223           0 :                         e->world_pos = read_v3f(L, 4);
    1224           0 :                         value = &e->world_pos;
    1225           0 :                         break;
    1226             :                 case HUD_STAT_SIZE:
    1227           0 :                         e->size = read_v2s32(L, 4);
    1228           0 :                         value = &e->size;
    1229           0 :                         break;
    1230             :         }
    1231             : 
    1232           0 :         getServer(L)->hudChange(player, id, stat, value);
    1233             : 
    1234           0 :         lua_pushboolean(L, true);
    1235           0 :         return 1;
    1236             : }
    1237             : 
    1238             : // hud_get(self, id)
    1239           0 : int ObjectRef::l_hud_get(lua_State *L)
    1240             : {
    1241           0 :         ObjectRef *ref = checkobject(L, 1);
    1242           0 :         Player *player = getplayer(ref);
    1243           0 :         if (player == NULL)
    1244           0 :                 return 0;
    1245             : 
    1246           0 :         u32 id = lua_tonumber(L, -1);
    1247             : 
    1248           0 :         HudElement *e = player->getHud(id);
    1249           0 :         if (!e)
    1250           0 :                 return 0;
    1251             : 
    1252           0 :         lua_newtable(L);
    1253             : 
    1254           0 :         lua_pushstring(L, es_HudElementType[(u8)e->type].str);
    1255           0 :         lua_setfield(L, -2, "type");
    1256             : 
    1257           0 :         push_v2f(L, e->pos);
    1258           0 :         lua_setfield(L, -2, "position");
    1259             : 
    1260           0 :         lua_pushstring(L, e->name.c_str());
    1261           0 :         lua_setfield(L, -2, "name");
    1262             : 
    1263           0 :         push_v2f(L, e->scale);
    1264           0 :         lua_setfield(L, -2, "scale");
    1265             : 
    1266           0 :         lua_pushstring(L, e->text.c_str());
    1267           0 :         lua_setfield(L, -2, "text");
    1268             : 
    1269           0 :         lua_pushnumber(L, e->number);
    1270           0 :         lua_setfield(L, -2, "number");
    1271             : 
    1272           0 :         lua_pushnumber(L, e->item);
    1273           0 :         lua_setfield(L, -2, "item");
    1274             : 
    1275           0 :         lua_pushnumber(L, e->dir);
    1276           0 :         lua_setfield(L, -2, "direction");
    1277             : 
    1278             :         // Deprecated, only for compatibility's sake
    1279           0 :         lua_pushnumber(L, e->dir);
    1280           0 :         lua_setfield(L, -2, "dir");
    1281             : 
    1282           0 :         push_v3f(L, e->world_pos);
    1283           0 :         lua_setfield(L, -2, "world_pos");
    1284             : 
    1285           0 :         return 1;
    1286             : }
    1287             : 
    1288             : // hud_set_flags(self, flags)
    1289           0 : int ObjectRef::l_hud_set_flags(lua_State *L)
    1290             : {
    1291           0 :         ObjectRef *ref = checkobject(L, 1);
    1292           0 :         Player *player = getplayer(ref);
    1293           0 :         if (player == NULL)
    1294           0 :                 return 0;
    1295             : 
    1296           0 :         u32 flags = 0;
    1297           0 :         u32 mask  = 0;
    1298             :         bool flag;
    1299             : 
    1300           0 :         const EnumString *esp = es_HudBuiltinElement;
    1301           0 :         for (int i = 0; esp[i].str; i++) {
    1302           0 :                 if (getboolfield(L, 2, esp[i].str, flag)) {
    1303           0 :                         flags |= esp[i].num * flag;
    1304           0 :                         mask  |= esp[i].num;
    1305             :                 }
    1306             :         }
    1307           0 :         if (!getServer(L)->hudSetFlags(player, flags, mask))
    1308           0 :                 return 0;
    1309             : 
    1310           0 :         lua_pushboolean(L, true);
    1311           0 :         return 1;
    1312             : }
    1313             : 
    1314           0 : int ObjectRef::l_hud_get_flags(lua_State *L)
    1315             : {
    1316           0 :         ObjectRef *ref = checkobject(L, 1);
    1317           0 :         Player *player = getplayer(ref);
    1318           0 :         if (player == NULL)
    1319           0 :                 return 0;
    1320             : 
    1321           0 :         lua_newtable(L);
    1322           0 :         lua_pushboolean(L, player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE);
    1323           0 :         lua_setfield(L, -2, "hotbar");
    1324           0 :         lua_pushboolean(L, player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE);
    1325           0 :         lua_setfield(L, -2, "healthbar");
    1326           0 :         lua_pushboolean(L, player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE);
    1327           0 :         lua_setfield(L, -2, "crosshair");
    1328           0 :         lua_pushboolean(L, player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE);
    1329           0 :         lua_setfield(L, -2, "wielditem");
    1330           0 :         lua_pushboolean(L, player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE);
    1331           0 :         lua_setfield(L, -2, "breathbar");
    1332             : 
    1333           0 :         return 1;
    1334             : }
    1335             : 
    1336             : // hud_set_hotbar_itemcount(self, hotbar_itemcount)
    1337           0 : int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
    1338             : {
    1339           0 :         ObjectRef *ref = checkobject(L, 1);
    1340           0 :         Player *player = getplayer(ref);
    1341           0 :         if (player == NULL)
    1342           0 :                 return 0;
    1343             : 
    1344           0 :         s32 hotbar_itemcount = lua_tonumber(L, 2);
    1345             : 
    1346           0 :         if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
    1347           0 :                 return 0;
    1348             : 
    1349           0 :         lua_pushboolean(L, true);
    1350           0 :         return 1;
    1351             : }
    1352             : 
    1353             : // hud_get_hotbar_itemcount(self)
    1354           0 : int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L)
    1355             : {
    1356           0 :         ObjectRef *ref = checkobject(L, 1);
    1357           0 :         Player *player = getplayer(ref);
    1358           0 :         if (player == NULL)
    1359           0 :                 return 0;
    1360             : 
    1361           0 :         s32 hotbar_itemcount = getServer(L)->hudGetHotbarItemcount(player);
    1362             : 
    1363           0 :         lua_pushnumber(L, hotbar_itemcount);
    1364           0 :         return 1;
    1365             : }
    1366             : 
    1367             : // hud_set_hotbar_image(self, name)
    1368           0 : int ObjectRef::l_hud_set_hotbar_image(lua_State *L)
    1369             : {
    1370           0 :         ObjectRef *ref = checkobject(L, 1);
    1371           0 :         Player *player = getplayer(ref);
    1372           0 :         if (player == NULL)
    1373           0 :                 return 0;
    1374             : 
    1375           0 :         std::string name = lua_tostring(L, 2);
    1376             : 
    1377           0 :         getServer(L)->hudSetHotbarImage(player, name);
    1378           0 :         return 1;
    1379             : }
    1380             : 
    1381             : // hud_get_hotbar_image(self)
    1382           0 : int ObjectRef::l_hud_get_hotbar_image(lua_State *L)
    1383             : {
    1384           0 :         ObjectRef *ref = checkobject(L, 1);
    1385           0 :         Player *player = getplayer(ref);
    1386           0 :         if (player == NULL)
    1387           0 :                 return 0;
    1388             : 
    1389           0 :         std::string name = getServer(L)->hudGetHotbarImage(player);
    1390           0 :         lua_pushlstring(L, name.c_str(), name.size());
    1391           0 :         return 1;
    1392             : }
    1393             : 
    1394             : // hud_set_hotbar_selected_image(self, name)
    1395           0 : int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L)
    1396             : {
    1397           0 :         ObjectRef *ref = checkobject(L, 1);
    1398           0 :         Player *player = getplayer(ref);
    1399           0 :         if (player == NULL)
    1400           0 :                 return 0;
    1401             : 
    1402           0 :         std::string name = lua_tostring(L, 2);
    1403             : 
    1404           0 :         getServer(L)->hudSetHotbarSelectedImage(player, name);
    1405           0 :         return 1;
    1406             : }
    1407             : 
    1408             : // hud_get_hotbar_selected_image(self)
    1409           0 : int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L)
    1410             : {
    1411           0 :         ObjectRef *ref = checkobject(L, 1);
    1412           0 :         Player *player = getplayer(ref);
    1413           0 :         if (player == NULL)
    1414           0 :                 return 0;
    1415             : 
    1416           0 :         std::string name = getServer(L)->hudGetHotbarSelectedImage(player);
    1417           0 :         lua_pushlstring(L, name.c_str(), name.size());
    1418           0 :         return 1;
    1419             : }
    1420             : 
    1421             : // set_sky(self, bgcolor, type, list)
    1422           0 : int ObjectRef::l_set_sky(lua_State *L)
    1423             : {
    1424           0 :         ObjectRef *ref = checkobject(L, 1);
    1425           0 :         Player *player = getplayer(ref);
    1426           0 :         if (player == NULL)
    1427           0 :                 return 0;
    1428             : 
    1429           0 :         video::SColor bgcolor(255,255,255,255);
    1430           0 :         read_color(L, 2, &bgcolor);
    1431             : 
    1432           0 :         std::string type = luaL_checkstring(L, 3);
    1433             : 
    1434           0 :         std::vector<std::string> params;
    1435           0 :         if (lua_istable(L, 4)) {
    1436           0 :                 int table = lua_gettop(L);
    1437           0 :                 lua_pushnil(L);
    1438           0 :                 while (lua_next(L, table) != 0) {
    1439             :                         // key at index -2 and value at index -1
    1440           0 :                         if (lua_isstring(L, -1))
    1441           0 :                                 params.push_back(lua_tostring(L, -1));
    1442             :                         else
    1443           0 :                                 params.push_back("");
    1444             :                         // removes value, keeps key for next iteration
    1445           0 :                         lua_pop(L, 1);
    1446             :                 }
    1447             :         }
    1448             : 
    1449           0 :         if (type == "skybox" && params.size() != 6)
    1450           0 :                 throw LuaError("skybox expects 6 textures");
    1451             : 
    1452           0 :         if (!getServer(L)->setSky(player, bgcolor, type, params))
    1453           0 :                 return 0;
    1454             : 
    1455           0 :         lua_pushboolean(L, true);
    1456           0 :         return 1;
    1457             : }
    1458             : 
    1459             : // get_sky(self)
    1460           0 : int ObjectRef::l_get_sky(lua_State *L)
    1461             : {
    1462           0 :         ObjectRef *ref = checkobject(L, 1);
    1463           0 :         Player *player = getplayer(ref);
    1464           0 :         if (player == NULL)
    1465           0 :                 return 0;
    1466           0 :         video::SColor bgcolor(255, 255, 255, 255);
    1467           0 :         std::string type;
    1468           0 :         std::vector<std::string> params;
    1469             : 
    1470           0 :         player->getSky(&bgcolor, &type, &params);
    1471           0 :         type = type == "" ? "regular" : type;
    1472             : 
    1473           0 :         push_ARGB8(L, bgcolor);
    1474           0 :         lua_pushlstring(L, type.c_str(), type.size());
    1475           0 :         lua_newtable(L);
    1476           0 :         s16 i = 1;
    1477           0 :         for (std::vector<std::string>::iterator it = params.begin();
    1478           0 :                         it != params.end(); ++it) {
    1479           0 :                 lua_pushlstring(L, it->c_str(), it->size());
    1480           0 :                 lua_rawseti(L, -2, i);
    1481           0 :                 i++;
    1482             :         }
    1483           0 :         return 3;
    1484             : }
    1485             : 
    1486             : // override_day_night_ratio(self, brightness=0...1)
    1487           0 : int ObjectRef::l_override_day_night_ratio(lua_State *L)
    1488             : {
    1489           0 :         ObjectRef *ref = checkobject(L, 1);
    1490           0 :         Player *player = getplayer(ref);
    1491           0 :         if (player == NULL)
    1492           0 :                 return 0;
    1493             : 
    1494           0 :         bool do_override = false;
    1495           0 :         float ratio = 0.0f;
    1496           0 :         if (!lua_isnil(L, 2)){
    1497           0 :                 do_override = true;
    1498           0 :                 ratio = luaL_checknumber(L, 2);
    1499             :         }
    1500             : 
    1501           0 :         if (!getServer(L)->overrideDayNightRatio(player, do_override, ratio))
    1502           0 :                 return 0;
    1503             : 
    1504           0 :         lua_pushboolean(L, true);
    1505           0 :         return 1;
    1506             : }
    1507             : 
    1508             : // get_day_night_ratio(self)
    1509           0 : int ObjectRef::l_get_day_night_ratio(lua_State *L)
    1510             : {
    1511           0 :         ObjectRef *ref = checkobject(L, 1);
    1512           0 :         Player *player = getplayer(ref);
    1513           0 :         if (player == NULL)
    1514           0 :                 return 0;
    1515             : 
    1516             :         bool do_override;
    1517             :         float ratio;
    1518           0 :         player->getDayNightRatio(&do_override, &ratio);
    1519             : 
    1520           0 :         if (do_override)
    1521           0 :                 lua_pushnumber(L, ratio);
    1522             :         else
    1523           0 :                 lua_pushnil(L);
    1524             : 
    1525           0 :         return 1;
    1526             : }
    1527             : 
    1528             : // set_nametag_attributes(self, attributes)
    1529           0 : int ObjectRef::l_set_nametag_attributes(lua_State *L)
    1530             : {
    1531           0 :         NO_MAP_LOCK_REQUIRED;
    1532           0 :         ObjectRef *ref = checkobject(L, 1);
    1533           0 :         PlayerSAO *playersao = getplayersao(ref);
    1534           0 :         if (playersao == NULL)
    1535           0 :                 return 0;
    1536             : 
    1537           0 :         lua_getfield(L, 2, "color");
    1538           0 :         if (!lua_isnil(L, -1)) {
    1539           0 :                 video::SColor color = playersao->getNametagColor();
    1540           0 :                 if (!read_color(L, -1, &color))
    1541           0 :                         return 0;
    1542           0 :                 playersao->setNametagColor(color);
    1543             :         }
    1544             : 
    1545           0 :         lua_pushboolean(L, true);
    1546           0 :         return 1;
    1547             : }
    1548             : 
    1549             : // get_nametag_attributes(self)
    1550           0 : int ObjectRef::l_get_nametag_attributes(lua_State *L)
    1551             : {
    1552           0 :         NO_MAP_LOCK_REQUIRED;
    1553           0 :         ObjectRef *ref = checkobject(L, 1);
    1554           0 :         PlayerSAO *playersao = getplayersao(ref);
    1555           0 :         if (playersao == NULL)
    1556           0 :                 return 0;
    1557             : 
    1558           0 :         video::SColor color = playersao->getNametagColor();
    1559             : 
    1560           0 :         lua_newtable(L);
    1561           0 :         push_ARGB8(L, color);
    1562           0 :         lua_setfield(L, -2, "color");
    1563             : 
    1564           0 :         return 1;
    1565             : }
    1566             : 
    1567           0 : ObjectRef::ObjectRef(ServerActiveObject *object):
    1568           0 :         m_object(object)
    1569             : {
    1570             :         //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
    1571           0 : }
    1572             : 
    1573           0 : ObjectRef::~ObjectRef()
    1574             : {
    1575             :         /*if(m_object)
    1576             :                 infostream<<"ObjectRef destructing for id="
    1577             :                                 <<m_object->getId()<<std::endl;
    1578             :         else
    1579             :                 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
    1580           0 : }
    1581             : 
    1582             : // Creates an ObjectRef and leaves it on top of stack
    1583             : // Not callable from Lua; all references are created on the C side.
    1584           0 : void ObjectRef::create(lua_State *L, ServerActiveObject *object)
    1585             : {
    1586           0 :         ObjectRef *o = new ObjectRef(object);
    1587             :         //infostream<<"ObjectRef::create: o="<<o<<std::endl;
    1588           0 :         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
    1589           0 :         luaL_getmetatable(L, className);
    1590           0 :         lua_setmetatable(L, -2);
    1591           0 : }
    1592             : 
    1593           0 : void ObjectRef::set_null(lua_State *L)
    1594             : {
    1595           0 :         ObjectRef *o = checkobject(L, -1);
    1596           0 :         o->m_object = NULL;
    1597           0 : }
    1598             : 
    1599           0 : void ObjectRef::Register(lua_State *L)
    1600             : {
    1601           0 :         lua_newtable(L);
    1602           0 :         int methodtable = lua_gettop(L);
    1603           0 :         luaL_newmetatable(L, className);
    1604           0 :         int metatable = lua_gettop(L);
    1605             : 
    1606           0 :         lua_pushliteral(L, "__metatable");
    1607           0 :         lua_pushvalue(L, methodtable);
    1608           0 :         lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
    1609             : 
    1610           0 :         lua_pushliteral(L, "__index");
    1611           0 :         lua_pushvalue(L, methodtable);
    1612           0 :         lua_settable(L, metatable);
    1613             : 
    1614           0 :         lua_pushliteral(L, "__gc");
    1615           0 :         lua_pushcfunction(L, gc_object);
    1616           0 :         lua_settable(L, metatable);
    1617             : 
    1618           0 :         lua_pop(L, 1);  // drop metatable
    1619             : 
    1620           0 :         luaL_openlib(L, 0, methods, 0);  // fill methodtable
    1621           0 :         lua_pop(L, 1);  // drop methodtable
    1622             : 
    1623             :         // Cannot be created from Lua
    1624             :         //lua_register(L, className, create_object);
    1625           0 : }
    1626             : 
    1627             : const char ObjectRef::className[] = "ObjectRef";
    1628             : const luaL_reg ObjectRef::methods[] = {
    1629             :         // ServerActiveObject
    1630             :         luamethod(ObjectRef, remove),
    1631             :         luamethod(ObjectRef, getpos),
    1632             :         luamethod(ObjectRef, setpos),
    1633             :         luamethod(ObjectRef, moveto),
    1634             :         luamethod(ObjectRef, punch),
    1635             :         luamethod(ObjectRef, right_click),
    1636             :         luamethod(ObjectRef, set_hp),
    1637             :         luamethod(ObjectRef, get_hp),
    1638             :         luamethod(ObjectRef, get_inventory),
    1639             :         luamethod(ObjectRef, get_wield_list),
    1640             :         luamethod(ObjectRef, get_wield_index),
    1641             :         luamethod(ObjectRef, get_wielded_item),
    1642             :         luamethod(ObjectRef, set_wielded_item),
    1643             :         luamethod(ObjectRef, set_armor_groups),
    1644             :         luamethod(ObjectRef, get_armor_groups),
    1645             :         luamethod(ObjectRef, set_animation),
    1646             :         luamethod(ObjectRef, get_animation),
    1647             :         luamethod(ObjectRef, set_bone_position),
    1648             :         luamethod(ObjectRef, get_bone_position),
    1649             :         luamethod(ObjectRef, set_attach),
    1650             :         luamethod(ObjectRef, get_attach),
    1651             :         luamethod(ObjectRef, set_detach),
    1652             :         luamethod(ObjectRef, set_properties),
    1653             :         luamethod(ObjectRef, get_properties),
    1654             :         // LuaEntitySAO-only
    1655             :         luamethod(ObjectRef, setvelocity),
    1656             :         luamethod(ObjectRef, getvelocity),
    1657             :         luamethod(ObjectRef, setacceleration),
    1658             :         luamethod(ObjectRef, getacceleration),
    1659             :         luamethod(ObjectRef, setyaw),
    1660             :         luamethod(ObjectRef, getyaw),
    1661             :         luamethod(ObjectRef, settexturemod),
    1662             :         luamethod(ObjectRef, setsprite),
    1663             :         luamethod(ObjectRef, get_entity_name),
    1664             :         luamethod(ObjectRef, get_luaentity),
    1665             :         // Player-only
    1666             :         luamethod(ObjectRef, is_player),
    1667             :         luamethod(ObjectRef, is_player_connected),
    1668             :         luamethod(ObjectRef, get_player_name),
    1669             :         luamethod(ObjectRef, get_look_dir),
    1670             :         luamethod(ObjectRef, get_look_pitch),
    1671             :         luamethod(ObjectRef, get_look_yaw),
    1672             :         luamethod(ObjectRef, set_look_yaw),
    1673             :         luamethod(ObjectRef, set_look_pitch),
    1674             :         luamethod(ObjectRef, get_breath),
    1675             :         luamethod(ObjectRef, set_breath),
    1676             :         luamethod(ObjectRef, set_inventory_formspec),
    1677             :         luamethod(ObjectRef, get_inventory_formspec),
    1678             :         luamethod(ObjectRef, get_player_control),
    1679             :         luamethod(ObjectRef, get_player_control_bits),
    1680             :         luamethod(ObjectRef, set_physics_override),
    1681             :         luamethod(ObjectRef, get_physics_override),
    1682             :         luamethod(ObjectRef, hud_add),
    1683             :         luamethod(ObjectRef, hud_remove),
    1684             :         luamethod(ObjectRef, hud_change),
    1685             :         luamethod(ObjectRef, hud_get),
    1686             :         luamethod(ObjectRef, hud_set_flags),
    1687             :         luamethod(ObjectRef, hud_get_flags),
    1688             :         luamethod(ObjectRef, hud_set_hotbar_itemcount),
    1689             :         luamethod(ObjectRef, hud_get_hotbar_itemcount),
    1690             :         luamethod(ObjectRef, hud_set_hotbar_image),
    1691             :         luamethod(ObjectRef, hud_get_hotbar_image),
    1692             :         luamethod(ObjectRef, hud_set_hotbar_selected_image),
    1693             :         luamethod(ObjectRef, hud_get_hotbar_selected_image),
    1694             :         luamethod(ObjectRef, set_sky),
    1695             :         luamethod(ObjectRef, get_sky),
    1696             :         luamethod(ObjectRef, override_day_night_ratio),
    1697             :         luamethod(ObjectRef, get_day_night_ratio),
    1698             :         luamethod(ObjectRef, set_local_animation),
    1699             :         luamethod(ObjectRef, get_local_animation),
    1700             :         luamethod(ObjectRef, set_eye_offset),
    1701             :         luamethod(ObjectRef, get_eye_offset),
    1702             :         luamethod(ObjectRef, set_nametag_attributes),
    1703             :         luamethod(ObjectRef, get_nametag_attributes),
    1704             :         {0,0}
    1705           3 : };

Generated by: LCOV version 1.11