bc150d70f4a1c704bfbd8ecbc8caa4be8a4ee188
[oweals/minetest.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         {HUD_FLAG_MINIMAP_RADAR_VISIBLE, "minimap_radar"},
70         {0, NULL},
71 };
72
73 /*
74         ObjectRef
75 */
76
77
78 ObjectRef* ObjectRef::checkobject(lua_State *L, int narg)
79 {
80         luaL_checktype(L, narg, LUA_TUSERDATA);
81         void *ud = luaL_checkudata(L, narg, className);
82         if (!ud) luaL_typerror(L, narg, className);
83         return *(ObjectRef**)ud;  // unbox pointer
84 }
85
86 ServerActiveObject* ObjectRef::getobject(ObjectRef *ref)
87 {
88         ServerActiveObject *co = ref->m_object;
89         return co;
90 }
91
92 LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref)
93 {
94         ServerActiveObject *obj = getobject(ref);
95         if (obj == NULL)
96                 return NULL;
97         if (obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
98                 return NULL;
99         return (LuaEntitySAO*)obj;
100 }
101
102 PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
103 {
104         ServerActiveObject *obj = getobject(ref);
105         if (obj == NULL)
106                 return NULL;
107         if (obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
108                 return NULL;
109         return (PlayerSAO*)obj;
110 }
111
112 RemotePlayer *ObjectRef::getplayer(ObjectRef *ref)
113 {
114         PlayerSAO *playersao = getplayersao(ref);
115         if (playersao == NULL)
116                 return NULL;
117         return playersao->getPlayer();
118 }
119
120 // Exported functions
121
122 // garbage collector
123 int ObjectRef::gc_object(lua_State *L) {
124         ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
125         //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
126         delete o;
127         return 0;
128 }
129
130 // remove(self)
131 int ObjectRef::l_remove(lua_State *L)
132 {
133         GET_ENV_PTR;
134
135         ObjectRef *ref = checkobject(L, 1);
136         ServerActiveObject *co = getobject(ref);
137         if (co == NULL)
138                 return 0;
139         if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
140                 return 0;
141
142         const std::unordered_set<int> &child_ids = co->getAttachmentChildIds();
143         for (int child_id : child_ids) {
144                 // Child can be NULL if it was deleted earlier
145                 if (ServerActiveObject *child = env->getActiveObject(child_id))
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_pending_removal = 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 (const 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_animation_frame_speed(self, frame_speed)
607 int ObjectRef::l_set_animation_frame_speed(lua_State *L)
608 {
609         NO_MAP_LOCK_REQUIRED;
610         ObjectRef *ref = checkobject(L, 1);
611         ServerActiveObject *co = getobject(ref);
612         if (co == NULL)
613                 return 0;
614
615         // Do it
616         if (!lua_isnil(L, 2)) {
617                 float frame_speed = lua_tonumber(L, 2);
618                 co->setAnimationSpeed(frame_speed);
619                 lua_pushboolean(L, true);
620         } else {
621                 lua_pushboolean(L, false);
622         }
623         return 1;
624 }
625
626 // set_bone_position(self, std::string bone, v3f position, v3f rotation)
627 int ObjectRef::l_set_bone_position(lua_State *L)
628 {
629         NO_MAP_LOCK_REQUIRED;
630         ObjectRef *ref = checkobject(L, 1);
631         ServerActiveObject *co = getobject(ref);
632         if (co == NULL) return 0;
633         // Do it
634         std::string bone;
635         if (!lua_isnil(L, 2))
636                 bone = lua_tostring(L, 2);
637         v3f position = v3f(0, 0, 0);
638         if (!lua_isnil(L, 3))
639                 position = check_v3f(L, 3);
640         v3f rotation = v3f(0, 0, 0);
641         if (!lua_isnil(L, 4))
642                 rotation = check_v3f(L, 4);
643         co->setBonePosition(bone, position, rotation);
644         return 0;
645 }
646
647 // get_bone_position(self, bone)
648 int ObjectRef::l_get_bone_position(lua_State *L)
649 {
650         NO_MAP_LOCK_REQUIRED;
651         ObjectRef *ref = checkobject(L, 1);
652         ServerActiveObject *co = getobject(ref);
653         if (co == NULL)
654                 return 0;
655         // Do it
656         std::string bone;
657         if (!lua_isnil(L, 2))
658                 bone = lua_tostring(L, 2);
659
660         v3f position = v3f(0, 0, 0);
661         v3f rotation = v3f(0, 0, 0);
662         co->getBonePosition(bone, &position, &rotation);
663
664         push_v3f(L, position);
665         push_v3f(L, rotation);
666         return 2;
667 }
668
669 // set_attach(self, parent, bone, position, rotation)
670 int ObjectRef::l_set_attach(lua_State *L)
671 {
672         GET_ENV_PTR;
673
674         ObjectRef *ref = checkobject(L, 1);
675         ObjectRef *parent_ref = checkobject(L, 2);
676         ServerActiveObject *co = getobject(ref);
677         ServerActiveObject *parent = getobject(parent_ref);
678         if (co == NULL)
679                 return 0;
680         if (parent == NULL)
681                 return 0;
682         // Do it
683         int parent_id = 0;
684         std::string bone;
685         v3f position = v3f(0, 0, 0);
686         v3f rotation = v3f(0, 0, 0);
687         co->getAttachment(&parent_id, &bone, &position, &rotation);
688         if (parent_id) {
689                 ServerActiveObject *old_parent = env->getActiveObject(parent_id);
690                 old_parent->removeAttachmentChild(co->getId());
691         }
692
693         bone = "";
694         if (!lua_isnil(L, 3))
695                 bone = lua_tostring(L, 3);
696         position = v3f(0, 0, 0);
697         if (!lua_isnil(L, 4))
698                 position = read_v3f(L, 4);
699         rotation = v3f(0, 0, 0);
700         if (!lua_isnil(L, 5))
701                 rotation = read_v3f(L, 5);
702         co->setAttachment(parent->getId(), bone, position, rotation);
703         parent->addAttachmentChild(co->getId());
704         return 0;
705 }
706
707 // get_attach(self)
708 int ObjectRef::l_get_attach(lua_State *L)
709 {
710         GET_ENV_PTR;
711
712         ObjectRef *ref = checkobject(L, 1);
713         ServerActiveObject *co = getobject(ref);
714         if (co == NULL)
715                 return 0;
716
717         // Do it
718         int parent_id = 0;
719         std::string bone;
720         v3f position = v3f(0, 0, 0);
721         v3f rotation = v3f(0, 0, 0);
722         co->getAttachment(&parent_id, &bone, &position, &rotation);
723         if (!parent_id)
724                 return 0;
725         ServerActiveObject *parent = env->getActiveObject(parent_id);
726
727         getScriptApiBase(L)->objectrefGetOrCreate(L, parent);
728         lua_pushlstring(L, bone.c_str(), bone.size());
729         push_v3f(L, position);
730         push_v3f(L, rotation);
731         return 4;
732 }
733
734 // set_detach(self)
735 int ObjectRef::l_set_detach(lua_State *L)
736 {
737         GET_ENV_PTR;
738
739         ObjectRef *ref = checkobject(L, 1);
740         ServerActiveObject *co = getobject(ref);
741         if (co == NULL)
742                 return 0;
743
744         int parent_id = 0;
745         std::string bone;
746         v3f position;
747         v3f rotation;
748         co->getAttachment(&parent_id, &bone, &position, &rotation);
749         ServerActiveObject *parent = NULL;
750         if (parent_id) {
751                 parent = env->getActiveObject(parent_id);
752                 co->setAttachment(0, "", position, rotation);
753         } else {
754                 co->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0));
755         }
756         // Do it
757         if (parent != NULL)
758                 parent->removeAttachmentChild(co->getId());
759         return 0;
760 }
761
762 // set_properties(self, properties)
763 int ObjectRef::l_set_properties(lua_State *L)
764 {
765         NO_MAP_LOCK_REQUIRED;
766         ObjectRef *ref = checkobject(L, 1);
767         ServerActiveObject *co = getobject(ref);
768         if (co == NULL) return 0;
769         ObjectProperties *prop = co->accessObjectProperties();
770         if (!prop)
771                 return 0;
772         read_object_properties(L, 2, prop, getServer(L)->idef());
773         if (prop->hp_max < co->getHP()) {
774                 co->setHP(prop->hp_max);
775                 if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
776                         getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co);
777         }
778         co->notifyObjectPropertiesModified();
779         return 0;
780 }
781
782 // get_properties(self)
783 int ObjectRef::l_get_properties(lua_State *L)
784 {
785         NO_MAP_LOCK_REQUIRED;
786         ObjectRef *ref = checkobject(L, 1);
787         ServerActiveObject *co = getobject(ref);
788         if (co == NULL)
789                 return 0;
790         ObjectProperties *prop = co->accessObjectProperties();
791         if (!prop)
792                 return 0;
793         push_object_properties(L, prop);
794         return 1;
795 }
796
797 // is_player(self)
798 int ObjectRef::l_is_player(lua_State *L)
799 {
800         NO_MAP_LOCK_REQUIRED;
801         ObjectRef *ref = checkobject(L, 1);
802         RemotePlayer *player = getplayer(ref);
803         lua_pushboolean(L, (player != NULL));
804         return 1;
805 }
806
807 // set_nametag_attributes(self, attributes)
808 int ObjectRef::l_set_nametag_attributes(lua_State *L)
809 {
810         NO_MAP_LOCK_REQUIRED;
811         ObjectRef *ref = checkobject(L, 1);
812         ServerActiveObject *co = getobject(ref);
813
814         if (co == NULL)
815                 return 0;
816         ObjectProperties *prop = co->accessObjectProperties();
817         if (!prop)
818                 return 0;
819
820         lua_getfield(L, 2, "color");
821         if (!lua_isnil(L, -1)) {
822                 video::SColor color = prop->nametag_color;
823                 read_color(L, -1, &color);
824                 prop->nametag_color = color;
825         }
826         lua_pop(L, 1);
827
828         std::string nametag = getstringfield_default(L, 2, "text", "");
829         prop->nametag = nametag;
830
831         co->notifyObjectPropertiesModified();
832         lua_pushboolean(L, true);
833         return 1;
834 }
835
836 // get_nametag_attributes(self)
837 int ObjectRef::l_get_nametag_attributes(lua_State *L)
838 {
839         NO_MAP_LOCK_REQUIRED;
840         ObjectRef *ref = checkobject(L, 1);
841         ServerActiveObject *co = getobject(ref);
842
843         if (co == NULL)
844                 return 0;
845         ObjectProperties *prop = co->accessObjectProperties();
846         if (!prop)
847                 return 0;
848
849         video::SColor color = prop->nametag_color;
850
851         lua_newtable(L);
852         push_ARGB8(L, color);
853         lua_setfield(L, -2, "color");
854         lua_pushstring(L, prop->nametag.c_str());
855         lua_setfield(L, -2, "text");
856         return 1;
857 }
858
859 /* LuaEntitySAO-only */
860
861 // set_velocity(self, {x=num, y=num, z=num})
862 int ObjectRef::l_set_velocity(lua_State *L)
863 {
864         NO_MAP_LOCK_REQUIRED;
865         ObjectRef *ref = checkobject(L, 1);
866         LuaEntitySAO *co = getluaobject(ref);
867         if (co == NULL) return 0;
868         v3f pos = checkFloatPos(L, 2);
869         // Do it
870         co->setVelocity(pos);
871         return 0;
872 }
873
874 // get_velocity(self)
875 int ObjectRef::l_get_velocity(lua_State *L)
876 {
877         NO_MAP_LOCK_REQUIRED;
878         ObjectRef *ref = checkobject(L, 1);
879         LuaEntitySAO *co = getluaobject(ref);
880         if (co == NULL) return 0;
881         // Do it
882         v3f v = co->getVelocity();
883         pushFloatPos(L, v);
884         return 1;
885 }
886
887 // set_acceleration(self, {x=num, y=num, z=num})
888 int ObjectRef::l_set_acceleration(lua_State *L)
889 {
890         NO_MAP_LOCK_REQUIRED;
891         ObjectRef *ref = checkobject(L, 1);
892         LuaEntitySAO *co = getluaobject(ref);
893         if (co == NULL) return 0;
894         // pos
895         v3f pos = checkFloatPos(L, 2);
896         // Do it
897         co->setAcceleration(pos);
898         return 0;
899 }
900
901 // get_acceleration(self)
902 int ObjectRef::l_get_acceleration(lua_State *L)
903 {
904         NO_MAP_LOCK_REQUIRED;
905         ObjectRef *ref = checkobject(L, 1);
906         LuaEntitySAO *co = getluaobject(ref);
907         if (co == NULL) return 0;
908         // Do it
909         v3f v = co->getAcceleration();
910         pushFloatPos(L, v);
911         return 1;
912 }
913
914 // set_yaw(self, radians)
915 int ObjectRef::l_set_yaw(lua_State *L)
916 {
917         NO_MAP_LOCK_REQUIRED;
918         ObjectRef *ref = checkobject(L, 1);
919         LuaEntitySAO *co = getluaobject(ref);
920         if (co == NULL) return 0;
921         float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
922         // Do it
923         co->setYaw(yaw);
924         return 0;
925 }
926
927 // get_yaw(self)
928 int ObjectRef::l_get_yaw(lua_State *L)
929 {
930         NO_MAP_LOCK_REQUIRED;
931         ObjectRef *ref = checkobject(L, 1);
932         LuaEntitySAO *co = getluaobject(ref);
933         if (co == NULL) return 0;
934         // Do it
935         float yaw = co->getYaw() * core::DEGTORAD;
936         lua_pushnumber(L, yaw);
937         return 1;
938 }
939
940 // set_texture_mod(self, mod)
941 int ObjectRef::l_set_texture_mod(lua_State *L)
942 {
943         NO_MAP_LOCK_REQUIRED;
944         ObjectRef *ref = checkobject(L, 1);
945         LuaEntitySAO *co = getluaobject(ref);
946         if (co == NULL) return 0;
947         // Do it
948         std::string mod = luaL_checkstring(L, 2);
949         co->setTextureMod(mod);
950         return 0;
951 }
952
953 // get_texture_mod(self)
954 int ObjectRef::l_get_texture_mod(lua_State *L)
955 {
956         NO_MAP_LOCK_REQUIRED;
957         ObjectRef *ref = checkobject(L, 1);
958         LuaEntitySAO *co = getluaobject(ref);
959         if (co == NULL) return 0;
960         // Do it
961         std::string mod = co->getTextureMod();
962         lua_pushstring(L, mod.c_str());
963         return 1;
964 }
965
966 // set_sprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
967 //           select_horiz_by_yawpitch=false)
968 int ObjectRef::l_set_sprite(lua_State *L)
969 {
970         NO_MAP_LOCK_REQUIRED;
971         ObjectRef *ref = checkobject(L, 1);
972         LuaEntitySAO *co = getluaobject(ref);
973         if (co == NULL) return 0;
974         // Do it
975         v2s16 p(0,0);
976         if (!lua_isnil(L, 2))
977                 p = read_v2s16(L, 2);
978         int num_frames = 1;
979         if (!lua_isnil(L, 3))
980                 num_frames = lua_tonumber(L, 3);
981         float framelength = 0.2;
982         if (!lua_isnil(L, 4))
983                 framelength = lua_tonumber(L, 4);
984         bool select_horiz_by_yawpitch = false;
985         if (!lua_isnil(L, 5))
986                 select_horiz_by_yawpitch = lua_toboolean(L, 5);
987         co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
988         return 0;
989 }
990
991 // DEPRECATED
992 // get_entity_name(self)
993 int ObjectRef::l_get_entity_name(lua_State *L)
994 {
995         NO_MAP_LOCK_REQUIRED;
996         ObjectRef *ref = checkobject(L, 1);
997         LuaEntitySAO *co = getluaobject(ref);
998         log_deprecated(L,"Deprecated call to \"get_entity_name");
999         if (co == NULL) return 0;
1000         // Do it
1001         std::string name = co->getName();
1002         lua_pushstring(L, name.c_str());
1003         return 1;
1004 }
1005
1006 // get_luaentity(self)
1007 int ObjectRef::l_get_luaentity(lua_State *L)
1008 {
1009         NO_MAP_LOCK_REQUIRED;
1010         ObjectRef *ref = checkobject(L, 1);
1011         LuaEntitySAO *co = getluaobject(ref);
1012         if (co == NULL) return 0;
1013         // Do it
1014         luaentity_get(L, co->getId());
1015         return 1;
1016 }
1017
1018 /* Player-only */
1019
1020 // is_player_connected(self)
1021 int ObjectRef::l_is_player_connected(lua_State *L)
1022 {
1023         NO_MAP_LOCK_REQUIRED;
1024         ObjectRef *ref = checkobject(L, 1);
1025         RemotePlayer *player = getplayer(ref);
1026         lua_pushboolean(L, (player != NULL && player->getPeerId() != PEER_ID_INEXISTENT));
1027         return 1;
1028 }
1029
1030 // get_player_name(self)
1031 int ObjectRef::l_get_player_name(lua_State *L)
1032 {
1033         NO_MAP_LOCK_REQUIRED;
1034         ObjectRef *ref = checkobject(L, 1);
1035         RemotePlayer *player = getplayer(ref);
1036         if (player == NULL) {
1037                 lua_pushlstring(L, "", 0);
1038                 return 1;
1039         }
1040         // Do it
1041         lua_pushstring(L, player->getName());
1042         return 1;
1043 }
1044
1045 // get_player_velocity(self)
1046 int ObjectRef::l_get_player_velocity(lua_State *L)
1047 {
1048         NO_MAP_LOCK_REQUIRED;
1049         ObjectRef *ref = checkobject(L, 1);
1050         RemotePlayer *player = getplayer(ref);
1051         if (player == NULL) {
1052                 lua_pushnil(L);
1053                 return 1;
1054         }
1055         // Do it
1056         push_v3f(L, player->getSpeed() / BS);
1057         return 1;
1058 }
1059
1060 // get_look_dir(self)
1061 int ObjectRef::l_get_look_dir(lua_State *L)
1062 {
1063         NO_MAP_LOCK_REQUIRED;
1064         ObjectRef *ref = checkobject(L, 1);
1065         PlayerSAO* co = getplayersao(ref);
1066         if (co == NULL) return 0;
1067         // Do it
1068         float pitch = co->getRadPitchDep();
1069         float yaw = co->getRadYawDep();
1070         v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
1071         push_v3f(L, v);
1072         return 1;
1073 }
1074
1075 // DEPRECATED
1076 // get_look_pitch(self)
1077 int ObjectRef::l_get_look_pitch(lua_State *L)
1078 {
1079         NO_MAP_LOCK_REQUIRED;
1080
1081         log_deprecated(L,
1082                 "Deprecated call to get_look_pitch, use get_look_vertical instead");
1083
1084         ObjectRef *ref = checkobject(L, 1);
1085         PlayerSAO* co = getplayersao(ref);
1086         if (co == NULL) return 0;
1087         // Do it
1088         lua_pushnumber(L, co->getRadPitchDep());
1089         return 1;
1090 }
1091
1092 // DEPRECATED
1093 // get_look_yaw(self)
1094 int ObjectRef::l_get_look_yaw(lua_State *L)
1095 {
1096         NO_MAP_LOCK_REQUIRED;
1097
1098         log_deprecated(L,
1099                 "Deprecated call to get_look_yaw, use get_look_horizontal instead");
1100
1101         ObjectRef *ref = checkobject(L, 1);
1102         PlayerSAO* co = getplayersao(ref);
1103         if (co == NULL) return 0;
1104         // Do it
1105         lua_pushnumber(L, co->getRadYawDep());
1106         return 1;
1107 }
1108
1109 // get_look_pitch2(self)
1110 int ObjectRef::l_get_look_vertical(lua_State *L)
1111 {
1112         NO_MAP_LOCK_REQUIRED;
1113         ObjectRef *ref = checkobject(L, 1);
1114         PlayerSAO* co = getplayersao(ref);
1115         if (co == NULL) return 0;
1116         // Do it
1117         lua_pushnumber(L, co->getRadPitch());
1118         return 1;
1119 }
1120
1121 // get_look_yaw2(self)
1122 int ObjectRef::l_get_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         // Do it
1129         lua_pushnumber(L, co->getRadYaw());
1130         return 1;
1131 }
1132
1133 // set_look_vertical(self, radians)
1134 int ObjectRef::l_set_look_vertical(lua_State *L)
1135 {
1136         NO_MAP_LOCK_REQUIRED;
1137         ObjectRef *ref = checkobject(L, 1);
1138         PlayerSAO* co = getplayersao(ref);
1139         if (co == NULL) return 0;
1140         float pitch = luaL_checknumber(L, 2) * core::RADTODEG;
1141         // Do it
1142         co->setPitchAndSend(pitch);
1143         return 1;
1144 }
1145
1146 // set_look_horizontal(self, radians)
1147 int ObjectRef::l_set_look_horizontal(lua_State *L)
1148 {
1149         NO_MAP_LOCK_REQUIRED;
1150         ObjectRef *ref = checkobject(L, 1);
1151         PlayerSAO* co = getplayersao(ref);
1152         if (co == NULL) return 0;
1153         float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
1154         // Do it
1155         co->setYawAndSend(yaw);
1156         return 1;
1157 }
1158
1159 // DEPRECATED
1160 // set_look_pitch(self, radians)
1161 int ObjectRef::l_set_look_pitch(lua_State *L)
1162 {
1163         NO_MAP_LOCK_REQUIRED;
1164
1165         log_deprecated(L,
1166                 "Deprecated call to set_look_pitch, use set_look_vertical instead.");
1167
1168         ObjectRef *ref = checkobject(L, 1);
1169         PlayerSAO* co = getplayersao(ref);
1170         if (co == NULL) return 0;
1171         float pitch = luaL_checknumber(L, 2) * core::RADTODEG;
1172         // Do it
1173         co->setPitchAndSend(pitch);
1174         return 1;
1175 }
1176
1177 // DEPRECATED
1178 // set_look_yaw(self, radians)
1179 int ObjectRef::l_set_look_yaw(lua_State *L)
1180 {
1181         NO_MAP_LOCK_REQUIRED;
1182
1183         log_deprecated(L,
1184                 "Deprecated call to set_look_yaw, use set_look_horizontal instead.");
1185
1186         ObjectRef *ref = checkobject(L, 1);
1187         PlayerSAO* co = getplayersao(ref);
1188         if (co == NULL) return 0;
1189         float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
1190         // Do it
1191         co->setYawAndSend(yaw);
1192         return 1;
1193 }
1194
1195 // set_breath(self, breath)
1196 int ObjectRef::l_set_breath(lua_State *L)
1197 {
1198         NO_MAP_LOCK_REQUIRED;
1199         ObjectRef *ref = checkobject(L, 1);
1200         PlayerSAO* co = getplayersao(ref);
1201         if (co == NULL) return 0;
1202         u16 breath = luaL_checknumber(L, 2);
1203         co->setBreath(breath);
1204
1205         return 0;
1206 }
1207
1208 // get_breath(self)
1209 int ObjectRef::l_get_breath(lua_State *L)
1210 {
1211         NO_MAP_LOCK_REQUIRED;
1212         ObjectRef *ref = checkobject(L, 1);
1213         PlayerSAO* co = getplayersao(ref);
1214         if (co == NULL) return 0;
1215         // Do it
1216         u16 breath = co->getBreath();
1217         lua_pushinteger (L, breath);
1218         return 1;
1219 }
1220
1221 // set_attribute(self, attribute, value)
1222 int ObjectRef::l_set_attribute(lua_State *L)
1223 {
1224         ObjectRef *ref = checkobject(L, 1);
1225         PlayerSAO* co = getplayersao(ref);
1226         if (co == NULL) {
1227                 return 0;
1228         }
1229
1230         std::string attr = luaL_checkstring(L, 2);
1231         if (lua_isnil(L, 3)) {
1232                 co->removeExtendedAttribute(attr);
1233         } else {
1234                 std::string value = luaL_checkstring(L, 3);
1235                 co->setExtendedAttribute(attr, value);
1236         }
1237         return 1;
1238 }
1239
1240 // get_attribute(self, attribute)
1241 int ObjectRef::l_get_attribute(lua_State *L)
1242 {
1243         ObjectRef *ref = checkobject(L, 1);
1244         PlayerSAO* co = getplayersao(ref);
1245         if (co == NULL) {
1246                 return 0;
1247         }
1248
1249         std::string attr = luaL_checkstring(L, 2);
1250
1251         std::string value;
1252         if (co->getExtendedAttribute(attr, &value)) {
1253                 lua_pushstring(L, value.c_str());
1254                 return 1;
1255         }
1256
1257         return 0;
1258 }
1259
1260
1261 // set_inventory_formspec(self, formspec)
1262 int ObjectRef::l_set_inventory_formspec(lua_State *L)
1263 {
1264         NO_MAP_LOCK_REQUIRED;
1265         ObjectRef *ref = checkobject(L, 1);
1266         RemotePlayer *player = getplayer(ref);
1267         if (player == NULL) return 0;
1268         std::string formspec = luaL_checkstring(L, 2);
1269
1270         player->inventory_formspec = formspec;
1271         getServer(L)->reportInventoryFormspecModified(player->getName());
1272         lua_pushboolean(L, true);
1273         return 1;
1274 }
1275
1276 // get_inventory_formspec(self) -> formspec
1277 int ObjectRef::l_get_inventory_formspec(lua_State *L)
1278 {
1279         NO_MAP_LOCK_REQUIRED;
1280         ObjectRef *ref = checkobject(L, 1);
1281         RemotePlayer *player = getplayer(ref);
1282         if (player == NULL) return 0;
1283
1284         std::string formspec = player->inventory_formspec;
1285         lua_pushlstring(L, formspec.c_str(), formspec.size());
1286         return 1;
1287 }
1288
1289 // get_player_control(self)
1290 int ObjectRef::l_get_player_control(lua_State *L)
1291 {
1292         NO_MAP_LOCK_REQUIRED;
1293         ObjectRef *ref = checkobject(L, 1);
1294         RemotePlayer *player = getplayer(ref);
1295         if (player == NULL) {
1296                 lua_pushlstring(L, "", 0);
1297                 return 1;
1298         }
1299
1300         const PlayerControl &control = player->getPlayerControl();
1301         lua_newtable(L);
1302         lua_pushboolean(L, control.up);
1303         lua_setfield(L, -2, "up");
1304         lua_pushboolean(L, control.down);
1305         lua_setfield(L, -2, "down");
1306         lua_pushboolean(L, control.left);
1307         lua_setfield(L, -2, "left");
1308         lua_pushboolean(L, control.right);
1309         lua_setfield(L, -2, "right");
1310         lua_pushboolean(L, control.jump);
1311         lua_setfield(L, -2, "jump");
1312         lua_pushboolean(L, control.aux1);
1313         lua_setfield(L, -2, "aux1");
1314         lua_pushboolean(L, control.sneak);
1315         lua_setfield(L, -2, "sneak");
1316         lua_pushboolean(L, control.LMB);
1317         lua_setfield(L, -2, "LMB");
1318         lua_pushboolean(L, control.RMB);
1319         lua_setfield(L, -2, "RMB");
1320         return 1;
1321 }
1322
1323 // get_player_control_bits(self)
1324 int ObjectRef::l_get_player_control_bits(lua_State *L)
1325 {
1326         NO_MAP_LOCK_REQUIRED;
1327         ObjectRef *ref = checkobject(L, 1);
1328         RemotePlayer *player = getplayer(ref);
1329         if (player == NULL) {
1330                 lua_pushlstring(L, "", 0);
1331                 return 1;
1332         }
1333         // Do it
1334         lua_pushnumber(L, player->keyPressed);
1335         return 1;
1336 }
1337
1338 // hud_add(self, form)
1339 int ObjectRef::l_hud_add(lua_State *L)
1340 {
1341         NO_MAP_LOCK_REQUIRED;
1342         ObjectRef *ref = checkobject(L, 1);
1343         RemotePlayer *player = getplayer(ref);
1344         if (player == NULL)
1345                 return 0;
1346
1347         HudElement *elem = new HudElement;
1348
1349         elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type",
1350                                                                 es_HudElementType, HUD_ELEM_TEXT);
1351
1352         lua_getfield(L, 2, "position");
1353         elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
1354         lua_pop(L, 1);
1355
1356         lua_getfield(L, 2, "scale");
1357         elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
1358         lua_pop(L, 1);
1359
1360         lua_getfield(L, 2, "size");
1361         elem->size = lua_istable(L, -1) ? read_v2s32(L, -1) : v2s32();
1362         lua_pop(L, 1);
1363
1364         elem->name   = getstringfield_default(L, 2, "name", "");
1365         elem->text   = getstringfield_default(L, 2, "text", "");
1366         elem->number = getintfield_default(L, 2, "number", 0);
1367         elem->item   = getintfield_default(L, 2, "item", 0);
1368         elem->dir    = getintfield_default(L, 2, "direction", 0);
1369
1370         // Deprecated, only for compatibility's sake
1371         if (elem->dir == 0)
1372                 elem->dir = getintfield_default(L, 2, "dir", 0);
1373
1374         lua_getfield(L, 2, "alignment");
1375         elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
1376         lua_pop(L, 1);
1377
1378         lua_getfield(L, 2, "offset");
1379         elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
1380         lua_pop(L, 1);
1381
1382         lua_getfield(L, 2, "world_pos");
1383         elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
1384         lua_pop(L, 1);
1385
1386         /* check for known deprecated element usage */
1387         if ((elem->type  == HUD_ELEM_STATBAR) && (elem->size == v2s32())) {
1388                 log_deprecated(L,"Deprecated usage of statbar without size!");
1389         }
1390
1391         u32 id = getServer(L)->hudAdd(player, elem);
1392         if (id == U32_MAX) {
1393                 delete elem;
1394                 return 0;
1395         }
1396
1397         lua_pushnumber(L, id);
1398         return 1;
1399 }
1400
1401 // hud_remove(self, id)
1402 int ObjectRef::l_hud_remove(lua_State *L)
1403 {
1404         NO_MAP_LOCK_REQUIRED;
1405         ObjectRef *ref = checkobject(L, 1);
1406         RemotePlayer *player = getplayer(ref);
1407         if (player == NULL)
1408                 return 0;
1409
1410         u32 id = -1;
1411         if (!lua_isnil(L, 2))
1412                 id = lua_tonumber(L, 2);
1413
1414         if (!getServer(L)->hudRemove(player, id))
1415                 return 0;
1416
1417         lua_pushboolean(L, true);
1418         return 1;
1419 }
1420
1421 // hud_change(self, id, stat, data)
1422 int ObjectRef::l_hud_change(lua_State *L)
1423 {
1424         NO_MAP_LOCK_REQUIRED;
1425         ObjectRef *ref = checkobject(L, 1);
1426         RemotePlayer *player = getplayer(ref);
1427         if (player == NULL)
1428                 return 0;
1429
1430         u32 id = lua_isnumber(L, 2) ? lua_tonumber(L, 2) : -1;
1431
1432         HudElement *e = player->getHud(id);
1433         if (!e)
1434                 return 0;
1435
1436         HudElementStat stat = HUD_STAT_NUMBER;
1437         if (lua_isstring(L, 3)) {
1438                 int statint;
1439                 std::string statstr = lua_tostring(L, 3);
1440                 stat = string_to_enum(es_HudElementStat, statint, statstr) ?
1441                                 (HudElementStat)statint : HUD_STAT_NUMBER;
1442         }
1443
1444         void *value = NULL;
1445         switch (stat) {
1446                 case HUD_STAT_POS:
1447                         e->pos = read_v2f(L, 4);
1448                         value = &e->pos;
1449                         break;
1450                 case HUD_STAT_NAME:
1451                         e->name = luaL_checkstring(L, 4);
1452                         value = &e->name;
1453                         break;
1454                 case HUD_STAT_SCALE:
1455                         e->scale = read_v2f(L, 4);
1456                         value = &e->scale;
1457                         break;
1458                 case HUD_STAT_TEXT:
1459                         e->text = luaL_checkstring(L, 4);
1460                         value = &e->text;
1461                         break;
1462                 case HUD_STAT_NUMBER:
1463                         e->number = luaL_checknumber(L, 4);
1464                         value = &e->number;
1465                         break;
1466                 case HUD_STAT_ITEM:
1467                         e->item = luaL_checknumber(L, 4);
1468                         value = &e->item;
1469                         break;
1470                 case HUD_STAT_DIR:
1471                         e->dir = luaL_checknumber(L, 4);
1472                         value = &e->dir;
1473                         break;
1474                 case HUD_STAT_ALIGN:
1475                         e->align = read_v2f(L, 4);
1476                         value = &e->align;
1477                         break;
1478                 case HUD_STAT_OFFSET:
1479                         e->offset = read_v2f(L, 4);
1480                         value = &e->offset;
1481                         break;
1482                 case HUD_STAT_WORLD_POS:
1483                         e->world_pos = read_v3f(L, 4);
1484                         value = &e->world_pos;
1485                         break;
1486                 case HUD_STAT_SIZE:
1487                         e->size = read_v2s32(L, 4);
1488                         value = &e->size;
1489                         break;
1490         }
1491
1492         getServer(L)->hudChange(player, id, stat, value);
1493
1494         lua_pushboolean(L, true);
1495         return 1;
1496 }
1497
1498 // hud_get(self, id)
1499 int ObjectRef::l_hud_get(lua_State *L)
1500 {
1501         NO_MAP_LOCK_REQUIRED;
1502         ObjectRef *ref = checkobject(L, 1);
1503         RemotePlayer *player = getplayer(ref);
1504         if (player == NULL)
1505                 return 0;
1506
1507         u32 id = lua_tonumber(L, -1);
1508
1509         HudElement *e = player->getHud(id);
1510         if (!e)
1511                 return 0;
1512
1513         lua_newtable(L);
1514
1515         lua_pushstring(L, es_HudElementType[(u8)e->type].str);
1516         lua_setfield(L, -2, "type");
1517
1518         push_v2f(L, e->pos);
1519         lua_setfield(L, -2, "position");
1520
1521         lua_pushstring(L, e->name.c_str());
1522         lua_setfield(L, -2, "name");
1523
1524         push_v2f(L, e->scale);
1525         lua_setfield(L, -2, "scale");
1526
1527         lua_pushstring(L, e->text.c_str());
1528         lua_setfield(L, -2, "text");
1529
1530         lua_pushnumber(L, e->number);
1531         lua_setfield(L, -2, "number");
1532
1533         lua_pushnumber(L, e->item);
1534         lua_setfield(L, -2, "item");
1535
1536         lua_pushnumber(L, e->dir);
1537         lua_setfield(L, -2, "direction");
1538
1539         // Deprecated, only for compatibility's sake
1540         lua_pushnumber(L, e->dir);
1541         lua_setfield(L, -2, "dir");
1542
1543         push_v3f(L, e->world_pos);
1544         lua_setfield(L, -2, "world_pos");
1545
1546         return 1;
1547 }
1548
1549 // hud_set_flags(self, flags)
1550 int ObjectRef::l_hud_set_flags(lua_State *L)
1551 {
1552         NO_MAP_LOCK_REQUIRED;
1553         ObjectRef *ref = checkobject(L, 1);
1554         RemotePlayer *player = getplayer(ref);
1555         if (player == NULL)
1556                 return 0;
1557
1558         u32 flags = 0;
1559         u32 mask  = 0;
1560         bool flag;
1561
1562         const EnumString *esp = es_HudBuiltinElement;
1563         for (int i = 0; esp[i].str; i++) {
1564                 if (getboolfield(L, 2, esp[i].str, flag)) {
1565                         flags |= esp[i].num * flag;
1566                         mask  |= esp[i].num;
1567                 }
1568         }
1569         if (!getServer(L)->hudSetFlags(player, flags, mask))
1570                 return 0;
1571
1572         lua_pushboolean(L, true);
1573         return 1;
1574 }
1575
1576 int ObjectRef::l_hud_get_flags(lua_State *L)
1577 {
1578         NO_MAP_LOCK_REQUIRED;
1579         ObjectRef *ref = checkobject(L, 1);
1580         RemotePlayer *player = getplayer(ref);
1581         if (player == NULL)
1582                 return 0;
1583
1584         lua_newtable(L);
1585         lua_pushboolean(L, player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE);
1586         lua_setfield(L, -2, "hotbar");
1587         lua_pushboolean(L, player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE);
1588         lua_setfield(L, -2, "healthbar");
1589         lua_pushboolean(L, player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE);
1590         lua_setfield(L, -2, "crosshair");
1591         lua_pushboolean(L, player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE);
1592         lua_setfield(L, -2, "wielditem");
1593         lua_pushboolean(L, player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE);
1594         lua_setfield(L, -2, "breathbar");
1595         lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE);
1596         lua_setfield(L, -2, "minimap");
1597         lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE);
1598         lua_setfield(L, -2, "minimap_radar");
1599
1600         return 1;
1601 }
1602
1603 // hud_set_hotbar_itemcount(self, hotbar_itemcount)
1604 int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
1605 {
1606         NO_MAP_LOCK_REQUIRED;
1607         ObjectRef *ref = checkobject(L, 1);
1608         RemotePlayer *player = getplayer(ref);
1609         if (player == NULL)
1610                 return 0;
1611
1612         s32 hotbar_itemcount = lua_tonumber(L, 2);
1613
1614         if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
1615                 return 0;
1616
1617         lua_pushboolean(L, true);
1618         return 1;
1619 }
1620
1621 // hud_get_hotbar_itemcount(self)
1622 int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L)
1623 {
1624         NO_MAP_LOCK_REQUIRED;
1625         ObjectRef *ref = checkobject(L, 1);
1626         RemotePlayer *player = getplayer(ref);
1627         if (player == NULL)
1628                 return 0;
1629
1630         s32 hotbar_itemcount = getServer(L)->hudGetHotbarItemcount(player);
1631
1632         lua_pushnumber(L, hotbar_itemcount);
1633         return 1;
1634 }
1635
1636 // hud_set_hotbar_image(self, name)
1637 int ObjectRef::l_hud_set_hotbar_image(lua_State *L)
1638 {
1639         NO_MAP_LOCK_REQUIRED;
1640         ObjectRef *ref = checkobject(L, 1);
1641         RemotePlayer *player = getplayer(ref);
1642         if (player == NULL)
1643                 return 0;
1644
1645         std::string name = lua_tostring(L, 2);
1646
1647         getServer(L)->hudSetHotbarImage(player, name);
1648         return 1;
1649 }
1650
1651 // hud_get_hotbar_image(self)
1652 int ObjectRef::l_hud_get_hotbar_image(lua_State *L)
1653 {
1654         NO_MAP_LOCK_REQUIRED;
1655         ObjectRef *ref = checkobject(L, 1);
1656         RemotePlayer *player = getplayer(ref);
1657         if (player == NULL)
1658                 return 0;
1659
1660         std::string name = getServer(L)->hudGetHotbarImage(player);
1661         lua_pushlstring(L, name.c_str(), name.size());
1662         return 1;
1663 }
1664
1665 // hud_set_hotbar_selected_image(self, name)
1666 int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L)
1667 {
1668         NO_MAP_LOCK_REQUIRED;
1669         ObjectRef *ref = checkobject(L, 1);
1670         RemotePlayer *player = getplayer(ref);
1671         if (player == NULL)
1672                 return 0;
1673
1674         std::string name = lua_tostring(L, 2);
1675
1676         getServer(L)->hudSetHotbarSelectedImage(player, name);
1677         return 1;
1678 }
1679
1680 // hud_get_hotbar_selected_image(self)
1681 int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L)
1682 {
1683         NO_MAP_LOCK_REQUIRED;
1684         ObjectRef *ref = checkobject(L, 1);
1685         RemotePlayer *player = getplayer(ref);
1686         if (player == NULL)
1687                 return 0;
1688
1689         const std::string &name = getServer(L)->hudGetHotbarSelectedImage(player);
1690         lua_pushlstring(L, name.c_str(), name.size());
1691         return 1;
1692 }
1693
1694 // set_sky(self, bgcolor, type, list, clouds = true)
1695 int ObjectRef::l_set_sky(lua_State *L)
1696 {
1697         NO_MAP_LOCK_REQUIRED;
1698         ObjectRef *ref = checkobject(L, 1);
1699         RemotePlayer *player = getplayer(ref);
1700         if (player == NULL)
1701                 return 0;
1702
1703         video::SColor bgcolor(255,255,255,255);
1704         read_color(L, 2, &bgcolor);
1705
1706         std::string type = luaL_checkstring(L, 3);
1707
1708         std::vector<std::string> params;
1709         if (lua_istable(L, 4)) {
1710                 lua_pushnil(L);
1711                 while (lua_next(L, 4) != 0) {
1712                         // key at index -2 and value at index -1
1713                         if (lua_isstring(L, -1))
1714                                 params.emplace_back(lua_tostring(L, -1));
1715                         else
1716                                 params.emplace_back("");
1717                         // removes value, keeps key for next iteration
1718                         lua_pop(L, 1);
1719                 }
1720         }
1721
1722         if (type == "skybox" && params.size() != 6)
1723                 throw LuaError("skybox expects 6 textures");
1724
1725         bool clouds = true;
1726         if (lua_isboolean(L, 5))
1727                 clouds = lua_toboolean(L, 5);
1728
1729         if (!getServer(L)->setSky(player, bgcolor, type, params, clouds))
1730                 return 0;
1731
1732         lua_pushboolean(L, true);
1733         return 1;
1734 }
1735
1736 // get_sky(self)
1737 int ObjectRef::l_get_sky(lua_State *L)
1738 {
1739         NO_MAP_LOCK_REQUIRED;
1740         ObjectRef *ref = checkobject(L, 1);
1741         RemotePlayer *player = getplayer(ref);
1742         if (player == NULL)
1743                 return 0;
1744         video::SColor bgcolor(255, 255, 255, 255);
1745         std::string type;
1746         std::vector<std::string> params;
1747         bool clouds;
1748
1749         player->getSky(&bgcolor, &type, &params, &clouds);
1750         type = type.empty() ? "regular" : type;
1751
1752         push_ARGB8(L, bgcolor);
1753         lua_pushlstring(L, type.c_str(), type.size());
1754         lua_newtable(L);
1755         s16 i = 1;
1756         for (const std::string &param : params) {
1757                 lua_pushlstring(L, param.c_str(), param.size());
1758                 lua_rawseti(L, -2, i);
1759                 i++;
1760         }
1761         lua_pushboolean(L, clouds);
1762         return 4;
1763 }
1764
1765 // set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=})
1766 int ObjectRef::l_set_clouds(lua_State *L)
1767 {
1768         NO_MAP_LOCK_REQUIRED;
1769         ObjectRef *ref = checkobject(L, 1);
1770         RemotePlayer *player = getplayer(ref);
1771         if (!player)
1772                 return 0;
1773         if (!lua_istable(L, 2))
1774                 return 0;
1775
1776         CloudParams cloud_params = player->getCloudParams();
1777
1778         cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density);
1779
1780         lua_getfield(L, 2, "color");
1781         if (!lua_isnil(L, -1))
1782                 read_color(L, -1, &cloud_params.color_bright);
1783         lua_pop(L, 1);
1784         lua_getfield(L, 2, "ambient");
1785         if (!lua_isnil(L, -1))
1786                 read_color(L, -1, &cloud_params.color_ambient);
1787         lua_pop(L, 1);
1788
1789         cloud_params.height    = getfloatfield_default(L, 2, "height",    cloud_params.height   );
1790         cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness);
1791
1792         lua_getfield(L, 2, "speed");
1793         if (lua_istable(L, -1)) {
1794                 v2f new_speed;
1795                 new_speed.X = getfloatfield_default(L, -1, "x", 0);
1796                 new_speed.Y = getfloatfield_default(L, -1, "z", 0);
1797                 cloud_params.speed = new_speed;
1798         }
1799         lua_pop(L, 1);
1800
1801         if (!getServer(L)->setClouds(player, cloud_params.density,
1802                         cloud_params.color_bright, cloud_params.color_ambient,
1803                         cloud_params.height, cloud_params.thickness,
1804                         cloud_params.speed))
1805                 return 0;
1806
1807         player->setCloudParams(cloud_params);
1808
1809         lua_pushboolean(L, true);
1810         return 1;
1811 }
1812
1813 int ObjectRef::l_get_clouds(lua_State *L)
1814 {
1815         NO_MAP_LOCK_REQUIRED;
1816         ObjectRef *ref = checkobject(L, 1);
1817         RemotePlayer *player = getplayer(ref);
1818         if (!player)
1819                 return 0;
1820         const CloudParams &cloud_params = player->getCloudParams();
1821
1822         lua_newtable(L);
1823         lua_pushnumber(L, cloud_params.density);
1824         lua_setfield(L, -2, "density");
1825         push_ARGB8(L, cloud_params.color_bright);
1826         lua_setfield(L, -2, "color");
1827         push_ARGB8(L, cloud_params.color_ambient);
1828         lua_setfield(L, -2, "ambient");
1829         lua_pushnumber(L, cloud_params.height);
1830         lua_setfield(L, -2, "height");
1831         lua_pushnumber(L, cloud_params.thickness);
1832         lua_setfield(L, -2, "thickness");
1833         lua_newtable(L);
1834         lua_pushnumber(L, cloud_params.speed.X);
1835         lua_setfield(L, -2, "x");
1836         lua_pushnumber(L, cloud_params.speed.Y);
1837         lua_setfield(L, -2, "y");
1838         lua_setfield(L, -2, "speed");
1839
1840         return 1;
1841 }
1842
1843
1844 // override_day_night_ratio(self, brightness=0...1)
1845 int ObjectRef::l_override_day_night_ratio(lua_State *L)
1846 {
1847         NO_MAP_LOCK_REQUIRED;
1848         ObjectRef *ref = checkobject(L, 1);
1849         RemotePlayer *player = getplayer(ref);
1850         if (player == NULL)
1851                 return 0;
1852
1853         bool do_override = false;
1854         float ratio = 0.0f;
1855         if (!lua_isnil(L, 2)) {
1856                 do_override = true;
1857                 ratio = luaL_checknumber(L, 2);
1858         }
1859
1860         if (!getServer(L)->overrideDayNightRatio(player, do_override, ratio))
1861                 return 0;
1862
1863         lua_pushboolean(L, true);
1864         return 1;
1865 }
1866
1867 // get_day_night_ratio(self)
1868 int ObjectRef::l_get_day_night_ratio(lua_State *L)
1869 {
1870         NO_MAP_LOCK_REQUIRED;
1871         ObjectRef *ref = checkobject(L, 1);
1872         RemotePlayer *player = getplayer(ref);
1873         if (player == NULL)
1874                 return 0;
1875
1876         bool do_override;
1877         float ratio;
1878         player->getDayNightRatio(&do_override, &ratio);
1879
1880         if (do_override)
1881                 lua_pushnumber(L, ratio);
1882         else
1883                 lua_pushnil(L);
1884
1885         return 1;
1886 }
1887
1888 ObjectRef::ObjectRef(ServerActiveObject *object):
1889         m_object(object)
1890 {
1891         //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1892 }
1893
1894 // Creates an ObjectRef and leaves it on top of stack
1895 // Not callable from Lua; all references are created on the C side.
1896 void ObjectRef::create(lua_State *L, ServerActiveObject *object)
1897 {
1898         ObjectRef *o = new ObjectRef(object);
1899         //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1900         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1901         luaL_getmetatable(L, className);
1902         lua_setmetatable(L, -2);
1903 }
1904
1905 void ObjectRef::set_null(lua_State *L)
1906 {
1907         ObjectRef *o = checkobject(L, -1);
1908         o->m_object = NULL;
1909 }
1910
1911 void ObjectRef::Register(lua_State *L)
1912 {
1913         lua_newtable(L);
1914         int methodtable = lua_gettop(L);
1915         luaL_newmetatable(L, className);
1916         int metatable = lua_gettop(L);
1917
1918         lua_pushliteral(L, "__metatable");
1919         lua_pushvalue(L, methodtable);
1920         lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1921
1922         lua_pushliteral(L, "__index");
1923         lua_pushvalue(L, methodtable);
1924         lua_settable(L, metatable);
1925
1926         lua_pushliteral(L, "__gc");
1927         lua_pushcfunction(L, gc_object);
1928         lua_settable(L, metatable);
1929
1930         lua_pop(L, 1);  // drop metatable
1931
1932         luaL_openlib(L, 0, methods, 0);  // fill methodtable
1933         lua_pop(L, 1);  // drop methodtable
1934
1935         // Cannot be created from Lua
1936         //lua_register(L, className, create_object);
1937 }
1938
1939 const char ObjectRef::className[] = "ObjectRef";
1940 const luaL_Reg ObjectRef::methods[] = {
1941         // ServerActiveObject
1942         luamethod(ObjectRef, remove),
1943         luamethod_aliased(ObjectRef, get_pos, getpos),
1944         luamethod_aliased(ObjectRef, set_pos, setpos),
1945         luamethod_aliased(ObjectRef, move_to, moveto),
1946         luamethod(ObjectRef, punch),
1947         luamethod(ObjectRef, right_click),
1948         luamethod(ObjectRef, set_hp),
1949         luamethod(ObjectRef, get_hp),
1950         luamethod(ObjectRef, get_inventory),
1951         luamethod(ObjectRef, get_wield_list),
1952         luamethod(ObjectRef, get_wield_index),
1953         luamethod(ObjectRef, get_wielded_item),
1954         luamethod(ObjectRef, set_wielded_item),
1955         luamethod(ObjectRef, set_armor_groups),
1956         luamethod(ObjectRef, get_armor_groups),
1957         luamethod(ObjectRef, set_animation),
1958         luamethod(ObjectRef, get_animation),
1959         luamethod(ObjectRef, set_animation_frame_speed),
1960         luamethod(ObjectRef, set_bone_position),
1961         luamethod(ObjectRef, get_bone_position),
1962         luamethod(ObjectRef, set_attach),
1963         luamethod(ObjectRef, get_attach),
1964         luamethod(ObjectRef, set_detach),
1965         luamethod(ObjectRef, set_properties),
1966         luamethod(ObjectRef, get_properties),
1967         luamethod(ObjectRef, set_nametag_attributes),
1968         luamethod(ObjectRef, get_nametag_attributes),
1969         // LuaEntitySAO-only
1970         luamethod_aliased(ObjectRef, set_velocity, setvelocity),
1971         luamethod_aliased(ObjectRef, get_velocity, getvelocity),
1972         luamethod_aliased(ObjectRef, set_acceleration, setacceleration),
1973         luamethod_aliased(ObjectRef, get_acceleration, getacceleration),
1974         luamethod_aliased(ObjectRef, set_yaw, setyaw),
1975         luamethod_aliased(ObjectRef, get_yaw, getyaw),
1976         luamethod_aliased(ObjectRef, set_texture_mod, settexturemod),
1977         luamethod_aliased(ObjectRef, set_sprite, setsprite),
1978         luamethod(ObjectRef, get_entity_name),
1979         luamethod(ObjectRef, get_luaentity),
1980         // Player-only
1981         luamethod(ObjectRef, is_player),
1982         luamethod(ObjectRef, is_player_connected),
1983         luamethod(ObjectRef, get_player_name),
1984         luamethod(ObjectRef, get_player_velocity),
1985         luamethod(ObjectRef, get_look_dir),
1986         luamethod(ObjectRef, get_look_pitch),
1987         luamethod(ObjectRef, get_look_yaw),
1988         luamethod(ObjectRef, get_look_vertical),
1989         luamethod(ObjectRef, get_look_horizontal),
1990         luamethod(ObjectRef, set_look_horizontal),
1991         luamethod(ObjectRef, set_look_vertical),
1992         luamethod(ObjectRef, set_look_yaw),
1993         luamethod(ObjectRef, set_look_pitch),
1994         luamethod(ObjectRef, get_breath),
1995         luamethod(ObjectRef, set_breath),
1996         luamethod(ObjectRef, get_attribute),
1997         luamethod(ObjectRef, set_attribute),
1998         luamethod(ObjectRef, set_inventory_formspec),
1999         luamethod(ObjectRef, get_inventory_formspec),
2000         luamethod(ObjectRef, get_player_control),
2001         luamethod(ObjectRef, get_player_control_bits),
2002         luamethod(ObjectRef, set_physics_override),
2003         luamethod(ObjectRef, get_physics_override),
2004         luamethod(ObjectRef, hud_add),
2005         luamethod(ObjectRef, hud_remove),
2006         luamethod(ObjectRef, hud_change),
2007         luamethod(ObjectRef, hud_get),
2008         luamethod(ObjectRef, hud_set_flags),
2009         luamethod(ObjectRef, hud_get_flags),
2010         luamethod(ObjectRef, hud_set_hotbar_itemcount),
2011         luamethod(ObjectRef, hud_get_hotbar_itemcount),
2012         luamethod(ObjectRef, hud_set_hotbar_image),
2013         luamethod(ObjectRef, hud_get_hotbar_image),
2014         luamethod(ObjectRef, hud_set_hotbar_selected_image),
2015         luamethod(ObjectRef, hud_get_hotbar_selected_image),
2016         luamethod(ObjectRef, set_sky),
2017         luamethod(ObjectRef, get_sky),
2018         luamethod(ObjectRef, set_clouds),
2019         luamethod(ObjectRef, get_clouds),
2020         luamethod(ObjectRef, override_day_night_ratio),
2021         luamethod(ObjectRef, get_day_night_ratio),
2022         luamethod(ObjectRef, set_local_animation),
2023         luamethod(ObjectRef, get_local_animation),
2024         luamethod(ObjectRef, set_eye_offset),
2025         luamethod(ObjectRef, get_eye_offset),
2026         {0,0}
2027 };