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)
64 - (not scripting) Putting items in node metadata (virtual)
67 static void stackDump(lua_State *L, std::ostream &o)
70 int top = lua_gettop(L);
71 for (i = 1; i <= top; i++) { /* repeat for each level */
72 int t = lua_type(L, i);
75 case LUA_TSTRING: /* strings */
76 o<<"\""<<lua_tostring(L, i)<<"\"";
79 case LUA_TBOOLEAN: /* booleans */
80 o<<(lua_toboolean(L, i) ? "true" : "false");
83 case LUA_TNUMBER: /* numbers */ {
85 snprintf(buf, 10, "%g", lua_tonumber(L, i));
89 default: /* other values */
90 o<<lua_typename(L, t);
99 static void realitycheck(lua_State *L)
101 int top = lua_gettop(L);
103 dstream<<"Stack is over 30:"<<std::endl;
104 stackDump(L, dstream);
105 script_error(L, "Stack is over 30 (reality check)");
115 StackUnroller(lua_State *L):
119 m_original_top = lua_gettop(m_lua); // store stack height
123 lua_settop(m_lua, m_original_top); // restore stack height
127 static v3f readFloatPos(lua_State *L, int index)
130 luaL_checktype(L, index, LUA_TTABLE);
131 lua_getfield(L, index, "x");
132 pos.X = lua_tonumber(L, -1);
134 lua_getfield(L, index, "y");
135 pos.Y = lua_tonumber(L, -1);
137 lua_getfield(L, index, "z");
138 pos.Z = lua_tonumber(L, -1);
140 pos *= BS; // Scale to internal format
144 static void pushpos(lua_State *L, v3s16 p)
147 lua_pushnumber(L, p.X);
148 lua_setfield(L, -2, "x");
149 lua_pushnumber(L, p.Y);
150 lua_setfield(L, -2, "y");
151 lua_pushnumber(L, p.Z);
152 lua_setfield(L, -2, "z");
155 static v3s16 readpos(lua_State *L, int index)
157 // Correct rounding at <0
158 v3f pf = readFloatPos(L, index);
159 return floatToInt(pf, BS);
161 lua_getfield(L, index, "x");
162 p.X = lua_tonumber(L, -1);
163 lua_getfield(L, index, "y");
164 p.Y = lua_tonumber(L, -1);
165 lua_getfield(L, index, "z");
166 p.Z = lua_tonumber(L, -1);
170 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
173 lua_pushstring(L, ndef->get(n).name.c_str());
174 lua_setfield(L, -2, "name");
175 lua_pushnumber(L, n.getParam1());
176 lua_setfield(L, -2, "param1");
177 lua_pushnumber(L, n.getParam2());
178 lua_setfield(L, -2, "param2");
181 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
183 lua_getfield(L, index, "name");
184 const char *name = lua_tostring(L, -1);
187 lua_getfield(L, index, "param1");
191 param1 = lua_tonumber(L, -1);
194 lua_getfield(L, index, "param2");
198 param2 = lua_tonumber(L, -1);
200 return MapNode(ndef, name, param1, param2);
207 // Register new object prototype
208 // register_entity(name, prototype)
209 static int l_register_entity(lua_State *L)
211 const char *name = luaL_checkstring(L, 1);
212 infostream<<"register_entity: "<<name<<std::endl;
213 luaL_checktype(L, 2, LUA_TTABLE);
215 // Get minetest.registered_entities
216 lua_getglobal(L, "minetest");
217 lua_getfield(L, -1, "registered_entities");
218 luaL_checktype(L, -1, LUA_TTABLE);
219 int registered_entities = lua_gettop(L);
220 lua_pushvalue(L, 2); // Object = param 2 -> stack top
221 // registered_entities[name] = object
222 lua_setfield(L, registered_entities, name);
224 // Get registered object to top of stack
227 // Set __index to point to itself
228 lua_pushvalue(L, -1);
229 lua_setfield(L, -2, "__index");
231 // Set metatable.__index = metatable
232 luaL_getmetatable(L, "minetest.entity");
233 lua_pushvalue(L, -1); // duplicate metatable
234 lua_setfield(L, -2, "__index");
235 // Set object metatable
236 lua_setmetatable(L, -2);
238 return 0; /* number of results */
241 // register_tool(name, {lots of stuff})
242 static int l_register_tool(lua_State *L)
244 const char *name = luaL_checkstring(L, 1);
245 infostream<<"register_tool: "<<name<<std::endl;
246 luaL_checktype(L, 2, LUA_TTABLE);
249 // Get server from registry
250 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
251 Server *server = (Server*)lua_touserdata(L, -1);
252 // And get the writable tool definition manager from the server
253 IWritableToolDefManager *tooldef =
254 server->getWritableToolDefManager();
258 lua_getfield(L, table, "image");
259 if(lua_isstring(L, -1))
260 def.imagename = lua_tostring(L, -1);
263 lua_getfield(L, table, "basetime");
264 def.properties.basetime = lua_tonumber(L, -1);
267 lua_getfield(L, table, "dt_weight");
268 def.properties.dt_weight = lua_tonumber(L, -1);
271 lua_getfield(L, table, "dt_crackiness");
272 def.properties.dt_crackiness = lua_tonumber(L, -1);
275 lua_getfield(L, table, "dt_crumbliness");
276 def.properties.dt_crumbliness = lua_tonumber(L, -1);
279 lua_getfield(L, table, "dt_cuttability");
280 def.properties.dt_cuttability = lua_tonumber(L, -1);
283 lua_getfield(L, table, "basedurability");
284 def.properties.basedurability = lua_tonumber(L, -1);
287 lua_getfield(L, table, "dd_weight");
288 def.properties.dd_weight = lua_tonumber(L, -1);
291 lua_getfield(L, table, "dd_crackiness");
292 def.properties.dd_crackiness = lua_tonumber(L, -1);
295 lua_getfield(L, table, "dd_crumbliness");
296 def.properties.dd_crumbliness = lua_tonumber(L, -1);
299 lua_getfield(L, table, "dd_cuttability");
300 def.properties.dd_cuttability = lua_tonumber(L, -1);
303 tooldef->registerTool(name, def);
304 return 0; /* number of results */
307 // register_node(name, {lots of stuff})
308 static int l_register_node(lua_State *L)
310 const char *name = luaL_checkstring(L, 1);
311 infostream<<"register_node: "<<name<<std::endl;
312 luaL_checktype(L, 2, LUA_TTABLE);
315 // Get server from registry
316 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
317 Server *server = (Server*)lua_touserdata(L, -1);
318 // And get the writable node definition manager from the server
319 IWritableNodeDefManager *nodedef =
320 server->getWritableNodeDefManager();
325 lua_getfield(L, table0, "tile_images");
326 if(lua_istable(L, -1)){
327 int table = lua_gettop(L);
330 while(lua_next(L, table) != 0){
331 // key at index -2 and value at index -1
332 if(lua_isstring(L, -1))
333 f.tname_tiles[i] = lua_tostring(L, -1);
335 f.tname_tiles[i] = "";
336 // removes value, keeps key for next iteration
347 lua_getfield(L, table0, "inventory_image");
348 if(lua_isstring(L, -1))
349 f.tname_inventory = lua_tostring(L, -1);
352 // TODO: Replace with actual parameter reading
353 // Temporarily set some sane parameters to allow digging
354 f.material.diggability = DIGGABLE_NORMAL;
355 f.material.weight = 0;
356 f.material.crackiness = 0;
357 f.material.crumbliness = 0;
358 f.material.cuttability = 0;
359 f.dug_item = std::string("NodeItem \"")+name+"\" 1";
361 nodedef->set(name, f);
362 return 0; /* number of results */
365 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
366 static int l_register_craft(lua_State *L)
368 infostream<<"register_craft"<<std::endl;
369 luaL_checktype(L, 1, LUA_TTABLE);
372 // Get server from registry
373 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
374 Server *server = (Server*)lua_touserdata(L, -1);
375 // And get the writable craft definition manager from the server
376 IWritableCraftDefManager *craftdef =
377 server->getWritableCraftDefManager();
381 std::vector<std::string> input;
383 lua_getfield(L, table0, "output");
384 luaL_checktype(L, -1, LUA_TSTRING);
385 if(lua_isstring(L, -1))
386 output = lua_tostring(L, -1);
389 lua_getfield(L, table0, "recipe");
390 luaL_checktype(L, -1, LUA_TTABLE);
391 if(lua_istable(L, -1)){
392 int table1 = lua_gettop(L);
395 while(lua_next(L, table1) != 0){
397 // key at index -2 and value at index -1
398 luaL_checktype(L, -1, LUA_TTABLE);
399 if(lua_istable(L, -1)){
400 int table2 = lua_gettop(L);
402 while(lua_next(L, table2) != 0){
403 // key at index -2 and value at index -1
404 luaL_checktype(L, -1, LUA_TSTRING);
405 input.push_back(lua_tostring(L, -1));
406 // removes value, keeps key for next iteration
414 if(colcount != width){
415 script_error(L, "error: %s\n", "Invalid crafting recipe");
418 // removes value, keeps key for next iteration
425 CraftDefinition def(output, width, input);
426 craftdef->registerCraft(def);
428 return 0; /* number of results */
431 static int register_lua_callback(lua_State *L, const char *tablename)
433 luaL_checktype(L, 1, LUA_TFUNCTION);
435 lua_getglobal(L, "table");
436 lua_getfield(L, -1, "insert");
437 int table_insert = lua_gettop(L);
438 // Get minetest.registered_globalsteps
439 lua_getglobal(L, "minetest");
440 lua_getfield(L, -1, tablename);
441 luaL_checktype(L, -1, LUA_TTABLE);
442 int registered = lua_gettop(L);
443 // table.insert(registered_globalsteps, func)
444 lua_pushvalue(L, table_insert);
445 lua_pushvalue(L, registered);
446 lua_pushvalue(L, 1); // push function from argument 1
448 if(lua_pcall(L, 2, 0, 0))
449 script_error(L, "error: %s\n", lua_tostring(L, -1));
451 return 0; /* number of results */
454 // Register a global step function
455 // register_globalstep(function)
456 static int l_register_globalstep(lua_State *L)
458 infostream<<"register_globalstep"<<std::endl;
459 return register_lua_callback(L, "registered_globalsteps");
462 // register_on_placenode(function)
463 static int l_register_on_placenode(lua_State *L)
465 infostream<<"register_on_placenode"<<std::endl;
466 return register_lua_callback(L, "registered_on_placenodes");
469 // register_on_dignode(function)
470 static int l_register_on_dignode(lua_State *L)
472 infostream<<"register_on_dignode"<<std::endl;
473 return register_lua_callback(L, "registered_on_dignodes");
476 // register_on_punchnode(function)
477 static int l_register_on_punchnode(lua_State *L)
479 infostream<<"register_on_punchnode"<<std::endl;
480 return register_lua_callback(L, "registered_on_punchnodes");
483 static const struct luaL_Reg minetest_f [] = {
484 {"register_entity", l_register_entity},
485 {"register_tool", l_register_tool},
486 {"register_node", l_register_node},
487 {"register_craft", l_register_craft},
488 {"register_globalstep", l_register_globalstep},
489 {"register_on_placenode", l_register_on_placenode},
490 {"register_on_dignode", l_register_on_dignode},
491 {"register_on_punchnode", l_register_on_punchnode},
499 static const struct luaL_Reg minetest_entity_m [] = {
504 Getters for stuff in main tables
507 static void objectref_get(lua_State *L, u16 id)
509 // Get minetest.object_refs[i]
510 lua_getglobal(L, "minetest");
511 lua_getfield(L, -1, "object_refs");
512 luaL_checktype(L, -1, LUA_TTABLE);
513 lua_pushnumber(L, id);
515 lua_remove(L, -2); // object_refs
516 lua_remove(L, -2); // minetest
519 static void luaentity_get(lua_State *L, u16 id)
521 // Get minetest.luaentities[i]
522 lua_getglobal(L, "minetest");
523 lua_getfield(L, -1, "luaentities");
524 luaL_checktype(L, -1, LUA_TTABLE);
525 lua_pushnumber(L, id);
527 lua_remove(L, -2); // luaentities
528 lua_remove(L, -2); // minetest
534 #define method(class, name) {#name, class::l_##name}
539 ServerEnvironment *m_env;
541 static const char className[];
542 static const luaL_reg methods[];
544 static EnvRef *checkobject(lua_State *L, int narg)
546 luaL_checktype(L, narg, LUA_TUSERDATA);
547 void *ud = luaL_checkudata(L, narg, className);
548 if(!ud) luaL_typerror(L, narg, className);
549 return *(EnvRef**)ud; // unbox pointer
552 // Exported functions
554 // EnvRef:add_node(pos, node)
555 // pos = {x=num, y=num, z=num}
556 static int l_add_node(lua_State *L)
558 infostream<<"EnvRef::l_add_node()"<<std::endl;
559 EnvRef *o = checkobject(L, 1);
560 ServerEnvironment *env = o->m_env;
561 if(env == NULL) return 0;
563 v3s16 pos = readpos(L, 2);
565 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
567 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
568 lua_pushboolean(L, succeeded);
572 // EnvRef:remove_node(pos)
573 // pos = {x=num, y=num, z=num}
574 static int l_remove_node(lua_State *L)
576 infostream<<"EnvRef::l_remove_node()"<<std::endl;
577 EnvRef *o = checkobject(L, 1);
578 ServerEnvironment *env = o->m_env;
579 if(env == NULL) return 0;
581 v3s16 pos = readpos(L, 2);
583 bool succeeded = env->getMap().removeNodeWithEvent(pos);
584 lua_pushboolean(L, succeeded);
588 // EnvRef:get_node(pos)
589 // pos = {x=num, y=num, z=num}
590 static int l_get_node(lua_State *L)
592 infostream<<"EnvRef::l_get_node()"<<std::endl;
593 EnvRef *o = checkobject(L, 1);
594 ServerEnvironment *env = o->m_env;
595 if(env == NULL) return 0;
597 v3s16 pos = readpos(L, 2);
599 MapNode n = env->getMap().getNodeNoEx(pos);
601 pushnode(L, n, env->getGameDef()->ndef());
605 // EnvRef:add_luaentity(pos, entityname)
606 // pos = {x=num, y=num, z=num}
607 static int l_add_luaentity(lua_State *L)
609 infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
610 EnvRef *o = checkobject(L, 1);
611 ServerEnvironment *env = o->m_env;
612 if(env == NULL) return 0;
614 v3f pos = readFloatPos(L, 2);
616 const char *name = lua_tostring(L, 3);
618 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
619 env->addActiveObject(obj);
623 static int gc_object(lua_State *L) {
624 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
630 EnvRef(ServerEnvironment *env):
633 infostream<<"EnvRef created"<<std::endl;
638 infostream<<"EnvRef destructing"<<std::endl;
641 // Creates an EnvRef and leaves it on top of stack
642 // Not callable from Lua; all references are created on the C side.
643 static void create(lua_State *L, ServerEnvironment *env)
645 EnvRef *o = new EnvRef(env);
646 //infostream<<"EnvRef::create: o="<<o<<std::endl;
647 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
648 luaL_getmetatable(L, className);
649 lua_setmetatable(L, -2);
652 static void set_null(lua_State *L)
654 EnvRef *o = checkobject(L, -1);
658 static void Register(lua_State *L)
661 int methodtable = lua_gettop(L);
662 luaL_newmetatable(L, className);
663 int metatable = lua_gettop(L);
665 lua_pushliteral(L, "__metatable");
666 lua_pushvalue(L, methodtable);
667 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
669 lua_pushliteral(L, "__index");
670 lua_pushvalue(L, methodtable);
671 lua_settable(L, metatable);
673 lua_pushliteral(L, "__gc");
674 lua_pushcfunction(L, gc_object);
675 lua_settable(L, metatable);
677 lua_pop(L, 1); // drop metatable
679 luaL_openlib(L, 0, methods, 0); // fill methodtable
680 lua_pop(L, 1); // drop methodtable
682 // Cannot be created from Lua
683 //lua_register(L, className, create_object);
686 const char EnvRef::className[] = "EnvRef";
687 const luaL_reg EnvRef::methods[] = {
688 method(EnvRef, add_node),
689 method(EnvRef, remove_node),
690 method(EnvRef, get_node),
691 method(EnvRef, add_luaentity),
698 ServerActiveObject *m_object;
700 static const char className[];
701 static const luaL_reg methods[];
703 static ObjectRef *checkobject(lua_State *L, int narg)
705 luaL_checktype(L, narg, LUA_TUSERDATA);
706 void *ud = luaL_checkudata(L, narg, className);
707 if(!ud) luaL_typerror(L, narg, className);
708 return *(ObjectRef**)ud; // unbox pointer
711 static ServerActiveObject* getobject(ObjectRef *ref)
713 ServerActiveObject *co = ref->m_object;
717 static LuaEntitySAO* getluaobject(ObjectRef *ref)
719 ServerActiveObject *obj = getobject(ref);
722 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
724 return (LuaEntitySAO*)obj;
727 // Exported functions
730 static int gc_object(lua_State *L) {
731 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
732 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
738 static int l_remove(lua_State *L)
740 ObjectRef *ref = checkobject(L, 1);
741 ServerActiveObject *co = getobject(ref);
742 if(co == NULL) return 0;
743 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
744 co->m_removed = true;
749 // returns: {x=num, y=num, z=num}
750 static int l_getpos(lua_State *L)
752 ObjectRef *ref = checkobject(L, 1);
753 ServerActiveObject *co = getobject(ref);
754 if(co == NULL) return 0;
755 v3f pos = co->getBasePosition() / BS;
757 lua_pushnumber(L, pos.X);
758 lua_setfield(L, -2, "x");
759 lua_pushnumber(L, pos.Y);
760 lua_setfield(L, -2, "y");
761 lua_pushnumber(L, pos.Z);
762 lua_setfield(L, -2, "z");
767 static int l_setpos(lua_State *L)
769 ObjectRef *ref = checkobject(L, 1);
770 //LuaEntitySAO *co = getluaobject(ref);
771 ServerActiveObject *co = getobject(ref);
772 if(co == NULL) return 0;
774 v3f pos = readFloatPos(L, 2);
780 // moveto(self, pos, continuous=false)
781 static int l_moveto(lua_State *L)
783 ObjectRef *ref = checkobject(L, 1);
784 //LuaEntitySAO *co = getluaobject(ref);
785 ServerActiveObject *co = getobject(ref);
786 if(co == NULL) return 0;
788 v3f pos = readFloatPos(L, 2);
790 bool continuous = lua_toboolean(L, 3);
792 co->moveTo(pos, continuous);
796 // setvelocity(self, velocity)
797 static int l_setvelocity(lua_State *L)
799 ObjectRef *ref = checkobject(L, 1);
800 LuaEntitySAO *co = getluaobject(ref);
801 if(co == NULL) return 0;
803 v3f pos = readFloatPos(L, 2);
805 co->setVelocity(pos);
809 // setacceleration(self, acceleration)
810 static int l_setacceleration(lua_State *L)
812 ObjectRef *ref = checkobject(L, 1);
813 LuaEntitySAO *co = getluaobject(ref);
814 if(co == NULL) return 0;
816 v3f pos = readFloatPos(L, 2);
818 co->setAcceleration(pos);
822 // add_to_inventory(self, itemstring)
823 // returns: true if item was added, false otherwise
824 static int l_add_to_inventory(lua_State *L)
826 ObjectRef *ref = checkobject(L, 1);
827 luaL_checkstring(L, 2);
828 ServerActiveObject *co = getobject(ref);
829 if(co == NULL) return 0;
831 const char *itemstring = lua_tostring(L, 2);
832 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
833 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
835 std::istringstream is(itemstring, std::ios::binary);
836 ServerEnvironment *env = co->getEnv();
838 IGameDef *gamedef = env->getGameDef();
839 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
840 infostream<<"item="<<env<<std::endl;
841 bool fits = co->addToInventory(item);
843 lua_pushboolean(L, fits);
848 ObjectRef(ServerActiveObject *object):
851 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
857 infostream<<"ObjectRef destructing for id="
858 <<m_object->getId()<<std::endl;
860 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
863 // Creates an ObjectRef and leaves it on top of stack
864 // Not callable from Lua; all references are created on the C side.
865 static void create(lua_State *L, ServerActiveObject *object)
867 ObjectRef *o = new ObjectRef(object);
868 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
869 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
870 luaL_getmetatable(L, className);
871 lua_setmetatable(L, -2);
874 static void set_null(lua_State *L)
876 ObjectRef *o = checkobject(L, -1);
880 static void Register(lua_State *L)
883 int methodtable = lua_gettop(L);
884 luaL_newmetatable(L, className);
885 int metatable = lua_gettop(L);
887 lua_pushliteral(L, "__metatable");
888 lua_pushvalue(L, methodtable);
889 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
891 lua_pushliteral(L, "__index");
892 lua_pushvalue(L, methodtable);
893 lua_settable(L, metatable);
895 lua_pushliteral(L, "__gc");
896 lua_pushcfunction(L, gc_object);
897 lua_settable(L, metatable);
899 lua_pop(L, 1); // drop metatable
901 luaL_openlib(L, 0, methods, 0); // fill methodtable
902 lua_pop(L, 1); // drop methodtable
904 // Cannot be created from Lua
905 //lua_register(L, className, create_object);
908 const char ObjectRef::className[] = "ObjectRef";
909 const luaL_reg ObjectRef::methods[] = {
910 method(ObjectRef, remove),
911 method(ObjectRef, getpos),
912 method(ObjectRef, setpos),
913 method(ObjectRef, moveto),
914 method(ObjectRef, setvelocity),
915 method(ObjectRef, setacceleration),
916 method(ObjectRef, add_to_inventory),
920 // Creates a new anonymous reference if id=0
921 static void objectref_get_or_create(lua_State *L,
922 ServerActiveObject *cobj)
924 if(cobj->getId() == 0){
925 ObjectRef::create(L, cobj);
927 objectref_get(L, cobj->getId());
935 void scriptapi_export(lua_State *L, Server *server)
938 assert(lua_checkstack(L, 20));
939 infostream<<"scriptapi_export"<<std::endl;
940 StackUnroller stack_unroller(L);
942 // Store server as light userdata in registry
943 lua_pushlightuserdata(L, server);
944 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
946 // Register global functions in table minetest
948 luaL_register(L, NULL, minetest_f);
949 lua_setglobal(L, "minetest");
951 // Get the main minetest table
952 lua_getglobal(L, "minetest");
954 // Add tables to minetest
957 lua_setfield(L, -2, "registered_blocks");*/
960 lua_setfield(L, -2, "registered_entities");
963 lua_setfield(L, -2, "registered_globalsteps");
966 lua_setfield(L, -2, "registered_on_placenodes");
969 lua_setfield(L, -2, "registered_on_dignodes");
972 lua_setfield(L, -2, "registered_on_punchnodes");
975 lua_setfield(L, -2, "object_refs");
978 lua_setfield(L, -2, "luaentities");
980 // Create entity prototype
981 luaL_newmetatable(L, "minetest.entity");
982 // metatable.__index = metatable
983 lua_pushvalue(L, -1); // Duplicate metatable
984 lua_setfield(L, -2, "__index");
985 // Put functions in metatable
986 luaL_register(L, NULL, minetest_entity_m);
987 // Put other stuff in metatable
989 // Environment C reference
992 // Object C reference
993 ObjectRef::Register(L);
996 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
999 assert(lua_checkstack(L, 20));
1000 infostream<<"scriptapi_add_environment"<<std::endl;
1001 StackUnroller stack_unroller(L);
1003 // Create EnvRef on stack
1004 EnvRef::create(L, env);
1005 int envref = lua_gettop(L);
1007 // minetest.env = envref
1008 lua_getglobal(L, "minetest");
1009 luaL_checktype(L, -1, LUA_TTABLE);
1010 lua_pushvalue(L, envref);
1011 lua_setfield(L, -2, "env");
1015 // Dump stack top with the dump2 function
1016 static void dump2(lua_State *L, const char *name)
1018 // Dump object (debug)
1019 lua_getglobal(L, "dump2");
1020 luaL_checktype(L, -1, LUA_TFUNCTION);
1021 lua_pushvalue(L, -2); // Get previous stack top as first parameter
1022 lua_pushstring(L, name);
1023 if(lua_pcall(L, 2, 0, 0))
1024 script_error(L, "error: %s\n", lua_tostring(L, -1));
1032 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
1035 assert(lua_checkstack(L, 20));
1036 infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
1037 StackUnroller stack_unroller(L);
1039 // Create object on stack
1040 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
1041 int object = lua_gettop(L);
1043 // Get minetest.object_refs table
1044 lua_getglobal(L, "minetest");
1045 lua_getfield(L, -1, "object_refs");
1046 luaL_checktype(L, -1, LUA_TTABLE);
1047 int objectstable = lua_gettop(L);
1049 // object_refs[id] = object
1050 lua_pushnumber(L, cobj->getId()); // Push id
1051 lua_pushvalue(L, object); // Copy object to top of stack
1052 lua_settable(L, objectstable);
1055 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
1058 assert(lua_checkstack(L, 20));
1059 infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
1060 StackUnroller stack_unroller(L);
1062 // Get minetest.object_refs table
1063 lua_getglobal(L, "minetest");
1064 lua_getfield(L, -1, "object_refs");
1065 luaL_checktype(L, -1, LUA_TTABLE);
1066 int objectstable = lua_gettop(L);
1068 // Get object_refs[id]
1069 lua_pushnumber(L, cobj->getId()); // Push id
1070 lua_gettable(L, objectstable);
1071 // Set object reference to NULL
1072 ObjectRef::set_null(L);
1073 lua_pop(L, 1); // pop object
1075 // Set object_refs[id] = nil
1076 lua_pushnumber(L, cobj->getId()); // Push id
1078 lua_settable(L, objectstable);
1085 void scriptapi_environment_step(lua_State *L, float dtime)
1088 assert(lua_checkstack(L, 20));
1089 //infostream<<"scriptapi_environment_step"<<std::endl;
1090 StackUnroller stack_unroller(L);
1092 // Get minetest.registered_globalsteps
1093 lua_getglobal(L, "minetest");
1094 lua_getfield(L, -1, "registered_globalsteps");
1095 luaL_checktype(L, -1, LUA_TTABLE);
1096 int table = lua_gettop(L);
1099 while(lua_next(L, table) != 0){
1100 // key at index -2 and value at index -1
1101 luaL_checktype(L, -1, LUA_TFUNCTION);
1103 lua_pushnumber(L, dtime);
1104 if(lua_pcall(L, 1, 0, 0))
1105 script_error(L, "error: %s\n", lua_tostring(L, -1));
1106 // value removed, keep key for next iteration
1110 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode)
1113 assert(lua_checkstack(L, 20));
1114 //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
1115 StackUnroller stack_unroller(L);
1117 // Get server from registry
1118 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1119 Server *server = (Server*)lua_touserdata(L, -1);
1120 // And get the writable node definition manager from the server
1121 IWritableNodeDefManager *ndef =
1122 server->getWritableNodeDefManager();
1124 // Get minetest.registered_on_placenodes
1125 lua_getglobal(L, "minetest");
1126 lua_getfield(L, -1, "registered_on_placenodes");
1127 luaL_checktype(L, -1, LUA_TTABLE);
1128 int table = lua_gettop(L);
1131 while(lua_next(L, table) != 0){
1132 // key at index -2 and value at index -1
1133 luaL_checktype(L, -1, LUA_TFUNCTION);
1136 pushnode(L, newnode, ndef);
1137 if(lua_pcall(L, 2, 0, 0))
1138 script_error(L, "error: %s\n", lua_tostring(L, -1));
1139 // value removed, keep key for next iteration
1143 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode)
1146 assert(lua_checkstack(L, 20));
1147 //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
1148 StackUnroller stack_unroller(L);
1150 // Get server from registry
1151 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1152 Server *server = (Server*)lua_touserdata(L, -1);
1153 // And get the writable node definition manager from the server
1154 IWritableNodeDefManager *ndef =
1155 server->getWritableNodeDefManager();
1157 // Get minetest.registered_on_dignodes
1158 lua_getglobal(L, "minetest");
1159 lua_getfield(L, -1, "registered_on_dignodes");
1160 luaL_checktype(L, -1, LUA_TTABLE);
1161 int table = lua_gettop(L);
1164 while(lua_next(L, table) != 0){
1165 // key at index -2 and value at index -1
1166 luaL_checktype(L, -1, LUA_TFUNCTION);
1169 pushnode(L, oldnode, ndef);
1170 if(lua_pcall(L, 2, 0, 0))
1171 script_error(L, "error: %s\n", lua_tostring(L, -1));
1172 // value removed, keep key for next iteration
1176 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode oldnode)
1179 assert(lua_checkstack(L, 20));
1180 //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
1181 StackUnroller stack_unroller(L);
1183 // Get server from registry
1184 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1185 Server *server = (Server*)lua_touserdata(L, -1);
1186 // And get the writable node definition manager from the server
1187 IWritableNodeDefManager *ndef =
1188 server->getWritableNodeDefManager();
1190 // Get minetest.registered_on_punchnodes
1191 lua_getglobal(L, "minetest");
1192 lua_getfield(L, -1, "registered_on_punchnodes");
1193 luaL_checktype(L, -1, LUA_TTABLE);
1194 int table = lua_gettop(L);
1197 while(lua_next(L, table) != 0){
1198 // key at index -2 and value at index -1
1199 luaL_checktype(L, -1, LUA_TFUNCTION);
1202 pushnode(L, oldnode, ndef);
1203 if(lua_pcall(L, 2, 0, 0))
1204 script_error(L, "error: %s\n", lua_tostring(L, -1));
1205 // value removed, keep key for next iteration
1213 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
1214 const std::string &staticdata)
1217 assert(lua_checkstack(L, 20));
1218 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
1219 <<name<<"\""<<std::endl;
1220 StackUnroller stack_unroller(L);
1222 // Get minetest.registered_entities[name]
1223 lua_getglobal(L, "minetest");
1224 lua_getfield(L, -1, "registered_entities");
1225 luaL_checktype(L, -1, LUA_TTABLE);
1226 lua_pushstring(L, name);
1227 lua_gettable(L, -2);
1228 // Should be a table, which we will use as a prototype
1229 //luaL_checktype(L, -1, LUA_TTABLE);
1230 if(lua_type(L, -1) != LUA_TTABLE){
1231 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
1234 int prototype_table = lua_gettop(L);
1235 //dump2(L, "prototype_table");
1237 // Create entity object
1239 int object = lua_gettop(L);
1241 // Set object metatable
1242 lua_pushvalue(L, prototype_table);
1243 lua_setmetatable(L, -2);
1245 // Add object reference
1246 // This should be userdata with metatable ObjectRef
1247 objectref_get(L, id);
1248 luaL_checktype(L, -1, LUA_TUSERDATA);
1249 if(!luaL_checkudata(L, -1, "ObjectRef"))
1250 luaL_typerror(L, -1, "ObjectRef");
1251 lua_setfield(L, -2, "object");
1253 // minetest.luaentities[id] = object
1254 lua_getglobal(L, "minetest");
1255 lua_getfield(L, -1, "luaentities");
1256 luaL_checktype(L, -1, LUA_TTABLE);
1257 lua_pushnumber(L, id); // Push id
1258 lua_pushvalue(L, object); // Copy object to top of stack
1259 lua_settable(L, -3);
1261 // Get on_activate function
1262 lua_pushvalue(L, object);
1263 lua_getfield(L, -1, "on_activate");
1264 if(!lua_isnil(L, -1)){
1265 luaL_checktype(L, -1, LUA_TFUNCTION);
1266 lua_pushvalue(L, object); // self
1267 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
1268 // Call with 2 arguments, 0 results
1269 if(lua_pcall(L, 2, 0, 0))
1270 script_error(L, "error running function %s:on_activate: %s\n",
1271 name, lua_tostring(L, -1));
1277 void scriptapi_luaentity_rm(lua_State *L, u16 id)
1280 assert(lua_checkstack(L, 20));
1281 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
1283 // Get minetest.luaentities table
1284 lua_getglobal(L, "minetest");
1285 lua_getfield(L, -1, "luaentities");
1286 luaL_checktype(L, -1, LUA_TTABLE);
1287 int objectstable = lua_gettop(L);
1289 // Set luaentities[id] = nil
1290 lua_pushnumber(L, id); // Push id
1292 lua_settable(L, objectstable);
1294 lua_pop(L, 2); // pop luaentities, minetest
1297 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
1300 assert(lua_checkstack(L, 20));
1301 infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
1302 StackUnroller stack_unroller(L);
1304 // Get minetest.luaentities[id]
1305 luaentity_get(L, id);
1306 int object = lua_gettop(L);
1308 // Get get_staticdata function
1309 lua_pushvalue(L, object);
1310 lua_getfield(L, -1, "get_staticdata");
1311 if(lua_isnil(L, -1))
1314 luaL_checktype(L, -1, LUA_TFUNCTION);
1315 lua_pushvalue(L, object); // self
1316 // Call with 1 arguments, 1 results
1317 if(lua_pcall(L, 1, 1, 0))
1318 script_error(L, "error running function get_staticdata: %s\n",
1319 lua_tostring(L, -1));
1322 const char *s = lua_tolstring(L, -1, &len);
1323 return std::string(s, len);
1326 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
1327 LuaEntityProperties *prop)
1330 assert(lua_checkstack(L, 20));
1331 infostream<<"scriptapi_luaentity_get_properties: 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);
1338 lua_getfield(L, -1, "physical");
1339 if(lua_isboolean(L, -1))
1340 prop->physical = lua_toboolean(L, -1);
1343 lua_getfield(L, -1, "weight");
1344 prop->weight = lua_tonumber(L, -1);
1347 lua_getfield(L, -1, "collisionbox");
1348 if(lua_istable(L, -1)){
1349 lua_rawgeti(L, -1, 1);
1350 prop->collisionbox.MinEdge.X = lua_tonumber(L, -1);
1352 lua_rawgeti(L, -1, 2);
1353 prop->collisionbox.MinEdge.Y = lua_tonumber(L, -1);
1355 lua_rawgeti(L, -1, 3);
1356 prop->collisionbox.MinEdge.Z = lua_tonumber(L, -1);
1358 lua_rawgeti(L, -1, 4);
1359 prop->collisionbox.MaxEdge.X = lua_tonumber(L, -1);
1361 lua_rawgeti(L, -1, 5);
1362 prop->collisionbox.MaxEdge.Y = lua_tonumber(L, -1);
1364 lua_rawgeti(L, -1, 6);
1365 prop->collisionbox.MaxEdge.Z = lua_tonumber(L, -1);
1370 lua_getfield(L, -1, "visual");
1371 if(lua_isstring(L, -1))
1372 prop->visual = lua_tostring(L, -1);
1375 lua_getfield(L, -1, "textures");
1376 if(lua_istable(L, -1)){
1377 prop->textures.clear();
1378 int table = lua_gettop(L);
1380 while(lua_next(L, table) != 0){
1381 // key at index -2 and value at index -1
1382 if(lua_isstring(L, -1))
1383 prop->textures.push_back(lua_tostring(L, -1));
1385 prop->textures.push_back("");
1386 // removes value, keeps key for next iteration
1394 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
1397 assert(lua_checkstack(L, 20));
1398 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1399 StackUnroller stack_unroller(L);
1401 // Get minetest.luaentities[id]
1402 luaentity_get(L, id);
1403 int object = lua_gettop(L);
1404 // State: object is at top of stack
1405 // Get step function
1406 lua_getfield(L, -1, "on_step");
1407 if(lua_isnil(L, -1))
1409 luaL_checktype(L, -1, LUA_TFUNCTION);
1410 lua_pushvalue(L, object); // self
1411 lua_pushnumber(L, dtime); // dtime
1412 // Call with 2 arguments, 0 results
1413 if(lua_pcall(L, 2, 0, 0))
1414 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
1417 // Calls entity:on_punch(ObjectRef puncher)
1418 void scriptapi_luaentity_punch(lua_State *L, u16 id,
1419 ServerActiveObject *puncher)
1422 assert(lua_checkstack(L, 20));
1423 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1424 StackUnroller stack_unroller(L);
1426 // Get minetest.luaentities[id]
1427 luaentity_get(L, id);
1428 int object = lua_gettop(L);
1429 // State: object is at top of stack
1431 lua_getfield(L, -1, "on_punch");
1432 if(lua_isnil(L, -1))
1434 luaL_checktype(L, -1, LUA_TFUNCTION);
1435 lua_pushvalue(L, object); // self
1436 objectref_get_or_create(L, puncher); // Clicker reference
1437 // Call with 2 arguments, 0 results
1438 if(lua_pcall(L, 2, 0, 0))
1439 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
1442 // Calls entity:on_rightclick(ObjectRef clicker)
1443 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
1444 ServerActiveObject *clicker)
1447 assert(lua_checkstack(L, 20));
1448 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
1449 StackUnroller stack_unroller(L);
1451 // Get minetest.luaentities[id]
1452 luaentity_get(L, id);
1453 int object = lua_gettop(L);
1454 // State: object is at top of stack
1456 lua_getfield(L, -1, "on_rightclick");
1457 if(lua_isnil(L, -1))
1459 luaL_checktype(L, -1, LUA_TFUNCTION);
1460 lua_pushvalue(L, object); // self
1461 objectref_get_or_create(L, clicker); // Clicker reference
1462 // Call with 2 arguments, 0 results
1463 if(lua_pcall(L, 2, 0, 0))
1464 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));