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
45 - Random node triggers (like grass growth)
46 - Deterministic node triggers (like falling sand)
47 - Object visual client-side stuff
49 - Spritesheets and animation
51 blockdef.metadata_type =
58 - Stores an inventory and stuff in a Settings object
59 meta.inventory_add_list("main")
60 blockdef.on_inventory_modified
61 meta.set("owner", playername)
63 - Item definition (actually, only CraftItem)
66 static void stackDump(lua_State *L, std::ostream &o)
69 int top = lua_gettop(L);
70 for (i = 1; i <= top; i++) { /* repeat for each level */
71 int t = lua_type(L, i);
74 case LUA_TSTRING: /* strings */
75 o<<"\""<<lua_tostring(L, i)<<"\"";
78 case LUA_TBOOLEAN: /* booleans */
79 o<<(lua_toboolean(L, i) ? "true" : "false");
82 case LUA_TNUMBER: /* numbers */ {
84 snprintf(buf, 10, "%g", lua_tonumber(L, i));
88 default: /* other values */
89 o<<lua_typename(L, t);
98 static void realitycheck(lua_State *L)
100 int top = lua_gettop(L);
102 dstream<<"Stack is over 30:"<<std::endl;
103 stackDump(L, dstream);
104 script_error(L, "Stack is over 30 (reality check)");
114 StackUnroller(lua_State *L):
118 m_original_top = lua_gettop(m_lua); // store stack height
122 lua_settop(m_lua, m_original_top); // restore stack height
126 static v3f readFloatPos(lua_State *L, int index)
129 luaL_checktype(L, index, LUA_TTABLE);
130 lua_getfield(L, index, "x");
131 pos.X = lua_tonumber(L, -1);
133 lua_getfield(L, index, "y");
134 pos.Y = lua_tonumber(L, -1);
136 lua_getfield(L, index, "z");
137 pos.Z = lua_tonumber(L, -1);
139 pos *= BS; // Scale to internal format
143 static void pushpos(lua_State *L, v3s16 p)
146 lua_pushnumber(L, p.X);
147 lua_setfield(L, -2, "x");
148 lua_pushnumber(L, p.Y);
149 lua_setfield(L, -2, "y");
150 lua_pushnumber(L, p.Z);
151 lua_setfield(L, -2, "z");
154 static v3s16 readpos(lua_State *L, int index)
157 lua_getfield(L, index, "x");
158 p.X = lua_tonumber(L, -1);
159 lua_getfield(L, index, "y");
160 p.Y = lua_tonumber(L, -1);
161 lua_getfield(L, index, "z");
162 p.Z = lua_tonumber(L, -1);
166 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
169 lua_pushstring(L, ndef->get(n).name.c_str());
170 lua_setfield(L, -2, "name");
171 lua_pushnumber(L, n.getParam1());
172 lua_setfield(L, -2, "param1");
173 lua_pushnumber(L, n.getParam2());
174 lua_setfield(L, -2, "param2");
177 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
179 lua_getfield(L, index, "name");
180 const char *name = lua_tostring(L, -1);
183 lua_getfield(L, index, "param1");
187 param1 = lua_tonumber(L, -1);
190 lua_getfield(L, index, "param2");
194 param2 = lua_tonumber(L, -1);
196 return MapNode(ndef, name, param1, param2);
203 // Register new object prototype
204 // register_entity(name, prototype)
205 static int l_register_entity(lua_State *L)
207 const char *name = luaL_checkstring(L, 1);
208 infostream<<"register_entity: "<<name<<std::endl;
209 luaL_checktype(L, 2, LUA_TTABLE);
211 // Get minetest.registered_entities
212 lua_getglobal(L, "minetest");
213 lua_getfield(L, -1, "registered_entities");
214 luaL_checktype(L, -1, LUA_TTABLE);
215 int registered_entities = lua_gettop(L);
216 lua_pushvalue(L, 2); // Object = param 2 -> stack top
217 // registered_entities[name] = object
218 lua_setfield(L, registered_entities, name);
220 // Get registered object to top of stack
223 // Set __index to point to itself
224 lua_pushvalue(L, -1);
225 lua_setfield(L, -2, "__index");
227 // Set metatable.__index = metatable
228 luaL_getmetatable(L, "minetest.entity");
229 lua_pushvalue(L, -1); // duplicate metatable
230 lua_setfield(L, -2, "__index");
231 // Set object metatable
232 lua_setmetatable(L, -2);
234 return 0; /* number of results */
237 // register_tool(name, {lots of stuff})
238 static int l_register_tool(lua_State *L)
240 const char *name = luaL_checkstring(L, 1);
241 infostream<<"register_tool: "<<name<<std::endl;
242 luaL_checktype(L, 2, LUA_TTABLE);
245 // Get server from registry
246 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
247 Server *server = (Server*)lua_touserdata(L, -1);
248 // And get the writable tool definition manager from the server
249 IWritableToolDefManager *tooldef =
250 server->getWritableToolDefManager();
254 lua_getfield(L, table, "image");
255 if(lua_isstring(L, -1))
256 def.imagename = lua_tostring(L, -1);
259 lua_getfield(L, table, "basetime");
260 def.properties.basetime = lua_tonumber(L, -1);
263 lua_getfield(L, table, "dt_weight");
264 def.properties.dt_weight = lua_tonumber(L, -1);
267 lua_getfield(L, table, "dt_crackiness");
268 def.properties.dt_crackiness = lua_tonumber(L, -1);
271 lua_getfield(L, table, "dt_crumbliness");
272 def.properties.dt_crumbliness = lua_tonumber(L, -1);
275 lua_getfield(L, table, "dt_cuttability");
276 def.properties.dt_cuttability = lua_tonumber(L, -1);
279 lua_getfield(L, table, "basedurability");
280 def.properties.basedurability = lua_tonumber(L, -1);
283 lua_getfield(L, table, "dd_weight");
284 def.properties.dd_weight = lua_tonumber(L, -1);
287 lua_getfield(L, table, "dd_crackiness");
288 def.properties.dd_crackiness = lua_tonumber(L, -1);
291 lua_getfield(L, table, "dd_crumbliness");
292 def.properties.dd_crumbliness = lua_tonumber(L, -1);
295 lua_getfield(L, table, "dd_cuttability");
296 def.properties.dd_cuttability = lua_tonumber(L, -1);
299 tooldef->registerTool(name, def);
300 return 0; /* number of results */
303 // register_node(name, {lots of stuff})
304 static int l_register_node(lua_State *L)
306 const char *name = luaL_checkstring(L, 1);
307 infostream<<"register_node: "<<name<<std::endl;
308 luaL_checktype(L, 2, LUA_TTABLE);
311 // Get server from registry
312 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
313 Server *server = (Server*)lua_touserdata(L, -1);
314 // And get the writable node definition manager from the server
315 IWritableNodeDefManager *nodedef =
316 server->getWritableNodeDefManager();
321 lua_getfield(L, table0, "tile_images");
322 if(lua_istable(L, -1)){
323 int table = lua_gettop(L);
326 while(lua_next(L, table) != 0){
327 // key at index -2 and value at index -1
328 if(lua_isstring(L, -1))
329 f.tname_tiles[i] = lua_tostring(L, -1);
331 f.tname_tiles[i] = "";
332 // removes value, keeps key for next iteration
343 lua_getfield(L, table0, "inventory_image");
344 if(lua_isstring(L, -1))
345 f.tname_inventory = lua_tostring(L, -1);
348 // TODO: Replace with actual parameter reading
349 // Temporarily set some sane parameters to allow digging
350 f.material.diggability = DIGGABLE_NORMAL;
351 f.material.weight = 0;
352 f.material.crackiness = 0;
353 f.material.crumbliness = 0;
354 f.material.cuttability = 0;
355 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
357 nodedef->set(name, f);
358 return 0; /* number of results */
361 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
362 static int l_register_craft(lua_State *L)
364 infostream<<"register_craft"<<std::endl;
365 luaL_checktype(L, 1, LUA_TTABLE);
368 // Get server from registry
369 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
370 Server *server = (Server*)lua_touserdata(L, -1);
371 // And get the writable craft definition manager from the server
372 IWritableCraftDefManager *craftdef =
373 server->getWritableCraftDefManager();
377 std::vector<std::string> input;
379 lua_getfield(L, table0, "output");
380 luaL_checktype(L, -1, LUA_TSTRING);
381 if(lua_isstring(L, -1))
382 output = lua_tostring(L, -1);
385 lua_getfield(L, table0, "recipe");
386 luaL_checktype(L, -1, LUA_TTABLE);
387 if(lua_istable(L, -1)){
388 int table1 = lua_gettop(L);
391 while(lua_next(L, table1) != 0){
393 // key at index -2 and value at index -1
394 luaL_checktype(L, -1, LUA_TTABLE);
395 if(lua_istable(L, -1)){
396 int table2 = lua_gettop(L);
398 while(lua_next(L, table2) != 0){
399 // key at index -2 and value at index -1
400 luaL_checktype(L, -1, LUA_TSTRING);
401 input.push_back(lua_tostring(L, -1));
402 // removes value, keeps key for next iteration
410 if(colcount != width){
411 script_error(L, "error: %s\n", "Invalid crafting recipe");
414 // removes value, keeps key for next iteration
421 CraftDefinition def(output, width, input);
422 craftdef->registerCraft(def);
424 return 0; /* number of results */
427 // Register a global step function
428 // register_globalstep(function)
429 static int l_register_globalstep(lua_State *L)
431 luaL_checktype(L, 1, LUA_TFUNCTION);
432 infostream<<"register_globalstep"<<std::endl;
434 lua_getglobal(L, "table");
435 lua_getfield(L, -1, "insert");
436 int table_insert = lua_gettop(L);
437 // Get minetest.registered_globalsteps
438 lua_getglobal(L, "minetest");
439 lua_getfield(L, -1, "registered_globalsteps");
440 luaL_checktype(L, -1, LUA_TTABLE);
441 int registered_globalsteps = lua_gettop(L);
442 // table.insert(registered_globalsteps, func)
443 lua_pushvalue(L, table_insert);
444 lua_pushvalue(L, registered_globalsteps);
445 lua_pushvalue(L, 1); // push function from argument 1
447 if(lua_pcall(L, 2, 0, 0))
448 script_error(L, "error: %s\n", lua_tostring(L, -1));
450 return 0; /* number of results */
453 // register_on_placenode(function)
454 static int l_register_on_placenode(lua_State *L)
456 luaL_checktype(L, 1, LUA_TFUNCTION);
457 infostream<<"register_on_placenode"<<std::endl;
459 lua_getglobal(L, "table");
460 lua_getfield(L, -1, "insert");
461 int table_insert = lua_gettop(L);
462 // Get minetest.registered_on_placenodes
463 lua_getglobal(L, "minetest");
464 lua_getfield(L, -1, "registered_on_placenodes");
465 luaL_checktype(L, -1, LUA_TTABLE);
466 int registered_on_placenodes = lua_gettop(L);
467 // table.insert(registered_on_placenodes, func)
468 lua_pushvalue(L, table_insert);
469 lua_pushvalue(L, registered_on_placenodes);
470 lua_pushvalue(L, 1); // push function from argument 1
472 if(lua_pcall(L, 2, 0, 0))
473 script_error(L, "error: %s\n", lua_tostring(L, -1));
475 return 0; /* number of results */
478 // register_on_dignode(function)
479 static int l_register_on_dignode(lua_State *L)
481 luaL_checktype(L, 1, LUA_TFUNCTION);
482 infostream<<"register_on_dignode"<<std::endl;
484 lua_getglobal(L, "table");
485 lua_getfield(L, -1, "insert");
486 int table_insert = lua_gettop(L);
487 // Get minetest.registered_on_dignodes
488 lua_getglobal(L, "minetest");
489 lua_getfield(L, -1, "registered_on_dignodes");
490 luaL_checktype(L, -1, LUA_TTABLE);
491 int registered_on_dignodes = lua_gettop(L);
492 // table.insert(registered_on_dignodes, func)
493 lua_pushvalue(L, table_insert);
494 lua_pushvalue(L, registered_on_dignodes);
495 lua_pushvalue(L, 1); // push function from argument 1
497 if(lua_pcall(L, 2, 0, 0))
498 script_error(L, "error: %s\n", lua_tostring(L, -1));
500 return 0; /* number of results */
503 static const struct luaL_Reg minetest_f [] = {
504 {"register_entity", l_register_entity},
505 {"register_tool", l_register_tool},
506 {"register_node", l_register_node},
507 {"register_craft", l_register_craft},
508 {"register_globalstep", l_register_globalstep},
509 {"register_on_placenode", l_register_on_placenode},
510 {"register_on_dignode", l_register_on_dignode},
518 static const struct luaL_Reg minetest_entity_m [] = {
523 Getters for stuff in main tables
526 static void objectref_get(lua_State *L, u16 id)
528 // Get minetest.object_refs[i]
529 lua_getglobal(L, "minetest");
530 lua_getfield(L, -1, "object_refs");
531 luaL_checktype(L, -1, LUA_TTABLE);
532 lua_pushnumber(L, id);
534 lua_remove(L, -2); // object_refs
535 lua_remove(L, -2); // minetest
538 static void luaentity_get(lua_State *L, u16 id)
540 // Get minetest.luaentities[i]
541 lua_getglobal(L, "minetest");
542 lua_getfield(L, -1, "luaentities");
543 luaL_checktype(L, -1, LUA_TTABLE);
544 lua_pushnumber(L, id);
546 lua_remove(L, -2); // luaentities
547 lua_remove(L, -2); // minetest
553 #define method(class, name) {#name, class::l_##name}
558 ServerEnvironment *m_env;
560 static const char className[];
561 static const luaL_reg methods[];
563 static EnvRef *checkobject(lua_State *L, int narg)
565 luaL_checktype(L, narg, LUA_TUSERDATA);
566 void *ud = luaL_checkudata(L, narg, className);
567 if(!ud) luaL_typerror(L, narg, className);
568 return *(EnvRef**)ud; // unbox pointer
571 // Exported functions
573 // EnvRef:add_node(pos, node)
574 // pos = {x=num, y=num, z=num}
575 static int l_add_node(lua_State *L)
577 infostream<<"EnvRef::l_add_node()"<<std::endl;
578 EnvRef *o = checkobject(L, 1);
579 ServerEnvironment *env = o->m_env;
580 if(env == NULL) return 0;
582 v3s16 pos = readpos(L, 2);
584 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
586 env->getMap().addNodeWithEvent(pos, n);
590 // EnvRef:remove_node(pos)
591 // pos = {x=num, y=num, z=num}
592 static int l_remove_node(lua_State *L)
594 infostream<<"EnvRef::l_remove_node()"<<std::endl;
595 EnvRef *o = checkobject(L, 1);
596 ServerEnvironment *env = o->m_env;
597 if(env == NULL) return 0;
599 v3s16 pos = readpos(L, 2);
601 env->getMap().removeNodeWithEvent(pos);
605 // EnvRef:get_node(pos)
606 // pos = {x=num, y=num, z=num}
607 static int l_get_node(lua_State *L)
609 infostream<<"EnvRef::l_get_node()"<<std::endl;
610 EnvRef *o = checkobject(L, 1);
611 ServerEnvironment *env = o->m_env;
612 if(env == NULL) return 0;
614 v3s16 pos = readpos(L, 2);
616 MapNode n = env->getMap().getNodeNoEx(pos);
618 pushnode(L, n, env->getGameDef()->ndef());
622 // EnvRef:add_luaentity(pos, entityname)
623 // pos = {x=num, y=num, z=num}
624 static int l_add_luaentity(lua_State *L)
626 infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
627 EnvRef *o = checkobject(L, 1);
628 ServerEnvironment *env = o->m_env;
629 if(env == NULL) return 0;
631 v3f pos = readFloatPos(L, 2);
633 const char *name = lua_tostring(L, 3);
635 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
636 env->addActiveObject(obj);
640 static int gc_object(lua_State *L) {
641 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
647 EnvRef(ServerEnvironment *env):
650 infostream<<"EnvRef created"<<std::endl;
655 infostream<<"EnvRef destructing"<<std::endl;
658 // Creates an EnvRef and leaves it on top of stack
659 // Not callable from Lua; all references are created on the C side.
660 static void create(lua_State *L, ServerEnvironment *env)
662 EnvRef *o = new EnvRef(env);
663 //infostream<<"EnvRef::create: o="<<o<<std::endl;
664 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
665 luaL_getmetatable(L, className);
666 lua_setmetatable(L, -2);
669 static void set_null(lua_State *L)
671 EnvRef *o = checkobject(L, -1);
675 static void Register(lua_State *L)
678 int methodtable = lua_gettop(L);
679 luaL_newmetatable(L, className);
680 int metatable = lua_gettop(L);
682 lua_pushliteral(L, "__metatable");
683 lua_pushvalue(L, methodtable);
684 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
686 lua_pushliteral(L, "__index");
687 lua_pushvalue(L, methodtable);
688 lua_settable(L, metatable);
690 lua_pushliteral(L, "__gc");
691 lua_pushcfunction(L, gc_object);
692 lua_settable(L, metatable);
694 lua_pop(L, 1); // drop metatable
696 luaL_openlib(L, 0, methods, 0); // fill methodtable
697 lua_pop(L, 1); // drop methodtable
699 // Cannot be created from Lua
700 //lua_register(L, className, create_object);
703 const char EnvRef::className[] = "EnvRef";
704 const luaL_reg EnvRef::methods[] = {
705 method(EnvRef, add_node),
706 method(EnvRef, remove_node),
707 method(EnvRef, get_node),
708 method(EnvRef, add_luaentity),
715 ServerActiveObject *m_object;
717 static const char className[];
718 static const luaL_reg methods[];
720 static ObjectRef *checkobject(lua_State *L, int narg)
722 luaL_checktype(L, narg, LUA_TUSERDATA);
723 void *ud = luaL_checkudata(L, narg, className);
724 if(!ud) luaL_typerror(L, narg, className);
725 return *(ObjectRef**)ud; // unbox pointer
728 static ServerActiveObject* getobject(ObjectRef *ref)
730 ServerActiveObject *co = ref->m_object;
734 static LuaEntitySAO* getluaobject(ObjectRef *ref)
736 ServerActiveObject *obj = getobject(ref);
739 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
741 return (LuaEntitySAO*)obj;
744 // Exported functions
747 static int gc_object(lua_State *L) {
748 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
749 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
755 static int l_remove(lua_State *L)
757 ObjectRef *ref = checkobject(L, 1);
758 ServerActiveObject *co = getobject(ref);
759 if(co == NULL) return 0;
760 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
761 co->m_removed = true;
766 // returns: {x=num, y=num, z=num}
767 static int l_getpos(lua_State *L)
769 ObjectRef *ref = checkobject(L, 1);
770 ServerActiveObject *co = getobject(ref);
771 if(co == NULL) return 0;
772 v3f pos = co->getBasePosition() / BS;
774 lua_pushnumber(L, pos.X);
775 lua_setfield(L, -2, "x");
776 lua_pushnumber(L, pos.Y);
777 lua_setfield(L, -2, "y");
778 lua_pushnumber(L, pos.Z);
779 lua_setfield(L, -2, "z");
784 static int l_setpos(lua_State *L)
786 ObjectRef *ref = checkobject(L, 1);
787 //LuaEntitySAO *co = getluaobject(ref);
788 ServerActiveObject *co = getobject(ref);
789 if(co == NULL) return 0;
791 v3f pos = readFloatPos(L, 2);
797 // moveto(self, pos, continuous=false)
798 static int l_moveto(lua_State *L)
800 ObjectRef *ref = checkobject(L, 1);
801 //LuaEntitySAO *co = getluaobject(ref);
802 ServerActiveObject *co = getobject(ref);
803 if(co == NULL) return 0;
805 v3f pos = readFloatPos(L, 2);
807 bool continuous = lua_toboolean(L, 3);
809 co->moveTo(pos, continuous);
813 // add_to_inventory(self, itemstring)
814 // returns: true if item was added, false otherwise
815 static int l_add_to_inventory(lua_State *L)
817 ObjectRef *ref = checkobject(L, 1);
818 luaL_checkstring(L, 2);
819 ServerActiveObject *co = getobject(ref);
820 if(co == NULL) return 0;
822 const char *itemstring = lua_tostring(L, 2);
823 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
824 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
826 std::istringstream is(itemstring, std::ios::binary);
827 ServerEnvironment *env = co->getEnv();
829 IGameDef *gamedef = env->getGameDef();
830 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
831 infostream<<"item="<<env<<std::endl;
832 bool fits = co->addToInventory(item);
834 lua_pushboolean(L, fits);
839 ObjectRef(ServerActiveObject *object):
842 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
848 infostream<<"ObjectRef destructing for id="
849 <<m_object->getId()<<std::endl;
851 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
854 // Creates an ObjectRef and leaves it on top of stack
855 // Not callable from Lua; all references are created on the C side.
856 static void create(lua_State *L, ServerActiveObject *object)
858 ObjectRef *o = new ObjectRef(object);
859 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
860 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
861 luaL_getmetatable(L, className);
862 lua_setmetatable(L, -2);
865 static void set_null(lua_State *L)
867 ObjectRef *o = checkobject(L, -1);
871 static void Register(lua_State *L)
874 int methodtable = lua_gettop(L);
875 luaL_newmetatable(L, className);
876 int metatable = lua_gettop(L);
878 lua_pushliteral(L, "__metatable");
879 lua_pushvalue(L, methodtable);
880 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
882 lua_pushliteral(L, "__index");
883 lua_pushvalue(L, methodtable);
884 lua_settable(L, metatable);
886 lua_pushliteral(L, "__gc");
887 lua_pushcfunction(L, gc_object);
888 lua_settable(L, metatable);
890 lua_pop(L, 1); // drop metatable
892 luaL_openlib(L, 0, methods, 0); // fill methodtable
893 lua_pop(L, 1); // drop methodtable
895 // Cannot be created from Lua
896 //lua_register(L, className, create_object);
899 const char ObjectRef::className[] = "ObjectRef";
900 const luaL_reg ObjectRef::methods[] = {
901 method(ObjectRef, remove),
902 method(ObjectRef, getpos),
903 method(ObjectRef, setpos),
904 method(ObjectRef, moveto),
905 method(ObjectRef, add_to_inventory),
909 // Creates a new anonymous reference if id=0
910 static void objectref_get_or_create(lua_State *L,
911 ServerActiveObject *cobj)
913 if(cobj->getId() == 0){
914 ObjectRef::create(L, cobj);
916 objectref_get(L, cobj->getId());
924 void scriptapi_export(lua_State *L, Server *server)
927 assert(lua_checkstack(L, 20));
928 infostream<<"scriptapi_export"<<std::endl;
929 StackUnroller stack_unroller(L);
931 // Store server as light userdata in registry
932 lua_pushlightuserdata(L, server);
933 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
935 // Register global functions in table minetest
937 luaL_register(L, NULL, minetest_f);
938 lua_setglobal(L, "minetest");
940 // Get the main minetest table
941 lua_getglobal(L, "minetest");
943 // Add tables to minetest
946 lua_setfield(L, -2, "registered_blocks");*/
949 lua_setfield(L, -2, "registered_entities");
952 lua_setfield(L, -2, "registered_globalsteps");
955 lua_setfield(L, -2, "registered_on_placenodes");
958 lua_setfield(L, -2, "registered_on_dignodes");
961 lua_setfield(L, -2, "object_refs");
964 lua_setfield(L, -2, "luaentities");
966 // Create entity prototype
967 luaL_newmetatable(L, "minetest.entity");
968 // metatable.__index = metatable
969 lua_pushvalue(L, -1); // Duplicate metatable
970 lua_setfield(L, -2, "__index");
971 // Put functions in metatable
972 luaL_register(L, NULL, minetest_entity_m);
973 // Put other stuff in metatable
975 // Environment C reference
978 // Object C reference
979 ObjectRef::Register(L);
982 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
985 assert(lua_checkstack(L, 20));
986 infostream<<"scriptapi_add_environment"<<std::endl;
987 StackUnroller stack_unroller(L);
989 // Create EnvRef on stack
990 EnvRef::create(L, env);
991 int envref = lua_gettop(L);
993 // minetest.env = envref
994 lua_getglobal(L, "minetest");
995 luaL_checktype(L, -1, LUA_TTABLE);
996 lua_pushvalue(L, envref);
997 lua_setfield(L, -2, "env");
1001 // Dump stack top with the dump2 function
1002 static void dump2(lua_State *L, const char *name)
1004 // Dump object (debug)
1005 lua_getglobal(L, "dump2");
1006 luaL_checktype(L, -1, LUA_TFUNCTION);
1007 lua_pushvalue(L, -2); // Get previous stack top as first parameter
1008 lua_pushstring(L, name);
1009 if(lua_pcall(L, 2, 0, 0))
1010 script_error(L, "error: %s\n", lua_tostring(L, -1));
1018 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
1021 assert(lua_checkstack(L, 20));
1022 infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
1023 StackUnroller stack_unroller(L);
1025 // Create object on stack
1026 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
1027 int object = lua_gettop(L);
1029 // Get minetest.object_refs table
1030 lua_getglobal(L, "minetest");
1031 lua_getfield(L, -1, "object_refs");
1032 luaL_checktype(L, -1, LUA_TTABLE);
1033 int objectstable = lua_gettop(L);
1035 // object_refs[id] = object
1036 lua_pushnumber(L, cobj->getId()); // Push id
1037 lua_pushvalue(L, object); // Copy object to top of stack
1038 lua_settable(L, objectstable);
1041 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
1044 assert(lua_checkstack(L, 20));
1045 infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
1046 StackUnroller stack_unroller(L);
1048 // Get minetest.object_refs table
1049 lua_getglobal(L, "minetest");
1050 lua_getfield(L, -1, "object_refs");
1051 luaL_checktype(L, -1, LUA_TTABLE);
1052 int objectstable = lua_gettop(L);
1054 // Get object_refs[id]
1055 lua_pushnumber(L, cobj->getId()); // Push id
1056 lua_gettable(L, objectstable);
1057 // Set object reference to NULL
1058 ObjectRef::set_null(L);
1059 lua_pop(L, 1); // pop object
1061 // Set object_refs[id] = nil
1062 lua_pushnumber(L, cobj->getId()); // Push id
1064 lua_settable(L, objectstable);
1071 void scriptapi_environment_step(lua_State *L, float dtime)
1074 assert(lua_checkstack(L, 20));
1075 //infostream<<"scriptapi_environment_step"<<std::endl;
1076 StackUnroller stack_unroller(L);
1078 // Get minetest.registered_globalsteps
1079 lua_getglobal(L, "minetest");
1080 lua_getfield(L, -1, "registered_globalsteps");
1081 luaL_checktype(L, -1, LUA_TTABLE);
1082 int table = lua_gettop(L);
1085 while(lua_next(L, table) != 0){
1086 // key at index -2 and value at index -1
1087 luaL_checktype(L, -1, LUA_TFUNCTION);
1089 lua_pushnumber(L, dtime);
1090 if(lua_pcall(L, 1, 0, 0))
1091 script_error(L, "error: %s\n", lua_tostring(L, -1));
1092 // value removed, keep key for next iteration
1096 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode)
1099 assert(lua_checkstack(L, 20));
1100 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
1101 StackUnroller stack_unroller(L);
1103 // Get server from registry
1104 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1105 Server *server = (Server*)lua_touserdata(L, -1);
1106 // And get the writable node definition manager from the server
1107 IWritableNodeDefManager *ndef =
1108 server->getWritableNodeDefManager();
1110 // Get minetest.registered_on_placenodes
1111 lua_getglobal(L, "minetest");
1112 lua_getfield(L, -1, "registered_on_placenodes");
1113 luaL_checktype(L, -1, LUA_TTABLE);
1114 int table = lua_gettop(L);
1117 while(lua_next(L, table) != 0){
1118 // key at index -2 and value at index -1
1119 luaL_checktype(L, -1, LUA_TFUNCTION);
1122 pushnode(L, newnode, ndef);
1123 if(lua_pcall(L, 2, 0, 0))
1124 script_error(L, "error: %s\n", lua_tostring(L, -1));
1125 // value removed, keep key for next iteration
1129 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode)
1132 assert(lua_checkstack(L, 20));
1133 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
1134 StackUnroller stack_unroller(L);
1136 // Get server from registry
1137 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1138 Server *server = (Server*)lua_touserdata(L, -1);
1139 // And get the writable node definition manager from the server
1140 IWritableNodeDefManager *ndef =
1141 server->getWritableNodeDefManager();
1143 // Get minetest.registered_on_dignodes
1144 lua_getglobal(L, "minetest");
1145 lua_getfield(L, -1, "registered_on_dignodes");
1146 luaL_checktype(L, -1, LUA_TTABLE);
1147 int table = lua_gettop(L);
1150 while(lua_next(L, table) != 0){
1151 // key at index -2 and value at index -1
1152 luaL_checktype(L, -1, LUA_TFUNCTION);
1155 pushnode(L, oldnode, ndef);
1156 if(lua_pcall(L, 2, 0, 0))
1157 script_error(L, "error: %s\n", lua_tostring(L, -1));
1158 // value removed, keep key for next iteration
1166 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
1167 const char *init_state)
1170 assert(lua_checkstack(L, 20));
1171 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
1172 <<name<<"\""<<std::endl;
1173 StackUnroller stack_unroller(L);
1175 // Create object as a dummy string (TODO: Create properly)
1177 // Get minetest.registered_entities[name]
1178 lua_getglobal(L, "minetest");
1179 lua_getfield(L, -1, "registered_entities");
1180 luaL_checktype(L, -1, LUA_TTABLE);
1181 lua_pushstring(L, name);
1182 lua_gettable(L, -2);
1183 // Should be a table, which we will use as a prototype
1184 //luaL_checktype(L, -1, LUA_TTABLE);
1185 if(lua_type(L, -1) != LUA_TTABLE){
1186 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
1189 int prototype_table = lua_gettop(L);
1190 //dump2(L, "prototype_table");
1192 // Create entity object
1194 int object = lua_gettop(L);
1196 // Set object metatable
1197 lua_pushvalue(L, prototype_table);
1198 lua_setmetatable(L, -2);
1200 // Add object reference
1201 // This should be userdata with metatable ObjectRef
1202 objectref_get(L, id);
1203 luaL_checktype(L, -1, LUA_TUSERDATA);
1204 if(!luaL_checkudata(L, -1, "ObjectRef"))
1205 luaL_typerror(L, -1, "ObjectRef");
1206 lua_setfield(L, -2, "object");
1208 // minetest.luaentities[id] = object
1209 lua_getglobal(L, "minetest");
1210 lua_getfield(L, -1, "luaentities");
1211 luaL_checktype(L, -1, LUA_TTABLE);
1212 lua_pushnumber(L, id); // Push id
1213 lua_pushvalue(L, object); // Copy object to top of stack
1214 lua_settable(L, -3);
1216 // This callback doesn't really make sense
1217 /*// Get on_activate function
1218 lua_pushvalue(L, object);
1219 lua_getfield(L, -1, "on_activate");
1220 luaL_checktype(L, -1, LUA_TFUNCTION);
1221 lua_pushvalue(L, object); // self
1222 // Call with 1 arguments, 0 results
1223 if(lua_pcall(L, 1, 0, 0))
1224 script_error(L, "error running function %s:on_activate: %s\n",
1225 name, lua_tostring(L, -1));*/
1230 void scriptapi_luaentity_rm(lua_State *L, u16 id)
1233 assert(lua_checkstack(L, 20));
1234 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
1236 // Get minetest.luaentities table
1237 lua_getglobal(L, "minetest");
1238 lua_getfield(L, -1, "luaentities");
1239 luaL_checktype(L, -1, LUA_TTABLE);
1240 int objectstable = lua_gettop(L);
1242 // Set luaentities[id] = nil
1243 lua_pushnumber(L, id); // Push id
1245 lua_settable(L, objectstable);
1247 lua_pop(L, 2); // pop luaentities, minetest
1250 std::string scriptapi_luaentity_get_state(lua_State *L, u16 id)
1253 assert(lua_checkstack(L, 20));
1254 infostream<<"scriptapi_luaentity_get_state: id="<<id<<std::endl;
1259 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
1260 LuaEntityProperties *prop)
1263 assert(lua_checkstack(L, 20));
1264 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
1265 StackUnroller stack_unroller(L);
1267 // Get minetest.luaentities[id]
1268 luaentity_get(L, id);
1269 //int object = lua_gettop(L);
1271 lua_getfield(L, -1, "physical");
1272 if(lua_isboolean(L, -1))
1273 prop->physical = lua_toboolean(L, -1);
1276 lua_getfield(L, -1, "weight");
1277 prop->weight = lua_tonumber(L, -1);
1280 lua_getfield(L, -1, "collisionbox");
1281 if(lua_istable(L, -1)){
1282 lua_rawgeti(L, -1, 1);
1283 prop->collisionbox.MinEdge.X = lua_tonumber(L, -1);
1285 lua_rawgeti(L, -1, 2);
1286 prop->collisionbox.MinEdge.Y = lua_tonumber(L, -1);
1288 lua_rawgeti(L, -1, 3);
1289 prop->collisionbox.MinEdge.Z = lua_tonumber(L, -1);
1291 lua_rawgeti(L, -1, 4);
1292 prop->collisionbox.MaxEdge.X = lua_tonumber(L, -1);
1294 lua_rawgeti(L, -1, 5);
1295 prop->collisionbox.MaxEdge.Y = lua_tonumber(L, -1);
1297 lua_rawgeti(L, -1, 6);
1298 prop->collisionbox.MaxEdge.Z = lua_tonumber(L, -1);
1303 lua_getfield(L, -1, "visual");
1304 if(lua_isstring(L, -1))
1305 prop->visual = lua_tostring(L, -1);
1308 lua_getfield(L, -1, "textures");
1309 if(lua_istable(L, -1)){
1310 prop->textures.clear();
1311 int table = lua_gettop(L);
1313 while(lua_next(L, table) != 0){
1314 // key at index -2 and value at index -1
1315 if(lua_isstring(L, -1))
1316 prop->textures.push_back(lua_tostring(L, -1));
1318 prop->textures.push_back("");
1319 // removes value, keeps key for next iteration
1327 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
1330 assert(lua_checkstack(L, 20));
1331 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1332 StackUnroller stack_unroller(L);
1334 // Get minetest.luaentities[id]
1335 luaentity_get(L, id);
1336 int object = lua_gettop(L);
1337 // State: object is at top of stack
1338 // Get step function
1339 lua_getfield(L, -1, "on_step");
1340 if(lua_isnil(L, -1))
1342 luaL_checktype(L, -1, LUA_TFUNCTION);
1343 lua_pushvalue(L, object); // self
1344 lua_pushnumber(L, dtime); // dtime
1345 // Call with 2 arguments, 0 results
1346 if(lua_pcall(L, 2, 0, 0))
1347 script_error(L, "error running function 'step': %s\n", lua_tostring(L, -1));
1350 // Calls entity:on_punch(ObjectRef puncher)
1351 void scriptapi_luaentity_punch(lua_State *L, u16 id,
1352 ServerActiveObject *puncher)
1355 assert(lua_checkstack(L, 20));
1356 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1357 StackUnroller stack_unroller(L);
1359 // Get minetest.luaentities[id]
1360 luaentity_get(L, id);
1361 int object = lua_gettop(L);
1362 // State: object is at top of stack
1364 lua_getfield(L, -1, "on_punch");
1365 if(lua_isnil(L, -1))
1367 luaL_checktype(L, -1, LUA_TFUNCTION);
1368 lua_pushvalue(L, object); // self
1369 objectref_get_or_create(L, puncher); // Clicker reference
1370 // Call with 2 arguments, 0 results
1371 if(lua_pcall(L, 2, 0, 0))
1372 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
1375 // Calls entity:on_rightclick(ObjectRef clicker)
1376 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
1377 ServerActiveObject *clicker)
1380 assert(lua_checkstack(L, 20));
1381 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1382 StackUnroller stack_unroller(L);
1384 // Get minetest.luaentities[id]
1385 luaentity_get(L, id);
1386 int object = lua_gettop(L);
1387 // State: object is at top of stack
1389 lua_getfield(L, -1, "on_rightclick");
1390 if(lua_isnil(L, -1))
1392 luaL_checktype(L, -1, LUA_TFUNCTION);
1393 lua_pushvalue(L, object); // self
1394 objectref_get_or_create(L, clicker); // Clicker reference
1395 // Call with 2 arguments, 0 results
1396 if(lua_pcall(L, 2, 0, 0))
1397 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));