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 "scriptapi.h"
21 #include "scriptapi_object.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"
35 ObjectRef* ObjectRef::checkobject(lua_State *L, int narg)
37 luaL_checktype(L, narg, LUA_TUSERDATA);
38 void *ud = luaL_checkudata(L, narg, className);
39 if(!ud) luaL_typerror(L, narg, className);
40 return *(ObjectRef**)ud; // unbox pointer
43 ServerActiveObject* ObjectRef::getobject(ObjectRef *ref)
45 ServerActiveObject *co = ref->m_object;
49 LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref)
51 ServerActiveObject *obj = getobject(ref);
54 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
56 return (LuaEntitySAO*)obj;
59 PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
61 ServerActiveObject *obj = getobject(ref);
64 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
66 return (PlayerSAO*)obj;
69 Player* ObjectRef::getplayer(ObjectRef *ref)
71 PlayerSAO *playersao = getplayersao(ref);
74 return playersao->getPlayer();
80 int ObjectRef::gc_object(lua_State *L) {
81 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
82 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
88 int ObjectRef::l_remove(lua_State *L)
90 ObjectRef *ref = checkobject(L, 1);
91 ServerActiveObject *co = getobject(ref);
92 if(co == NULL) return 0;
93 verbosestream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
99 // returns: {x=num, y=num, z=num}
100 int ObjectRef::l_getpos(lua_State *L)
102 ObjectRef *ref = checkobject(L, 1);
103 ServerActiveObject *co = getobject(ref);
104 if(co == NULL) return 0;
105 v3f pos = co->getBasePosition() / BS;
107 lua_pushnumber(L, pos.X);
108 lua_setfield(L, -2, "x");
109 lua_pushnumber(L, pos.Y);
110 lua_setfield(L, -2, "y");
111 lua_pushnumber(L, pos.Z);
112 lua_setfield(L, -2, "z");
117 int ObjectRef::l_setpos(lua_State *L)
119 ObjectRef *ref = checkobject(L, 1);
120 //LuaEntitySAO *co = getluaobject(ref);
121 ServerActiveObject *co = getobject(ref);
122 if(co == NULL) return 0;
124 v3f pos = checkFloatPos(L, 2);
130 // moveto(self, pos, continuous=false)
131 int ObjectRef::l_moveto(lua_State *L)
133 ObjectRef *ref = checkobject(L, 1);
134 //LuaEntitySAO *co = getluaobject(ref);
135 ServerActiveObject *co = getobject(ref);
136 if(co == NULL) return 0;
138 v3f pos = checkFloatPos(L, 2);
140 bool continuous = lua_toboolean(L, 3);
142 co->moveTo(pos, continuous);
146 // punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
147 int ObjectRef::l_punch(lua_State *L)
149 ObjectRef *ref = checkobject(L, 1);
150 ObjectRef *puncher_ref = checkobject(L, 2);
151 ServerActiveObject *co = getobject(ref);
152 ServerActiveObject *puncher = getobject(puncher_ref);
153 if(co == NULL) return 0;
154 if(puncher == NULL) return 0;
156 if(lua_type(L, 5) != LUA_TTABLE)
157 dir = co->getBasePosition() - puncher->getBasePosition();
159 dir = read_v3f(L, 5);
160 float time_from_last_punch = 1000000;
161 if(lua_isnumber(L, 3))
162 time_from_last_punch = lua_tonumber(L, 3);
163 ToolCapabilities toolcap = read_tool_capabilities(L, 4);
166 co->punch(dir, &toolcap, puncher, time_from_last_punch);
170 // right_click(self, clicker); clicker = an another ObjectRef
171 int ObjectRef::l_right_click(lua_State *L)
173 ObjectRef *ref = checkobject(L, 1);
174 ObjectRef *ref2 = checkobject(L, 2);
175 ServerActiveObject *co = getobject(ref);
176 ServerActiveObject *co2 = getobject(ref2);
177 if(co == NULL) return 0;
178 if(co2 == NULL) return 0;
185 // hp = number of hitpoints (2 * number of hearts)
187 int ObjectRef::l_set_hp(lua_State *L)
189 ObjectRef *ref = checkobject(L, 1);
190 luaL_checknumber(L, 2);
191 ServerActiveObject *co = getobject(ref);
192 if(co == NULL) return 0;
193 int hp = lua_tonumber(L, 2);
194 /*infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
195 <<" hp="<<hp<<std::endl;*/
203 // returns: number of hitpoints (2 * number of hearts)
204 // 0 if not applicable to this type of object
205 int ObjectRef::l_get_hp(lua_State *L)
207 ObjectRef *ref = checkobject(L, 1);
208 ServerActiveObject *co = getobject(ref);
211 lua_pushnumber(L, 1);
214 int hp = co->getHP();
215 /*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
216 <<" hp="<<hp<<std::endl;*/
218 lua_pushnumber(L, hp);
222 // get_inventory(self)
223 int ObjectRef::l_get_inventory(lua_State *L)
225 ObjectRef *ref = checkobject(L, 1);
226 ServerActiveObject *co = getobject(ref);
227 if(co == NULL) return 0;
229 InventoryLocation loc = co->getInventoryLocation();
230 if(get_server(L)->getInventory(loc) != NULL)
231 InvRef::create(L, loc);
233 lua_pushnil(L); // An object may have no inventory (nil)
237 // get_wield_list(self)
238 int ObjectRef::l_get_wield_list(lua_State *L)
240 ObjectRef *ref = checkobject(L, 1);
241 ServerActiveObject *co = getobject(ref);
242 if(co == NULL) return 0;
244 lua_pushstring(L, co->getWieldList().c_str());
248 // get_wield_index(self)
249 int ObjectRef::l_get_wield_index(lua_State *L)
251 ObjectRef *ref = checkobject(L, 1);
252 ServerActiveObject *co = getobject(ref);
253 if(co == NULL) return 0;
255 lua_pushinteger(L, co->getWieldIndex() + 1);
259 // get_wielded_item(self)
260 int ObjectRef::l_get_wielded_item(lua_State *L)
262 ObjectRef *ref = checkobject(L, 1);
263 ServerActiveObject *co = getobject(ref);
266 LuaItemStack::create(L, ItemStack());
270 LuaItemStack::create(L, co->getWieldedItem());
274 // set_wielded_item(self, itemstack or itemstring or table or nil)
275 int ObjectRef::l_set_wielded_item(lua_State *L)
277 ObjectRef *ref = checkobject(L, 1);
278 ServerActiveObject *co = getobject(ref);
279 if(co == NULL) return 0;
281 ItemStack item = read_item(L, 2);
282 bool success = co->setWieldedItem(item);
283 lua_pushboolean(L, success);
287 // set_armor_groups(self, groups)
288 int ObjectRef::l_set_armor_groups(lua_State *L)
290 ObjectRef *ref = checkobject(L, 1);
291 ServerActiveObject *co = getobject(ref);
292 if(co == NULL) return 0;
294 ItemGroupList groups;
295 read_groups(L, 2, groups);
296 co->setArmorGroups(groups);
300 // set_physics_override(self, physics_override_speed, physics_override_jump, physics_override_gravity)
301 int ObjectRef::l_set_physics_override(lua_State *L)
303 ObjectRef *ref = checkobject(L, 1);
304 PlayerSAO *co = (PlayerSAO *) getobject(ref);
305 if(co == NULL) return 0;
307 if(!lua_isnil(L, 2)){
308 co->m_physics_override_speed = lua_tonumber(L, 2);
309 co->m_physics_override_sent = false;
311 if(!lua_isnil(L, 3)){
312 co->m_physics_override_jump = lua_tonumber(L, 3);
313 co->m_physics_override_sent = false;
315 if(!lua_isnil(L, 4)){
316 co->m_physics_override_gravity = lua_tonumber(L, 4);
317 co->m_physics_override_sent = false;
322 // set_animation(self, frame_range, frame_speed, frame_blend)
323 int ObjectRef::l_set_animation(lua_State *L)
325 ObjectRef *ref = checkobject(L, 1);
326 ServerActiveObject *co = getobject(ref);
327 if(co == NULL) return 0;
329 v2f frames = v2f(1, 1);
331 frames = read_v2f(L, 2);
332 float frame_speed = 15;
334 frame_speed = lua_tonumber(L, 3);
335 float frame_blend = 0;
337 frame_blend = lua_tonumber(L, 4);
338 co->setAnimation(frames, frame_speed, frame_blend);
342 // set_bone_position(self, std::string bone, v3f position, v3f rotation)
343 int ObjectRef::l_set_bone_position(lua_State *L)
345 ObjectRef *ref = checkobject(L, 1);
346 ServerActiveObject *co = getobject(ref);
347 if(co == NULL) return 0;
349 std::string bone = "";
351 bone = lua_tostring(L, 2);
352 v3f position = v3f(0, 0, 0);
354 position = read_v3f(L, 3);
355 v3f rotation = v3f(0, 0, 0);
357 rotation = read_v3f(L, 4);
358 co->setBonePosition(bone, position, rotation);
362 // set_attach(self, parent, bone, position, rotation)
363 int ObjectRef::l_set_attach(lua_State *L)
365 ObjectRef *ref = checkobject(L, 1);
366 ObjectRef *parent_ref = checkobject(L, 2);
367 ServerActiveObject *co = getobject(ref);
368 ServerActiveObject *parent = getobject(parent_ref);
369 if(co == NULL) return 0;
370 if(parent == NULL) return 0;
372 std::string bone = "";
374 bone = lua_tostring(L, 3);
375 v3f position = v3f(0, 0, 0);
377 position = read_v3f(L, 4);
378 v3f rotation = v3f(0, 0, 0);
380 rotation = read_v3f(L, 5);
381 co->setAttachment(parent->getId(), bone, position, rotation);
386 int ObjectRef::l_set_detach(lua_State *L)
388 ObjectRef *ref = checkobject(L, 1);
389 ServerActiveObject *co = getobject(ref);
390 if(co == NULL) return 0;
392 co->setAttachment(0, "", v3f(0,0,0), v3f(0,0,0));
396 // set_properties(self, properties)
397 int ObjectRef::l_set_properties(lua_State *L)
399 ObjectRef *ref = checkobject(L, 1);
400 ServerActiveObject *co = getobject(ref);
401 if(co == NULL) return 0;
402 ObjectProperties *prop = co->accessObjectProperties();
405 read_object_properties(L, 2, prop);
406 co->notifyObjectPropertiesModified();
410 /* LuaEntitySAO-only */
412 // setvelocity(self, {x=num, y=num, z=num})
413 int ObjectRef::l_setvelocity(lua_State *L)
415 ObjectRef *ref = checkobject(L, 1);
416 LuaEntitySAO *co = getluaobject(ref);
417 if(co == NULL) return 0;
418 v3f pos = checkFloatPos(L, 2);
420 co->setVelocity(pos);
425 int ObjectRef::l_getvelocity(lua_State *L)
427 ObjectRef *ref = checkobject(L, 1);
428 LuaEntitySAO *co = getluaobject(ref);
429 if(co == NULL) return 0;
431 v3f v = co->getVelocity();
436 // setacceleration(self, {x=num, y=num, z=num})
437 int ObjectRef::l_setacceleration(lua_State *L)
439 ObjectRef *ref = checkobject(L, 1);
440 LuaEntitySAO *co = getluaobject(ref);
441 if(co == NULL) return 0;
443 v3f pos = checkFloatPos(L, 2);
445 co->setAcceleration(pos);
449 // getacceleration(self)
450 int ObjectRef::l_getacceleration(lua_State *L)
452 ObjectRef *ref = checkobject(L, 1);
453 LuaEntitySAO *co = getluaobject(ref);
454 if(co == NULL) return 0;
456 v3f v = co->getAcceleration();
461 // setyaw(self, radians)
462 int ObjectRef::l_setyaw(lua_State *L)
464 ObjectRef *ref = checkobject(L, 1);
465 LuaEntitySAO *co = getluaobject(ref);
466 if(co == NULL) return 0;
467 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
474 int ObjectRef::l_getyaw(lua_State *L)
476 ObjectRef *ref = checkobject(L, 1);
477 LuaEntitySAO *co = getluaobject(ref);
478 if(co == NULL) return 0;
480 float yaw = co->getYaw() * core::DEGTORAD;
481 lua_pushnumber(L, yaw);
485 // settexturemod(self, mod)
486 int ObjectRef::l_settexturemod(lua_State *L)
488 ObjectRef *ref = checkobject(L, 1);
489 LuaEntitySAO *co = getluaobject(ref);
490 if(co == NULL) return 0;
492 std::string mod = luaL_checkstring(L, 2);
493 co->setTextureMod(mod);
497 // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
498 // select_horiz_by_yawpitch=false)
499 int ObjectRef::l_setsprite(lua_State *L)
501 ObjectRef *ref = checkobject(L, 1);
502 LuaEntitySAO *co = getluaobject(ref);
503 if(co == NULL) return 0;
507 p = read_v2s16(L, 2);
510 num_frames = lua_tonumber(L, 3);
511 float framelength = 0.2;
513 framelength = lua_tonumber(L, 4);
514 bool select_horiz_by_yawpitch = false;
516 select_horiz_by_yawpitch = lua_toboolean(L, 5);
517 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
522 // get_entity_name(self)
523 int ObjectRef::l_get_entity_name(lua_State *L)
525 ObjectRef *ref = checkobject(L, 1);
526 LuaEntitySAO *co = getluaobject(ref);
527 if(co == NULL) return 0;
529 std::string name = co->getName();
530 lua_pushstring(L, name.c_str());
534 // get_luaentity(self)
535 int ObjectRef::l_get_luaentity(lua_State *L)
537 ObjectRef *ref = checkobject(L, 1);
538 LuaEntitySAO *co = getluaobject(ref);
539 if(co == NULL) return 0;
541 luaentity_get(L, co->getId());
548 int ObjectRef::l_is_player(lua_State *L)
550 ObjectRef *ref = checkobject(L, 1);
551 Player *player = getplayer(ref);
552 lua_pushboolean(L, (player != NULL));
556 // get_player_name(self)
557 int ObjectRef::l_get_player_name(lua_State *L)
559 ObjectRef *ref = checkobject(L, 1);
560 Player *player = getplayer(ref);
562 lua_pushlstring(L, "", 0);
566 lua_pushstring(L, player->getName());
570 // get_look_dir(self)
571 int ObjectRef::l_get_look_dir(lua_State *L)
573 ObjectRef *ref = checkobject(L, 1);
574 Player *player = getplayer(ref);
575 if(player == NULL) return 0;
577 float pitch = player->getRadPitch();
578 float yaw = player->getRadYaw();
579 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
584 // get_look_pitch(self)
585 int ObjectRef::l_get_look_pitch(lua_State *L)
587 ObjectRef *ref = checkobject(L, 1);
588 Player *player = getplayer(ref);
589 if(player == NULL) return 0;
591 lua_pushnumber(L, player->getRadPitch());
595 // get_look_yaw(self)
596 int ObjectRef::l_get_look_yaw(lua_State *L)
598 ObjectRef *ref = checkobject(L, 1);
599 Player *player = getplayer(ref);
600 if(player == NULL) return 0;
602 lua_pushnumber(L, player->getRadYaw());
606 // set_look_pitch(self, radians)
607 int ObjectRef::l_set_look_pitch(lua_State *L)
609 ObjectRef *ref = checkobject(L, 1);
610 PlayerSAO* co = getplayersao(ref);
611 if(co == NULL) return 0;
612 float pitch = luaL_checknumber(L, 2) * core::RADTODEG;
618 // set_look_yaw(self, radians)
619 int ObjectRef::l_set_look_yaw(lua_State *L)
621 ObjectRef *ref = checkobject(L, 1);
622 PlayerSAO* co = getplayersao(ref);
623 if(co == NULL) return 0;
624 float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
630 // set_inventory_formspec(self, formspec)
631 int ObjectRef::l_set_inventory_formspec(lua_State *L)
633 ObjectRef *ref = checkobject(L, 1);
634 Player *player = getplayer(ref);
635 if(player == NULL) return 0;
636 std::string formspec = luaL_checkstring(L, 2);
638 player->inventory_formspec = formspec;
639 get_server(L)->reportInventoryFormspecModified(player->getName());
640 lua_pushboolean(L, true);
644 // get_inventory_formspec(self) -> formspec
645 int ObjectRef::l_get_inventory_formspec(lua_State *L)
647 ObjectRef *ref = checkobject(L, 1);
648 Player *player = getplayer(ref);
649 if(player == NULL) return 0;
651 std::string formspec = player->inventory_formspec;
652 lua_pushlstring(L, formspec.c_str(), formspec.size());
656 // get_player_control(self)
657 int ObjectRef::l_get_player_control(lua_State *L)
659 ObjectRef *ref = checkobject(L, 1);
660 Player *player = getplayer(ref);
662 lua_pushlstring(L, "", 0);
666 PlayerControl control = player->getPlayerControl();
668 lua_pushboolean(L, control.up);
669 lua_setfield(L, -2, "up");
670 lua_pushboolean(L, control.down);
671 lua_setfield(L, -2, "down");
672 lua_pushboolean(L, control.left);
673 lua_setfield(L, -2, "left");
674 lua_pushboolean(L, control.right);
675 lua_setfield(L, -2, "right");
676 lua_pushboolean(L, control.jump);
677 lua_setfield(L, -2, "jump");
678 lua_pushboolean(L, control.aux1);
679 lua_setfield(L, -2, "aux1");
680 lua_pushboolean(L, control.sneak);
681 lua_setfield(L, -2, "sneak");
682 lua_pushboolean(L, control.LMB);
683 lua_setfield(L, -2, "LMB");
684 lua_pushboolean(L, control.RMB);
685 lua_setfield(L, -2, "RMB");
689 // get_player_control_bits(self)
690 int ObjectRef::l_get_player_control_bits(lua_State *L)
692 ObjectRef *ref = checkobject(L, 1);
693 Player *player = getplayer(ref);
695 lua_pushlstring(L, "", 0);
699 lua_pushnumber(L, player->keyPressed);
704 ObjectRef::ObjectRef(ServerActiveObject *object):
707 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
710 ObjectRef::~ObjectRef()
713 infostream<<"ObjectRef destructing for id="
714 <<m_object->getId()<<std::endl;
716 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
719 // Creates an ObjectRef and leaves it on top of stack
720 // Not callable from Lua; all references are created on the C side.
721 void ObjectRef::create(lua_State *L, ServerActiveObject *object)
723 ObjectRef *o = new ObjectRef(object);
724 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
725 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
726 luaL_getmetatable(L, className);
727 lua_setmetatable(L, -2);
730 void ObjectRef::set_null(lua_State *L)
732 ObjectRef *o = checkobject(L, -1);
736 void ObjectRef::Register(lua_State *L)
739 int methodtable = lua_gettop(L);
740 luaL_newmetatable(L, className);
741 int metatable = lua_gettop(L);
743 lua_pushliteral(L, "__metatable");
744 lua_pushvalue(L, methodtable);
745 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
747 lua_pushliteral(L, "__index");
748 lua_pushvalue(L, methodtable);
749 lua_settable(L, metatable);
751 lua_pushliteral(L, "__gc");
752 lua_pushcfunction(L, gc_object);
753 lua_settable(L, metatable);
755 lua_pop(L, 1); // drop metatable
757 luaL_openlib(L, 0, methods, 0); // fill methodtable
758 lua_pop(L, 1); // drop methodtable
760 // Cannot be created from Lua
761 //lua_register(L, className, create_object);
764 const char ObjectRef::className[] = "ObjectRef";
765 const luaL_reg ObjectRef::methods[] = {
766 // ServerActiveObject
767 luamethod(ObjectRef, remove),
768 luamethod(ObjectRef, getpos),
769 luamethod(ObjectRef, setpos),
770 luamethod(ObjectRef, moveto),
771 luamethod(ObjectRef, punch),
772 luamethod(ObjectRef, right_click),
773 luamethod(ObjectRef, set_hp),
774 luamethod(ObjectRef, get_hp),
775 luamethod(ObjectRef, get_inventory),
776 luamethod(ObjectRef, get_wield_list),
777 luamethod(ObjectRef, get_wield_index),
778 luamethod(ObjectRef, get_wielded_item),
779 luamethod(ObjectRef, set_wielded_item),
780 luamethod(ObjectRef, set_armor_groups),
781 luamethod(ObjectRef, set_physics_override),
782 luamethod(ObjectRef, set_animation),
783 luamethod(ObjectRef, set_bone_position),
784 luamethod(ObjectRef, set_attach),
785 luamethod(ObjectRef, set_detach),
786 luamethod(ObjectRef, set_properties),
788 luamethod(ObjectRef, setvelocity),
789 luamethod(ObjectRef, getvelocity),
790 luamethod(ObjectRef, setacceleration),
791 luamethod(ObjectRef, getacceleration),
792 luamethod(ObjectRef, setyaw),
793 luamethod(ObjectRef, getyaw),
794 luamethod(ObjectRef, settexturemod),
795 luamethod(ObjectRef, setsprite),
796 luamethod(ObjectRef, get_entity_name),
797 luamethod(ObjectRef, get_luaentity),
799 luamethod(ObjectRef, is_player),
800 luamethod(ObjectRef, get_player_name),
801 luamethod(ObjectRef, get_look_dir),
802 luamethod(ObjectRef, get_look_pitch),
803 luamethod(ObjectRef, get_look_yaw),
804 luamethod(ObjectRef, set_look_yaw),
805 luamethod(ObjectRef, set_look_pitch),
806 luamethod(ObjectRef, set_inventory_formspec),
807 luamethod(ObjectRef, get_inventory_formspec),
808 luamethod(ObjectRef, get_player_control),
809 luamethod(ObjectRef, get_player_control_bits),
813 // Creates a new anonymous reference if cobj=NULL or id=0
814 void objectref_get_or_create(lua_State *L,
815 ServerActiveObject *cobj)
817 if(cobj == NULL || cobj->getId() == 0){
818 ObjectRef::create(L, cobj);
820 objectref_get(L, cobj->getId());
824 void objectref_get(lua_State *L, u16 id)
826 // Get minetest.object_refs[i]
827 lua_getglobal(L, "minetest");
828 lua_getfield(L, -1, "object_refs");
829 luaL_checktype(L, -1, LUA_TTABLE);
830 lua_pushnumber(L, id);
832 lua_remove(L, -2); // object_refs
833 lua_remove(L, -2); // minetest
840 void read_object_properties(lua_State *L, int index,
841 ObjectProperties *prop)
844 index = lua_gettop(L) + 1 + index;
845 if(!lua_istable(L, index))
848 prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
850 getboolfield(L, -1, "physical", prop->physical);
852 getfloatfield(L, -1, "weight", prop->weight);
854 lua_getfield(L, -1, "collisionbox");
855 if(lua_istable(L, -1))
856 prop->collisionbox = read_aabb3f(L, -1, 1.0);
859 getstringfield(L, -1, "visual", prop->visual);
861 getstringfield(L, -1, "mesh", prop->mesh);
863 lua_getfield(L, -1, "visual_size");
864 if(lua_istable(L, -1))
865 prop->visual_size = read_v2f(L, -1);
868 lua_getfield(L, -1, "textures");
869 if(lua_istable(L, -1)){
870 prop->textures.clear();
871 int table = lua_gettop(L);
873 while(lua_next(L, table) != 0){
874 // key at index -2 and value at index -1
875 if(lua_isstring(L, -1))
876 prop->textures.push_back(lua_tostring(L, -1));
878 prop->textures.push_back("");
879 // removes value, keeps key for next iteration
885 lua_getfield(L, -1, "colors");
886 if(lua_istable(L, -1)){
887 prop->colors.clear();
888 int table = lua_gettop(L);
890 while(lua_next(L, table) != 0){
891 // key at index -2 and value at index -1
892 if(lua_isstring(L, -1))
893 prop->colors.push_back(readARGB8(L, -1));
895 prop->colors.push_back(video::SColor(255, 255, 255, 255));
896 // removes value, keeps key for next iteration
902 lua_getfield(L, -1, "spritediv");
903 if(lua_istable(L, -1))
904 prop->spritediv = read_v2s16(L, -1);
907 lua_getfield(L, -1, "initial_sprite_basepos");
908 if(lua_istable(L, -1))
909 prop->initial_sprite_basepos = read_v2s16(L, -1);
912 getboolfield(L, -1, "is_visible", prop->is_visible);
913 getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound);
914 getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate);
921 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
924 assert(lua_checkstack(L, 20));
925 //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
926 StackUnroller stack_unroller(L);
928 // Create object on stack
929 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
930 int object = lua_gettop(L);
932 // Get minetest.object_refs table
933 lua_getglobal(L, "minetest");
934 lua_getfield(L, -1, "object_refs");
935 luaL_checktype(L, -1, LUA_TTABLE);
936 int objectstable = lua_gettop(L);
938 // object_refs[id] = object
939 lua_pushnumber(L, cobj->getId()); // Push id
940 lua_pushvalue(L, object); // Copy object to top of stack
941 lua_settable(L, objectstable);
944 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
947 assert(lua_checkstack(L, 20));
948 //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
949 StackUnroller stack_unroller(L);
951 // Get minetest.object_refs table
952 lua_getglobal(L, "minetest");
953 lua_getfield(L, -1, "object_refs");
954 luaL_checktype(L, -1, LUA_TTABLE);
955 int objectstable = lua_gettop(L);
957 // Get object_refs[id]
958 lua_pushnumber(L, cobj->getId()); // Push id
959 lua_gettable(L, objectstable);
960 // Set object reference to NULL
961 ObjectRef::set_null(L);
962 lua_pop(L, 1); // pop object
964 // Set object_refs[id] = nil
965 lua_pushnumber(L, cobj->getId()); // Push id
967 lua_settable(L, objectstable);