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"
40 - Global environment step function
41 - Random node triggers
42 - Object network and client-side stuff
43 - Named node types and dynamic id allocation
45 blockdef.has_metadata = true/false
46 - Stores an inventory and stuff in a Settings object
47 meta.inventory_add_list("main")
48 blockdef.on_inventory_modified
49 meta.set("owner", playername)
53 static void stackDump(lua_State *L, std::ostream &o)
56 int top = lua_gettop(L);
57 for (i = 1; i <= top; i++) { /* repeat for each level */
58 int t = lua_type(L, i);
61 case LUA_TSTRING: /* strings */
62 o<<"\""<<lua_tostring(L, i)<<"\"";
65 case LUA_TBOOLEAN: /* booleans */
66 o<<(lua_toboolean(L, i) ? "true" : "false");
69 case LUA_TNUMBER: /* numbers */ {
71 snprintf(buf, 10, "%g", lua_tonumber(L, i));
75 default: /* other values */
76 o<<lua_typename(L, t);
85 static void realitycheck(lua_State *L)
87 int top = lua_gettop(L);
89 dstream<<"Stack is over 30:"<<std::endl;
90 stackDump(L, dstream);
91 script_error(L, "Stack is over 30 (reality check)");
101 StackUnroller(lua_State *L):
105 m_original_top = lua_gettop(m_lua); // store stack height
109 lua_settop(m_lua, m_original_top); // restore stack height
113 // Register new object prototype
114 // register_entity(name, prototype)
115 static int l_register_entity(lua_State *L)
117 const char *name = luaL_checkstring(L, 1);
118 luaL_checktype(L, 2, LUA_TTABLE);
119 infostream<<"register_entity: "<<name<<std::endl;
121 // Get minetest.registered_entities
122 lua_getglobal(L, "minetest");
123 lua_getfield(L, -1, "registered_entities");
124 luaL_checktype(L, -1, LUA_TTABLE);
125 int registered_entities = lua_gettop(L);
126 lua_pushvalue(L, 2); // Object = param 2 -> stack top
127 // registered_entities[name] = object
128 lua_setfield(L, registered_entities, name);
130 // Get registered object to top of stack
133 // Set __index to point to itself
134 lua_pushvalue(L, -1);
135 lua_setfield(L, -2, "__index");
137 // Set metatable.__index = metatable
138 luaL_getmetatable(L, "minetest.entity");
139 lua_pushvalue(L, -1); // duplicate metatable
140 lua_setfield(L, -2, "__index");
141 // Set object metatable
142 lua_setmetatable(L, -2);
144 return 0; /* number of results */
147 static const struct luaL_Reg minetest_f [] = {
148 {"register_entity", l_register_entity},
152 static int l_entity_set_deleted(lua_State *L)
157 static const struct luaL_Reg minetest_entity_m [] = {
158 {"set_deleted", l_entity_set_deleted},
162 static void objectref_get(lua_State *L, u16 id)
164 // Get minetest.object_refs[i]
165 lua_getglobal(L, "minetest");
166 lua_getfield(L, -1, "object_refs");
167 luaL_checktype(L, -1, LUA_TTABLE);
168 lua_pushnumber(L, id);
170 lua_remove(L, -2); // object_refs
171 lua_remove(L, -2); // minetest
174 static void luaentity_get(lua_State *L, u16 id)
176 // Get minetest.luaentities[i]
177 lua_getglobal(L, "minetest");
178 lua_getfield(L, -1, "luaentities");
179 luaL_checktype(L, -1, LUA_TTABLE);
180 lua_pushnumber(L, id);
182 lua_remove(L, -2); // luaentities
183 lua_remove(L, -2); // minetest
189 #define method(class, name) {#name, class::l_##name}
194 ServerEnvironment *m_env;
196 static const char className[];
197 static const luaL_reg methods[];
199 static EnvRef *checkobject(lua_State *L, int narg)
201 luaL_checktype(L, narg, LUA_TUSERDATA);
202 void *ud = luaL_checkudata(L, narg, className);
203 if(!ud) luaL_typerror(L, narg, className);
204 return *(EnvRef**)ud; // unbox pointer
207 // Exported functions
209 // EnvRef:add_node(pos, content)
210 // pos = {x=num, y=num, z=num}
212 static int l_add_node(lua_State *L)
214 infostream<<"EnvRef::l_add_node()"<<std::endl;
215 EnvRef *o = checkobject(L, 1);
216 ServerEnvironment *env = o->m_env;
217 if(env == NULL) return 0;
220 lua_pushvalue(L, 2); // Push pos
221 luaL_checktype(L, -1, LUA_TTABLE);
222 lua_getfield(L, -1, "x");
223 pos.X = lua_tonumber(L, -1);
225 lua_getfield(L, -1, "y");
226 pos.Y = lua_tonumber(L, -1);
228 lua_getfield(L, -1, "z");
229 pos.Z = lua_tonumber(L, -1);
231 lua_pop(L, 1); // Pop pos
234 lua_pushvalue(L, 3); // Push content
235 content = lua_tonumber(L, -1);
236 lua_pop(L, 1); // Pop content
238 env->getMap().addNodeWithEvent(pos, MapNode(content));
242 static int gc_object(lua_State *L) {
243 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
249 EnvRef(ServerEnvironment *env):
252 infostream<<"EnvRef created"<<std::endl;
257 infostream<<"EnvRef destructing"<<std::endl;
260 // Creates an EnvRef and leaves it on top of stack
261 // Not callable from Lua; all references are created on the C side.
262 static void create(lua_State *L, ServerEnvironment *env)
264 EnvRef *o = new EnvRef(env);
265 //infostream<<"EnvRef::create: o="<<o<<std::endl;
266 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
267 luaL_getmetatable(L, className);
268 lua_setmetatable(L, -2);
271 static void set_null(lua_State *L)
273 EnvRef *o = checkobject(L, -1);
277 static void Register(lua_State *L)
280 int methodtable = lua_gettop(L);
281 luaL_newmetatable(L, className);
282 int metatable = lua_gettop(L);
284 lua_pushliteral(L, "__metatable");
285 lua_pushvalue(L, methodtable);
286 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
288 lua_pushliteral(L, "__index");
289 lua_pushvalue(L, methodtable);
290 lua_settable(L, metatable);
292 lua_pushliteral(L, "__gc");
293 lua_pushcfunction(L, gc_object);
294 lua_settable(L, metatable);
296 lua_pop(L, 1); // drop metatable
298 luaL_openlib(L, 0, methods, 0); // fill methodtable
299 lua_pop(L, 1); // drop methodtable
301 // Cannot be created from Lua
302 //lua_register(L, className, create_object);
305 const char EnvRef::className[] = "EnvRef";
306 const luaL_reg EnvRef::methods[] = {
307 method(EnvRef, add_node),
314 ServerActiveObject *m_object;
316 static const char className[];
317 static const luaL_reg methods[];
319 static ObjectRef *checkobject(lua_State *L, int narg)
321 luaL_checktype(L, narg, LUA_TUSERDATA);
322 void *ud = luaL_checkudata(L, narg, className);
323 if(!ud) luaL_typerror(L, narg, className);
324 return *(ObjectRef**)ud; // unbox pointer
327 // Exported functions
329 static int l_remove(lua_State *L)
331 ObjectRef *o = checkobject(L, 1);
332 ServerActiveObject *co = o->m_object;
333 if(co == NULL) return 0;
334 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
335 co->m_removed = true;
339 static int l_getpos(lua_State *L)
341 ObjectRef *o = checkobject(L, 1);
342 ServerActiveObject *co = o->m_object;
343 if(co == NULL) return 0;
344 infostream<<"ObjectRef::l_getpos(): id="<<co->getId()<<std::endl;
345 v3f pos = co->getBasePosition() / BS;
347 lua_pushnumber(L, pos.X);
348 lua_setfield(L, -2, "x");
349 lua_pushnumber(L, pos.Y);
350 lua_setfield(L, -2, "y");
351 lua_pushnumber(L, pos.Z);
352 lua_setfield(L, -2, "z");
356 static int gc_object(lua_State *L) {
357 //ObjectRef *o = checkobject(L, 1);
358 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
359 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
365 ObjectRef(ServerActiveObject *object):
368 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
374 infostream<<"ObjectRef destructing for id="
375 <<m_object->getId()<<std::endl;
377 infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
380 // Creates an ObjectRef and leaves it on top of stack
381 // Not callable from Lua; all references are created on the C side.
382 static void create(lua_State *L, ServerActiveObject *object)
384 ObjectRef *o = new ObjectRef(object);
385 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
386 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
387 luaL_getmetatable(L, className);
388 lua_setmetatable(L, -2);
391 static void set_null(lua_State *L)
393 ObjectRef *o = checkobject(L, -1);
397 static void Register(lua_State *L)
400 int methodtable = lua_gettop(L);
401 luaL_newmetatable(L, className);
402 int metatable = lua_gettop(L);
404 lua_pushliteral(L, "__metatable");
405 lua_pushvalue(L, methodtable);
406 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
408 lua_pushliteral(L, "__index");
409 lua_pushvalue(L, methodtable);
410 lua_settable(L, metatable);
412 lua_pushliteral(L, "__gc");
413 lua_pushcfunction(L, gc_object);
414 lua_settable(L, metatable);
416 lua_pop(L, 1); // drop metatable
418 luaL_openlib(L, 0, methods, 0); // fill methodtable
419 lua_pop(L, 1); // drop methodtable
421 // Cannot be created from Lua
422 //lua_register(L, className, create_object);
425 const char ObjectRef::className[] = "ObjectRef";
426 const luaL_reg ObjectRef::methods[] = {
427 method(ObjectRef, remove),
428 method(ObjectRef, getpos),
436 void scriptapi_export(lua_State *L, Server *server)
439 assert(lua_checkstack(L, 20));
440 infostream<<"scriptapi_export"<<std::endl;
442 // Register global functions in table minetest
444 luaL_register(L, NULL, minetest_f);
445 lua_setglobal(L, "minetest");
447 // Get the main minetest table
448 lua_getglobal(L, "minetest");
450 // Add registered_entities table in minetest
452 lua_setfield(L, -2, "registered_entities");
454 // Add object_refs table in minetest
456 lua_setfield(L, -2, "object_refs");
458 // Add luaentities table in minetest
460 lua_setfield(L, -2, "luaentities");
462 // Load and run some base Lua stuff
463 /*script_load(L, (porting::path_data + DIR_DELIM + "scripts"
464 + DIR_DELIM + "base.lua").c_str());*/
466 // Create entity reference metatable
467 //luaL_newmetatable(L, "minetest.entity_reference");
470 // Create entity prototype
471 luaL_newmetatable(L, "minetest.entity");
472 // metatable.__index = metatable
473 lua_pushvalue(L, -1); // Duplicate metatable
474 lua_setfield(L, -2, "__index");
475 // Put functions in metatable
476 luaL_register(L, NULL, minetest_entity_m);
477 // Put other stuff in metatable
479 // Environment C reference
482 // Object C reference
483 ObjectRef::Register(L);
486 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
489 assert(lua_checkstack(L, 20));
490 infostream<<"scriptapi_add_environment"<<std::endl;
492 // Create EnvRef on stack
493 EnvRef::create(L, env);
494 int envref = lua_gettop(L);
496 // minetest.env = envref
497 lua_getglobal(L, "minetest");
498 luaL_checktype(L, -1, LUA_TTABLE);
499 lua_pushvalue(L, envref);
500 lua_setfield(L, -2, "env");
502 // pop minetest and envref
506 // Dump stack top with the dump2 function
507 static void dump2(lua_State *L, const char *name)
509 // Dump object (debug)
510 lua_getglobal(L, "dump2");
511 luaL_checktype(L, -1, LUA_TFUNCTION);
512 lua_pushvalue(L, -2); // Get previous stack top as first parameter
513 lua_pushstring(L, name);
514 if(lua_pcall(L, 2, 0, 0))
515 script_error(L, "error: %s\n", lua_tostring(L, -1));
522 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
525 assert(lua_checkstack(L, 20));
526 infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
528 // Create object on stack
529 ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
530 int object = lua_gettop(L);
532 // Get minetest.object_refs table
533 lua_getglobal(L, "minetest");
534 lua_getfield(L, -1, "object_refs");
535 luaL_checktype(L, -1, LUA_TTABLE);
536 int objectstable = lua_gettop(L);
538 // object_refs[id] = object
539 lua_pushnumber(L, cobj->getId()); // Push id
540 lua_pushvalue(L, object); // Copy object to top of stack
541 lua_settable(L, objectstable);
543 // pop object_refs, minetest and the object
547 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
550 assert(lua_checkstack(L, 20));
551 infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
553 // Get minetest.object_refs table
554 lua_getglobal(L, "minetest");
555 lua_getfield(L, -1, "object_refs");
556 luaL_checktype(L, -1, LUA_TTABLE);
557 int objectstable = lua_gettop(L);
559 // Get object_refs[id]
560 lua_pushnumber(L, cobj->getId()); // Push id
561 lua_gettable(L, objectstable);
562 // Set object reference to NULL
563 ObjectRef::set_null(L);
564 lua_pop(L, 1); // pop object
566 // Set object_refs[id] = nil
567 lua_pushnumber(L, cobj->getId()); // Push id
569 lua_settable(L, objectstable);
571 // pop object_refs, minetest
579 void scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
580 const char *init_state)
583 assert(lua_checkstack(L, 20));
584 infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
585 <<name<<"\""<<std::endl;
586 StackUnroller stack_unroller(L);
588 // Create object as a dummy string (TODO: Create properly)
590 // Get minetest.registered_entities[name]
591 lua_getglobal(L, "minetest");
592 lua_getfield(L, -1, "registered_entities");
593 luaL_checktype(L, -1, LUA_TTABLE);
594 lua_pushstring(L, name);
596 // Should be a table, which we will use as a prototype
597 luaL_checktype(L, -1, LUA_TTABLE);
598 int prototype_table = lua_gettop(L);
599 //dump2(L, "prototype_table");
601 // Create entity object
603 int object = lua_gettop(L);
605 // Set object metatable
606 lua_pushvalue(L, prototype_table);
607 lua_setmetatable(L, -2);
609 // Add object reference
610 // This should be userdata with metatable ObjectRef
611 objectref_get(L, id);
612 luaL_checktype(L, -1, LUA_TUSERDATA);
613 if(!luaL_checkudata(L, -1, "ObjectRef"))
614 luaL_typerror(L, -1, "ObjectRef");
615 lua_setfield(L, -2, "object");
617 // minetest.luaentities[id] = object
618 lua_getglobal(L, "minetest");
619 lua_getfield(L, -1, "luaentities");
620 luaL_checktype(L, -1, LUA_TTABLE);
621 lua_pushnumber(L, id); // Push id
622 lua_pushvalue(L, object); // Copy object to top of stack
625 // This callback doesn't really make sense
626 /*// Get on_activate function
627 lua_pushvalue(L, object);
628 lua_getfield(L, -1, "on_activate");
629 luaL_checktype(L, -1, LUA_TFUNCTION);
630 lua_pushvalue(L, object); // self
631 // Call with 1 arguments, 0 results
632 if(lua_pcall(L, 1, 0, 0))
633 script_error(L, "error running function %s:on_activate: %s\n",
634 name, lua_tostring(L, -1));*/
637 void scriptapi_luaentity_rm(lua_State *L, u16 id)
640 assert(lua_checkstack(L, 20));
641 infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
643 // Get minetest.luaentities table
644 lua_getglobal(L, "minetest");
645 lua_getfield(L, -1, "luaentities");
646 luaL_checktype(L, -1, LUA_TTABLE);
647 int objectstable = lua_gettop(L);
649 // Set luaentities[id] = nil
650 lua_pushnumber(L, id); // Push id
652 lua_settable(L, objectstable);
654 lua_pop(L, 2); // pop luaentities, minetest
657 std::string scriptapi_luaentity_get_state(lua_State *L, u16 id)
660 assert(lua_checkstack(L, 20));
661 infostream<<"scriptapi_luaentity_get_state: id="<<id<<std::endl;
666 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
667 LuaEntityProperties *prop)
670 assert(lua_checkstack(L, 20));
671 infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
672 StackUnroller stack_unroller(L);
674 // Get minetest.luaentities[id]
675 luaentity_get(L, id);
676 //int object = lua_gettop(L);
678 lua_getfield(L, -1, "physical");
679 if(lua_isboolean(L, -1))
680 prop->physical = lua_toboolean(L, -1);
683 lua_getfield(L, -1, "weight");
684 prop->weight = lua_tonumber(L, -1);
687 lua_getfield(L, -1, "collisionbox");
688 if(lua_istable(L, -1)){
689 lua_rawgeti(L, -1, 1);
690 prop->collisionbox.MinEdge.X = lua_tonumber(L, -1);
692 lua_rawgeti(L, -1, 2);
693 prop->collisionbox.MinEdge.Y = lua_tonumber(L, -1);
695 lua_rawgeti(L, -1, 3);
696 prop->collisionbox.MinEdge.Z = lua_tonumber(L, -1);
698 lua_rawgeti(L, -1, 4);
699 prop->collisionbox.MaxEdge.X = lua_tonumber(L, -1);
701 lua_rawgeti(L, -1, 5);
702 prop->collisionbox.MaxEdge.Y = lua_tonumber(L, -1);
704 lua_rawgeti(L, -1, 6);
705 prop->collisionbox.MaxEdge.Z = lua_tonumber(L, -1);
710 lua_getfield(L, -1, "visual");
711 if(lua_isstring(L, -1))
712 prop->visual = lua_tostring(L, -1);
715 lua_getfield(L, -1, "textures");
716 if(lua_istable(L, -1)){
717 prop->textures.clear();
718 int table = lua_gettop(L);
720 while(lua_next(L, table) != 0){
721 // key at index -2 and value at index -1
722 if(lua_isstring(L, -1))
723 prop->textures.push_back(lua_tostring(L, -1));
725 prop->textures.push_back("");
726 // removes value, keeps key for next iteration
733 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
736 assert(lua_checkstack(L, 20));
737 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
738 StackUnroller stack_unroller(L);
740 // Get minetest.luaentities[id]
741 luaentity_get(L, id);
742 int object = lua_gettop(L);
743 // State: object is at top of stack
745 lua_getfield(L, -1, "on_step");
746 luaL_checktype(L, -1, LUA_TFUNCTION);
747 lua_pushvalue(L, object); // self
748 lua_pushnumber(L, dtime); // dtime
749 // Call with 2 arguments, 0 results
750 if(lua_pcall(L, 2, 0, 0))
751 script_error(L, "error running function 'step': %s\n", lua_tostring(L, -1));
754 void scriptapi_luaentity_rightclick_player(lua_State *L, u16 id,
755 const char *playername)
758 assert(lua_checkstack(L, 20));
759 //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
760 StackUnroller stack_unroller(L);
762 // Get minetest.luaentities[id]
763 luaentity_get(L, id);
764 int object = lua_gettop(L);
765 // State: object is at top of stack
767 lua_getfield(L, -1, "on_rightclick");
768 luaL_checktype(L, -1, LUA_TFUNCTION);
769 lua_pushvalue(L, object); // self
770 // Call with 1 arguments, 0 results
771 if(lua_pcall(L, 1, 0, 0))
772 script_error(L, "error running function 'step': %s\n", lua_tostring(L, -1));