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