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