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