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