3 Copyright (C) 2011 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 General Public License as published by
7 the Free Software Foundation; either version 2 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 General Public License for more details.
15 You should have received a copy of the GNU 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"
33 #include "serverobject.h"
36 #include "luaentity_common.h"
37 #include "content_sao.h" // For LuaEntitySAO
43 - Random node triggers (like grass growth)
44 - Deterministic node triggers (like falling sand)
45 - Object visual client-side stuff
47 - Spritesheets and animation
48 - Named node types and dynamic id allocation per MapBlock
50 blockdef.has_metadata = true/false
51 - Stores an inventory and stuff in a Settings object
52 meta.inventory_add_list("main")
53 blockdef.on_inventory_modified
54 meta.set("owner", playername)
56 - Item definition (actually, only CraftItem)
59 static void stackDump(lua_State *L, std::ostream &o)
62 int top = lua_gettop(L);
63 for (i = 1; i <= top; i++) { /* repeat for each level */
64 int t = lua_type(L, i);
67 case LUA_TSTRING: /* strings */
68 o<<"\""<<lua_tostring(L, i)<<"\"";
71 case LUA_TBOOLEAN: /* booleans */
72 o<<(lua_toboolean(L, i) ? "true" : "false");
75 case LUA_TNUMBER: /* numbers */ {
77 snprintf(buf, 10, "%g", lua_tonumber(L, i));
81 default: /* other values */
82 o<<lua_typename(L, t);
91 static void realitycheck(lua_State *L)
93 int top = lua_gettop(L);
95 dstream<<"Stack is over 30:"<<std::endl;
96 stackDump(L, dstream);
97 script_error(L, "Stack is over 30 (reality check)");
107 StackUnroller(lua_State *L):
111 m_original_top = lua_gettop(m_lua); // store stack height
115 lua_settop(m_lua, m_original_top); // restore stack height
119 v3f readFloatPos(lua_State *L, int index)
122 lua_pushvalue(L, index); // Push pos
123 luaL_checktype(L, -1, LUA_TTABLE);
124 lua_getfield(L, -1, "x");
125 pos.X = lua_tonumber(L, -1);
127 lua_getfield(L, -1, "y");
128 pos.Y = lua_tonumber(L, -1);
130 lua_getfield(L, -1, "z");
131 pos.Z = lua_tonumber(L, -1);
133 lua_pop(L, 1); // Pop pos
134 pos *= BS; // Scale to internal format
142 // Register new object prototype
143 // register_entity(name, prototype)
144 static int l_register_entity(lua_State *L)
146 const char *name = luaL_checkstring(L, 1);
147 infostream<<"register_entity: "<<name<<std::endl;
148 luaL_checktype(L, 2, LUA_TTABLE);
150 // Get minetest.registered_entities
151 lua_getglobal(L, "minetest");
152 lua_getfield(L, -1, "registered_entities");
153 luaL_checktype(L, -1, LUA_TTABLE);
154 int registered_entities = lua_gettop(L);
155 lua_pushvalue(L, 2); // Object = param 2 -> stack top
156 // registered_entities[name] = object
157 lua_setfield(L, registered_entities, name);
159 // Get registered object to top of stack
162 // Set __index to point to itself
163 lua_pushvalue(L, -1);
164 lua_setfield(L, -2, "__index");
166 // Set metatable.__index = metatable
167 luaL_getmetatable(L, "minetest.entity");
168 lua_pushvalue(L, -1); // duplicate metatable
169 lua_setfield(L, -2, "__index");
170 // Set object metatable
171 lua_setmetatable(L, -2);
173 return 0; /* number of results */
176 // Register a global step function
177 // register_globalstep(function)
178 static int l_register_globalstep(lua_State *L)
180 luaL_checktype(L, 1, LUA_TFUNCTION);
181 infostream<<"register_globalstep"<<std::endl;
183 lua_getglobal(L, "table");
184 lua_getfield(L, -1, "insert");
185 int table_insert = lua_gettop(L);
186 // Get minetest.registered_globalsteps
187 lua_getglobal(L, "minetest");
188 lua_getfield(L, -1, "registered_globalsteps");
189 luaL_checktype(L, -1, LUA_TTABLE);
190 int registered_globalsteps = lua_gettop(L);
191 // table.insert(registered_globalsteps, func)
192 lua_pushvalue(L, table_insert);
193 lua_pushvalue(L, registered_globalsteps);
194 lua_pushvalue(L, 1); // push function from argument 1
196 if(lua_pcall(L, 2, 0, 0))
197 script_error(L, "error: %s\n", lua_tostring(L, -1));
199 return 0; /* number of results */
203 // Clear all registered tools
204 // deregister_tools()
205 static int l_deregister_tools(lua_State *L)
207 infostream<<"deregister_tools"<<std::endl;
209 // Get server from registry
210 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
211 Server *server = (Server*)lua_touserdata(L, -1);
212 // And get the writable tool definition manager from the server
213 IWritableToolDefManager *tooldef =
214 server->getWritableToolDefManager();
218 return 0; /* number of results */
222 // register_tool(name, {lots of stuff})
223 static int l_register_tool(lua_State *L)
225 const char *name = luaL_checkstring(L, 1);
226 infostream<<"register_tool: "<<name<<std::endl;
227 luaL_checktype(L, 2, LUA_TTABLE);
229 // Get server from registry
230 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
231 Server *server = (Server*)lua_touserdata(L, -1);
232 // And get the writable tool definition manager from the server
233 IWritableToolDefManager *tooldef =
234 server->getWritableToolDefManager();
240 lua_getfield(L, table, "image");
241 if(lua_isstring(L, -1))
242 def.imagename = lua_tostring(L, -1);
245 lua_getfield(L, table, "basetime");
246 def.properties.basetime = lua_tonumber(L, -1);
249 lua_getfield(L, table, "dt_weight");
250 def.properties.dt_weight = lua_tonumber(L, -1);
253 lua_getfield(L, table, "dt_crackiness");
254 def.properties.dt_crackiness = lua_tonumber(L, -1);
257 lua_getfield(L, table, "dt_crumbliness");
258 def.properties.dt_crumbliness = lua_tonumber(L, -1);
261 lua_getfield(L, table, "dt_cuttability");
262 def.properties.dt_cuttability = lua_tonumber(L, -1);
265 lua_getfield(L, table, "basedurability");
266 def.properties.basedurability = lua_tonumber(L, -1);
269 lua_getfield(L, table, "dd_weight");
270 def.properties.dd_weight = lua_tonumber(L, -1);
273 lua_getfield(L, table, "dd_crackiness");
274 def.properties.dd_crackiness = lua_tonumber(L, -1);
277 lua_getfield(L, table, "dd_crumbliness");
278 def.properties.dd_crumbliness = lua_tonumber(L, -1);
281 lua_getfield(L, table, "dd_cuttability");
282 def.properties.dd_cuttability = lua_tonumber(L, -1);
285 tooldef->registerTool(name, def);
287 return 0; /* number of results */
290 static const struct luaL_Reg minetest_f [] = {
291 {"register_entity", l_register_entity},
292 {"register_globalstep", l_register_globalstep},
293 //{"deregister_tools", l_deregister_tools},
294 {"register_tool", l_register_tool},
302 static const struct luaL_Reg minetest_entity_m [] = {
307 Getters for stuff in main tables
310 static void objectref_get(lua_State *L, u16 id)
312 // Get minetest.object_refs[i]
313 lua_getglobal(L, "minetest");
314 lua_getfield(L, -1, "object_refs");
315 luaL_checktype(L, -1, LUA_TTABLE);
316 lua_pushnumber(L, id);
318 lua_remove(L, -2); // object_refs
319 lua_remove(L, -2); // minetest
322 static void luaentity_get(lua_State *L, u16 id)
324 // Get minetest.luaentities[i]
325 lua_getglobal(L, "minetest");
326 lua_getfield(L, -1, "luaentities");
327 luaL_checktype(L, -1, LUA_TTABLE);
328 lua_pushnumber(L, id);
330 lua_remove(L, -2); // luaentities
331 lua_remove(L, -2); // minetest
337 #define method(class, name) {#name, class::l_##name}
342 ServerEnvironment *m_env;
344 static const char className[];
345 static const luaL_reg methods[];
347 static EnvRef *checkobject(lua_State *L, int narg)
349 luaL_checktype(L, narg, LUA_TUSERDATA);
350 void *ud = luaL_checkudata(L, narg, className);
351 if(!ud) luaL_typerror(L, narg, className);
352 return *(EnvRef**)ud; // unbox pointer
355 // Exported functions
357 // EnvRef:add_node(pos, content)
358 // pos = {x=num, y=num, z=num}
360 static int l_add_node(lua_State *L)
362 infostream<<"EnvRef::l_add_node()"<<std::endl;
363 EnvRef *o = checkobject(L, 1);
364 ServerEnvironment *env = o->m_env;
365 if(env == NULL) return 0;
368 lua_pushvalue(L, 2); // Push pos
369 luaL_checktype(L, -1, LUA_TTABLE);
370 lua_getfield(L, -1, "x");
371 pos.X = lua_tonumber(L, -1);
373 lua_getfield(L, -1, "y");
374 pos.Y = lua_tonumber(L, -1);
376 lua_getfield(L, -1, "z");
377 pos.Z = lua_tonumber(L, -1);
379 lua_pop(L, 1); // Pop pos
382 lua_pushvalue(L, 3); // Push content
383 content = lua_tonumber(L, -1);
384 lua_pop(L, 1); // Pop content
386 env->getMap().addNodeWithEvent(pos, MapNode(content));
390 static int gc_object(lua_State *L) {
391 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
397 EnvRef(ServerEnvironment *env):
400 infostream<<"EnvRef created"<<std::endl;
405 infostream<<"EnvRef destructing"<<std::endl;
408 // Creates an EnvRef and leaves it on top of stack
409 // Not callable from Lua; all references are created on the C side.
410 static void create(lua_State *L, ServerEnvironment *env)
412 EnvRef *o = new EnvRef(env);
413 //infostream<<"EnvRef::create: o="<<o<<std::endl;
414 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
415 luaL_getmetatable(L, className);
416 lua_setmetatable(L, -2);
419 static void set_null(lua_State *L)
421 EnvRef *o = checkobject(L, -1);
425 static void Register(lua_State *L)
428 int methodtable = lua_gettop(L);
429 luaL_newmetatable(L, className);
430 int metatable = lua_gettop(L);
432 lua_pushliteral(L, "__metatable");
433 lua_pushvalue(L, methodtable);
434 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
436 lua_pushliteral(L, "__index");
437 lua_pushvalue(L, methodtable);
438 lua_settable(L, metatable);
440 lua_pushliteral(L, "__gc");
441 lua_pushcfunction(L, gc_object);
442 lua_settable(L, metatable);
444 lua_pop(L, 1); // drop metatable
446 luaL_openlib(L, 0, methods, 0); // fill methodtable
447 lua_pop(L, 1); // drop methodtable
449 // Cannot be created from Lua
450 //lua_register(L, className, create_object);
453 const char EnvRef::className[] = "EnvRef";
454 const luaL_reg EnvRef::methods[] = {
455 method(EnvRef, add_node),
462 ServerActiveObject *m_object;
464 static const char className[];
465 static const luaL_reg methods[];
467 static ObjectRef *checkobject(lua_State *L, int narg)
469 luaL_checktype(L, narg, LUA_TUSERDATA);
470 void *ud = luaL_checkudata(L, narg, className);
471 if(!ud) luaL_typerror(L, narg, className);
472 return *(ObjectRef**)ud; // unbox pointer
475 static ServerActiveObject* getobject(ObjectRef *ref)
477 ServerActiveObject *co = ref->m_object;
481 static LuaEntitySAO* getluaobject(ObjectRef *ref)
483 ServerActiveObject *obj = getobject(ref);
486 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
488 return (LuaEntitySAO*)obj;
491 // Exported functions
494 static int gc_object(lua_State *L) {
495 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
496 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
502 static int l_remove(lua_State *L)
504 ObjectRef *ref = checkobject(L, 1);
505 ServerActiveObject *co = getobject(ref);
506 if(co == NULL) return 0;
507 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
508 co->m_removed = true;
513 // returns: {x=num, y=num, z=num}
514 static int l_getpos(lua_State *L)
516 ObjectRef *ref = checkobject(L, 1);
517 ServerActiveObject *co = getobject(ref);
518 if(co == NULL) return 0;
519 v3f pos = co->getBasePosition() / BS;
521 lua_pushnumber(L, pos.X);
522 lua_setfield(L, -2, "x");
523 lua_pushnumber(L, pos.Y);
524 lua_setfield(L, -2, "y");
525 lua_pushnumber(L, pos.Z);
526 lua_setfield(L, -2, "z");
531 static int l_setpos(lua_State *L)
533 ObjectRef *ref = checkobject(L, 1);
534 //LuaEntitySAO *co = getluaobject(ref);
535 ServerActiveObject *co = getobject(ref);
536 if(co == NULL) return 0;
538 v3f pos = readFloatPos(L, 2);
544 // moveto(self, pos, continuous=false)
545 static int l_moveto(lua_State *L)
547 ObjectRef *ref = checkobject(L, 1);
548 //LuaEntitySAO *co = getluaobject(ref);
549 ServerActiveObject *co = getobject(ref);
550 if(co == NULL) return 0;
552 v3f pos = readFloatPos(L, 2);
554 bool continuous = lua_toboolean(L, 3);
556 co->moveTo(pos, continuous);
560 // add_to_inventory(self, itemstring)
561 // returns: true if item was added, false otherwise
562 static int l_add_to_inventory(lua_State *L)
564 ObjectRef *ref = checkobject(L, 1);
565 luaL_checkstring(L, 2);
566 ServerActiveObject *co = getobject(ref);
567 if(co == NULL) return 0;
569 const char *itemstring = lua_tostring(L, 2);
570 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
571 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
573 std::istringstream is(itemstring, std::ios::binary);
574 ServerEnvironment *env = co->getEnv();
576 IGameDef *gamedef = env->getGameDef();
577 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
578 infostream<<"item="<<env<<std::endl;
579 bool fits = co->addToInventory(item);
581 lua_pushboolean(L, fits);
586 ObjectRef(ServerActiveObject *object):
589 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
595 infostream<<"ObjectRef destructing for id="
596 <<m_object->getId()<<std::endl;
598 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
601 // Creates an ObjectRef and leaves it on top of stack
602 // Not callable from Lua; all references are created on the C side.
603 static void create(lua_State *L, ServerActiveObject *object)
605 ObjectRef *o = new ObjectRef(object);
606 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
607 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
608 luaL_getmetatable(L, className);
609 lua_setmetatable(L, -2);
612 static void set_null(lua_State *L)
614 ObjectRef *o = checkobject(L, -1);
618 static void Register(lua_State *L)
621 int methodtable = lua_gettop(L);
622 luaL_newmetatable(L, className);
623 int metatable = lua_gettop(L);
625 lua_pushliteral(L, "__metatable");
626 lua_pushvalue(L, methodtable);
627 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
629 lua_pushliteral(L, "__index");
630 lua_pushvalue(L, methodtable);
631 lua_settable(L, metatable);
633 lua_pushliteral(L, "__gc");
634 lua_pushcfunction(L, gc_object);
635 lua_settable(L, metatable);
637 lua_pop(L, 1); // drop metatable
639 luaL_openlib(L, 0, methods, 0); // fill methodtable
640 lua_pop(L, 1); // drop methodtable
642 // Cannot be created from Lua
643 //lua_register(L, className, create_object);
646 const char ObjectRef::className[] = "ObjectRef";
647 const luaL_reg ObjectRef::methods[] = {
648 method(ObjectRef, remove),
649 method(ObjectRef, getpos),
650 method(ObjectRef, setpos),
651 method(ObjectRef, moveto),
652 method(ObjectRef, add_to_inventory),
656 // Creates a new anonymous reference if id=0
657 static void objectref_get_or_create(lua_State *L,
658 ServerActiveObject *cobj)
660 if(cobj->getId() == 0){
661 ObjectRef::create(L, cobj);
663 objectref_get(L, cobj->getId());
671 void scriptapi_export(lua_State *L, Server *server)
674 assert(lua_checkstack(L, 20));
675 infostream<<"scriptapi_export"<<std::endl;
676 StackUnroller stack_unroller(L);
678 // Store server as light userdata in registry
679 lua_pushlightuserdata(L, server);
680 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
682 // Register global functions in table minetest
684 luaL_register(L, NULL, minetest_f);
685 lua_setglobal(L, "minetest");
687 // Get the main minetest table
688 lua_getglobal(L, "minetest");
690 // Add tables to minetest
693 lua_setfield(L, -2, "registered_blocks");*/
696 lua_setfield(L, -2, "registered_entities");
699 lua_setfield(L, -2, "registered_globalsteps");
702 lua_setfield(L, -2, "object_refs");
705 lua_setfield(L, -2, "luaentities");
707 // Create entity prototype
708 luaL_newmetatable(L, "minetest.entity");
709 // metatable.__index = metatable
710 lua_pushvalue(L, -1); // Duplicate metatable
711 lua_setfield(L, -2, "__index");
712 // Put functions in metatable
713 luaL_register(L, NULL, minetest_entity_m);
714 // Put other stuff in metatable
716 // Environment C reference
719 // Object C reference
720 ObjectRef::Register(L);
723 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
726 assert(lua_checkstack(L, 20));
727 infostream<<"scriptapi_add_environment"<<std::endl;
728 StackUnroller stack_unroller(L);
730 // Create EnvRef on stack
731 EnvRef::create(L, env);
732 int envref = lua_gettop(L);
734 // minetest.env = envref
735 lua_getglobal(L, "minetest");
736 luaL_checktype(L, -1, LUA_TTABLE);
737 lua_pushvalue(L, envref);
738 lua_setfield(L, -2, "env");
742 // Dump stack top with the dump2 function
743 static void dump2(lua_State *L, const char *name)
745 // Dump object (debug)
746 lua_getglobal(L, "dump2");
747 luaL_checktype(L, -1, LUA_TFUNCTION);
748 lua_pushvalue(L, -2); // Get previous stack top as first parameter
749 lua_pushstring(L, name);
750 if(lua_pcall(L, 2, 0, 0))
751 script_error(L, "error: %s\n", lua_tostring(L, -1));
759 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
762 assert(lua_checkstack(L, 20));
763 infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
764 StackUnroller stack_unroller(L);
766 // Create object on stack
767 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
768 int object = lua_gettop(L);
770 // Get minetest.object_refs table
771 lua_getglobal(L, "minetest");
772 lua_getfield(L, -1, "object_refs");
773 luaL_checktype(L, -1, LUA_TTABLE);
774 int objectstable = lua_gettop(L);
776 // object_refs[id] = object
777 lua_pushnumber(L, cobj->getId()); // Push id
778 lua_pushvalue(L, object); // Copy object to top of stack
779 lua_settable(L, objectstable);
782 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
785 assert(lua_checkstack(L, 20));
786 infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
787 StackUnroller stack_unroller(L);
789 // Get minetest.object_refs table
790 lua_getglobal(L, "minetest");
791 lua_getfield(L, -1, "object_refs");
792 luaL_checktype(L, -1, LUA_TTABLE);
793 int objectstable = lua_gettop(L);
795 // Get object_refs[id]
796 lua_pushnumber(L, cobj->getId()); // Push id
797 lua_gettable(L, objectstable);
798 // Set object reference to NULL
799 ObjectRef::set_null(L);
800 lua_pop(L, 1); // pop object
802 // Set object_refs[id] = nil
803 lua_pushnumber(L, cobj->getId()); // Push id
805 lua_settable(L, objectstable);
812 void scriptapi_environment_step(lua_State *L, float dtime)
815 assert(lua_checkstack(L, 20));
816 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
817 StackUnroller stack_unroller(L);
819 // Get minetest.registered_globalsteps
820 lua_getglobal(L, "minetest");
821 lua_getfield(L, -1, "registered_globalsteps");
822 luaL_checktype(L, -1, LUA_TTABLE);
823 int table = lua_gettop(L);
826 while(lua_next(L, table) != 0){
827 // key at index -2 and value at index -1
828 luaL_checktype(L, -1, LUA_TFUNCTION);
830 lua_pushnumber(L, dtime);
831 if(lua_pcall(L, 1, 0, 0))
832 script_error(L, "error: %s\n", lua_tostring(L, -1));
833 // value removed, keep key for next iteration
841 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
842 const char *init_state)
845 assert(lua_checkstack(L, 20));
846 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
847 <<name<<"\""<<std::endl;
848 StackUnroller stack_unroller(L);
850 // Create object as a dummy string (TODO: Create properly)
852 // Get minetest.registered_entities[name]
853 lua_getglobal(L, "minetest");
854 lua_getfield(L, -1, "registered_entities");
855 luaL_checktype(L, -1, LUA_TTABLE);
856 lua_pushstring(L, name);
858 // Should be a table, which we will use as a prototype
859 //luaL_checktype(L, -1, LUA_TTABLE);
860 if(lua_type(L, -1) != LUA_TTABLE){
861 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
864 int prototype_table = lua_gettop(L);
865 //dump2(L, "prototype_table");
867 // Create entity object
869 int object = lua_gettop(L);
871 // Set object metatable
872 lua_pushvalue(L, prototype_table);
873 lua_setmetatable(L, -2);
875 // Add object reference
876 // This should be userdata with metatable ObjectRef
877 objectref_get(L, id);
878 luaL_checktype(L, -1, LUA_TUSERDATA);
879 if(!luaL_checkudata(L, -1, "ObjectRef"))
880 luaL_typerror(L, -1, "ObjectRef");
881 lua_setfield(L, -2, "object");
883 // minetest.luaentities[id] = object
884 lua_getglobal(L, "minetest");
885 lua_getfield(L, -1, "luaentities");
886 luaL_checktype(L, -1, LUA_TTABLE);
887 lua_pushnumber(L, id); // Push id
888 lua_pushvalue(L, object); // Copy object to top of stack
891 // This callback doesn't really make sense
892 /*// Get on_activate function
893 lua_pushvalue(L, object);
894 lua_getfield(L, -1, "on_activate");
895 luaL_checktype(L, -1, LUA_TFUNCTION);
896 lua_pushvalue(L, object); // self
897 // Call with 1 arguments, 0 results
898 if(lua_pcall(L, 1, 0, 0))
899 script_error(L, "error running function %s:on_activate: %s\n",
900 name, lua_tostring(L, -1));*/
905 void scriptapi_luaentity_rm(lua_State *L, u16 id)
908 assert(lua_checkstack(L, 20));
909 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
911 // Get minetest.luaentities table
912 lua_getglobal(L, "minetest");
913 lua_getfield(L, -1, "luaentities");
914 luaL_checktype(L, -1, LUA_TTABLE);
915 int objectstable = lua_gettop(L);
917 // Set luaentities[id] = nil
918 lua_pushnumber(L, id); // Push id
920 lua_settable(L, objectstable);
922 lua_pop(L, 2); // pop luaentities, minetest
925 std::string scriptapi_luaentity_get_state(lua_State *L, u16 id)
928 assert(lua_checkstack(L, 20));
929 infostream<<"scriptapi_luaentity_get_state: id="<<id<<std::endl;
934 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
935 LuaEntityProperties *prop)
938 assert(lua_checkstack(L, 20));
939 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
940 StackUnroller stack_unroller(L);
942 // Get minetest.luaentities[id]
943 luaentity_get(L, id);
944 //int object = lua_gettop(L);
946 lua_getfield(L, -1, "physical");
947 if(lua_isboolean(L, -1))
948 prop->physical = lua_toboolean(L, -1);
951 lua_getfield(L, -1, "weight");
952 prop->weight = lua_tonumber(L, -1);
955 lua_getfield(L, -1, "collisionbox");
956 if(lua_istable(L, -1)){
957 lua_rawgeti(L, -1, 1);
958 prop->collisionbox.MinEdge.X = lua_tonumber(L, -1);
960 lua_rawgeti(L, -1, 2);
961 prop->collisionbox.MinEdge.Y = lua_tonumber(L, -1);
963 lua_rawgeti(L, -1, 3);
964 prop->collisionbox.MinEdge.Z = lua_tonumber(L, -1);
966 lua_rawgeti(L, -1, 4);
967 prop->collisionbox.MaxEdge.X = lua_tonumber(L, -1);
969 lua_rawgeti(L, -1, 5);
970 prop->collisionbox.MaxEdge.Y = lua_tonumber(L, -1);
972 lua_rawgeti(L, -1, 6);
973 prop->collisionbox.MaxEdge.Z = lua_tonumber(L, -1);
978 lua_getfield(L, -1, "visual");
979 if(lua_isstring(L, -1))
980 prop->visual = lua_tostring(L, -1);
983 lua_getfield(L, -1, "textures");
984 if(lua_istable(L, -1)){
985 prop->textures.clear();
986 int table = lua_gettop(L);
988 while(lua_next(L, table) != 0){
989 // key at index -2 and value at index -1
990 if(lua_isstring(L, -1))
991 prop->textures.push_back(lua_tostring(L, -1));
993 prop->textures.push_back("");
994 // removes value, keeps key for next iteration
1002 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
1005 assert(lua_checkstack(L, 20));
1006 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1007 StackUnroller stack_unroller(L);
1009 // Get minetest.luaentities[id]
1010 luaentity_get(L, id);
1011 int object = lua_gettop(L);
1012 // State: object is at top of stack
1013 // Get step function
1014 lua_getfield(L, -1, "on_step");
1015 luaL_checktype(L, -1, LUA_TFUNCTION);
1016 lua_pushvalue(L, object); // self
1017 lua_pushnumber(L, dtime); // dtime
1018 // Call with 2 arguments, 0 results
1019 if(lua_pcall(L, 2, 0, 0))
1020 script_error(L, "error running function 'step': %s\n", lua_tostring(L, -1));
1023 // Calls entity:on_punch(ObjectRef puncher)
1024 void scriptapi_luaentity_punch(lua_State *L, u16 id,
1025 ServerActiveObject *puncher)
1028 assert(lua_checkstack(L, 20));
1029 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1030 StackUnroller stack_unroller(L);
1032 // Get minetest.luaentities[id]
1033 luaentity_get(L, id);
1034 int object = lua_gettop(L);
1035 // State: object is at top of stack
1037 lua_getfield(L, -1, "on_punch");
1038 luaL_checktype(L, -1, LUA_TFUNCTION);
1039 lua_pushvalue(L, object); // self
1040 objectref_get_or_create(L, puncher); // Clicker reference
1041 // Call with 2 arguments, 0 results
1042 if(lua_pcall(L, 2, 0, 0))
1043 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
1046 // Calls entity:on_rightclick(ObjectRef clicker)
1047 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
1048 ServerActiveObject *clicker)
1051 assert(lua_checkstack(L, 20));
1052 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1053 StackUnroller stack_unroller(L);
1055 // Get minetest.luaentities[id]
1056 luaentity_get(L, id);
1057 int object = lua_gettop(L);
1058 // State: object is at top of stack
1060 lua_getfield(L, -1, "on_rightclick");
1061 luaL_checktype(L, -1, LUA_TFUNCTION);
1062 lua_pushvalue(L, object); // self
1063 objectref_get_or_create(L, clicker); // Clicker reference
1064 // Call with 2 arguments, 0 results
1065 if(lua_pcall(L, 2, 0, 0))
1066 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));