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