3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
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"
28 #include "serverobject.h"
29 #include "content_object.h"
30 #include "content_sao.h"
35 struct EnumString es_HudElementType[] =
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"},
45 struct EnumString es_HudElementStat[] =
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"},
61 struct EnumString es_HudBuiltinElement[] =
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"},
76 ObjectRef* ObjectRef::checkobject(lua_State *L, int narg)
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
84 ServerActiveObject* ObjectRef::getobject(ObjectRef *ref)
86 ServerActiveObject *co = ref->m_object;
90 LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref)
92 ServerActiveObject *obj = getobject(ref);
95 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
97 return (LuaEntitySAO*)obj;
100 PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
102 ServerActiveObject *obj = getobject(ref);
105 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
107 return (PlayerSAO*)obj;
110 Player* ObjectRef::getplayer(ObjectRef *ref)
112 PlayerSAO *playersao = getplayersao(ref);
113 if(playersao == NULL)
115 return playersao->getPlayer();
118 // Exported functions
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;
129 int ObjectRef::l_remove(lua_State *L)
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;
141 // returns: {x=num, y=num, z=num}
142 int ObjectRef::l_getpos(lua_State *L)
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;
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");
160 int ObjectRef::l_setpos(lua_State *L)
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;
168 v3f pos = checkFloatPos(L, 2);
174 // moveto(self, pos, continuous=false)
175 int ObjectRef::l_moveto(lua_State *L)
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;
183 v3f pos = checkFloatPos(L, 2);
185 bool continuous = lua_toboolean(L, 3);
187 co->moveTo(pos, continuous);
191 // punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
192 int ObjectRef::l_punch(lua_State *L)
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;
202 if(lua_type(L, 5) != LUA_TTABLE)
203 dir = co->getBasePosition() - puncher->getBasePosition();
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);
212 co->punch(dir, &toolcap, puncher, time_from_last_punch);
216 // right_click(self, clicker); clicker = an another ObjectRef
217 int ObjectRef::l_right_click(lua_State *L)
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;
232 // hp = number of hitpoints (2 * number of hearts)
234 int ObjectRef::l_set_hp(lua_State *L)
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;*/
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)
255 NO_MAP_LOCK_REQUIRED;
256 ObjectRef *ref = checkobject(L, 1);
257 ServerActiveObject *co = getobject(ref);
260 lua_pushnumber(L, 1);
263 int hp = co->getHP();
264 /*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
265 <<" hp="<<hp<<std::endl;*/
267 lua_pushnumber(L, hp);
271 // get_inventory(self)
272 int ObjectRef::l_get_inventory(lua_State *L)
274 NO_MAP_LOCK_REQUIRED;
275 ObjectRef *ref = checkobject(L, 1);
276 ServerActiveObject *co = getobject(ref);
277 if(co == NULL) return 0;
279 InventoryLocation loc = co->getInventoryLocation();
280 if(getServer(L)->getInventory(loc) != NULL)
281 InvRef::create(L, loc);
283 lua_pushnil(L); // An object may have no inventory (nil)
287 // get_wield_list(self)
288 int ObjectRef::l_get_wield_list(lua_State *L)
290 NO_MAP_LOCK_REQUIRED;
291 ObjectRef *ref = checkobject(L, 1);
292 ServerActiveObject *co = getobject(ref);
293 if(co == NULL) return 0;
295 lua_pushstring(L, co->getWieldList().c_str());
299 // get_wield_index(self)
300 int ObjectRef::l_get_wield_index(lua_State *L)
302 NO_MAP_LOCK_REQUIRED;
303 ObjectRef *ref = checkobject(L, 1);
304 ServerActiveObject *co = getobject(ref);
305 if(co == NULL) return 0;
307 lua_pushinteger(L, co->getWieldIndex() + 1);
311 // get_wielded_item(self)
312 int ObjectRef::l_get_wielded_item(lua_State *L)
314 NO_MAP_LOCK_REQUIRED;
315 ObjectRef *ref = checkobject(L, 1);
316 ServerActiveObject *co = getobject(ref);
319 LuaItemStack::create(L, ItemStack());
323 LuaItemStack::create(L, co->getWieldedItem());
327 // set_wielded_item(self, itemstack or itemstring or table or nil)
328 int ObjectRef::l_set_wielded_item(lua_State *L)
330 NO_MAP_LOCK_REQUIRED;
331 ObjectRef *ref = checkobject(L, 1);
332 ServerActiveObject *co = getobject(ref);
333 if(co == NULL) return 0;
335 ItemStack item = read_item(L, 2, getServer(L));
336 bool success = co->setWieldedItem(item);
337 lua_pushboolean(L, success);
341 // set_armor_groups(self, groups)
342 int ObjectRef::l_set_armor_groups(lua_State *L)
344 NO_MAP_LOCK_REQUIRED;
345 ObjectRef *ref = checkobject(L, 1);
346 ServerActiveObject *co = getobject(ref);
347 if(co == NULL) return 0;
349 ItemGroupList groups;
350 read_groups(L, 2, groups);
351 co->setArmorGroups(groups);
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)
359 ObjectRef *ref = checkobject(L, 1);
360 PlayerSAO *co = (PlayerSAO *) getobject(ref);
361 if(co == NULL) return 0;
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;
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;
376 if(!lua_isnil(L, 3)){
377 co->m_physics_override_jump = lua_tonumber(L, 3);
378 co->m_physics_override_sent = false;
380 if(!lua_isnil(L, 4)){
381 co->m_physics_override_gravity = lua_tonumber(L, 4);
382 co->m_physics_override_sent = false;
388 // set_animation(self, frame_range, frame_speed, frame_blend)
389 int ObjectRef::l_set_animation(lua_State *L)
391 NO_MAP_LOCK_REQUIRED;
392 ObjectRef *ref = checkobject(L, 1);
393 ServerActiveObject *co = getobject(ref);
394 if(co == NULL) return 0;
396 v2f frames = v2f(1, 1);
398 frames = read_v2f(L, 2);
399 float frame_speed = 15;
401 frame_speed = lua_tonumber(L, 3);
402 float frame_blend = 0;
404 frame_blend = lua_tonumber(L, 4);
405 co->setAnimation(frames, frame_speed, frame_blend);
409 // set_local_animation(self, {stand/ilde}, {walk}, {dig}, {walk+dig}, frame_speed)
410 int ObjectRef::l_set_local_animation(lua_State *L)
412 //NO_MAP_LOCK_REQUIRED;
413 ObjectRef *ref = checkobject(L, 1);
414 Player *player = getplayer(ref);
419 for (int i=0;i<4;i++) {
420 if(!lua_isnil(L, 2+1))
421 frames[i] = read_v2f(L, 2+i);
423 float frame_speed = 30;
425 frame_speed = lua_tonumber(L, 6);
427 if (!getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed))
430 lua_pushboolean(L, true);
434 // set_bone_position(self, std::string bone, v3f position, v3f rotation)
435 int ObjectRef::l_set_bone_position(lua_State *L)
437 NO_MAP_LOCK_REQUIRED;
438 ObjectRef *ref = checkobject(L, 1);
439 ServerActiveObject *co = getobject(ref);
440 if(co == NULL) return 0;
442 std::string bone = "";
444 bone = lua_tostring(L, 2);
445 v3f position = v3f(0, 0, 0);
447 position = read_v3f(L, 3);
448 v3f rotation = v3f(0, 0, 0);
450 rotation = read_v3f(L, 4);
451 co->setBonePosition(bone, position, rotation);
455 // set_attach(self, parent, bone, position, rotation)
456 int ObjectRef::l_set_attach(lua_State *L)
458 NO_MAP_LOCK_REQUIRED;
459 ObjectRef *ref = checkobject(L, 1);
460 ObjectRef *parent_ref = checkobject(L, 2);
461 ServerActiveObject *co = getobject(ref);
462 ServerActiveObject *parent = getobject(parent_ref);
463 if(co == NULL) return 0;
464 if(parent == NULL) return 0;
466 std::string bone = "";
468 bone = lua_tostring(L, 3);
469 v3f position = v3f(0, 0, 0);
471 position = read_v3f(L, 4);
472 v3f rotation = v3f(0, 0, 0);
474 rotation = read_v3f(L, 5);
475 co->setAttachment(parent->getId(), bone, position, rotation);
480 int ObjectRef::l_set_detach(lua_State *L)
482 NO_MAP_LOCK_REQUIRED;
483 ObjectRef *ref = checkobject(L, 1);
484 ServerActiveObject *co = getobject(ref);
485 if(co == NULL) return 0;
487 co->setAttachment(0, "", v3f(0,0,0), v3f(0,0,0));
491 // set_properties(self, properties)
492 int ObjectRef::l_set_properties(lua_State *L)
494 NO_MAP_LOCK_REQUIRED;
495 ObjectRef *ref = checkobject(L, 1);
496 ServerActiveObject *co = getobject(ref);
497 if(co == NULL) return 0;
498 ObjectProperties *prop = co->accessObjectProperties();
501 read_object_properties(L, 2, prop);
502 co->notifyObjectPropertiesModified();
506 /* LuaEntitySAO-only */
508 // setvelocity(self, {x=num, y=num, z=num})
509 int ObjectRef::l_setvelocity(lua_State *L)
511 NO_MAP_LOCK_REQUIRED;
512 ObjectRef *ref = checkobject(L, 1);
513 LuaEntitySAO *co = getluaobject(ref);
514 if(co == NULL) return 0;
515 v3f pos = checkFloatPos(L, 2);
517 co->setVelocity(pos);
522 int ObjectRef::l_getvelocity(lua_State *L)
524 NO_MAP_LOCK_REQUIRED;
525 ObjectRef *ref = checkobject(L, 1);
526 LuaEntitySAO *co = getluaobject(ref);
527 if(co == NULL) return 0;
529 v3f v = co->getVelocity();
534 // setacceleration(self, {x=num, y=num, z=num})
535 int ObjectRef::l_setacceleration(lua_State *L)
537 NO_MAP_LOCK_REQUIRED;
538 ObjectRef *ref = checkobject(L, 1);
539 LuaEntitySAO *co = getluaobject(ref);
540 if(co == NULL) return 0;
542 v3f pos = checkFloatPos(L, 2);
544 co->setAcceleration(pos);
548 // getacceleration(self)
549 int ObjectRef::l_getacceleration(lua_State *L)
551 NO_MAP_LOCK_REQUIRED;
552 ObjectRef *ref = checkobject(L, 1);
553 LuaEntitySAO *co = getluaobject(ref);
554 if(co == NULL) return 0;
556 v3f v = co->getAcceleration();
561 // setyaw(self, radians)
562 int ObjectRef::l_setyaw(lua_State *L)
564 NO_MAP_LOCK_REQUIRED;
565 ObjectRef *ref = checkobject(L, 1);
566 LuaEntitySAO *co = getluaobject(ref);
567 if(co == NULL) return 0;
568 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
575 int ObjectRef::l_getyaw(lua_State *L)
577 NO_MAP_LOCK_REQUIRED;
578 ObjectRef *ref = checkobject(L, 1);
579 LuaEntitySAO *co = getluaobject(ref);
580 if(co == NULL) return 0;
582 float yaw = co->getYaw() * core::DEGTORAD;
583 lua_pushnumber(L, yaw);
587 // settexturemod(self, mod)
588 int ObjectRef::l_settexturemod(lua_State *L)
590 NO_MAP_LOCK_REQUIRED;
591 ObjectRef *ref = checkobject(L, 1);
592 LuaEntitySAO *co = getluaobject(ref);
593 if(co == NULL) return 0;
595 std::string mod = luaL_checkstring(L, 2);
596 co->setTextureMod(mod);
600 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
601 // select_horiz_by_yawpitch=false)
602 int ObjectRef::l_setsprite(lua_State *L)
604 NO_MAP_LOCK_REQUIRED;
605 ObjectRef *ref = checkobject(L, 1);
606 LuaEntitySAO *co = getluaobject(ref);
607 if(co == NULL) return 0;
611 p = read_v2s16(L, 2);
614 num_frames = lua_tonumber(L, 3);
615 float framelength = 0.2;
617 framelength = lua_tonumber(L, 4);
618 bool select_horiz_by_yawpitch = false;
620 select_horiz_by_yawpitch = lua_toboolean(L, 5);
621 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
626 // get_entity_name(self)
627 int ObjectRef::l_get_entity_name(lua_State *L)
629 NO_MAP_LOCK_REQUIRED;
630 ObjectRef *ref = checkobject(L, 1);
631 LuaEntitySAO *co = getluaobject(ref);
632 if(co == NULL) return 0;
634 std::string name = co->getName();
635 lua_pushstring(L, name.c_str());
639 // get_luaentity(self)
640 int ObjectRef::l_get_luaentity(lua_State *L)
642 NO_MAP_LOCK_REQUIRED;
643 ObjectRef *ref = checkobject(L, 1);
644 LuaEntitySAO *co = getluaobject(ref);
645 if(co == NULL) return 0;
647 luaentity_get(L, co->getId());
654 int ObjectRef::l_is_player(lua_State *L)
656 NO_MAP_LOCK_REQUIRED;
657 ObjectRef *ref = checkobject(L, 1);
658 Player *player = getplayer(ref);
659 lua_pushboolean(L, (player != NULL));
663 // is_player_connected(self)
664 int ObjectRef::l_is_player_connected(lua_State *L)
666 NO_MAP_LOCK_REQUIRED;
667 ObjectRef *ref = checkobject(L, 1);
668 Player *player = getplayer(ref);
669 lua_pushboolean(L, (player != NULL && player->peer_id != 0));
673 // get_player_name(self)
674 int ObjectRef::l_get_player_name(lua_State *L)
676 NO_MAP_LOCK_REQUIRED;
677 ObjectRef *ref = checkobject(L, 1);
678 Player *player = getplayer(ref);
680 lua_pushlstring(L, "", 0);
684 lua_pushstring(L, player->getName());
688 // get_look_dir(self)
689 int ObjectRef::l_get_look_dir(lua_State *L)
691 NO_MAP_LOCK_REQUIRED;
692 ObjectRef *ref = checkobject(L, 1);
693 Player *player = getplayer(ref);
694 if(player == NULL) return 0;
696 float pitch = player->getRadPitch();
697 float yaw = player->getRadYaw();
698 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
703 // get_look_pitch(self)
704 int ObjectRef::l_get_look_pitch(lua_State *L)
706 NO_MAP_LOCK_REQUIRED;
707 ObjectRef *ref = checkobject(L, 1);
708 Player *player = getplayer(ref);
709 if(player == NULL) return 0;
711 lua_pushnumber(L, player->getRadPitch());
715 // get_look_yaw(self)
716 int ObjectRef::l_get_look_yaw(lua_State *L)
718 NO_MAP_LOCK_REQUIRED;
719 ObjectRef *ref = checkobject(L, 1);
720 Player *player = getplayer(ref);
721 if(player == NULL) return 0;
723 lua_pushnumber(L, player->getRadYaw());
727 // set_look_pitch(self, radians)
728 int ObjectRef::l_set_look_pitch(lua_State *L)
730 NO_MAP_LOCK_REQUIRED;
731 ObjectRef *ref = checkobject(L, 1);
732 PlayerSAO* co = getplayersao(ref);
733 if(co == NULL) return 0;
734 float pitch = luaL_checknumber(L, 2) * core::RADTODEG;
740 // set_look_yaw(self, radians)
741 int ObjectRef::l_set_look_yaw(lua_State *L)
743 NO_MAP_LOCK_REQUIRED;
744 ObjectRef *ref = checkobject(L, 1);
745 PlayerSAO* co = getplayersao(ref);
746 if(co == NULL) return 0;
747 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
753 // set_breath(self, breath)
754 int ObjectRef::l_set_breath(lua_State *L)
756 NO_MAP_LOCK_REQUIRED;
757 ObjectRef *ref = checkobject(L, 1);
758 PlayerSAO* co = getplayersao(ref);
759 if(co == NULL) return 0;
760 u16 breath = luaL_checknumber(L, 2);
762 co->setBreath(breath);
763 co->m_breath_not_sent = true;
768 int ObjectRef::l_get_breath(lua_State *L)
770 NO_MAP_LOCK_REQUIRED;
771 ObjectRef *ref = checkobject(L, 1);
772 PlayerSAO* co = getplayersao(ref);
773 if(co == NULL) return 0;
775 u16 breath = co->getBreath();
776 lua_pushinteger (L, breath);
780 // set_inventory_formspec(self, formspec)
781 int ObjectRef::l_set_inventory_formspec(lua_State *L)
783 NO_MAP_LOCK_REQUIRED;
784 ObjectRef *ref = checkobject(L, 1);
785 Player *player = getplayer(ref);
786 if(player == NULL) return 0;
787 std::string formspec = luaL_checkstring(L, 2);
789 player->inventory_formspec = formspec;
790 getServer(L)->reportInventoryFormspecModified(player->getName());
791 lua_pushboolean(L, true);
795 // get_inventory_formspec(self) -> formspec
796 int ObjectRef::l_get_inventory_formspec(lua_State *L)
798 NO_MAP_LOCK_REQUIRED;
799 ObjectRef *ref = checkobject(L, 1);
800 Player *player = getplayer(ref);
801 if(player == NULL) return 0;
803 std::string formspec = player->inventory_formspec;
804 lua_pushlstring(L, formspec.c_str(), formspec.size());
808 // get_player_control(self)
809 int ObjectRef::l_get_player_control(lua_State *L)
811 NO_MAP_LOCK_REQUIRED;
812 ObjectRef *ref = checkobject(L, 1);
813 Player *player = getplayer(ref);
815 lua_pushlstring(L, "", 0);
819 PlayerControl control = player->getPlayerControl();
821 lua_pushboolean(L, control.up);
822 lua_setfield(L, -2, "up");
823 lua_pushboolean(L, control.down);
824 lua_setfield(L, -2, "down");
825 lua_pushboolean(L, control.left);
826 lua_setfield(L, -2, "left");
827 lua_pushboolean(L, control.right);
828 lua_setfield(L, -2, "right");
829 lua_pushboolean(L, control.jump);
830 lua_setfield(L, -2, "jump");
831 lua_pushboolean(L, control.aux1);
832 lua_setfield(L, -2, "aux1");
833 lua_pushboolean(L, control.sneak);
834 lua_setfield(L, -2, "sneak");
835 lua_pushboolean(L, control.LMB);
836 lua_setfield(L, -2, "LMB");
837 lua_pushboolean(L, control.RMB);
838 lua_setfield(L, -2, "RMB");
842 // get_player_control_bits(self)
843 int ObjectRef::l_get_player_control_bits(lua_State *L)
845 NO_MAP_LOCK_REQUIRED;
846 ObjectRef *ref = checkobject(L, 1);
847 Player *player = getplayer(ref);
849 lua_pushlstring(L, "", 0);
853 lua_pushnumber(L, player->keyPressed);
857 // hud_add(self, form)
858 int ObjectRef::l_hud_add(lua_State *L)
860 ObjectRef *ref = checkobject(L, 1);
861 Player *player = getplayer(ref);
865 HudElement *elem = new HudElement;
867 elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type",
868 es_HudElementType, HUD_ELEM_TEXT);
870 lua_getfield(L, 2, "position");
871 elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
874 lua_getfield(L, 2, "scale");
875 elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
878 elem->name = getstringfield_default(L, 2, "name", "");
879 elem->text = getstringfield_default(L, 2, "text", "");
880 elem->number = getintfield_default(L, 2, "number", 0);
881 elem->item = getintfield_default(L, 2, "item", 0);
882 elem->dir = getintfield_default(L, 2, "dir", 0);
884 lua_getfield(L, 2, "alignment");
885 elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
888 lua_getfield(L, 2, "offset");
889 elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
892 lua_getfield(L, 2, "world_pos");
893 elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
896 u32 id = getServer(L)->hudAdd(player, elem);
902 lua_pushnumber(L, id);
906 // hud_remove(self, id)
907 int ObjectRef::l_hud_remove(lua_State *L)
909 ObjectRef *ref = checkobject(L, 1);
910 Player *player = getplayer(ref);
915 if (!lua_isnil(L, 2))
916 id = lua_tonumber(L, 2);
918 if (!getServer(L)->hudRemove(player, id))
921 lua_pushboolean(L, true);
925 // hud_change(self, id, stat, data)
926 int ObjectRef::l_hud_change(lua_State *L)
928 ObjectRef *ref = checkobject(L, 1);
929 Player *player = getplayer(ref);
933 u32 id = !lua_isnil(L, 2) ? lua_tonumber(L, 2) : -1;
934 if (id >= player->hud.size())
937 HudElementStat stat = HUD_STAT_NUMBER;
938 if (!lua_isnil(L, 3)) {
940 std::string statstr = lua_tostring(L, 3);
941 stat = string_to_enum(es_HudElementStat, statint, statstr) ?
942 (HudElementStat)statint : HUD_STAT_NUMBER;
946 HudElement *e = player->hud[id];
952 e->pos = read_v2f(L, 4);
956 e->name = lua_tostring(L, 4);
960 e->scale = read_v2f(L, 4);
964 e->text = lua_tostring(L, 4);
967 case HUD_STAT_NUMBER:
968 e->number = lua_tonumber(L, 4);
972 e->item = lua_tonumber(L, 4);
976 e->dir = lua_tonumber(L, 4);
980 e->align = read_v2f(L, 4);
983 case HUD_STAT_OFFSET:
984 e->offset = read_v2f(L, 4);
987 case HUD_STAT_WORLD_POS:
988 e->world_pos = read_v3f(L, 4);
989 value = &e->world_pos;
993 getServer(L)->hudChange(player, id, stat, value);
995 lua_pushboolean(L, true);
1000 int ObjectRef::l_hud_get(lua_State *L)
1002 ObjectRef *ref = checkobject(L, 1);
1003 Player *player = getplayer(ref);
1007 u32 id = lua_tonumber(L, -1);
1008 if (id >= player->hud.size())
1011 HudElement *e = player->hud[id];
1017 lua_pushstring(L, es_HudElementType[(u8)e->type].str);
1018 lua_setfield(L, -2, "type");
1020 push_v2f(L, e->pos);
1021 lua_setfield(L, -2, "position");
1023 lua_pushstring(L, e->name.c_str());
1024 lua_setfield(L, -2, "name");
1026 push_v2f(L, e->scale);
1027 lua_setfield(L, -2, "scale");
1029 lua_pushstring(L, e->text.c_str());
1030 lua_setfield(L, -2, "text");
1032 lua_pushnumber(L, e->number);
1033 lua_setfield(L, -2, "number");
1035 lua_pushnumber(L, e->item);
1036 lua_setfield(L, -2, "item");
1038 lua_pushnumber(L, e->dir);
1039 lua_setfield(L, -2, "dir");
1041 push_v3f(L, e->world_pos);
1042 lua_setfield(L, -2, "world_pos");
1047 // hud_set_flags(self, flags)
1048 int ObjectRef::l_hud_set_flags(lua_State *L)
1050 ObjectRef *ref = checkobject(L, 1);
1051 Player *player = getplayer(ref);
1059 const EnumString *esp = es_HudBuiltinElement;
1060 for (int i = 0; esp[i].str; i++) {
1061 if (getboolfield(L, 2, esp[i].str, flag)) {
1062 flags |= esp[i].num * flag;
1066 if (!getServer(L)->hudSetFlags(player, flags, mask))
1069 lua_pushboolean(L, true);
1073 // hud_set_hotbar_itemcount(self, hotbar_itemcount)
1074 int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
1076 ObjectRef *ref = checkobject(L, 1);
1077 Player *player = getplayer(ref);
1081 s32 hotbar_itemcount = lua_tonumber(L, 2);
1083 if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
1086 lua_pushboolean(L, true);
1090 // hud_set_hotbar_image(self, name)
1091 int ObjectRef::l_hud_set_hotbar_image(lua_State *L)
1093 ObjectRef *ref = checkobject(L, 1);
1094 Player *player = getplayer(ref);
1098 std::string name = lua_tostring(L, 2);
1100 getServer(L)->hudSetHotbarImage(player, name);
1104 // hud_set_hotbar_selected_image(self, name)
1105 int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L)
1107 ObjectRef *ref = checkobject(L, 1);
1108 Player *player = getplayer(ref);
1112 std::string name = lua_tostring(L, 2);
1114 getServer(L)->hudSetHotbarSelectedImage(player, name);
1118 // set_sky(self, bgcolor, type, list)
1119 int ObjectRef::l_set_sky(lua_State *L)
1121 ObjectRef *ref = checkobject(L, 1);
1122 Player *player = getplayer(ref);
1126 video::SColor bgcolor(255,255,255,255);
1127 if (!lua_isnil(L, 2))
1128 bgcolor = readARGB8(L, 2);
1130 std::string type = luaL_checkstring(L, 3);
1132 std::vector<std::string> params;
1133 if (lua_istable(L, 4)) {
1134 int table = lua_gettop(L);
1136 while (lua_next(L, table) != 0) {
1137 // key at index -2 and value at index -1
1138 if (lua_isstring(L, -1))
1139 params.push_back(lua_tostring(L, -1));
1141 params.push_back("");
1142 // removes value, keeps key for next iteration
1147 if (type == "skybox" && params.size() != 6)
1148 throw LuaError("skybox expects 6 textures");
1150 if (!getServer(L)->setSky(player, bgcolor, type, params))
1153 lua_pushboolean(L, true);
1157 // override_day_night_ratio(self, brightness=0...1)
1158 int ObjectRef::l_override_day_night_ratio(lua_State *L)
1160 ObjectRef *ref = checkobject(L, 1);
1161 Player *player = getplayer(ref);
1165 bool do_override = false;
1167 if (!lua_isnil(L, 2)){
1169 ratio = luaL_checknumber(L, 2);
1172 if (!getServer(L)->overrideDayNightRatio(player, do_override, ratio))
1175 lua_pushboolean(L, true);
1179 ObjectRef::ObjectRef(ServerActiveObject *object):
1182 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
1185 ObjectRef::~ObjectRef()
1188 infostream<<"ObjectRef destructing for id="
1189 <<m_object->getId()<<std::endl;
1191 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
1194 // Creates an ObjectRef and leaves it on top of stack
1195 // Not callable from Lua; all references are created on the C side.
1196 void ObjectRef::create(lua_State *L, ServerActiveObject *object)
1198 ObjectRef *o = new ObjectRef(object);
1199 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
1200 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1201 luaL_getmetatable(L, className);
1202 lua_setmetatable(L, -2);
1205 void ObjectRef::set_null(lua_State *L)
1207 ObjectRef *o = checkobject(L, -1);
1211 void ObjectRef::Register(lua_State *L)
1214 int methodtable = lua_gettop(L);
1215 luaL_newmetatable(L, className);
1216 int metatable = lua_gettop(L);
1218 lua_pushliteral(L, "__metatable");
1219 lua_pushvalue(L, methodtable);
1220 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
1222 lua_pushliteral(L, "__index");
1223 lua_pushvalue(L, methodtable);
1224 lua_settable(L, metatable);
1226 lua_pushliteral(L, "__gc");
1227 lua_pushcfunction(L, gc_object);
1228 lua_settable(L, metatable);
1230 lua_pop(L, 1); // drop metatable
1232 luaL_openlib(L, 0, methods, 0); // fill methodtable
1233 lua_pop(L, 1); // drop methodtable
1235 // Cannot be created from Lua
1236 //lua_register(L, className, create_object);
1239 const char ObjectRef::className[] = "ObjectRef";
1240 const luaL_reg ObjectRef::methods[] = {
1241 // ServerActiveObject
1242 luamethod(ObjectRef, remove),
1243 luamethod(ObjectRef, getpos),
1244 luamethod(ObjectRef, setpos),
1245 luamethod(ObjectRef, moveto),
1246 luamethod(ObjectRef, punch),
1247 luamethod(ObjectRef, right_click),
1248 luamethod(ObjectRef, set_hp),
1249 luamethod(ObjectRef, get_hp),
1250 luamethod(ObjectRef, get_inventory),
1251 luamethod(ObjectRef, get_wield_list),
1252 luamethod(ObjectRef, get_wield_index),
1253 luamethod(ObjectRef, get_wielded_item),
1254 luamethod(ObjectRef, set_wielded_item),
1255 luamethod(ObjectRef, set_armor_groups),
1256 luamethod(ObjectRef, set_physics_override),
1257 luamethod(ObjectRef, set_animation),
1258 luamethod(ObjectRef, set_bone_position),
1259 luamethod(ObjectRef, set_attach),
1260 luamethod(ObjectRef, set_detach),
1261 luamethod(ObjectRef, set_properties),
1262 // LuaEntitySAO-only
1263 luamethod(ObjectRef, setvelocity),
1264 luamethod(ObjectRef, getvelocity),
1265 luamethod(ObjectRef, setacceleration),
1266 luamethod(ObjectRef, getacceleration),
1267 luamethod(ObjectRef, setyaw),
1268 luamethod(ObjectRef, getyaw),
1269 luamethod(ObjectRef, settexturemod),
1270 luamethod(ObjectRef, setsprite),
1271 luamethod(ObjectRef, get_entity_name),
1272 luamethod(ObjectRef, get_luaentity),
1274 luamethod(ObjectRef, is_player),
1275 luamethod(ObjectRef, is_player_connected),
1276 luamethod(ObjectRef, get_player_name),
1277 luamethod(ObjectRef, get_look_dir),
1278 luamethod(ObjectRef, get_look_pitch),
1279 luamethod(ObjectRef, get_look_yaw),
1280 luamethod(ObjectRef, set_look_yaw),
1281 luamethod(ObjectRef, set_look_pitch),
1282 luamethod(ObjectRef, get_breath),
1283 luamethod(ObjectRef, set_breath),
1284 luamethod(ObjectRef, set_inventory_formspec),
1285 luamethod(ObjectRef, get_inventory_formspec),
1286 luamethod(ObjectRef, get_player_control),
1287 luamethod(ObjectRef, get_player_control_bits),
1288 luamethod(ObjectRef, hud_add),
1289 luamethod(ObjectRef, hud_remove),
1290 luamethod(ObjectRef, hud_change),
1291 luamethod(ObjectRef, hud_get),
1292 luamethod(ObjectRef, hud_set_flags),
1293 luamethod(ObjectRef, hud_set_hotbar_itemcount),
1294 luamethod(ObjectRef, hud_set_hotbar_image),
1295 luamethod(ObjectRef, hud_set_hotbar_selected_image),
1296 luamethod(ObjectRef, set_sky),
1297 luamethod(ObjectRef, override_day_night_ratio),
1298 luamethod(ObjectRef, set_local_animation),