+ // get_owner(self)
+ static int l_get_owner(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ std::string owner = meta->getOwner();
+ lua_pushstring(L, owner.c_str());
+ return 1;
+ }
+
+ /* IGenericNodeMetadata interface */
+
+ // set_infotext(self, text)
+ static int l_set_infotext(lua_State *L)
+ {
+ infostream<<__FUNCTION_NAME<<std::endl;
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ std::string text = luaL_checkstring(L, 2);
+ meta->setInfoText(text);
+ reportMetadataChange(ref);
+ return 0;
+ }
+
+ // inventory_set_list(self, name, {item1, item2, ...})
+ static int l_inventory_set_list(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ Inventory *inv = meta->getInventory();
+ const char *name = luaL_checkstring(L, 2);
+ inventory_set_list_from_lua(inv, name, L, 3,
+ ref->m_env->getGameDef());
+ reportMetadataChange(ref);
+ return 0;
+ }
+
+ // inventory_get_list(self, name)
+ static int l_inventory_get_list(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ Inventory *inv = meta->getInventory();
+ const char *name = luaL_checkstring(L, 2);
+ inventory_get_list_to_lua(inv, name, L);
+ return 1;
+ }
+
+ // set_inventory_draw_spec(self, text)
+ static int l_set_inventory_draw_spec(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ std::string text = luaL_checkstring(L, 2);
+ meta->setInventoryDrawSpec(text);
+ reportMetadataChange(ref);
+ return 0;
+ }
+
+ // set_allow_text_input(self, text)
+ static int l_set_allow_text_input(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ bool b = lua_toboolean(L, 2);
+ meta->setAllowTextInput(b);
+ reportMetadataChange(ref);
+ return 0;
+ }
+
+ // set_allow_removal(self, text)
+ static int l_set_allow_removal(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ bool b = lua_toboolean(L, 2);
+ meta->setRemovalDisabled(!b);
+ reportMetadataChange(ref);
+ return 0;
+ }
+
+ // set_enforce_owner(self, text)
+ static int l_set_enforce_owner(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ bool b = lua_toboolean(L, 2);
+ meta->setEnforceOwner(b);
+ reportMetadataChange(ref);
+ return 0;
+ }
+
+ // is_inventory_modified(self)
+ static int l_is_inventory_modified(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ lua_pushboolean(L, meta->isInventoryModified());
+ return 1;
+ }
+
+ // reset_inventory_modified(self)
+ static int l_reset_inventory_modified(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ meta->resetInventoryModified();
+ reportMetadataChange(ref);
+ return 0;
+ }
+
+ // is_text_modified(self)
+ static int l_is_text_modified(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ lua_pushboolean(L, meta->isTextModified());
+ return 1;
+ }
+
+ // reset_text_modified(self)
+ static int l_reset_text_modified(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ meta->resetTextModified();
+ reportMetadataChange(ref);
+ return 0;
+ }
+
+ // set_string(self, name, var)
+ static int l_set_string(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ std::string name = luaL_checkstring(L, 2);
+ size_t len = 0;
+ const char *s = lua_tolstring(L, 3, &len);
+ std::string str(s, len);
+ meta->setString(name, str);
+ reportMetadataChange(ref);
+ return 0;
+ }
+
+ // get_string(self, name)
+ static int l_get_string(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ std::string name = luaL_checkstring(L, 2);
+ std::string str = meta->getString(name);
+ lua_pushlstring(L, str.c_str(), str.size());
+ return 1;
+ }
+
+public:
+ NodeMetaRef(v3s16 p, ServerEnvironment *env):
+ m_p(p),
+ m_env(env)
+ {
+ }
+
+ ~NodeMetaRef()
+ {
+ }
+
+ // Creates an NodeMetaRef and leaves it on top of stack
+ // Not callable from Lua; all references are created on the C side.
+ static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
+ {
+ NodeMetaRef *o = new NodeMetaRef(p, env);
+ //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+ }
+
+ static void Register(lua_State *L)
+ {
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable); // hide metatable from Lua getmetatable()
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1); // drop metatable
+
+ luaL_openlib(L, 0, methods, 0); // fill methodtable
+ lua_pop(L, 1); // drop methodtable
+
+ // Cannot be created from Lua
+ //lua_register(L, className, create_object);
+ }
+};
+const char NodeMetaRef::className[] = "NodeMetaRef";
+const luaL_reg NodeMetaRef::methods[] = {
+ method(NodeMetaRef, get_type),
+ method(NodeMetaRef, allows_text_input),
+ method(NodeMetaRef, set_text),
+ method(NodeMetaRef, get_text),
+ method(NodeMetaRef, get_owner),
+ method(NodeMetaRef, set_infotext),
+ method(NodeMetaRef, inventory_set_list),
+ method(NodeMetaRef, inventory_get_list),
+ method(NodeMetaRef, set_inventory_draw_spec),
+ method(NodeMetaRef, set_allow_text_input),
+ method(NodeMetaRef, set_allow_removal),
+ method(NodeMetaRef, set_enforce_owner),
+ method(NodeMetaRef, is_inventory_modified),
+ method(NodeMetaRef, reset_inventory_modified),
+ method(NodeMetaRef, is_text_modified),
+ method(NodeMetaRef, reset_text_modified),
+ method(NodeMetaRef, set_string),
+ method(NodeMetaRef, get_string),
+ {0,0}
+};
+
+/*
+ ObjectRef
+*/
+
+class ObjectRef
+{
+private:
+ ServerActiveObject *m_object;
+
+ static const char className[];
+ static const luaL_reg methods[];
+
+ static ObjectRef *checkobject(lua_State *L, int narg)
+ {
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+ void *ud = luaL_checkudata(L, narg, className);
+ if(!ud) luaL_typerror(L, narg, className);
+ return *(ObjectRef**)ud; // unbox pointer
+ }
+
+ static ServerActiveObject* getobject(ObjectRef *ref)
+ {
+ ServerActiveObject *co = ref->m_object;
+ return co;
+ }
+
+ static LuaEntitySAO* getluaobject(ObjectRef *ref)
+ {
+ ServerActiveObject *obj = getobject(ref);
+ if(obj == NULL)
+ return NULL;
+ if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
+ return NULL;
+ return (LuaEntitySAO*)obj;
+ }
+
+ static ServerRemotePlayer* getplayer(ObjectRef *ref)
+ {
+ ServerActiveObject *obj = getobject(ref);
+ if(obj == NULL)
+ return NULL;
+ if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
+ return NULL;
+ return static_cast<ServerRemotePlayer*>(obj);
+ }
+
+ // Exported functions
+
+ // garbage collector
+ static int gc_object(lua_State *L) {
+ ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
+ //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
+ delete o;
+ return 0;
+ }
+
+ // remove(self)
+ static int l_remove(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerActiveObject *co = getobject(ref);
+ if(co == NULL) return 0;
+ infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
+ co->m_removed = true;
+ return 0;
+ }
+
+ // getpos(self)
+ // returns: {x=num, y=num, z=num}
+ static int l_getpos(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerActiveObject *co = getobject(ref);
+ if(co == NULL) return 0;
+ v3f pos = co->getBasePosition() / BS;
+ lua_newtable(L);
+ lua_pushnumber(L, pos.X);
+ lua_setfield(L, -2, "x");
+ lua_pushnumber(L, pos.Y);
+ lua_setfield(L, -2, "y");
+ lua_pushnumber(L, pos.Z);
+ lua_setfield(L, -2, "z");
+ return 1;
+ }
+
+ // setpos(self, pos)
+ static int l_setpos(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ //LuaEntitySAO *co = getluaobject(ref);
+ ServerActiveObject *co = getobject(ref);
+ if(co == NULL) return 0;
+ // pos
+ v3f pos = readFloatPos(L, 2);
+ // Do it
+ co->setPos(pos);
+ return 0;
+ }
+
+ // moveto(self, pos, continuous=false)
+ static int l_moveto(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ //LuaEntitySAO *co = getluaobject(ref);
+ ServerActiveObject *co = getobject(ref);
+ if(co == NULL) return 0;
+ // pos
+ v3f pos = readFloatPos(L, 2);
+ // continuous
+ bool continuous = lua_toboolean(L, 3);
+ // Do it
+ co->moveTo(pos, continuous);
+ return 0;
+ }
+
+ // punch(self, puncher); puncher = an another ObjectRef
+ static int l_punch(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ObjectRef *ref2 = checkobject(L, 2);
+ ServerActiveObject *co = getobject(ref);
+ ServerActiveObject *co2 = getobject(ref2);
+ if(co == NULL) return 0;
+ if(co2 == NULL) return 0;
+ // Do it
+ co->punch(co2);
+ return 0;
+ }
+
+ // right_click(self, clicker); clicker = an another ObjectRef
+ static int l_right_click(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ObjectRef *ref2 = checkobject(L, 2);
+ ServerActiveObject *co = getobject(ref);
+ ServerActiveObject *co2 = getobject(ref2);
+ if(co == NULL) return 0;
+ if(co2 == NULL) return 0;
+ // Do it
+ co->rightClick(co2);
+ return 0;
+ }
+
+ // get_wield_digging_properties(self)
+ static int l_get_wield_digging_properties(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerActiveObject *co = getobject(ref);
+ if(co == NULL) return 0;
+ // Do it
+ ToolDiggingProperties prop;
+ co->getWieldDiggingProperties(&prop);
+ push_tool_digging_properties(L, prop);
+ return 1;
+ }
+
+ // damage_wielded_item(self, amount)
+ static int l_damage_wielded_item(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerActiveObject *co = getobject(ref);
+ if(co == NULL) return 0;
+ // Do it
+ int amount = lua_tonumber(L, 2);
+ co->damageWieldedItem(amount);
+ return 0;
+ }
+
+ // add_to_inventory(self, itemstring)
+ // returns: true if item was added, (false, "reason") otherwise
+ static int l_add_to_inventory(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ luaL_checkstring(L, 2);
+ ServerActiveObject *co = getobject(ref);
+ if(co == NULL) return 0;
+ // itemstring
+ const char *itemstring = luaL_checkstring(L, 2);
+ infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
+ <<" itemstring=\""<<itemstring<<"\""<<std::endl;
+ // Do it
+ std::istringstream is(itemstring, std::ios::binary);
+ ServerEnvironment *env = co->getEnv();
+ assert(env);
+ IGameDef *gamedef = env->getGameDef();
+ try{
+ InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
+ if(item->getCount() == 0)
+ item->setCount(1);
+ bool added = co->addToInventory(item);
+ // Return
+ lua_pushboolean(L, added);
+ if(!added)
+ lua_pushstring(L, "failed to add item");
+ return 2;
+ } catch(SerializationError &e){
+ // Return
+ lua_pushboolean(L, false);
+ lua_pushstring(L, (std::string("Invalid item: ")
+ + e.what()).c_str());
+ return 2;
+ }
+ }
+
+ // add_to_inventory_later(self, itemstring)
+ // returns: nil
+ static int l_add_to_inventory_later(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ luaL_checkstring(L, 2);
+ ServerActiveObject *co = getobject(ref);
+ if(co == NULL) return 0;
+ // itemstring
+ const char *itemstring = luaL_checkstring(L, 2);
+ infostream<<"ObjectRef::l_add_to_inventory_later(): id="<<co->getId()
+ <<" itemstring=\""<<itemstring<<"\""<<std::endl;
+ // Do it
+ std::istringstream is(itemstring, std::ios::binary);
+ ServerEnvironment *env = co->getEnv();
+ assert(env);
+ IGameDef *gamedef = env->getGameDef();
+ InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
+ infostream<<"item="<<env<<std::endl;
+ co->addToInventoryLater(item);
+ // Return
+ return 0;
+ }
+
+ // set_hp(self, hp)
+ // hp = number of hitpoints (2 * number of hearts)
+ // returns: nil
+ static int l_set_hp(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ luaL_checknumber(L, 2);
+ ServerActiveObject *co = getobject(ref);
+ if(co == NULL) return 0;
+ int hp = lua_tonumber(L, 2);
+ infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
+ <<" hp="<<hp<<std::endl;
+ // Do it
+ co->setHP(hp);
+ // Return
+ return 0;
+ }
+
+ // get_hp(self)
+ // returns: number of hitpoints (2 * number of hearts)
+ // 0 if not applicable to this type of object
+ static int l_get_hp(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerActiveObject *co = getobject(ref);
+ if(co == NULL) return 0;
+ int hp = co->getHP();
+ infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
+ <<" hp="<<hp<<std::endl;
+ // Return
+ lua_pushnumber(L, hp);
+ return 1;
+ }
+
+ /* LuaEntitySAO-only */
+
+ // setvelocity(self, {x=num, y=num, z=num})
+ static int l_setvelocity(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ LuaEntitySAO *co = getluaobject(ref);
+ if(co == NULL) return 0;
+ // pos
+ v3f pos = readFloatPos(L, 2);
+ // Do it
+ co->setVelocity(pos);
+ return 0;
+ }
+
+ // setacceleration(self, {x=num, y=num, z=num})
+ static int l_setacceleration(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ LuaEntitySAO *co = getluaobject(ref);
+ if(co == NULL) return 0;
+ // pos
+ v3f pos = readFloatPos(L, 2);
+ // Do it
+ co->setAcceleration(pos);
+ return 0;
+ }
+
+ // getacceleration(self)
+ static int l_getacceleration(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ LuaEntitySAO *co = getluaobject(ref);
+ if(co == NULL) return 0;
+ // Do it
+ v3f v = co->getAcceleration();
+ pushFloatPos(L, v);
+ return 1;
+ }
+
+ // settexturemod(self, mod)
+ static int l_settexturemod(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ LuaEntitySAO *co = getluaobject(ref);
+ if(co == NULL) return 0;
+ // Do it
+ std::string mod = luaL_checkstring(L, 2);
+ co->setTextureMod(mod);
+ return 0;
+ }
+
+ // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
+ // select_horiz_by_yawpitch=false)
+ static int l_setsprite(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ LuaEntitySAO *co = getluaobject(ref);
+ if(co == NULL) return 0;
+ // Do it
+ v2s16 p(0,0);
+ if(!lua_isnil(L, 2))
+ p = read_v2s16(L, 2);
+ int num_frames = 1;
+ if(!lua_isnil(L, 3))
+ num_frames = lua_tonumber(L, 3);
+ float framelength = 0.2;
+ if(!lua_isnil(L, 4))
+ framelength = lua_tonumber(L, 4);
+ bool select_horiz_by_yawpitch = false;
+ if(!lua_isnil(L, 5))
+ select_horiz_by_yawpitch = lua_toboolean(L, 5);
+ co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
+ return 0;
+ }
+
+ /* Player-only */
+
+ // get_player_name(self)
+ static int l_get_player_name(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerRemotePlayer *player = getplayer(ref);
+ if(player == NULL){
+ lua_pushnil(L);
+ return 1;
+ }
+ // Do it
+ lua_pushstring(L, player->getName());
+ return 1;
+ }
+
+ // inventory_set_list(self, name, {item1, item2, ...})
+ static int l_inventory_set_list(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerRemotePlayer *player = getplayer(ref);
+ if(player == NULL) return 0;
+ const char *name = luaL_checkstring(L, 2);
+ // Do it
+ inventory_set_list_from_lua(&player->inventory, name, L, 3,
+ player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
+ player->m_inventory_not_sent = true;
+ return 0;
+ }
+
+ // inventory_get_list(self, name)
+ static int l_inventory_get_list(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerRemotePlayer *player = getplayer(ref);
+ if(player == NULL) return 0;
+ const char *name = luaL_checkstring(L, 2);
+ // Do it
+ inventory_get_list_to_lua(&player->inventory, name, L);
+ return 1;
+ }
+
+ // get_wielded_itemstring(self)
+ static int l_get_wielded_itemstring(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerRemotePlayer *player = getplayer(ref);
+ if(player == NULL) return 0;
+ // Do it
+ InventoryItem *item = player->getWieldedItem();
+ if(item == NULL){
+ lua_pushnil(L);
+ return 1;
+ }
+ lua_pushstring(L, item->getItemString().c_str());
+ return 1;
+ }
+
+ // get_wielded_item(self)
+ static int l_get_wielded_item(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerRemotePlayer *player = getplayer(ref);
+ if(player == NULL) return 0;
+ // Do it
+ InventoryItem *item0 = player->getWieldedItem();
+ if(item0 == NULL){
+ lua_pushnil(L);
+ return 1;
+ }
+ if(std::string("MaterialItem") == item0->getName()){
+ MaterialItem *item = (MaterialItem*)item0;
+ lua_newtable(L);
+ lua_pushstring(L, "NodeItem");
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, item->getNodeName().c_str());
+ lua_setfield(L, -2, "name");
+ }
+ else if(std::string("CraftItem") == item0->getName()){
+ CraftItem *item = (CraftItem*)item0;
+ lua_newtable(L);
+ lua_pushstring(L, "CraftItem");
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, item->getSubName().c_str());
+ lua_setfield(L, -2, "name");
+ }
+ else if(std::string("ToolItem") == item0->getName()){
+ ToolItem *item = (ToolItem*)item0;
+ lua_newtable(L);
+ lua_pushstring(L, "ToolItem");
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, item->getToolName().c_str());
+ lua_setfield(L, -2, "name");
+ lua_pushstring(L, itos(item->getWear()).c_str());
+ lua_setfield(L, -2, "wear");
+ }
+ else{
+ errorstream<<"l_get_wielded_item: Unknown item name: \""
+ <<item0->getName()<<"\""<<std::endl;
+ lua_pushnil(L);
+ }
+ return 1;
+ }
+
+ // get_look_dir(self)
+ static int l_get_look_dir(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerRemotePlayer *player = getplayer(ref);
+ if(player == NULL) return 0;
+ // Do it
+ float pitch = player->getRadPitch();
+ float yaw = player->getRadYaw();
+ v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
+ push_v3f(L, v);
+ return 1;
+ }
+
+ // get_look_pitch(self)
+ static int l_get_look_pitch(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerRemotePlayer *player = getplayer(ref);
+ if(player == NULL) return 0;
+ // Do it
+ lua_pushnumber(L, player->getRadPitch());
+ return 1;
+ }
+
+ // get_look_yaw(self)
+ static int l_get_look_yaw(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ ServerRemotePlayer *player = getplayer(ref);
+ if(player == NULL) return 0;
+ // Do it
+ lua_pushnumber(L, player->getRadYaw());
+ return 1;
+ }
+
+public:
+ ObjectRef(ServerActiveObject *object):
+ m_object(object)
+ {
+ //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
+ }
+
+ ~ObjectRef()