3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "scriptapi.h"
21 #include "scriptapi_common.h"
28 #include "scriptapi_types.h"
29 #include "scriptapi_object.h"
32 Server* get_server(lua_State *L)
34 // Get server from registry
35 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
36 Server *server = (Server*)lua_touserdata(L, -1);
41 ServerEnvironment* get_env(lua_State *L)
43 // Get environment from registry
44 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_env");
45 ServerEnvironment *env = (ServerEnvironment*)lua_touserdata(L, -1);
50 void warn_if_field_exists(lua_State *L, int table,
51 const char *fieldname, const std::string &message)
53 lua_getfield(L, table, fieldname);
54 if(!lua_isnil(L, -1)){
55 infostream<<script_get_backtrace(L)<<std::endl;
56 infostream<<"WARNING: field \""<<fieldname<<"\": "
66 ToolCapabilities read_tool_capabilities(
67 lua_State *L, int table)
69 ToolCapabilities toolcap;
70 getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
71 getintfield(L, table, "max_drop_level", toolcap.max_drop_level);
72 lua_getfield(L, table, "groupcaps");
73 if(lua_istable(L, -1)){
74 int table_groupcaps = lua_gettop(L);
76 while(lua_next(L, table_groupcaps) != 0){
77 // key at index -2 and value at index -1
78 std::string groupname = luaL_checkstring(L, -2);
79 if(lua_istable(L, -1)){
80 int table_groupcap = lua_gettop(L);
81 // This will be created
82 ToolGroupCap groupcap;
83 // Read simple parameters
84 getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel);
85 getintfield(L, table_groupcap, "uses", groupcap.uses);
86 // DEPRECATED: maxwear
88 if(getfloatfield(L, table_groupcap, "maxwear", maxwear)){
90 groupcap.uses = 1.0/maxwear;
93 infostream<<script_get_backtrace(L)<<std::endl;
94 infostream<<"WARNING: field \"maxwear\" is deprecated; "
95 <<"should replace with uses=1/maxwear"<<std::endl;
98 lua_getfield(L, table_groupcap, "times");
99 if(lua_istable(L, -1)){
100 int table_times = lua_gettop(L);
102 while(lua_next(L, table_times) != 0){
103 // key at index -2 and value at index -1
104 int rating = luaL_checkinteger(L, -2);
105 float time = luaL_checknumber(L, -1);
106 groupcap.times[rating] = time;
107 // removes value, keeps key for next iteration
112 // Insert groupcap into toolcap
113 toolcap.groupcaps[groupname] = groupcap;
115 // removes value, keeps key for next iteration
123 void set_tool_capabilities(lua_State *L, int table,
124 const ToolCapabilities &toolcap)
126 setfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
127 setintfield(L, table, "max_drop_level", toolcap.max_drop_level);
128 // Create groupcaps table
131 for(std::map<std::string, ToolGroupCap>::const_iterator
132 i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){
133 // Create groupcap table
135 const std::string &name = i->first;
136 const ToolGroupCap &groupcap = i->second;
137 // Create subtable "times"
139 for(std::map<int, float>::const_iterator
140 i = groupcap.times.begin(); i != groupcap.times.end(); i++){
141 int rating = i->first;
142 float time = i->second;
143 lua_pushinteger(L, rating);
144 lua_pushnumber(L, time);
147 // Set subtable "times"
148 lua_setfield(L, -2, "times");
149 // Set simple parameters
150 setintfield(L, -1, "maxlevel", groupcap.maxlevel);
151 setintfield(L, -1, "uses", groupcap.uses);
152 // Insert groupcap table into groupcaps table
153 lua_setfield(L, -2, name.c_str());
155 // Set groupcaps table
156 lua_setfield(L, -2, "groupcaps");
159 void push_tool_capabilities(lua_State *L,
160 const ToolCapabilities &prop)
163 set_tool_capabilities(L, -1, prop);
166 void realitycheck(lua_State *L)
168 int top = lua_gettop(L);
170 dstream<<"Stack is over 30:"<<std::endl;
171 stackDump(L, dstream);
172 script_error(L, "Stack is over 30 (reality check)");
180 void push_pointed_thing(lua_State *L, const PointedThing& pointed)
183 if(pointed.type == POINTEDTHING_NODE)
185 lua_pushstring(L, "node");
186 lua_setfield(L, -2, "type");
187 push_v3s16(L, pointed.node_undersurface);
188 lua_setfield(L, -2, "under");
189 push_v3s16(L, pointed.node_abovesurface);
190 lua_setfield(L, -2, "above");
192 else if(pointed.type == POINTEDTHING_OBJECT)
194 lua_pushstring(L, "object");
195 lua_setfield(L, -2, "type");
196 objectref_get(L, pointed.object_id);
197 lua_setfield(L, -2, "ref");
201 lua_pushstring(L, "nothing");
202 lua_setfield(L, -2, "type");
206 void stackDump(lua_State *L, std::ostream &o)
209 int top = lua_gettop(L);
210 for (i = 1; i <= top; i++) { /* repeat for each level */
211 int t = lua_type(L, i);
214 case LUA_TSTRING: /* strings */
215 o<<"\""<<lua_tostring(L, i)<<"\"";
218 case LUA_TBOOLEAN: /* booleans */
219 o<<(lua_toboolean(L, i) ? "true" : "false");
222 case LUA_TNUMBER: /* numbers */ {
224 snprintf(buf, 10, "%g", lua_tonumber(L, i));
228 default: /* other values */
229 o<<lua_typename(L, t);
239 // Dump stack top with the dump2 function
240 static void dump2(lua_State *L, const char *name)
242 // Dump object (debug)
243 lua_getglobal(L, "dump2");
244 luaL_checktype(L, -1, LUA_TFUNCTION);
245 lua_pushvalue(L, -2); // Get previous stack top as first parameter
246 lua_pushstring(L, name);
247 if(lua_pcall(L, 2, 0, 0))
248 script_error(L, "error: %s", lua_tostring(L, -1));
252 bool string_to_enum(const EnumString *spec, int &result,
253 const std::string &str)
255 const EnumString *esp = spec;
257 if(str == std::string(esp->str)){
266 /*bool enum_to_string(const EnumString *spec, std::string &result,
269 const EnumString *esp = spec;
280 int getenumfield(lua_State *L, int table,
281 const char *fieldname, const EnumString *spec, int default_)
283 int result = default_;
284 string_to_enum(spec, result,
285 getstringfield_default(L, table, fieldname, ""));