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"
22 #include "lua_api/l_internal.h"
23 #include "lua_api/l_inventory.h"
24 #include "lua_api/l_item.h"
25 #include "lua_api/l_playermeta.h"
26 #include "common/c_converter.h"
27 #include "common/c_content.h"
30 #include "remoteplayer.h"
33 #include "scripting_server.h"
34 #include "server/luaentity_sao.h"
35 #include "server/player_sao.h"
42 ObjectRef* ObjectRef::checkobject(lua_State *L, int narg)
44 luaL_checktype(L, narg, LUA_TUSERDATA);
45 void *ud = luaL_checkudata(L, narg, className);
46 if (!ud) luaL_typerror(L, narg, className);
47 return *(ObjectRef**)ud; // unbox pointer
50 ServerActiveObject* ObjectRef::getobject(ObjectRef *ref)
52 ServerActiveObject *co = ref->m_object;
53 if (co && co->isGone())
58 LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref)
60 ServerActiveObject *obj = getobject(ref);
63 if (obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
65 return (LuaEntitySAO*)obj;
68 PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
70 ServerActiveObject *obj = getobject(ref);
73 if (obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
75 return (PlayerSAO*)obj;
78 RemotePlayer *ObjectRef::getplayer(ObjectRef *ref)
80 PlayerSAO *playersao = getplayersao(ref);
81 if (playersao == NULL)
83 return playersao->getPlayer();
89 int ObjectRef::gc_object(lua_State *L) {
90 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
91 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
97 int ObjectRef::l_remove(lua_State *L)
101 ObjectRef *ref = checkobject(L, 1);
102 ServerActiveObject *co = getobject(ref);
105 if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
108 co->clearChildAttachments();
109 co->clearParentAttachment();
111 verbosestream << "ObjectRef::l_remove(): id=" << co->getId() << std::endl;
112 co->m_pending_removal = true;
117 // returns: {x=num, y=num, z=num}
118 int ObjectRef::l_get_pos(lua_State *L)
120 NO_MAP_LOCK_REQUIRED;
121 ObjectRef *ref = checkobject(L, 1);
122 ServerActiveObject *co = getobject(ref);
123 if (co == NULL) return 0;
124 push_v3f(L, co->getBasePosition() / BS);
128 // set_pos(self, pos)
129 int ObjectRef::l_set_pos(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;
136 v3f pos = checkFloatPos(L, 2);
142 // move_to(self, pos, continuous=false)
143 int ObjectRef::l_move_to(lua_State *L)
145 NO_MAP_LOCK_REQUIRED;
146 ObjectRef *ref = checkobject(L, 1);
147 ServerActiveObject *co = getobject(ref);
148 if (co == NULL) return 0;
150 v3f pos = checkFloatPos(L, 2);
152 bool continuous = readParam<bool>(L, 3);
154 co->moveTo(pos, continuous);
158 // punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
159 int ObjectRef::l_punch(lua_State *L)
161 NO_MAP_LOCK_REQUIRED;
162 ObjectRef *ref = checkobject(L, 1);
163 ObjectRef *puncher_ref = checkobject(L, 2);
164 ServerActiveObject *co = getobject(ref);
165 ServerActiveObject *puncher = getobject(puncher_ref);
169 if (lua_type(L, 5) != LUA_TTABLE)
170 dir = co->getBasePosition() - puncher->getBasePosition();
172 dir = read_v3f(L, 5);
173 float time_from_last_punch = 1000000;
174 if (lua_isnumber(L, 3))
175 time_from_last_punch = lua_tonumber(L, 3);
176 ToolCapabilities toolcap = read_tool_capabilities(L, 4);
179 u16 src_original_hp = co->getHP();
180 u16 dst_origin_hp = puncher->getHP();
183 u16 wear = co->punch(dir, &toolcap, puncher, time_from_last_punch);
184 lua_pushnumber(L, wear);
186 // If the punched is a player, and its HP changed
187 if (src_original_hp != co->getHP() &&
188 co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
189 getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co,
190 PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher));
193 // If the puncher is a player, and its HP changed
194 if (dst_origin_hp != puncher->getHP() &&
195 puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
196 getServer(L)->SendPlayerHPOrDie((PlayerSAO *)puncher,
197 PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, co));
202 // right_click(self, clicker); clicker = an another ObjectRef
203 int ObjectRef::l_right_click(lua_State *L)
205 NO_MAP_LOCK_REQUIRED;
206 ObjectRef *ref = checkobject(L, 1);
207 ObjectRef *ref2 = checkobject(L, 2);
208 ServerActiveObject *co = getobject(ref);
209 ServerActiveObject *co2 = getobject(ref2);
210 if (co == NULL) return 0;
211 if (co2 == NULL) return 0;
218 // hp = number of hitpoints (2 * number of hearts)
220 int ObjectRef::l_set_hp(lua_State *L)
222 NO_MAP_LOCK_REQUIRED;
225 ObjectRef *ref = checkobject(L, 1);
226 luaL_checknumber(L, 2);
227 ServerActiveObject *co = getobject(ref);
232 int hp = lua_tonumber(L, 2);
235 PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP);
236 reason.from_mod = true;
237 if (lua_istable(L, 3)) {
240 lua_getfield(L, -1, "type");
241 if (lua_isstring(L, -1) &&
242 !reason.setTypeFromString(readParam<std::string>(L, -1))) {
243 errorstream << "Bad type given!" << std::endl;
247 reason.lua_reference = luaL_ref(L, LUA_REGISTRYINDEX);
251 co->setHP(hp, reason);
252 if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
253 getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, reason);
255 if (reason.hasLuaReference())
256 luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference);
263 // returns: number of hitpoints (2 * number of hearts)
264 // 0 if not applicable to this type of object
265 int ObjectRef::l_get_hp(lua_State *L)
267 NO_MAP_LOCK_REQUIRED;
268 ObjectRef *ref = checkobject(L, 1);
269 ServerActiveObject *co = getobject(ref);
272 lua_pushnumber(L, 1);
275 int hp = co->getHP();
276 /*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
277 <<" hp="<<hp<<std::endl;*/
279 lua_pushnumber(L, hp);
283 // get_inventory(self)
284 int ObjectRef::l_get_inventory(lua_State *L)
286 NO_MAP_LOCK_REQUIRED;
287 ObjectRef *ref = checkobject(L, 1);
288 ServerActiveObject *co = getobject(ref);
289 if (co == NULL) return 0;
291 InventoryLocation loc = co->getInventoryLocation();
292 if (getServer(L)->getInventory(loc) != NULL)
293 InvRef::create(L, loc);
295 lua_pushnil(L); // An object may have no inventory (nil)
299 // get_wield_list(self)
300 int ObjectRef::l_get_wield_list(lua_State *L)
302 NO_MAP_LOCK_REQUIRED;
303 ObjectRef *ref = checkobject(L, 1);
304 ServerActiveObject *co = getobject(ref);
308 lua_pushstring(L, co->getWieldList().c_str());
312 // get_wield_index(self)
313 int ObjectRef::l_get_wield_index(lua_State *L)
315 NO_MAP_LOCK_REQUIRED;
316 ObjectRef *ref = checkobject(L, 1);
317 ServerActiveObject *co = getobject(ref);
321 lua_pushinteger(L, co->getWieldIndex() + 1);
325 // get_wielded_item(self)
326 int ObjectRef::l_get_wielded_item(lua_State *L)
328 NO_MAP_LOCK_REQUIRED;
329 ObjectRef *ref = checkobject(L, 1);
330 ServerActiveObject *co = getobject(ref);
333 LuaItemStack::create(L, ItemStack());
337 ItemStack selected_item;
338 co->getWieldedItem(&selected_item, nullptr);
339 LuaItemStack::create(L, selected_item);
343 // set_wielded_item(self, itemstack or itemstring or table or nil)
344 int ObjectRef::l_set_wielded_item(lua_State *L)
346 NO_MAP_LOCK_REQUIRED;
347 ObjectRef *ref = checkobject(L, 1);
348 ServerActiveObject *co = getobject(ref);
349 if (co == NULL) return 0;
351 ItemStack item = read_item(L, 2, getServer(L)->idef());
352 bool success = co->setWieldedItem(item);
353 if (success && co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
354 getServer(L)->SendInventory((PlayerSAO *)co, true);
356 lua_pushboolean(L, success);
360 // set_armor_groups(self, groups)
361 int ObjectRef::l_set_armor_groups(lua_State *L)
363 NO_MAP_LOCK_REQUIRED;
364 ObjectRef *ref = checkobject(L, 1);
365 ServerActiveObject *co = getobject(ref);
366 if (co == NULL) return 0;
368 ItemGroupList groups;
369 read_groups(L, 2, groups);
370 co->setArmorGroups(groups);
374 // get_armor_groups(self)
375 int ObjectRef::l_get_armor_groups(lua_State *L)
377 NO_MAP_LOCK_REQUIRED;
378 ObjectRef *ref = checkobject(L, 1);
379 ServerActiveObject *co = getobject(ref);
383 push_groups(L, co->getArmorGroups());
387 // set_physics_override(self, physics_override_speed, physics_override_jump,
388 // physics_override_gravity, sneak, sneak_glitch, new_move)
389 int ObjectRef::l_set_physics_override(lua_State *L)
391 NO_MAP_LOCK_REQUIRED;
392 ObjectRef *ref = checkobject(L, 1);
393 PlayerSAO *co = (PlayerSAO *) getobject(ref);
394 if (co == NULL) return 0;
396 if (lua_istable(L, 2)) {
397 co->m_physics_override_speed = getfloatfield_default(
398 L, 2, "speed", co->m_physics_override_speed);
399 co->m_physics_override_jump = getfloatfield_default(
400 L, 2, "jump", co->m_physics_override_jump);
401 co->m_physics_override_gravity = getfloatfield_default(
402 L, 2, "gravity", co->m_physics_override_gravity);
403 co->m_physics_override_sneak = getboolfield_default(
404 L, 2, "sneak", co->m_physics_override_sneak);
405 co->m_physics_override_sneak_glitch = getboolfield_default(
406 L, 2, "sneak_glitch", co->m_physics_override_sneak_glitch);
407 co->m_physics_override_new_move = getboolfield_default(
408 L, 2, "new_move", co->m_physics_override_new_move);
409 co->m_physics_override_sent = false;
411 // old, non-table format
412 if (!lua_isnil(L, 2)) {
413 co->m_physics_override_speed = lua_tonumber(L, 2);
414 co->m_physics_override_sent = false;
416 if (!lua_isnil(L, 3)) {
417 co->m_physics_override_jump = lua_tonumber(L, 3);
418 co->m_physics_override_sent = false;
420 if (!lua_isnil(L, 4)) {
421 co->m_physics_override_gravity = lua_tonumber(L, 4);
422 co->m_physics_override_sent = false;
428 // get_physics_override(self)
429 int ObjectRef::l_get_physics_override(lua_State *L)
431 NO_MAP_LOCK_REQUIRED;
432 ObjectRef *ref = checkobject(L, 1);
433 PlayerSAO *co = (PlayerSAO *)getobject(ref);
438 lua_pushnumber(L, co->m_physics_override_speed);
439 lua_setfield(L, -2, "speed");
440 lua_pushnumber(L, co->m_physics_override_jump);
441 lua_setfield(L, -2, "jump");
442 lua_pushnumber(L, co->m_physics_override_gravity);
443 lua_setfield(L, -2, "gravity");
444 lua_pushboolean(L, co->m_physics_override_sneak);
445 lua_setfield(L, -2, "sneak");
446 lua_pushboolean(L, co->m_physics_override_sneak_glitch);
447 lua_setfield(L, -2, "sneak_glitch");
448 lua_pushboolean(L, co->m_physics_override_new_move);
449 lua_setfield(L, -2, "new_move");
453 // set_animation(self, frame_range, frame_speed, frame_blend, frame_loop)
454 int ObjectRef::l_set_animation(lua_State *L)
456 NO_MAP_LOCK_REQUIRED;
457 ObjectRef *ref = checkobject(L, 1);
458 ServerActiveObject *co = getobject(ref);
459 if (co == NULL) return 0;
461 v2f frames = v2f(1, 1);
462 if (!lua_isnil(L, 2))
463 frames = readParam<v2f>(L, 2);
464 float frame_speed = 15;
465 if (!lua_isnil(L, 3))
466 frame_speed = lua_tonumber(L, 3);
467 float frame_blend = 0;
468 if (!lua_isnil(L, 4))
469 frame_blend = lua_tonumber(L, 4);
470 bool frame_loop = true;
471 if (lua_isboolean(L, 5))
472 frame_loop = readParam<bool>(L, 5);
473 co->setAnimation(frames, frame_speed, frame_blend, frame_loop);
477 // get_animation(self)
478 int ObjectRef::l_get_animation(lua_State *L)
480 NO_MAP_LOCK_REQUIRED;
481 ObjectRef *ref = checkobject(L, 1);
482 ServerActiveObject *co = getobject(ref);
486 v2f frames = v2f(1,1);
487 float frame_speed = 15;
488 float frame_blend = 0;
489 bool frame_loop = true;
490 co->getAnimation(&frames, &frame_speed, &frame_blend, &frame_loop);
493 lua_pushnumber(L, frame_speed);
494 lua_pushnumber(L, frame_blend);
495 lua_pushboolean(L, frame_loop);
499 // set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed)
500 int ObjectRef::l_set_local_animation(lua_State *L)
502 NO_MAP_LOCK_REQUIRED;
503 ObjectRef *ref = checkobject(L, 1);
504 RemotePlayer *player = getplayer(ref);
509 for (int i=0;i<4;i++) {
510 if (!lua_isnil(L, 2+1))
511 frames[i] = read_v2s32(L, 2+i);
513 float frame_speed = 30;
514 if (!lua_isnil(L, 6))
515 frame_speed = lua_tonumber(L, 6);
517 getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed);
518 lua_pushboolean(L, true);
522 // get_local_animation(self)
523 int ObjectRef::l_get_local_animation(lua_State *L)
525 NO_MAP_LOCK_REQUIRED;
526 ObjectRef *ref = checkobject(L, 1);
527 RemotePlayer *player = getplayer(ref);
533 player->getLocalAnimations(frames, &frame_speed);
535 for (const v2s32 &frame : frames) {
536 push_v2s32(L, frame);
539 lua_pushnumber(L, frame_speed);
543 // set_eye_offset(self, v3f first pv, v3f third pv)
544 int ObjectRef::l_set_eye_offset(lua_State *L)
546 NO_MAP_LOCK_REQUIRED;
547 ObjectRef *ref = checkobject(L, 1);
548 RemotePlayer *player = getplayer(ref);
552 v3f offset_first = v3f(0, 0, 0);
553 v3f offset_third = v3f(0, 0, 0);
555 if (!lua_isnil(L, 2))
556 offset_first = read_v3f(L, 2);
557 if (!lua_isnil(L, 3))
558 offset_third = read_v3f(L, 3);
560 // Prevent abuse of offset values (keep player always visible)
561 offset_third.X = rangelim(offset_third.X,-10,10);
562 offset_third.Z = rangelim(offset_third.Z,-5,5);
563 /* TODO: if possible: improve the camera colision detetion to allow Y <= -1.5) */
564 offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS
566 getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third);
567 lua_pushboolean(L, true);
571 // get_eye_offset(self)
572 int ObjectRef::l_get_eye_offset(lua_State *L)
574 NO_MAP_LOCK_REQUIRED;
575 ObjectRef *ref = checkobject(L, 1);
576 RemotePlayer *player = getplayer(ref);
580 push_v3f(L, player->eye_offset_first);
581 push_v3f(L, player->eye_offset_third);
585 // send_mapblock(self, pos)
586 int ObjectRef::l_send_mapblock(lua_State *L)
588 NO_MAP_LOCK_REQUIRED;
589 ObjectRef *ref = checkobject(L, 1);
591 RemotePlayer *player = getplayer(ref);
594 v3s16 p = read_v3s16(L, 2);
596 session_t peer_id = player->getPeerId();
597 bool r = getServer(L)->SendBlock(peer_id, p);
599 lua_pushboolean(L, r);
603 // set_animation_frame_speed(self, frame_speed)
604 int ObjectRef::l_set_animation_frame_speed(lua_State *L)
606 NO_MAP_LOCK_REQUIRED;
607 ObjectRef *ref = checkobject(L, 1);
608 ServerActiveObject *co = getobject(ref);
613 if (!lua_isnil(L, 2)) {
614 float frame_speed = lua_tonumber(L, 2);
615 co->setAnimationSpeed(frame_speed);
616 lua_pushboolean(L, true);
618 lua_pushboolean(L, false);
623 // set_bone_position(self, std::string bone, v3f position, v3f rotation)
624 int ObjectRef::l_set_bone_position(lua_State *L)
626 NO_MAP_LOCK_REQUIRED;
627 ObjectRef *ref = checkobject(L, 1);
628 ServerActiveObject *co = getobject(ref);
629 if (co == NULL) return 0;
632 if (!lua_isnil(L, 2))
633 bone = readParam<std::string>(L, 2);
634 v3f position = v3f(0, 0, 0);
635 if (!lua_isnil(L, 3))
636 position = check_v3f(L, 3);
637 v3f rotation = v3f(0, 0, 0);
638 if (!lua_isnil(L, 4))
639 rotation = check_v3f(L, 4);
640 co->setBonePosition(bone, position, rotation);
644 // get_bone_position(self, bone)
645 int ObjectRef::l_get_bone_position(lua_State *L)
647 NO_MAP_LOCK_REQUIRED;
648 ObjectRef *ref = checkobject(L, 1);
649 ServerActiveObject *co = getobject(ref);
654 if (!lua_isnil(L, 2))
655 bone = readParam<std::string>(L, 2);
657 v3f position = v3f(0, 0, 0);
658 v3f rotation = v3f(0, 0, 0);
659 co->getBonePosition(bone, &position, &rotation);
661 push_v3f(L, position);
662 push_v3f(L, rotation);
666 // set_attach(self, parent, bone, position, rotation)
667 int ObjectRef::l_set_attach(lua_State *L)
671 ObjectRef *ref = checkobject(L, 1);
672 ObjectRef *parent_ref = checkobject(L, 2);
673 ServerActiveObject *co = getobject(ref);
674 ServerActiveObject *parent = getobject(parent_ref);
682 v3f position = v3f(0, 0, 0);
683 v3f rotation = v3f(0, 0, 0);
684 co->getAttachment(&parent_id, &bone, &position, &rotation);
686 ServerActiveObject *old_parent = env->getActiveObject(parent_id);
687 old_parent->removeAttachmentChild(co->getId());
691 if (!lua_isnil(L, 3))
692 bone = readParam<std::string>(L, 3);
693 position = v3f(0, 0, 0);
694 if (!lua_isnil(L, 4))
695 position = read_v3f(L, 4);
696 rotation = v3f(0, 0, 0);
697 if (!lua_isnil(L, 5))
698 rotation = read_v3f(L, 5);
699 co->setAttachment(parent->getId(), bone, position, rotation);
700 parent->addAttachmentChild(co->getId());
705 int ObjectRef::l_get_attach(lua_State *L)
709 ObjectRef *ref = checkobject(L, 1);
710 ServerActiveObject *co = getobject(ref);
717 v3f position = v3f(0, 0, 0);
718 v3f rotation = v3f(0, 0, 0);
719 co->getAttachment(&parent_id, &bone, &position, &rotation);
722 ServerActiveObject *parent = env->getActiveObject(parent_id);
724 getScriptApiBase(L)->objectrefGetOrCreate(L, parent);
725 lua_pushlstring(L, bone.c_str(), bone.size());
726 push_v3f(L, position);
727 push_v3f(L, rotation);
732 int ObjectRef::l_set_detach(lua_State *L)
736 ObjectRef *ref = checkobject(L, 1);
737 ServerActiveObject *co = getobject(ref);
741 co->clearParentAttachment();
745 // set_properties(self, properties)
746 int ObjectRef::l_set_properties(lua_State *L)
748 NO_MAP_LOCK_REQUIRED;
749 ObjectRef *ref = checkobject(L, 1);
750 ServerActiveObject *co = getobject(ref);
754 ObjectProperties *prop = co->accessObjectProperties();
758 read_object_properties(L, 2, co, prop, getServer(L)->idef());
759 co->notifyObjectPropertiesModified();
763 // get_properties(self)
764 int ObjectRef::l_get_properties(lua_State *L)
766 NO_MAP_LOCK_REQUIRED;
767 ObjectRef *ref = checkobject(L, 1);
768 ServerActiveObject *co = getobject(ref);
771 ObjectProperties *prop = co->accessObjectProperties();
774 push_object_properties(L, prop);
779 int ObjectRef::l_is_player(lua_State *L)
781 NO_MAP_LOCK_REQUIRED;
782 ObjectRef *ref = checkobject(L, 1);
783 RemotePlayer *player = getplayer(ref);
784 lua_pushboolean(L, (player != NULL));
788 // set_nametag_attributes(self, attributes)
789 int ObjectRef::l_set_nametag_attributes(lua_State *L)
791 NO_MAP_LOCK_REQUIRED;
792 ObjectRef *ref = checkobject(L, 1);
793 ServerActiveObject *co = getobject(ref);
797 ObjectProperties *prop = co->accessObjectProperties();
801 lua_getfield(L, 2, "color");
802 if (!lua_isnil(L, -1)) {
803 video::SColor color = prop->nametag_color;
804 read_color(L, -1, &color);
805 prop->nametag_color = color;
809 std::string nametag = getstringfield_default(L, 2, "text", "");
810 prop->nametag = nametag;
812 co->notifyObjectPropertiesModified();
813 lua_pushboolean(L, true);
817 // get_nametag_attributes(self)
818 int ObjectRef::l_get_nametag_attributes(lua_State *L)
820 NO_MAP_LOCK_REQUIRED;
821 ObjectRef *ref = checkobject(L, 1);
822 ServerActiveObject *co = getobject(ref);
826 ObjectProperties *prop = co->accessObjectProperties();
830 video::SColor color = prop->nametag_color;
833 push_ARGB8(L, color);
834 lua_setfield(L, -2, "color");
835 lua_pushstring(L, prop->nametag.c_str());
836 lua_setfield(L, -2, "text");
840 /* LuaEntitySAO-only */
842 // set_velocity(self, {x=num, y=num, z=num})
843 int ObjectRef::l_set_velocity(lua_State *L)
845 NO_MAP_LOCK_REQUIRED;
846 ObjectRef *ref = checkobject(L, 1);
847 LuaEntitySAO *co = getluaobject(ref);
848 if (co == NULL) return 0;
849 v3f pos = checkFloatPos(L, 2);
851 co->setVelocity(pos);
855 // add_velocity(self, {x=num, y=num, z=num})
856 int ObjectRef::l_add_velocity(lua_State *L)
858 NO_MAP_LOCK_REQUIRED;
859 ObjectRef *ref = checkobject(L, 1);
860 LuaEntitySAO *co = getluaobject(ref);
863 v3f pos = checkFloatPos(L, 2);
865 co->addVelocity(pos);
869 // get_velocity(self)
870 int ObjectRef::l_get_velocity(lua_State *L)
872 NO_MAP_LOCK_REQUIRED;
873 ObjectRef *ref = checkobject(L, 1);
874 LuaEntitySAO *co = getluaobject(ref);
875 if (co == NULL) return 0;
877 v3f v = co->getVelocity();
882 // set_acceleration(self, {x=num, y=num, z=num})
883 int ObjectRef::l_set_acceleration(lua_State *L)
885 NO_MAP_LOCK_REQUIRED;
886 ObjectRef *ref = checkobject(L, 1);
887 LuaEntitySAO *co = getluaobject(ref);
888 if (co == NULL) return 0;
890 v3f pos = checkFloatPos(L, 2);
892 co->setAcceleration(pos);
896 // get_acceleration(self)
897 int ObjectRef::l_get_acceleration(lua_State *L)
899 NO_MAP_LOCK_REQUIRED;
900 ObjectRef *ref = checkobject(L, 1);
901 LuaEntitySAO *co = getluaobject(ref);
902 if (co == NULL) return 0;
904 v3f v = co->getAcceleration();
909 // set_rotation(self, {x=num, y=num, z=num})
910 // Each 'num' is in radians
911 int ObjectRef::l_set_rotation(lua_State *L)
913 NO_MAP_LOCK_REQUIRED;
914 ObjectRef *ref = checkobject(L, 1);
915 LuaEntitySAO *co = getluaobject(ref);
919 v3f rotation = check_v3f(L, 2) * core::RADTODEG;
920 co->setRotation(rotation);
924 // get_rotation(self)
925 // returns: {x=num, y=num, z=num}
926 // Each 'num' is in radians
927 int ObjectRef::l_get_rotation(lua_State *L)
929 NO_MAP_LOCK_REQUIRED;
930 ObjectRef *ref = checkobject(L, 1);
931 LuaEntitySAO *co = getluaobject(ref);
936 v3f rotation = co->getRotation() * core::DEGTORAD;
937 push_v3f(L, rotation);
941 // set_yaw(self, radians)
942 int ObjectRef::l_set_yaw(lua_State *L)
944 NO_MAP_LOCK_REQUIRED;
945 ObjectRef *ref = checkobject(L, 1);
946 LuaEntitySAO *co = getluaobject(ref);
948 if (co == NULL) return 0;
950 throw LuaError("ObjectRef::set_yaw: NaN value is not allowed.");
952 float yaw = readParam<float>(L, 2) * core::RADTODEG;
953 co->setRotation(v3f(0, yaw, 0));
958 int ObjectRef::l_get_yaw(lua_State *L)
960 NO_MAP_LOCK_REQUIRED;
961 ObjectRef *ref = checkobject(L, 1);
962 LuaEntitySAO *co = getluaobject(ref);
966 float yaw = co->getRotation().Y * core::DEGTORAD;
967 lua_pushnumber(L, yaw);
971 // set_texture_mod(self, mod)
972 int ObjectRef::l_set_texture_mod(lua_State *L)
974 NO_MAP_LOCK_REQUIRED;
975 ObjectRef *ref = checkobject(L, 1);
976 LuaEntitySAO *co = getluaobject(ref);
977 if (co == NULL) return 0;
979 std::string mod = luaL_checkstring(L, 2);
980 co->setTextureMod(mod);
984 // get_texture_mod(self)
985 int ObjectRef::l_get_texture_mod(lua_State *L)
987 NO_MAP_LOCK_REQUIRED;
988 ObjectRef *ref = checkobject(L, 1);
989 LuaEntitySAO *co = getluaobject(ref);
990 if (co == NULL) return 0;
992 std::string mod = co->getTextureMod();
993 lua_pushstring(L, mod.c_str());
997 // set_sprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
998 // select_horiz_by_yawpitch=false)
999 int ObjectRef::l_set_sprite(lua_State *L)
1001 NO_MAP_LOCK_REQUIRED;
1002 ObjectRef *ref = checkobject(L, 1);
1003 LuaEntitySAO *co = getluaobject(ref);
1004 if (co == NULL) return 0;
1007 if (!lua_isnil(L, 2))
1008 p = readParam<v2s16>(L, 2);
1010 if (!lua_isnil(L, 3))
1011 num_frames = lua_tonumber(L, 3);
1012 float framelength = 0.2;
1013 if (!lua_isnil(L, 4))
1014 framelength = lua_tonumber(L, 4);
1015 bool select_horiz_by_yawpitch = false;
1016 if (!lua_isnil(L, 5))
1017 select_horiz_by_yawpitch = readParam<bool>(L, 5);
1018 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
1023 // get_entity_name(self)
1024 int ObjectRef::l_get_entity_name(lua_State *L)
1026 NO_MAP_LOCK_REQUIRED;
1027 ObjectRef *ref = checkobject(L, 1);
1028 LuaEntitySAO *co = getluaobject(ref);
1029 log_deprecated(L,"Deprecated call to \"get_entity_name");
1030 if (co == NULL) return 0;
1032 std::string name = co->getName();
1033 lua_pushstring(L, name.c_str());
1037 // get_luaentity(self)
1038 int ObjectRef::l_get_luaentity(lua_State *L)
1040 NO_MAP_LOCK_REQUIRED;
1041 ObjectRef *ref = checkobject(L, 1);
1042 LuaEntitySAO *co = getluaobject(ref);
1043 if (co == NULL) return 0;
1045 luaentity_get(L, co->getId());
1051 // is_player_connected(self)
1052 int ObjectRef::l_is_player_connected(lua_State *L)
1054 NO_MAP_LOCK_REQUIRED;
1055 // This method was once added for a bugfix, but never documented
1056 log_deprecated(L, "is_player_connected is undocumented and "
1057 "will be removed in a future release");
1058 ObjectRef *ref = checkobject(L, 1);
1059 RemotePlayer *player = getplayer(ref);
1060 lua_pushboolean(L, (player != NULL && player->getPeerId() != PEER_ID_INEXISTENT));
1064 // get_player_name(self)
1065 int ObjectRef::l_get_player_name(lua_State *L)
1067 NO_MAP_LOCK_REQUIRED;
1068 ObjectRef *ref = checkobject(L, 1);
1069 RemotePlayer *player = getplayer(ref);
1070 if (player == NULL) {
1071 lua_pushlstring(L, "", 0);
1075 lua_pushstring(L, player->getName());
1079 // get_player_velocity(self)
1080 int ObjectRef::l_get_player_velocity(lua_State *L)
1082 NO_MAP_LOCK_REQUIRED;
1083 ObjectRef *ref = checkobject(L, 1);
1084 RemotePlayer *player = getplayer(ref);
1085 if (player == NULL) {
1090 push_v3f(L, player->getSpeed() / BS);
1094 // add_player_velocity(self, {x=num, y=num, z=num})
1095 int ObjectRef::l_add_player_velocity(lua_State *L)
1097 NO_MAP_LOCK_REQUIRED;
1098 ObjectRef *ref = checkobject(L, 1);
1099 v3f vel = checkFloatPos(L, 2);
1101 PlayerSAO *co = getplayersao(ref);
1106 co->setMaxSpeedOverride(vel);
1107 getServer(L)->SendPlayerSpeed(co->getPeerID(), vel);
1111 // get_look_dir(self)
1112 int ObjectRef::l_get_look_dir(lua_State *L)
1114 NO_MAP_LOCK_REQUIRED;
1115 ObjectRef *ref = checkobject(L, 1);
1116 PlayerSAO* co = getplayersao(ref);
1117 if (co == NULL) return 0;
1119 float pitch = co->getRadLookPitchDep();
1120 float yaw = co->getRadYawDep();
1121 v3f v(std::cos(pitch) * std::cos(yaw), std::sin(pitch), std::cos(pitch) *
1128 // get_look_pitch(self)
1129 int ObjectRef::l_get_look_pitch(lua_State *L)
1131 NO_MAP_LOCK_REQUIRED;
1134 "Deprecated call to get_look_pitch, use get_look_vertical instead");
1136 ObjectRef *ref = checkobject(L, 1);
1137 PlayerSAO* co = getplayersao(ref);
1138 if (co == NULL) return 0;
1140 lua_pushnumber(L, co->getRadLookPitchDep());
1145 // get_look_yaw(self)
1146 int ObjectRef::l_get_look_yaw(lua_State *L)
1148 NO_MAP_LOCK_REQUIRED;
1151 "Deprecated call to get_look_yaw, use get_look_horizontal instead");
1153 ObjectRef *ref = checkobject(L, 1);
1154 PlayerSAO* co = getplayersao(ref);
1155 if (co == NULL) return 0;
1157 lua_pushnumber(L, co->getRadYawDep());
1161 // get_look_pitch2(self)
1162 int ObjectRef::l_get_look_vertical(lua_State *L)
1164 NO_MAP_LOCK_REQUIRED;
1165 ObjectRef *ref = checkobject(L, 1);
1166 PlayerSAO* co = getplayersao(ref);
1167 if (co == NULL) return 0;
1169 lua_pushnumber(L, co->getRadLookPitch());
1173 // get_look_yaw2(self)
1174 int ObjectRef::l_get_look_horizontal(lua_State *L)
1176 NO_MAP_LOCK_REQUIRED;
1177 ObjectRef *ref = checkobject(L, 1);
1178 PlayerSAO* co = getplayersao(ref);
1179 if (co == NULL) return 0;
1181 lua_pushnumber(L, co->getRadRotation().Y);
1185 // set_look_vertical(self, radians)
1186 int ObjectRef::l_set_look_vertical(lua_State *L)
1188 NO_MAP_LOCK_REQUIRED;
1189 ObjectRef *ref = checkobject(L, 1);
1190 PlayerSAO* co = getplayersao(ref);
1191 if (co == NULL) return 0;
1192 float pitch = readParam<float>(L, 2) * core::RADTODEG;
1194 co->setLookPitchAndSend(pitch);
1198 // set_look_horizontal(self, radians)
1199 int ObjectRef::l_set_look_horizontal(lua_State *L)
1201 NO_MAP_LOCK_REQUIRED;
1202 ObjectRef *ref = checkobject(L, 1);
1203 PlayerSAO* co = getplayersao(ref);
1204 if (co == NULL) return 0;
1205 float yaw = readParam<float>(L, 2) * core::RADTODEG;
1207 co->setPlayerYawAndSend(yaw);
1212 // set_look_pitch(self, radians)
1213 int ObjectRef::l_set_look_pitch(lua_State *L)
1215 NO_MAP_LOCK_REQUIRED;
1218 "Deprecated call to set_look_pitch, use set_look_vertical instead.");
1220 ObjectRef *ref = checkobject(L, 1);
1221 PlayerSAO* co = getplayersao(ref);
1222 if (co == NULL) return 0;
1223 float pitch = readParam<float>(L, 2) * core::RADTODEG;
1225 co->setLookPitchAndSend(pitch);
1230 // set_look_yaw(self, radians)
1231 int ObjectRef::l_set_look_yaw(lua_State *L)
1233 NO_MAP_LOCK_REQUIRED;
1236 "Deprecated call to set_look_yaw, use set_look_horizontal instead.");
1238 ObjectRef *ref = checkobject(L, 1);
1239 PlayerSAO* co = getplayersao(ref);
1240 if (co == NULL) return 0;
1241 float yaw = readParam<float>(L, 2) * core::RADTODEG;
1243 co->setPlayerYawAndSend(yaw);
1247 // set_fov(self, degrees[, is_multiplier])
1248 int ObjectRef::l_set_fov(lua_State *L)
1250 NO_MAP_LOCK_REQUIRED;
1251 ObjectRef *ref = checkobject(L, 1);
1252 RemotePlayer *player = getplayer(ref);
1256 player->setFov({ static_cast<f32>(luaL_checknumber(L, 2)), readParam<bool>(L, 3) });
1257 getServer(L)->SendPlayerFov(player->getPeerId());
1263 int ObjectRef::l_get_fov(lua_State *L)
1265 NO_MAP_LOCK_REQUIRED;
1266 ObjectRef *ref = checkobject(L, 1);
1267 RemotePlayer *player = getplayer(ref);
1271 PlayerFovSpec fov_spec = player->getFov();
1272 lua_pushnumber(L, fov_spec.fov);
1273 lua_pushboolean(L, fov_spec.is_multiplier);
1278 // set_breath(self, breath)
1279 int ObjectRef::l_set_breath(lua_State *L)
1281 NO_MAP_LOCK_REQUIRED;
1282 ObjectRef *ref = checkobject(L, 1);
1283 PlayerSAO* co = getplayersao(ref);
1284 if (co == NULL) return 0;
1285 u16 breath = luaL_checknumber(L, 2);
1286 co->setBreath(breath);
1292 int ObjectRef::l_get_breath(lua_State *L)
1294 NO_MAP_LOCK_REQUIRED;
1295 ObjectRef *ref = checkobject(L, 1);
1296 PlayerSAO* co = getplayersao(ref);
1297 if (co == NULL) return 0;
1299 u16 breath = co->getBreath();
1300 lua_pushinteger (L, breath);
1304 // set_attribute(self, attribute, value)
1305 int ObjectRef::l_set_attribute(lua_State *L)
1308 "Deprecated call to set_attribute, use MetaDataRef methods instead.");
1310 ObjectRef *ref = checkobject(L, 1);
1311 PlayerSAO* co = getplayersao(ref);
1315 std::string attr = luaL_checkstring(L, 2);
1316 if (lua_isnil(L, 3)) {
1317 co->getMeta().removeString(attr);
1319 std::string value = luaL_checkstring(L, 3);
1320 co->getMeta().setString(attr, value);
1325 // get_attribute(self, attribute)
1326 int ObjectRef::l_get_attribute(lua_State *L)
1329 "Deprecated call to get_attribute, use MetaDataRef methods instead.");
1331 ObjectRef *ref = checkobject(L, 1);
1332 PlayerSAO* co = getplayersao(ref);
1336 std::string attr = luaL_checkstring(L, 2);
1339 if (co->getMeta().getStringToRef(attr, value)) {
1340 lua_pushstring(L, value.c_str());
1348 // get_meta(self, attribute)
1349 int ObjectRef::l_get_meta(lua_State *L)
1351 ObjectRef *ref = checkobject(L, 1);
1352 PlayerSAO *co = getplayersao(ref);
1356 PlayerMetaRef::create(L, &co->getMeta());
1361 // set_inventory_formspec(self, formspec)
1362 int ObjectRef::l_set_inventory_formspec(lua_State *L)
1364 NO_MAP_LOCK_REQUIRED;
1365 ObjectRef *ref = checkobject(L, 1);
1366 RemotePlayer *player = getplayer(ref);
1367 if (player == NULL) return 0;
1368 std::string formspec = luaL_checkstring(L, 2);
1370 player->inventory_formspec = formspec;
1371 getServer(L)->reportInventoryFormspecModified(player->getName());
1372 lua_pushboolean(L, true);
1376 // get_inventory_formspec(self) -> formspec
1377 int ObjectRef::l_get_inventory_formspec(lua_State *L)
1379 NO_MAP_LOCK_REQUIRED;
1380 ObjectRef *ref = checkobject(L, 1);
1381 RemotePlayer *player = getplayer(ref);
1382 if (player == NULL) return 0;
1384 std::string formspec = player->inventory_formspec;
1385 lua_pushlstring(L, formspec.c_str(), formspec.size());
1389 // set_formspec_prepend(self, formspec)
1390 int ObjectRef::l_set_formspec_prepend(lua_State *L)
1392 NO_MAP_LOCK_REQUIRED;
1393 ObjectRef *ref = checkobject(L, 1);
1394 RemotePlayer *player = getplayer(ref);
1398 std::string formspec = luaL_checkstring(L, 2);
1400 player->formspec_prepend = formspec;
1401 getServer(L)->reportFormspecPrependModified(player->getName());
1402 lua_pushboolean(L, true);
1406 // get_formspec_prepend(self) -> formspec
1407 int ObjectRef::l_get_formspec_prepend(lua_State *L)
1409 NO_MAP_LOCK_REQUIRED;
1410 ObjectRef *ref = checkobject(L, 1);
1411 RemotePlayer *player = getplayer(ref);
1415 std::string formspec = player->formspec_prepend;
1416 lua_pushlstring(L, formspec.c_str(), formspec.size());
1420 // get_player_control(self)
1421 int ObjectRef::l_get_player_control(lua_State *L)
1423 NO_MAP_LOCK_REQUIRED;
1424 ObjectRef *ref = checkobject(L, 1);
1425 RemotePlayer *player = getplayer(ref);
1426 if (player == NULL) {
1427 lua_pushlstring(L, "", 0);
1431 const PlayerControl &control = player->getPlayerControl();
1433 lua_pushboolean(L, control.up);
1434 lua_setfield(L, -2, "up");
1435 lua_pushboolean(L, control.down);
1436 lua_setfield(L, -2, "down");
1437 lua_pushboolean(L, control.left);
1438 lua_setfield(L, -2, "left");
1439 lua_pushboolean(L, control.right);
1440 lua_setfield(L, -2, "right");
1441 lua_pushboolean(L, control.jump);
1442 lua_setfield(L, -2, "jump");
1443 lua_pushboolean(L, control.aux1);
1444 lua_setfield(L, -2, "aux1");
1445 lua_pushboolean(L, control.sneak);
1446 lua_setfield(L, -2, "sneak");
1447 lua_pushboolean(L, control.LMB);
1448 lua_setfield(L, -2, "LMB");
1449 lua_pushboolean(L, control.RMB);
1450 lua_setfield(L, -2, "RMB");
1454 // get_player_control_bits(self)
1455 int ObjectRef::l_get_player_control_bits(lua_State *L)
1457 NO_MAP_LOCK_REQUIRED;
1458 ObjectRef *ref = checkobject(L, 1);
1459 RemotePlayer *player = getplayer(ref);
1460 if (player == NULL) {
1461 lua_pushlstring(L, "", 0);
1465 lua_pushnumber(L, player->keyPressed);
1469 // hud_add(self, form)
1470 int ObjectRef::l_hud_add(lua_State *L)
1472 NO_MAP_LOCK_REQUIRED;
1473 ObjectRef *ref = checkobject(L, 1);
1474 RemotePlayer *player = getplayer(ref);
1478 HudElement *elem = new HudElement;
1479 read_hud_element(L, elem);
1481 u32 id = getServer(L)->hudAdd(player, elem);
1482 if (id == U32_MAX) {
1487 lua_pushnumber(L, id);
1491 // hud_remove(self, id)
1492 int ObjectRef::l_hud_remove(lua_State *L)
1494 NO_MAP_LOCK_REQUIRED;
1495 ObjectRef *ref = checkobject(L, 1);
1496 RemotePlayer *player = getplayer(ref);
1501 if (!lua_isnil(L, 2))
1502 id = lua_tonumber(L, 2);
1504 if (!getServer(L)->hudRemove(player, id))
1507 lua_pushboolean(L, true);
1511 // hud_change(self, id, stat, data)
1512 int ObjectRef::l_hud_change(lua_State *L)
1514 NO_MAP_LOCK_REQUIRED;
1515 ObjectRef *ref = checkobject(L, 1);
1516 RemotePlayer *player = getplayer(ref);
1520 u32 id = lua_isnumber(L, 2) ? lua_tonumber(L, 2) : -1;
1522 HudElement *e = player->getHud(id);
1527 HudElementStat stat = read_hud_change(L, e, &value);
1529 getServer(L)->hudChange(player, id, stat, value);
1531 lua_pushboolean(L, true);
1535 // hud_get(self, id)
1536 int ObjectRef::l_hud_get(lua_State *L)
1538 NO_MAP_LOCK_REQUIRED;
1539 ObjectRef *ref = checkobject(L, 1);
1540 RemotePlayer *player = getplayer(ref);
1544 u32 id = lua_tonumber(L, -1);
1546 HudElement *e = player->getHud(id);
1549 push_hud_element(L, e);
1553 // hud_set_flags(self, flags)
1554 int ObjectRef::l_hud_set_flags(lua_State *L)
1556 NO_MAP_LOCK_REQUIRED;
1557 ObjectRef *ref = checkobject(L, 1);
1558 RemotePlayer *player = getplayer(ref);
1566 const EnumString *esp = es_HudBuiltinElement;
1567 for (int i = 0; esp[i].str; i++) {
1568 if (getboolfield(L, 2, esp[i].str, flag)) {
1569 flags |= esp[i].num * flag;
1573 if (!getServer(L)->hudSetFlags(player, flags, mask))
1576 lua_pushboolean(L, true);
1580 int ObjectRef::l_hud_get_flags(lua_State *L)
1582 NO_MAP_LOCK_REQUIRED;
1583 ObjectRef *ref = checkobject(L, 1);
1584 RemotePlayer *player = getplayer(ref);
1589 lua_pushboolean(L, player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE);
1590 lua_setfield(L, -2, "hotbar");
1591 lua_pushboolean(L, player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE);
1592 lua_setfield(L, -2, "healthbar");
1593 lua_pushboolean(L, player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE);
1594 lua_setfield(L, -2, "crosshair");
1595 lua_pushboolean(L, player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE);
1596 lua_setfield(L, -2, "wielditem");
1597 lua_pushboolean(L, player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE);
1598 lua_setfield(L, -2, "breathbar");
1599 lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE);
1600 lua_setfield(L, -2, "minimap");
1601 lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE);
1602 lua_setfield(L, -2, "minimap_radar");
1607 // hud_set_hotbar_itemcount(self, hotbar_itemcount)
1608 int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
1610 NO_MAP_LOCK_REQUIRED;
1611 ObjectRef *ref = checkobject(L, 1);
1612 RemotePlayer *player = getplayer(ref);
1616 s32 hotbar_itemcount = lua_tonumber(L, 2);
1618 if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
1621 lua_pushboolean(L, true);
1625 // hud_get_hotbar_itemcount(self)
1626 int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L)
1628 NO_MAP_LOCK_REQUIRED;
1629 ObjectRef *ref = checkobject(L, 1);
1630 RemotePlayer *player = getplayer(ref);
1634 lua_pushnumber(L, player->getHotbarItemcount());
1638 // hud_set_hotbar_image(self, name)
1639 int ObjectRef::l_hud_set_hotbar_image(lua_State *L)
1641 NO_MAP_LOCK_REQUIRED;
1642 ObjectRef *ref = checkobject(L, 1);
1643 RemotePlayer *player = getplayer(ref);
1647 std::string name = readParam<std::string>(L, 2);
1649 getServer(L)->hudSetHotbarImage(player, name);
1653 // hud_get_hotbar_image(self)
1654 int ObjectRef::l_hud_get_hotbar_image(lua_State *L)
1656 NO_MAP_LOCK_REQUIRED;
1657 ObjectRef *ref = checkobject(L, 1);
1658 RemotePlayer *player = getplayer(ref);
1662 const std::string &name = player->getHotbarImage();
1663 lua_pushlstring(L, name.c_str(), name.size());
1667 // hud_set_hotbar_selected_image(self, name)
1668 int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L)
1670 NO_MAP_LOCK_REQUIRED;
1671 ObjectRef *ref = checkobject(L, 1);
1672 RemotePlayer *player = getplayer(ref);
1676 std::string name = readParam<std::string>(L, 2);
1678 getServer(L)->hudSetHotbarSelectedImage(player, name);
1682 // hud_get_hotbar_selected_image(self)
1683 int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L)
1685 NO_MAP_LOCK_REQUIRED;
1686 ObjectRef *ref = checkobject(L, 1);
1687 RemotePlayer *player = getplayer(ref);
1691 const std::string &name = player->getHotbarSelectedImage();
1692 lua_pushlstring(L, name.c_str(), name.size());
1696 // set_sky(self, {base_color=, type=, textures=, clouds=, sky_colors={}})
1697 int ObjectRef::l_set_sky(lua_State *L)
1699 NO_MAP_LOCK_REQUIRED;
1700 ObjectRef *ref = checkobject(L, 1);
1701 RemotePlayer *player = getplayer(ref);
1705 bool is_colorspec = is_color_table(L, 2);
1707 SkyboxParams skybox_params = player->getSkyParams();
1708 if (lua_istable(L, 2) && !is_colorspec) {
1709 lua_getfield(L, 2, "base_color");
1710 if (!lua_isnil(L, -1))
1711 read_color(L, -1, &skybox_params.bgcolor);
1714 lua_getfield(L, 2, "type");
1715 if (!lua_isnil(L, -1))
1716 skybox_params.type = luaL_checkstring(L, -1);
1719 lua_getfield(L, 2, "textures");
1720 skybox_params.textures.clear();
1721 if (lua_istable(L, -1) && skybox_params.type == "skybox") {
1723 while (lua_next(L, -2) != 0) {
1724 // Key is at index -2 and value at index -1
1725 skybox_params.textures.emplace_back(readParam<std::string>(L, -1));
1726 // Removes the value, but keeps the key for iteration
1733 We want to avoid crashes, so we're checking even if we're not using them.
1734 However, we want to ensure that the skybox can be set to nil when
1735 using "regular" or "plain" skybox modes as textures aren't needed.
1738 if (skybox_params.textures.size() != 6 && skybox_params.textures.size() > 0)
1739 throw LuaError("Skybox expects 6 textures!");
1741 skybox_params.clouds = getboolfield_default(L, 2,
1742 "clouds", skybox_params.clouds);
1744 lua_getfield(L, 2, "sky_color");
1745 if (lua_istable(L, -1)) {
1746 lua_getfield(L, -1, "day_sky");
1747 read_color(L, -1, &skybox_params.sky_color.day_sky);
1750 lua_getfield(L, -1, "day_horizon");
1751 read_color(L, -1, &skybox_params.sky_color.day_horizon);
1754 lua_getfield(L, -1, "dawn_sky");
1755 read_color(L, -1, &skybox_params.sky_color.dawn_sky);
1758 lua_getfield(L, -1, "dawn_horizon");
1759 read_color(L, -1, &skybox_params.sky_color.dawn_horizon);
1762 lua_getfield(L, -1, "night_sky");
1763 read_color(L, -1, &skybox_params.sky_color.night_sky);
1766 lua_getfield(L, -1, "night_horizon");
1767 read_color(L, -1, &skybox_params.sky_color.night_horizon);
1770 lua_getfield(L, -1, "indoors");
1771 read_color(L, -1, &skybox_params.sky_color.indoors);
1774 // Prevent flickering clouds at dawn/dusk:
1775 skybox_params.sun_tint = video::SColor(255, 255, 255, 255);
1776 lua_getfield(L, -1, "fog_sun_tint");
1777 read_color(L, -1, &skybox_params.sun_tint);
1780 skybox_params.moon_tint = video::SColor(255, 255, 255, 255);
1781 lua_getfield(L, -1, "fog_moon_tint");
1782 read_color(L, -1, &skybox_params.moon_tint);
1785 lua_getfield(L, -1, "fog_tint_type");
1786 if (!lua_isnil(L, -1))
1787 skybox_params.tint_type = luaL_checkstring(L, -1);
1790 // Because we need to leave the "sky_color" table.
1794 // Handle old set_sky calls, and log deprecated:
1795 log_deprecated(L, "Deprecated call to set_sky, please check lua_api.txt");
1797 // Fix sun, moon and stars showing when classic textured skyboxes are used
1798 SunParams sun_params = player->getSunParams();
1799 MoonParams moon_params = player->getMoonParams();
1800 StarParams star_params = player->getStarParams();
1802 // Prevent erroneous background colors
1803 skybox_params.bgcolor = video::SColor(255, 255, 255, 255);
1804 read_color(L, 2, &skybox_params.bgcolor);
1806 skybox_params.type = luaL_checkstring(L, 3);
1808 // Preserve old behaviour of the sun, moon and stars
1809 // when using the old set_sky call.
1810 if (skybox_params.type == "regular") {
1811 sun_params.visible = true;
1812 sun_params.sunrise_visible = true;
1813 moon_params.visible = true;
1814 star_params.visible = true;
1816 sun_params.visible = false;
1817 sun_params.sunrise_visible = false;
1818 moon_params.visible = false;
1819 star_params.visible = false;
1822 skybox_params.textures.clear();
1823 if (lua_istable(L, 4)) {
1825 while (lua_next(L, 4) != 0) {
1826 // Key at index -2, and value at index -1
1827 if (lua_isstring(L, -1))
1828 skybox_params.textures.emplace_back(readParam<std::string>(L, -1));
1830 skybox_params.textures.emplace_back("");
1831 // Remove the value, keep the key for the next iteration
1835 if (skybox_params.type == "skybox" && skybox_params.textures.size() != 6)
1836 throw LuaError("Skybox expects 6 textures.");
1838 skybox_params.clouds = true;
1839 if (lua_isboolean(L, 5))
1840 skybox_params.clouds = readParam<bool>(L, 5);
1842 getServer(L)->setSun(player, sun_params);
1843 getServer(L)->setMoon(player, moon_params);
1844 getServer(L)->setStars(player, star_params);
1846 getServer(L)->setSky(player, skybox_params);
1847 lua_pushboolean(L, true);
1852 int ObjectRef::l_get_sky(lua_State *L)
1854 NO_MAP_LOCK_REQUIRED;
1855 ObjectRef *ref = checkobject(L, 1);
1856 RemotePlayer *player = getplayer(ref);
1860 SkyboxParams skybox_params;
1861 skybox_params = player->getSkyParams();
1863 push_ARGB8(L, skybox_params.bgcolor);
1864 lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size());
1868 for (const std::string& texture : skybox_params.textures) {
1869 lua_pushlstring(L, texture.c_str(), texture.size());
1870 lua_rawseti(L, -2, i++);
1872 lua_pushboolean(L, skybox_params.clouds);
1876 // get_sky_color(self)
1877 int ObjectRef::l_get_sky_color(lua_State *L)
1879 NO_MAP_LOCK_REQUIRED;
1880 ObjectRef *ref = checkobject(L, 1);
1881 RemotePlayer *player = getplayer(ref);
1886 const SkyboxParams& skybox_params = player->getSkyParams();
1889 if (skybox_params.type == "regular") {
1890 push_ARGB8(L, skybox_params.sky_color.day_sky);
1891 lua_setfield(L, -2, "day_sky");
1892 push_ARGB8(L, skybox_params.sky_color.day_horizon);
1893 lua_setfield(L, -2, "day_horizon");
1894 push_ARGB8(L, skybox_params.sky_color.dawn_sky);
1895 lua_setfield(L, -2, "dawn_sky");
1896 push_ARGB8(L, skybox_params.sky_color.dawn_horizon);
1897 lua_setfield(L, -2, "dawn_horizon");
1898 push_ARGB8(L, skybox_params.sky_color.night_sky);
1899 lua_setfield(L, -2, "night_sky");
1900 push_ARGB8(L, skybox_params.sky_color.night_horizon);
1901 lua_setfield(L, -2, "night_horizon");
1902 push_ARGB8(L, skybox_params.sky_color.indoors);
1903 lua_setfield(L, -2, "indoors");
1905 push_ARGB8(L, skybox_params.sun_tint);
1906 lua_setfield(L, -2, "sun_tint");
1907 push_ARGB8(L, skybox_params.moon_tint);
1908 lua_setfield(L, -2, "moon_tint");
1909 lua_pushstring(L, skybox_params.tint_type.c_str());
1910 lua_setfield(L, -2, "tint_type");
1914 // set_sun(self, {visible, texture=, tonemap=, sunrise=, rotation=, scale=})
1915 int ObjectRef::l_set_sun(lua_State *L)
1917 NO_MAP_LOCK_REQUIRED;
1918 ObjectRef *ref = checkobject(L, 1);
1919 RemotePlayer *player = getplayer(ref);
1923 if (!lua_istable(L, 2))
1926 SunParams sun_params = player->getSunParams();
1928 sun_params.visible = getboolfield_default(L, 2,
1929 "visible", sun_params.visible);
1930 sun_params.texture = getstringfield_default(L, 2,
1931 "texture", sun_params.texture);
1932 sun_params.tonemap = getstringfield_default(L, 2,
1933 "tonemap", sun_params.tonemap);
1934 sun_params.sunrise = getstringfield_default(L, 2,
1935 "sunrise", sun_params.sunrise);
1936 sun_params.sunrise_visible = getboolfield_default(L, 2,
1937 "sunrise_visible", sun_params.sunrise_visible);
1938 sun_params.scale = getfloatfield_default(L, 2,
1939 "scale", sun_params.scale);
1941 getServer(L)->setSun(player, sun_params);
1942 lua_pushboolean(L, true);
1947 int ObjectRef::l_get_sun(lua_State *L)
1949 NO_MAP_LOCK_REQUIRED;
1950 ObjectRef *ref = checkobject(L, 1);
1951 RemotePlayer *player = getplayer(ref);
1954 const SunParams &sun_params = player->getSunParams();
1957 lua_pushboolean(L, sun_params.visible);
1958 lua_setfield(L, -2, "visible");
1959 lua_pushstring(L, sun_params.texture.c_str());
1960 lua_setfield(L, -2, "texture");
1961 lua_pushstring(L, sun_params.tonemap.c_str());
1962 lua_setfield(L, -2, "tonemap");
1963 lua_pushstring(L, sun_params.sunrise.c_str());
1964 lua_setfield(L, -2, "sunrise");
1965 lua_pushboolean(L, sun_params.sunrise_visible);
1966 lua_setfield(L, -2, "sunrise_visible");
1967 lua_pushnumber(L, sun_params.scale);
1968 lua_setfield(L, -2, "scale");
1973 // set_moon(self, {visible, texture=, tonemap=, sunrise=, rotation=, scale=})
1974 int ObjectRef::l_set_moon(lua_State *L)
1976 NO_MAP_LOCK_REQUIRED;
1977 ObjectRef *ref = checkobject(L, 1);
1978 RemotePlayer *player = getplayer(ref);
1981 if (!lua_istable(L, 2))
1984 MoonParams moon_params = player->getMoonParams();
1986 moon_params.visible = getboolfield_default(L, 2,
1987 "visible", moon_params.visible);
1988 moon_params.texture = getstringfield_default(L, 2,
1989 "texture", moon_params.texture);
1990 moon_params.tonemap = getstringfield_default(L, 2,
1991 "tonemap", moon_params.tonemap);
1992 moon_params.scale = getfloatfield_default(L, 2,
1993 "scale", moon_params.scale);
1995 getServer(L)->setMoon(player, moon_params);
1996 lua_pushboolean(L, true);
2001 int ObjectRef::l_get_moon(lua_State *L)
2003 NO_MAP_LOCK_REQUIRED;
2004 ObjectRef *ref = checkobject(L, 1);
2005 RemotePlayer *player = getplayer(ref);
2008 const MoonParams &moon_params = player->getMoonParams();
2011 lua_pushboolean(L, moon_params.visible);
2012 lua_setfield(L, -2, "visible");
2013 lua_pushstring(L, moon_params.texture.c_str());
2014 lua_setfield(L, -2, "texture");
2015 lua_pushstring(L, moon_params.tonemap.c_str());
2016 lua_setfield(L, -2, "tonemap");
2017 lua_pushnumber(L, moon_params.scale);
2018 lua_setfield(L, -2, "scale");
2023 // set_stars(self, {visible, count=, starcolor=, rotation=, scale=})
2024 int ObjectRef::l_set_stars(lua_State *L)
2026 NO_MAP_LOCK_REQUIRED;
2027 ObjectRef *ref = checkobject(L, 1);
2028 RemotePlayer *player = getplayer(ref);
2031 if (!lua_istable(L, 2))
2034 StarParams star_params = player->getStarParams();
2036 star_params.visible = getboolfield_default(L, 2,
2037 "visible", star_params.visible);
2038 star_params.count = getintfield_default(L, 2,
2039 "count", star_params.count);
2041 lua_getfield(L, 2, "star_color");
2042 if (!lua_isnil(L, -1))
2043 read_color(L, -1, &star_params.starcolor);
2046 star_params.scale = getfloatfield_default(L, 2,
2047 "scale", star_params.scale);
2049 getServer(L)->setStars(player, star_params);
2050 lua_pushboolean(L, true);
2055 int ObjectRef::l_get_stars(lua_State *L)
2057 NO_MAP_LOCK_REQUIRED;
2058 ObjectRef *ref = checkobject(L, 1);
2059 RemotePlayer *player = getplayer(ref);
2062 const StarParams &star_params = player->getStarParams();
2065 lua_pushboolean(L, star_params.visible);
2066 lua_setfield(L, -2, "visible");
2067 lua_pushnumber(L, star_params.count);
2068 lua_setfield(L, -2, "count");
2069 push_ARGB8(L, star_params.starcolor);
2070 lua_setfield(L, -2, "star_color");
2071 lua_pushnumber(L, star_params.scale);
2072 lua_setfield(L, -2, "scale");
2077 // set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=})
2078 int ObjectRef::l_set_clouds(lua_State *L)
2080 NO_MAP_LOCK_REQUIRED;
2081 ObjectRef *ref = checkobject(L, 1);
2082 RemotePlayer *player = getplayer(ref);
2085 if (!lua_istable(L, 2))
2088 CloudParams cloud_params = player->getCloudParams();
2090 cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density);
2092 lua_getfield(L, 2, "color");
2093 if (!lua_isnil(L, -1))
2094 read_color(L, -1, &cloud_params.color_bright);
2096 lua_getfield(L, 2, "ambient");
2097 if (!lua_isnil(L, -1))
2098 read_color(L, -1, &cloud_params.color_ambient);
2101 cloud_params.height = getfloatfield_default(L, 2, "height", cloud_params.height );
2102 cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness);
2104 lua_getfield(L, 2, "speed");
2105 if (lua_istable(L, -1)) {
2107 new_speed.X = getfloatfield_default(L, -1, "x", 0);
2108 new_speed.Y = getfloatfield_default(L, -1, "z", 0);
2109 cloud_params.speed = new_speed;
2113 getServer(L)->setClouds(player, cloud_params);
2114 lua_pushboolean(L, true);
2118 int ObjectRef::l_get_clouds(lua_State *L)
2120 NO_MAP_LOCK_REQUIRED;
2121 ObjectRef *ref = checkobject(L, 1);
2122 RemotePlayer *player = getplayer(ref);
2125 const CloudParams &cloud_params = player->getCloudParams();
2128 lua_pushnumber(L, cloud_params.density);
2129 lua_setfield(L, -2, "density");
2130 push_ARGB8(L, cloud_params.color_bright);
2131 lua_setfield(L, -2, "color");
2132 push_ARGB8(L, cloud_params.color_ambient);
2133 lua_setfield(L, -2, "ambient");
2134 lua_pushnumber(L, cloud_params.height);
2135 lua_setfield(L, -2, "height");
2136 lua_pushnumber(L, cloud_params.thickness);
2137 lua_setfield(L, -2, "thickness");
2139 lua_pushnumber(L, cloud_params.speed.X);
2140 lua_setfield(L, -2, "x");
2141 lua_pushnumber(L, cloud_params.speed.Y);
2142 lua_setfield(L, -2, "y");
2143 lua_setfield(L, -2, "speed");
2149 // override_day_night_ratio(self, brightness=0...1)
2150 int ObjectRef::l_override_day_night_ratio(lua_State *L)
2152 NO_MAP_LOCK_REQUIRED;
2153 ObjectRef *ref = checkobject(L, 1);
2154 RemotePlayer *player = getplayer(ref);
2158 bool do_override = false;
2160 if (!lua_isnil(L, 2)) {
2162 ratio = readParam<float>(L, 2);
2165 if (!getServer(L)->overrideDayNightRatio(player, do_override, ratio))
2168 lua_pushboolean(L, true);
2172 // get_day_night_ratio(self)
2173 int ObjectRef::l_get_day_night_ratio(lua_State *L)
2175 NO_MAP_LOCK_REQUIRED;
2176 ObjectRef *ref = checkobject(L, 1);
2177 RemotePlayer *player = getplayer(ref);
2183 player->getDayNightRatio(&do_override, &ratio);
2186 lua_pushnumber(L, ratio);
2193 ObjectRef::ObjectRef(ServerActiveObject *object):
2196 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2199 // Creates an ObjectRef and leaves it on top of stack
2200 // Not callable from Lua; all references are created on the C side.
2201 void ObjectRef::create(lua_State *L, ServerActiveObject *object)
2203 ObjectRef *o = new ObjectRef(object);
2204 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2205 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2206 luaL_getmetatable(L, className);
2207 lua_setmetatable(L, -2);
2210 void ObjectRef::set_null(lua_State *L)
2212 ObjectRef *o = checkobject(L, -1);
2216 void ObjectRef::Register(lua_State *L)
2219 int methodtable = lua_gettop(L);
2220 luaL_newmetatable(L, className);
2221 int metatable = lua_gettop(L);
2223 lua_pushliteral(L, "__metatable");
2224 lua_pushvalue(L, methodtable);
2225 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
2227 lua_pushliteral(L, "__index");
2228 lua_pushvalue(L, methodtable);
2229 lua_settable(L, metatable);
2231 lua_pushliteral(L, "__gc");
2232 lua_pushcfunction(L, gc_object);
2233 lua_settable(L, metatable);
2235 lua_pop(L, 1); // drop metatable
2237 markAliasDeprecated(methods);
2238 luaL_openlib(L, 0, methods, 0); // fill methodtable
2239 lua_pop(L, 1); // drop methodtable
2241 // Cannot be created from Lua
2242 //lua_register(L, className, create_object);
2245 const char ObjectRef::className[] = "ObjectRef";
2246 luaL_Reg ObjectRef::methods[] = {
2247 // ServerActiveObject
2248 luamethod(ObjectRef, remove),
2249 luamethod_aliased(ObjectRef, get_pos, getpos),
2250 luamethod_aliased(ObjectRef, set_pos, setpos),
2251 luamethod_aliased(ObjectRef, move_to, moveto),
2252 luamethod(ObjectRef, punch),
2253 luamethod(ObjectRef, right_click),
2254 luamethod(ObjectRef, set_hp),
2255 luamethod(ObjectRef, get_hp),
2256 luamethod(ObjectRef, get_inventory),
2257 luamethod(ObjectRef, get_wield_list),
2258 luamethod(ObjectRef, get_wield_index),
2259 luamethod(ObjectRef, get_wielded_item),
2260 luamethod(ObjectRef, set_wielded_item),
2261 luamethod(ObjectRef, set_armor_groups),
2262 luamethod(ObjectRef, get_armor_groups),
2263 luamethod(ObjectRef, set_animation),
2264 luamethod(ObjectRef, get_animation),
2265 luamethod(ObjectRef, set_animation_frame_speed),
2266 luamethod(ObjectRef, set_bone_position),
2267 luamethod(ObjectRef, get_bone_position),
2268 luamethod(ObjectRef, set_attach),
2269 luamethod(ObjectRef, get_attach),
2270 luamethod(ObjectRef, set_detach),
2271 luamethod(ObjectRef, set_properties),
2272 luamethod(ObjectRef, get_properties),
2273 luamethod(ObjectRef, set_nametag_attributes),
2274 luamethod(ObjectRef, get_nametag_attributes),
2275 // LuaEntitySAO-only
2276 luamethod_aliased(ObjectRef, set_velocity, setvelocity),
2277 luamethod(ObjectRef, add_velocity),
2278 luamethod_aliased(ObjectRef, get_velocity, getvelocity),
2279 luamethod_aliased(ObjectRef, set_acceleration, setacceleration),
2280 luamethod_aliased(ObjectRef, get_acceleration, getacceleration),
2281 luamethod_aliased(ObjectRef, set_yaw, setyaw),
2282 luamethod_aliased(ObjectRef, get_yaw, getyaw),
2283 luamethod(ObjectRef, set_rotation),
2284 luamethod(ObjectRef, get_rotation),
2285 luamethod_aliased(ObjectRef, set_texture_mod, settexturemod),
2286 luamethod_aliased(ObjectRef, set_sprite, setsprite),
2287 luamethod(ObjectRef, get_entity_name),
2288 luamethod(ObjectRef, get_luaentity),
2290 luamethod(ObjectRef, is_player),
2291 luamethod(ObjectRef, is_player_connected),
2292 luamethod(ObjectRef, get_player_name),
2293 luamethod(ObjectRef, get_player_velocity),
2294 luamethod(ObjectRef, add_player_velocity),
2295 luamethod(ObjectRef, get_look_dir),
2296 luamethod(ObjectRef, get_look_pitch),
2297 luamethod(ObjectRef, get_look_yaw),
2298 luamethod(ObjectRef, get_look_vertical),
2299 luamethod(ObjectRef, get_look_horizontal),
2300 luamethod(ObjectRef, set_look_horizontal),
2301 luamethod(ObjectRef, set_look_vertical),
2302 luamethod(ObjectRef, set_look_yaw),
2303 luamethod(ObjectRef, set_look_pitch),
2304 luamethod(ObjectRef, get_fov),
2305 luamethod(ObjectRef, set_fov),
2306 luamethod(ObjectRef, get_breath),
2307 luamethod(ObjectRef, set_breath),
2308 luamethod(ObjectRef, get_attribute),
2309 luamethod(ObjectRef, set_attribute),
2310 luamethod(ObjectRef, get_meta),
2311 luamethod(ObjectRef, set_inventory_formspec),
2312 luamethod(ObjectRef, get_inventory_formspec),
2313 luamethod(ObjectRef, set_formspec_prepend),
2314 luamethod(ObjectRef, get_formspec_prepend),
2315 luamethod(ObjectRef, get_player_control),
2316 luamethod(ObjectRef, get_player_control_bits),
2317 luamethod(ObjectRef, set_physics_override),
2318 luamethod(ObjectRef, get_physics_override),
2319 luamethod(ObjectRef, hud_add),
2320 luamethod(ObjectRef, hud_remove),
2321 luamethod(ObjectRef, hud_change),
2322 luamethod(ObjectRef, hud_get),
2323 luamethod(ObjectRef, hud_set_flags),
2324 luamethod(ObjectRef, hud_get_flags),
2325 luamethod(ObjectRef, hud_set_hotbar_itemcount),
2326 luamethod(ObjectRef, hud_get_hotbar_itemcount),
2327 luamethod(ObjectRef, hud_set_hotbar_image),
2328 luamethod(ObjectRef, hud_get_hotbar_image),
2329 luamethod(ObjectRef, hud_set_hotbar_selected_image),
2330 luamethod(ObjectRef, hud_get_hotbar_selected_image),
2331 luamethod(ObjectRef, set_sky),
2332 luamethod(ObjectRef, get_sky),
2333 luamethod(ObjectRef, get_sky_color),
2334 luamethod(ObjectRef, set_sun),
2335 luamethod(ObjectRef, get_sun),
2336 luamethod(ObjectRef, set_moon),
2337 luamethod(ObjectRef, get_moon),
2338 luamethod(ObjectRef, set_stars),
2339 luamethod(ObjectRef, get_stars),
2340 luamethod(ObjectRef, set_clouds),
2341 luamethod(ObjectRef, get_clouds),
2342 luamethod(ObjectRef, override_day_night_ratio),
2343 luamethod(ObjectRef, get_day_night_ratio),
2344 luamethod(ObjectRef, set_local_animation),
2345 luamethod(ObjectRef, get_local_animation),
2346 luamethod(ObjectRef, set_eye_offset),
2347 luamethod(ObjectRef, get_eye_offset),
2348 luamethod(ObjectRef, send_mapblock),