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