]> git.lizzy.rs Git - dragonfireclient.git/blob - src/scriptapi_types.cpp
Limit speed in collisionMoveResult for avoiding hangs
[dragonfireclient.git] / src / scriptapi_types.cpp
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
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.
9
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.
14
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.
18 */
19
20 #include "scriptapi.h"
21 #include "scriptapi_types.h"
22
23 extern "C" {
24 #include <lauxlib.h>
25 }
26
27 #include "util/numeric.h"
28 #include "nodedef.h"
29
30 /*
31         C struct <-> Lua table converter functions
32 */
33
34 void push_v3f(lua_State *L, v3f p)
35 {
36         lua_newtable(L);
37         lua_pushnumber(L, p.X);
38         lua_setfield(L, -2, "x");
39         lua_pushnumber(L, p.Y);
40         lua_setfield(L, -2, "y");
41         lua_pushnumber(L, p.Z);
42         lua_setfield(L, -2, "z");
43 }
44
45 v2s16 read_v2s16(lua_State *L, int index)
46 {
47         v2s16 p;
48         luaL_checktype(L, index, LUA_TTABLE);
49         lua_getfield(L, index, "x");
50         p.X = lua_tonumber(L, -1);
51         lua_pop(L, 1);
52         lua_getfield(L, index, "y");
53         p.Y = lua_tonumber(L, -1);
54         lua_pop(L, 1);
55         return p;
56 }
57
58 v2f read_v2f(lua_State *L, int index)
59 {
60         v2f p;
61         luaL_checktype(L, index, LUA_TTABLE);
62         lua_getfield(L, index, "x");
63         p.X = lua_tonumber(L, -1);
64         lua_pop(L, 1);
65         lua_getfield(L, index, "y");
66         p.Y = lua_tonumber(L, -1);
67         lua_pop(L, 1);
68         return p;
69 }
70
71 v3f read_v3f(lua_State *L, int index)
72 {
73         v3f pos;
74         luaL_checktype(L, index, LUA_TTABLE);
75         lua_getfield(L, index, "x");
76         pos.X = lua_tonumber(L, -1);
77         lua_pop(L, 1);
78         lua_getfield(L, index, "y");
79         pos.Y = lua_tonumber(L, -1);
80         lua_pop(L, 1);
81         lua_getfield(L, index, "z");
82         pos.Z = lua_tonumber(L, -1);
83         lua_pop(L, 1);
84         return pos;
85 }
86
87 v3f check_v3f(lua_State *L, int index)
88 {
89         v3f pos;
90         luaL_checktype(L, index, LUA_TTABLE);
91         lua_getfield(L, index, "x");
92         pos.X = luaL_checknumber(L, -1);
93         lua_pop(L, 1);
94         lua_getfield(L, index, "y");
95         pos.Y = luaL_checknumber(L, -1);
96         lua_pop(L, 1);
97         lua_getfield(L, index, "z");
98         pos.Z = luaL_checknumber(L, -1);
99         lua_pop(L, 1);
100         return pos;
101 }
102
103 void pushFloatPos(lua_State *L, v3f p)
104 {
105         p /= BS;
106         push_v3f(L, p);
107 }
108
109 v3f checkFloatPos(lua_State *L, int index)
110 {
111         return check_v3f(L, index) * BS;
112 }
113
114 void push_v3s16(lua_State *L, v3s16 p)
115 {
116         lua_newtable(L);
117         lua_pushnumber(L, p.X);
118         lua_setfield(L, -2, "x");
119         lua_pushnumber(L, p.Y);
120         lua_setfield(L, -2, "y");
121         lua_pushnumber(L, p.Z);
122         lua_setfield(L, -2, "z");
123 }
124
125 v3s16 read_v3s16(lua_State *L, int index)
126 {
127         // Correct rounding at <0
128         v3f pf = read_v3f(L, index);
129         return floatToInt(pf, 1.0);
130 }
131
132 v3s16 check_v3s16(lua_State *L, int index)
133 {
134         // Correct rounding at <0
135         v3f pf = check_v3f(L, index);
136         return floatToInt(pf, 1.0);
137 }
138
139 video::SColor readARGB8(lua_State *L, int index)
140 {
141         video::SColor color;
142         luaL_checktype(L, index, LUA_TTABLE);
143         lua_getfield(L, index, "a");
144         if(lua_isnumber(L, -1))
145                 color.setAlpha(lua_tonumber(L, -1));
146         lua_pop(L, 1);
147         lua_getfield(L, index, "r");
148         color.setRed(lua_tonumber(L, -1));
149         lua_pop(L, 1);
150         lua_getfield(L, index, "g");
151         color.setGreen(lua_tonumber(L, -1));
152         lua_pop(L, 1);
153         lua_getfield(L, index, "b");
154         color.setBlue(lua_tonumber(L, -1));
155         lua_pop(L, 1);
156         return color;
157 }
158
159 aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
160 {
161         aabb3f box;
162         if(lua_istable(L, index)){
163                 lua_rawgeti(L, index, 1);
164                 box.MinEdge.X = lua_tonumber(L, -1) * scale;
165                 lua_pop(L, 1);
166                 lua_rawgeti(L, index, 2);
167                 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
168                 lua_pop(L, 1);
169                 lua_rawgeti(L, index, 3);
170                 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
171                 lua_pop(L, 1);
172                 lua_rawgeti(L, index, 4);
173                 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
174                 lua_pop(L, 1);
175                 lua_rawgeti(L, index, 5);
176                 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
177                 lua_pop(L, 1);
178                 lua_rawgeti(L, index, 6);
179                 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
180                 lua_pop(L, 1);
181         }
182         return box;
183 }
184
185 std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale)
186 {
187         std::vector<aabb3f> boxes;
188         if(lua_istable(L, index)){
189                 int n = lua_objlen(L, index);
190                 // Check if it's a single box or a list of boxes
191                 bool possibly_single_box = (n == 6);
192                 for(int i = 1; i <= n && possibly_single_box; i++){
193                         lua_rawgeti(L, index, i);
194                         if(!lua_isnumber(L, -1))
195                                 possibly_single_box = false;
196                         lua_pop(L, 1);
197                 }
198                 if(possibly_single_box){
199                         // Read a single box
200                         boxes.push_back(read_aabb3f(L, index, scale));
201                 } else {
202                         // Read a list of boxes
203                         for(int i = 1; i <= n; i++){
204                                 lua_rawgeti(L, index, i);
205                                 boxes.push_back(read_aabb3f(L, -1, scale));
206                                 lua_pop(L, 1);
207                         }
208                 }
209         }
210         return boxes;
211 }
212
213 /*
214         Table field getters
215 */
216
217 bool getstringfield(lua_State *L, int table,
218                 const char *fieldname, std::string &result)
219 {
220         lua_getfield(L, table, fieldname);
221         bool got = false;
222         if(lua_isstring(L, -1)){
223                 size_t len = 0;
224                 const char *ptr = lua_tolstring(L, -1, &len);
225                 result.assign(ptr, len);
226                 got = true;
227         }
228         lua_pop(L, 1);
229         return got;
230 }
231
232 bool getintfield(lua_State *L, int table,
233                 const char *fieldname, int &result)
234 {
235         lua_getfield(L, table, fieldname);
236         bool got = false;
237         if(lua_isnumber(L, -1)){
238                 result = lua_tonumber(L, -1);
239                 got = true;
240         }
241         lua_pop(L, 1);
242         return got;
243 }
244
245 bool getfloatfield(lua_State *L, int table,
246                 const char *fieldname, float &result)
247 {
248         lua_getfield(L, table, fieldname);
249         bool got = false;
250         if(lua_isnumber(L, -1)){
251                 result = lua_tonumber(L, -1);
252                 got = true;
253         }
254         lua_pop(L, 1);
255         return got;
256 }
257
258 bool getboolfield(lua_State *L, int table,
259                 const char *fieldname, bool &result)
260 {
261         lua_getfield(L, table, fieldname);
262         bool got = false;
263         if(lua_isboolean(L, -1)){
264                 result = lua_toboolean(L, -1);
265                 got = true;
266         }
267         lua_pop(L, 1);
268         return got;
269 }
270
271 std::string checkstringfield(lua_State *L, int table,
272                 const char *fieldname)
273 {
274         lua_getfield(L, table, fieldname);
275         std::string s = luaL_checkstring(L, -1);
276         lua_pop(L, 1);
277         return s;
278 }
279
280 std::string getstringfield_default(lua_State *L, int table,
281                 const char *fieldname, const std::string &default_)
282 {
283         std::string result = default_;
284         getstringfield(L, table, fieldname, result);
285         return result;
286 }
287
288 int getintfield_default(lua_State *L, int table,
289                 const char *fieldname, int default_)
290 {
291         int result = default_;
292         getintfield(L, table, fieldname, result);
293         return result;
294 }
295
296 float getfloatfield_default(lua_State *L, int table,
297                 const char *fieldname, float default_)
298 {
299         float result = default_;
300         getfloatfield(L, table, fieldname, result);
301         return result;
302 }
303
304 bool getboolfield_default(lua_State *L, int table,
305                 const char *fieldname, bool default_)
306 {
307         bool result = default_;
308         getboolfield(L, table, fieldname, result);
309         return result;
310 }
311
312 void setintfield(lua_State *L, int table,
313                 const char *fieldname, int value)
314 {
315         lua_pushinteger(L, value);
316         if(table < 0)
317                 table -= 1;
318         lua_setfield(L, table, fieldname);
319 }
320
321 void setfloatfield(lua_State *L, int table,
322                 const char *fieldname, float value)
323 {
324         lua_pushnumber(L, value);
325         if(table < 0)
326                 table -= 1;
327         lua_setfield(L, table, fieldname);
328 }
329
330 void setboolfield(lua_State *L, int table,
331                 const char *fieldname, bool value)
332 {
333         lua_pushboolean(L, value);
334         if(table < 0)
335                 table -= 1;
336         lua_setfield(L, table, fieldname);
337 }
338
339 u32 getflagsfield(lua_State *L, int table,
340                 const char *fieldname, FlagDesc *flagdesc) {
341         std::string flagstring;
342         
343         flagstring = getstringfield_default(L, table, fieldname, "");
344         return readFlagString(flagstring, flagdesc);
345 }
346
347 /* minetest specific types */
348 MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
349 {
350         lua_getfield(L, index, "name");
351         const char *name = luaL_checkstring(L, -1);
352         lua_pop(L, 1);
353         u8 param1;
354         lua_getfield(L, index, "param1");
355         if(lua_isnil(L, -1))
356                 param1 = 0;
357         else
358                 param1 = lua_tonumber(L, -1);
359         lua_pop(L, 1);
360         u8 param2;
361         lua_getfield(L, index, "param2");
362         if(lua_isnil(L, -1))
363                 param2 = 0;
364         else
365                 param2 = lua_tonumber(L, -1);
366         lua_pop(L, 1);
367         return MapNode(ndef, name, param1, param2);
368 }
369
370 void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
371 {
372         lua_newtable(L);
373         lua_pushstring(L, ndef->get(n).name.c_str());
374         lua_setfield(L, -2, "name");
375         lua_pushnumber(L, n.getParam1());
376         lua_setfield(L, -2, "param1");
377         lua_pushnumber(L, n.getParam2());
378         lua_setfield(L, -2, "param2");
379 }