Add player:set_eye_offset() by @MirceaKitsune and clean up
[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/idle}, {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_eye_offset(self, v3f first pv, v3f third pv)
435 int ObjectRef::l_set_eye_offset(lua_State *L)
436 {
437         //NO_MAP_LOCK_REQUIRED;
438         ObjectRef *ref = checkobject(L, 1);
439         Player *player = getplayer(ref);
440         if (player == NULL)
441                 return 0;
442         // Do it
443         v3f offset_first = v3f(0, 0, 0);
444         v3f offset_third = v3f(0, 0, 0);
445         
446         if(!lua_isnil(L, 2))
447                 offset_first = read_v3f(L, 2);
448         if(!lua_isnil(L, 3))
449                 offset_third = read_v3f(L, 3);
450
451         // Prevent abuse of offset values (keep player always visible)
452         offset_third.X = rangelim(offset_third.X,-10,10);
453         offset_third.Z = rangelim(offset_third.Z,-5,5);
454         /* TODO: if possible: improve the camera colision detetion to allow Y <= -1.5) */
455         offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS
456
457         if (!getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third))
458                 return 0;
459
460         lua_pushboolean(L, true);
461         return 0;
462 }
463
464 // set_bone_position(self, std::string bone, v3f position, v3f rotation)
465 int ObjectRef::l_set_bone_position(lua_State *L)
466 {
467         NO_MAP_LOCK_REQUIRED;
468         ObjectRef *ref = checkobject(L, 1);
469         ServerActiveObject *co = getobject(ref);
470         if(co == NULL) return 0;
471         // Do it
472         std::string bone = "";
473         if(!lua_isnil(L, 2))
474                 bone = lua_tostring(L, 2);
475         v3f position = v3f(0, 0, 0);
476         if(!lua_isnil(L, 3))
477                 position = read_v3f(L, 3);
478         v3f rotation = v3f(0, 0, 0);
479         if(!lua_isnil(L, 4))
480                 rotation = read_v3f(L, 4);
481         co->setBonePosition(bone, position, rotation);
482         return 0;
483 }
484
485 // set_attach(self, parent, bone, position, rotation)
486 int ObjectRef::l_set_attach(lua_State *L)
487 {
488         NO_MAP_LOCK_REQUIRED;
489         ObjectRef *ref = checkobject(L, 1);
490         ObjectRef *parent_ref = checkobject(L, 2);
491         ServerActiveObject *co = getobject(ref);
492         ServerActiveObject *parent = getobject(parent_ref);
493         if(co == NULL) return 0;
494         if(parent == NULL) return 0;
495         // Do it
496         std::string bone = "";
497         if(!lua_isnil(L, 3))
498                 bone = lua_tostring(L, 3);
499         v3f position = v3f(0, 0, 0);
500         if(!lua_isnil(L, 4))
501                 position = read_v3f(L, 4);
502         v3f rotation = v3f(0, 0, 0);
503         if(!lua_isnil(L, 5))
504                 rotation = read_v3f(L, 5);
505         co->setAttachment(parent->getId(), bone, position, rotation);
506         return 0;
507 }
508
509 // set_detach(self)
510 int ObjectRef::l_set_detach(lua_State *L)
511 {
512         NO_MAP_LOCK_REQUIRED;
513         ObjectRef *ref = checkobject(L, 1);
514         ServerActiveObject *co = getobject(ref);
515         if(co == NULL) return 0;
516         // Do it
517         co->setAttachment(0, "", v3f(0,0,0), v3f(0,0,0));
518         return 0;
519 }
520
521 // set_properties(self, properties)
522 int ObjectRef::l_set_properties(lua_State *L)
523 {
524         NO_MAP_LOCK_REQUIRED;
525         ObjectRef *ref = checkobject(L, 1);
526         ServerActiveObject *co = getobject(ref);
527         if(co == NULL) return 0;
528         ObjectProperties *prop = co->accessObjectProperties();
529         if(!prop)
530                 return 0;
531         read_object_properties(L, 2, prop);
532         co->notifyObjectPropertiesModified();
533         return 0;
534 }
535
536 /* LuaEntitySAO-only */
537
538 // setvelocity(self, {x=num, y=num, z=num})
539 int ObjectRef::l_setvelocity(lua_State *L)
540 {
541         NO_MAP_LOCK_REQUIRED;
542         ObjectRef *ref = checkobject(L, 1);
543         LuaEntitySAO *co = getluaobject(ref);
544         if(co == NULL) return 0;
545         v3f pos = checkFloatPos(L, 2);
546         // Do it
547         co->setVelocity(pos);
548         return 0;
549 }
550
551 // getvelocity(self)
552 int ObjectRef::l_getvelocity(lua_State *L)
553 {
554         NO_MAP_LOCK_REQUIRED;
555         ObjectRef *ref = checkobject(L, 1);
556         LuaEntitySAO *co = getluaobject(ref);
557         if(co == NULL) return 0;
558         // Do it
559         v3f v = co->getVelocity();
560         pushFloatPos(L, v);
561         return 1;
562 }
563
564 // setacceleration(self, {x=num, y=num, z=num})
565 int ObjectRef::l_setacceleration(lua_State *L)
566 {
567         NO_MAP_LOCK_REQUIRED;
568         ObjectRef *ref = checkobject(L, 1);
569         LuaEntitySAO *co = getluaobject(ref);
570         if(co == NULL) return 0;
571         // pos
572         v3f pos = checkFloatPos(L, 2);
573         // Do it
574         co->setAcceleration(pos);
575         return 0;
576 }
577
578 // getacceleration(self)
579 int ObjectRef::l_getacceleration(lua_State *L)
580 {
581         NO_MAP_LOCK_REQUIRED;
582         ObjectRef *ref = checkobject(L, 1);
583         LuaEntitySAO *co = getluaobject(ref);
584         if(co == NULL) return 0;
585         // Do it
586         v3f v = co->getAcceleration();
587         pushFloatPos(L, v);
588         return 1;
589 }
590
591 // setyaw(self, radians)
592 int ObjectRef::l_setyaw(lua_State *L)
593 {
594         NO_MAP_LOCK_REQUIRED;
595         ObjectRef *ref = checkobject(L, 1);
596         LuaEntitySAO *co = getluaobject(ref);
597         if(co == NULL) return 0;
598         float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
599         // Do it
600         co->setYaw(yaw);
601         return 0;
602 }
603
604 // getyaw(self)
605 int ObjectRef::l_getyaw(lua_State *L)
606 {
607         NO_MAP_LOCK_REQUIRED;
608         ObjectRef *ref = checkobject(L, 1);
609         LuaEntitySAO *co = getluaobject(ref);
610         if(co == NULL) return 0;
611         // Do it
612         float yaw = co->getYaw() * core::DEGTORAD;
613         lua_pushnumber(L, yaw);
614         return 1;
615 }
616
617 // settexturemod(self, mod)
618 int ObjectRef::l_settexturemod(lua_State *L)
619 {
620         NO_MAP_LOCK_REQUIRED;
621         ObjectRef *ref = checkobject(L, 1);
622         LuaEntitySAO *co = getluaobject(ref);
623         if(co == NULL) return 0;
624         // Do it
625         std::string mod = luaL_checkstring(L, 2);
626         co->setTextureMod(mod);
627         return 0;
628 }
629
630 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
631 //           select_horiz_by_yawpitch=false)
632 int ObjectRef::l_setsprite(lua_State *L)
633 {
634         NO_MAP_LOCK_REQUIRED;
635         ObjectRef *ref = checkobject(L, 1);
636         LuaEntitySAO *co = getluaobject(ref);
637         if(co == NULL) return 0;
638         // Do it
639         v2s16 p(0,0);
640         if(!lua_isnil(L, 2))
641                 p = read_v2s16(L, 2);
642         int num_frames = 1;
643         if(!lua_isnil(L, 3))
644                 num_frames = lua_tonumber(L, 3);
645         float framelength = 0.2;
646         if(!lua_isnil(L, 4))
647                 framelength = lua_tonumber(L, 4);
648         bool select_horiz_by_yawpitch = false;
649         if(!lua_isnil(L, 5))
650                 select_horiz_by_yawpitch = lua_toboolean(L, 5);
651         co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
652         return 0;
653 }
654
655 // DEPRECATED
656 // get_entity_name(self)
657 int ObjectRef::l_get_entity_name(lua_State *L)
658 {
659         NO_MAP_LOCK_REQUIRED;
660         ObjectRef *ref = checkobject(L, 1);
661         LuaEntitySAO *co = getluaobject(ref);
662         if(co == NULL) return 0;
663         // Do it
664         std::string name = co->getName();
665         lua_pushstring(L, name.c_str());
666         return 1;
667 }
668
669 // get_luaentity(self)
670 int ObjectRef::l_get_luaentity(lua_State *L)
671 {
672         NO_MAP_LOCK_REQUIRED;
673         ObjectRef *ref = checkobject(L, 1);
674         LuaEntitySAO *co = getluaobject(ref);
675         if(co == NULL) return 0;
676         // Do it
677         luaentity_get(L, co->getId());
678         return 1;
679 }
680
681 /* Player-only */
682
683 // is_player(self)
684 int ObjectRef::l_is_player(lua_State *L)
685 {
686         NO_MAP_LOCK_REQUIRED;
687         ObjectRef *ref = checkobject(L, 1);
688         Player *player = getplayer(ref);
689         lua_pushboolean(L, (player != NULL));
690         return 1;
691 }
692
693 // is_player_connected(self)
694 int ObjectRef::l_is_player_connected(lua_State *L)
695 {
696         NO_MAP_LOCK_REQUIRED;
697         ObjectRef *ref = checkobject(L, 1);
698         Player *player = getplayer(ref);
699         lua_pushboolean(L, (player != NULL && player->peer_id != 0));
700         return 1;
701 }
702
703 // get_player_name(self)
704 int ObjectRef::l_get_player_name(lua_State *L)
705 {
706         NO_MAP_LOCK_REQUIRED;
707         ObjectRef *ref = checkobject(L, 1);
708         Player *player = getplayer(ref);
709         if(player == NULL){
710                 lua_pushlstring(L, "", 0);
711                 return 1;
712         }
713         // Do it
714         lua_pushstring(L, player->getName());
715         return 1;
716 }
717
718 // get_look_dir(self)
719 int ObjectRef::l_get_look_dir(lua_State *L)
720 {
721         NO_MAP_LOCK_REQUIRED;
722         ObjectRef *ref = checkobject(L, 1);
723         Player *player = getplayer(ref);
724         if(player == NULL) return 0;
725         // Do it
726         float pitch = player->getRadPitch();
727         float yaw = player->getRadYaw();
728         v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
729         push_v3f(L, v);
730         return 1;
731 }
732
733 // get_look_pitch(self)
734 int ObjectRef::l_get_look_pitch(lua_State *L)
735 {
736         NO_MAP_LOCK_REQUIRED;
737         ObjectRef *ref = checkobject(L, 1);
738         Player *player = getplayer(ref);
739         if(player == NULL) return 0;
740         // Do it
741         lua_pushnumber(L, player->getRadPitch());
742         return 1;
743 }
744
745 // get_look_yaw(self)
746 int ObjectRef::l_get_look_yaw(lua_State *L)
747 {
748         NO_MAP_LOCK_REQUIRED;
749         ObjectRef *ref = checkobject(L, 1);
750         Player *player = getplayer(ref);
751         if(player == NULL) return 0;
752         // Do it
753         lua_pushnumber(L, player->getRadYaw());
754         return 1;
755 }
756
757 // set_look_pitch(self, radians)
758 int ObjectRef::l_set_look_pitch(lua_State *L)
759 {
760         NO_MAP_LOCK_REQUIRED;
761         ObjectRef *ref = checkobject(L, 1);
762         PlayerSAO* co = getplayersao(ref);
763         if(co == NULL) return 0;
764         float pitch = luaL_checknumber(L, 2) * core::RADTODEG;
765         // Do it
766         co->setPitch(pitch);
767         return 1;
768 }
769
770 // set_look_yaw(self, radians)
771 int ObjectRef::l_set_look_yaw(lua_State *L)
772 {
773         NO_MAP_LOCK_REQUIRED;
774         ObjectRef *ref = checkobject(L, 1);
775         PlayerSAO* co = getplayersao(ref);
776         if(co == NULL) return 0;
777         float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
778         // Do it
779         co->setYaw(yaw);
780         return 1;
781 }
782
783 // set_breath(self, breath)
784 int ObjectRef::l_set_breath(lua_State *L)
785 {
786         NO_MAP_LOCK_REQUIRED;
787         ObjectRef *ref = checkobject(L, 1);
788         PlayerSAO* co = getplayersao(ref);
789         if(co == NULL) return 0;
790         u16 breath = luaL_checknumber(L, 2);
791         // Do it
792         co->setBreath(breath);
793         co->m_breath_not_sent = true;
794         return 0;
795 }
796
797 // get_breath(self)
798 int ObjectRef::l_get_breath(lua_State *L)
799 {
800         NO_MAP_LOCK_REQUIRED;
801         ObjectRef *ref = checkobject(L, 1);
802         PlayerSAO* co = getplayersao(ref);
803         if(co == NULL) return 0;
804         // Do it
805         u16 breath = co->getBreath();
806         lua_pushinteger (L, breath);
807         return 1;
808 }
809
810 // set_inventory_formspec(self, formspec)
811 int ObjectRef::l_set_inventory_formspec(lua_State *L)
812 {
813         NO_MAP_LOCK_REQUIRED;
814         ObjectRef *ref = checkobject(L, 1);
815         Player *player = getplayer(ref);
816         if(player == NULL) return 0;
817         std::string formspec = luaL_checkstring(L, 2);
818
819         player->inventory_formspec = formspec;
820         getServer(L)->reportInventoryFormspecModified(player->getName());
821         lua_pushboolean(L, true);
822         return 1;
823 }
824
825 // get_inventory_formspec(self) -> formspec
826 int ObjectRef::l_get_inventory_formspec(lua_State *L)
827 {
828         NO_MAP_LOCK_REQUIRED;
829         ObjectRef *ref = checkobject(L, 1);
830         Player *player = getplayer(ref);
831         if(player == NULL) return 0;
832
833         std::string formspec = player->inventory_formspec;
834         lua_pushlstring(L, formspec.c_str(), formspec.size());
835         return 1;
836 }
837
838 // get_player_control(self)
839 int ObjectRef::l_get_player_control(lua_State *L)
840 {
841         NO_MAP_LOCK_REQUIRED;
842         ObjectRef *ref = checkobject(L, 1);
843         Player *player = getplayer(ref);
844         if(player == NULL){
845                 lua_pushlstring(L, "", 0);
846                 return 1;
847         }
848         // Do it
849         PlayerControl control = player->getPlayerControl();
850         lua_newtable(L);
851         lua_pushboolean(L, control.up);
852         lua_setfield(L, -2, "up");
853         lua_pushboolean(L, control.down);
854         lua_setfield(L, -2, "down");
855         lua_pushboolean(L, control.left);
856         lua_setfield(L, -2, "left");
857         lua_pushboolean(L, control.right);
858         lua_setfield(L, -2, "right");
859         lua_pushboolean(L, control.jump);
860         lua_setfield(L, -2, "jump");
861         lua_pushboolean(L, control.aux1);
862         lua_setfield(L, -2, "aux1");
863         lua_pushboolean(L, control.sneak);
864         lua_setfield(L, -2, "sneak");
865         lua_pushboolean(L, control.LMB);
866         lua_setfield(L, -2, "LMB");
867         lua_pushboolean(L, control.RMB);
868         lua_setfield(L, -2, "RMB");
869         return 1;
870 }
871
872 // get_player_control_bits(self)
873 int ObjectRef::l_get_player_control_bits(lua_State *L)
874 {
875         NO_MAP_LOCK_REQUIRED;
876         ObjectRef *ref = checkobject(L, 1);
877         Player *player = getplayer(ref);
878         if(player == NULL){
879                 lua_pushlstring(L, "", 0);
880                 return 1;
881         }
882         // Do it
883         lua_pushnumber(L, player->keyPressed);
884         return 1;
885 }
886
887 // hud_add(self, form)
888 int ObjectRef::l_hud_add(lua_State *L)
889 {
890         ObjectRef *ref = checkobject(L, 1);
891         Player *player = getplayer(ref);
892         if (player == NULL)
893                 return 0;
894
895         HudElement *elem = new HudElement;
896
897         elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type",
898                                                                 es_HudElementType, HUD_ELEM_TEXT);
899
900         lua_getfield(L, 2, "position");
901         elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
902         lua_pop(L, 1);
903
904         lua_getfield(L, 2, "scale");
905         elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
906         lua_pop(L, 1);
907
908         elem->name   = getstringfield_default(L, 2, "name", "");
909         elem->text   = getstringfield_default(L, 2, "text", "");
910         elem->number = getintfield_default(L, 2, "number", 0);
911         elem->item   = getintfield_default(L, 2, "item", 0);
912         elem->dir    = getintfield_default(L, 2, "dir", 0);
913
914         lua_getfield(L, 2, "alignment");
915         elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
916         lua_pop(L, 1);
917
918         lua_getfield(L, 2, "offset");
919         elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
920         lua_pop(L, 1);
921
922         lua_getfield(L, 2, "world_pos");
923         elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
924         lua_pop(L, 1);
925
926         u32 id = getServer(L)->hudAdd(player, elem);
927         if (id == (u32)-1) {
928                 delete elem;
929                 return 0;
930         }
931
932         lua_pushnumber(L, id);
933         return 1;
934 }
935
936 // hud_remove(self, id)
937 int ObjectRef::l_hud_remove(lua_State *L)
938 {
939         ObjectRef *ref = checkobject(L, 1);
940         Player *player = getplayer(ref);
941         if (player == NULL)
942                 return 0;
943
944         u32 id = -1;
945         if (!lua_isnil(L, 2))
946                 id = lua_tonumber(L, 2);
947
948         if (!getServer(L)->hudRemove(player, id))
949                 return 0;
950
951         lua_pushboolean(L, true);
952         return 1;
953 }
954
955 // hud_change(self, id, stat, data)
956 int ObjectRef::l_hud_change(lua_State *L)
957 {
958         ObjectRef *ref = checkobject(L, 1);
959         Player *player = getplayer(ref);
960         if (player == NULL)
961                 return 0;
962
963         u32 id = !lua_isnil(L, 2) ? lua_tonumber(L, 2) : -1;
964         if (id >= player->hud.size())
965                 return 0;
966
967         HudElementStat stat = HUD_STAT_NUMBER;
968         if (!lua_isnil(L, 3)) {
969                 int statint;
970                 std::string statstr = lua_tostring(L, 3);
971                 stat = string_to_enum(es_HudElementStat, statint, statstr) ?
972                                 (HudElementStat)statint : HUD_STAT_NUMBER;
973         }
974
975         void *value = NULL;
976         HudElement *e = player->hud[id];
977         if (!e)
978                 return 0;
979
980         switch (stat) {
981                 case HUD_STAT_POS:
982                         e->pos = read_v2f(L, 4);
983                         value = &e->pos;
984                         break;
985                 case HUD_STAT_NAME:
986                         e->name = lua_tostring(L, 4);
987                         value = &e->name;
988                         break;
989                 case HUD_STAT_SCALE:
990                         e->scale = read_v2f(L, 4);
991                         value = &e->scale;
992                         break;
993                 case HUD_STAT_TEXT:
994                         e->text = lua_tostring(L, 4);
995                         value = &e->text;
996                         break;
997                 case HUD_STAT_NUMBER:
998                         e->number = lua_tonumber(L, 4);
999                         value = &e->number;
1000                         break;
1001                 case HUD_STAT_ITEM:
1002                         e->item = lua_tonumber(L, 4);
1003                         value = &e->item;
1004                         break;
1005                 case HUD_STAT_DIR:
1006                         e->dir = lua_tonumber(L, 4);
1007                         value = &e->dir;
1008                         break;
1009                 case HUD_STAT_ALIGN:
1010                         e->align = read_v2f(L, 4);
1011                         value = &e->align;
1012                         break;
1013                 case HUD_STAT_OFFSET:
1014                         e->offset = read_v2f(L, 4);
1015                         value = &e->offset;
1016                         break;
1017                 case HUD_STAT_WORLD_POS:
1018                         e->world_pos = read_v3f(L, 4);
1019                         value = &e->world_pos;
1020                         break;
1021         }
1022
1023         getServer(L)->hudChange(player, id, stat, value);
1024
1025         lua_pushboolean(L, true);
1026         return 1;
1027 }
1028
1029 // hud_get(self, id)
1030 int ObjectRef::l_hud_get(lua_State *L)
1031 {
1032         ObjectRef *ref = checkobject(L, 1);
1033         Player *player = getplayer(ref);
1034         if (player == NULL)
1035                 return 0;
1036
1037         u32 id = lua_tonumber(L, -1);
1038         if (id >= player->hud.size())
1039                 return 0;
1040
1041         HudElement *e = player->hud[id];
1042         if (!e)
1043                 return 0;
1044
1045         lua_newtable(L);
1046
1047         lua_pushstring(L, es_HudElementType[(u8)e->type].str);
1048         lua_setfield(L, -2, "type");
1049
1050         push_v2f(L, e->pos);
1051         lua_setfield(L, -2, "position");
1052
1053         lua_pushstring(L, e->name.c_str());
1054         lua_setfield(L, -2, "name");
1055
1056         push_v2f(L, e->scale);
1057         lua_setfield(L, -2, "scale");
1058
1059         lua_pushstring(L, e->text.c_str());
1060         lua_setfield(L, -2, "text");
1061
1062         lua_pushnumber(L, e->number);
1063         lua_setfield(L, -2, "number");
1064
1065         lua_pushnumber(L, e->item);
1066         lua_setfield(L, -2, "item");
1067
1068         lua_pushnumber(L, e->dir);
1069         lua_setfield(L, -2, "dir");
1070
1071         push_v3f(L, e->world_pos);
1072         lua_setfield(L, -2, "world_pos");
1073
1074         return 1;
1075 }
1076
1077 // hud_set_flags(self, flags)
1078 int ObjectRef::l_hud_set_flags(lua_State *L)
1079 {
1080         ObjectRef *ref = checkobject(L, 1);
1081         Player *player = getplayer(ref);
1082         if (player == NULL)
1083                 return 0;
1084
1085         u32 flags = 0;
1086         u32 mask  = 0;
1087         bool flag;
1088         
1089         const EnumString *esp = es_HudBuiltinElement;
1090         for (int i = 0; esp[i].str; i++) {
1091                 if (getboolfield(L, 2, esp[i].str, flag)) {
1092                         flags |= esp[i].num * flag;
1093                         mask  |= esp[i].num;
1094                 }
1095         }
1096         if (!getServer(L)->hudSetFlags(player, flags, mask))
1097                 return 0;
1098
1099         lua_pushboolean(L, true);
1100         return 1;
1101 }
1102
1103 // hud_set_hotbar_itemcount(self, hotbar_itemcount)
1104 int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
1105 {
1106         ObjectRef *ref = checkobject(L, 1);
1107         Player *player = getplayer(ref);
1108         if (player == NULL)
1109                 return 0;
1110
1111         s32 hotbar_itemcount = lua_tonumber(L, 2);
1112
1113         if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
1114                 return 0;
1115
1116         lua_pushboolean(L, true);
1117         return 1;
1118 }
1119
1120 // hud_set_hotbar_image(self, name)
1121 int ObjectRef::l_hud_set_hotbar_image(lua_State *L)
1122 {
1123         ObjectRef *ref = checkobject(L, 1);
1124         Player *player = getplayer(ref);
1125         if (player == NULL)
1126                 return 0;
1127
1128         std::string name = lua_tostring(L, 2);
1129
1130         getServer(L)->hudSetHotbarImage(player, name);
1131         return 1;
1132 }
1133
1134 // hud_set_hotbar_selected_image(self, name)
1135 int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L)
1136 {
1137         ObjectRef *ref = checkobject(L, 1);
1138         Player *player = getplayer(ref);
1139         if (player == NULL)
1140                 return 0;
1141
1142         std::string name = lua_tostring(L, 2);
1143
1144         getServer(L)->hudSetHotbarSelectedImage(player, name);
1145         return 1;
1146 }
1147
1148 // set_sky(self, bgcolor, type, list)
1149 int ObjectRef::l_set_sky(lua_State *L)
1150 {
1151         ObjectRef *ref = checkobject(L, 1);
1152         Player *player = getplayer(ref);
1153         if (player == NULL)
1154                 return 0;
1155
1156         video::SColor bgcolor(255,255,255,255);
1157         if (!lua_isnil(L, 2))
1158                 bgcolor = readARGB8(L, 2);
1159
1160         std::string type = luaL_checkstring(L, 3);
1161
1162         std::vector<std::string> params;
1163         if (lua_istable(L, 4)) {
1164                 int table = lua_gettop(L);
1165                 lua_pushnil(L);
1166                 while (lua_next(L, table) != 0) {
1167                         // key at index -2 and value at index -1
1168                         if (lua_isstring(L, -1))
1169                                 params.push_back(lua_tostring(L, -1));
1170                         else
1171                                 params.push_back("");
1172                         // removes value, keeps key for next iteration
1173                         lua_pop(L, 1);
1174                 }
1175         }
1176
1177         if (type == "skybox" && params.size() != 6)
1178                 throw LuaError("skybox expects 6 textures");
1179
1180         if (!getServer(L)->setSky(player, bgcolor, type, params))
1181                 return 0;
1182
1183         lua_pushboolean(L, true);
1184         return 1;
1185 }
1186
1187 // override_day_night_ratio(self, brightness=0...1)
1188 int ObjectRef::l_override_day_night_ratio(lua_State *L)
1189 {
1190         ObjectRef *ref = checkobject(L, 1);
1191         Player *player = getplayer(ref);
1192         if (player == NULL)
1193                 return 0;
1194
1195         bool do_override = false;
1196         float ratio = 0.0f;
1197         if (!lua_isnil(L, 2)){
1198                 do_override = true;
1199                 ratio = luaL_checknumber(L, 2);
1200         }
1201
1202         if (!getServer(L)->overrideDayNightRatio(player, do_override, ratio))
1203                 return 0;
1204
1205         lua_pushboolean(L, true);
1206         return 1;
1207 }
1208
1209 ObjectRef::ObjectRef(ServerActiveObject *object):
1210         m_object(object)
1211 {
1212         //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1213 }
1214
1215 ObjectRef::~ObjectRef()
1216 {
1217         /*if(m_object)
1218                 infostream<<"ObjectRef destructing for id="
1219                                 <<m_object->getId()<<std::endl;
1220         else
1221                 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1222 }
1223
1224 // Creates an ObjectRef and leaves it on top of stack
1225 // Not callable from Lua; all references are created on the C side.
1226 void ObjectRef::create(lua_State *L, ServerActiveObject *object)
1227 {
1228         ObjectRef *o = new ObjectRef(object);
1229         //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1230         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1231         luaL_getmetatable(L, className);
1232         lua_setmetatable(L, -2);
1233 }
1234
1235 void ObjectRef::set_null(lua_State *L)
1236 {
1237         ObjectRef *o = checkobject(L, -1);
1238         o->m_object = NULL;
1239 }
1240
1241 void ObjectRef::Register(lua_State *L)
1242 {
1243         lua_newtable(L);
1244         int methodtable = lua_gettop(L);
1245         luaL_newmetatable(L, className);
1246         int metatable = lua_gettop(L);
1247
1248         lua_pushliteral(L, "__metatable");
1249         lua_pushvalue(L, methodtable);
1250         lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1251
1252         lua_pushliteral(L, "__index");
1253         lua_pushvalue(L, methodtable);
1254         lua_settable(L, metatable);
1255
1256         lua_pushliteral(L, "__gc");
1257         lua_pushcfunction(L, gc_object);
1258         lua_settable(L, metatable);
1259
1260         lua_pop(L, 1);  // drop metatable
1261
1262         luaL_openlib(L, 0, methods, 0);  // fill methodtable
1263         lua_pop(L, 1);  // drop methodtable
1264
1265         // Cannot be created from Lua
1266         //lua_register(L, className, create_object);
1267 }
1268
1269 const char ObjectRef::className[] = "ObjectRef";
1270 const luaL_reg ObjectRef::methods[] = {
1271         // ServerActiveObject
1272         luamethod(ObjectRef, remove),
1273         luamethod(ObjectRef, getpos),
1274         luamethod(ObjectRef, setpos),
1275         luamethod(ObjectRef, moveto),
1276         luamethod(ObjectRef, punch),
1277         luamethod(ObjectRef, right_click),
1278         luamethod(ObjectRef, set_hp),
1279         luamethod(ObjectRef, get_hp),
1280         luamethod(ObjectRef, get_inventory),
1281         luamethod(ObjectRef, get_wield_list),
1282         luamethod(ObjectRef, get_wield_index),
1283         luamethod(ObjectRef, get_wielded_item),
1284         luamethod(ObjectRef, set_wielded_item),
1285         luamethod(ObjectRef, set_armor_groups),
1286         luamethod(ObjectRef, set_physics_override),
1287         luamethod(ObjectRef, set_animation),
1288         luamethod(ObjectRef, set_bone_position),
1289         luamethod(ObjectRef, set_attach),
1290         luamethod(ObjectRef, set_detach),
1291         luamethod(ObjectRef, set_properties),
1292         // LuaEntitySAO-only
1293         luamethod(ObjectRef, setvelocity),
1294         luamethod(ObjectRef, getvelocity),
1295         luamethod(ObjectRef, setacceleration),
1296         luamethod(ObjectRef, getacceleration),
1297         luamethod(ObjectRef, setyaw),
1298         luamethod(ObjectRef, getyaw),
1299         luamethod(ObjectRef, settexturemod),
1300         luamethod(ObjectRef, setsprite),
1301         luamethod(ObjectRef, get_entity_name),
1302         luamethod(ObjectRef, get_luaentity),
1303         // Player-only
1304         luamethod(ObjectRef, is_player),
1305         luamethod(ObjectRef, is_player_connected),
1306         luamethod(ObjectRef, get_player_name),
1307         luamethod(ObjectRef, get_look_dir),
1308         luamethod(ObjectRef, get_look_pitch),
1309         luamethod(ObjectRef, get_look_yaw),
1310         luamethod(ObjectRef, set_look_yaw),
1311         luamethod(ObjectRef, set_look_pitch),
1312         luamethod(ObjectRef, get_breath),
1313         luamethod(ObjectRef, set_breath),
1314         luamethod(ObjectRef, set_inventory_formspec),
1315         luamethod(ObjectRef, get_inventory_formspec),
1316         luamethod(ObjectRef, get_player_control),
1317         luamethod(ObjectRef, get_player_control_bits),
1318         luamethod(ObjectRef, hud_add),
1319         luamethod(ObjectRef, hud_remove),
1320         luamethod(ObjectRef, hud_change),
1321         luamethod(ObjectRef, hud_get),
1322         luamethod(ObjectRef, hud_set_flags),
1323         luamethod(ObjectRef, hud_set_hotbar_itemcount),
1324         luamethod(ObjectRef, hud_set_hotbar_image),
1325         luamethod(ObjectRef, hud_set_hotbar_selected_image),
1326         luamethod(ObjectRef, set_sky),
1327         luamethod(ObjectRef, override_day_night_ratio),
1328         luamethod(ObjectRef, set_local_animation),
1329         luamethod(ObjectRef, set_eye_offset),
1330         {0,0}
1331 };