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 "lua_api/l_particles.h"
21 #include "lua_api/l_object.h"
22 #include "lua_api/l_internal.h"
23 #include "common/c_converter.h"
24 #include "common/c_content.h"
25 #include "server.h"
26 #include "particles.h"
27
28 // add_particle({pos=, velocity=, acceleration=, expirationtime=,
29 // size=, collisiondetection=, collision_removal=, object_collision=,
30 // vertical=, texture=, player=})
31 // pos/velocity/acceleration = {x=num, y=num, z=num}
32 // expirationtime = num (seconds)
33 // size = num
34 // collisiondetection = bool
35 // collision_removal = bool
36 // object_collision = bool
37 // vertical = bool
38 // texture = e.g."default_wood.png"
39 // animation = TileAnimation definition
40 // glow = num
l_add_particle(lua_State * L)41 int ModApiParticles::l_add_particle(lua_State *L)
42 {
43 NO_MAP_LOCK_REQUIRED;
44
45 // Get parameters
46 struct ParticleParameters p;
47 std::string playername;
48
49 if (lua_gettop(L) > 1) // deprecated
50 {
51 log_deprecated(L, "Deprecated add_particle call with "
52 "individual parameters instead of definition");
53 p.pos = check_v3f(L, 1);
54 p.vel = check_v3f(L, 2);
55 p.acc = check_v3f(L, 3);
56 p.expirationtime = luaL_checknumber(L, 4);
57 p.size = luaL_checknumber(L, 5);
58 p.collisiondetection = readParam<bool>(L, 6);
59 p.texture = luaL_checkstring(L, 7);
60 if (lua_gettop(L) == 8) // only spawn for a single player
61 playername = luaL_checkstring(L, 8);
62 }
63 else if (lua_istable(L, 1))
64 {
65 lua_getfield(L, 1, "pos");
66 if (lua_istable(L, -1))
67 p.pos = check_v3f(L, -1);
68 lua_pop(L, 1);
69
70 lua_getfield(L, 1, "vel");
71 if (lua_istable(L, -1)) {
72 p.vel = check_v3f(L, -1);
73 log_deprecated(L, "The use of vel is deprecated. "
74 "Use velocity instead");
75 }
76 lua_pop(L, 1);
77
78 lua_getfield(L, 1, "velocity");
79 if (lua_istable(L, -1))
80 p.vel = check_v3f(L, -1);
81 lua_pop(L, 1);
82
83 lua_getfield(L, 1, "acc");
84 if (lua_istable(L, -1)) {
85 p.acc = check_v3f(L, -1);
86 log_deprecated(L, "The use of acc is deprecated. "
87 "Use acceleration instead");
88 }
89 lua_pop(L, 1);
90
91 lua_getfield(L, 1, "acceleration");
92 if (lua_istable(L, -1))
93 p.acc = check_v3f(L, -1);
94 lua_pop(L, 1);
95
96 p.expirationtime = getfloatfield_default(L, 1, "expirationtime",
97 p.expirationtime);
98 p.size = getfloatfield_default(L, 1, "size", p.size);
99 p.collisiondetection = getboolfield_default(L, 1,
100 "collisiondetection", p.collisiondetection);
101 p.collision_removal = getboolfield_default(L, 1,
102 "collision_removal", p.collision_removal);
103 p.object_collision = getboolfield_default(L, 1,
104 "object_collision", p.object_collision);
105 p.vertical = getboolfield_default(L, 1, "vertical", p.vertical);
106
107 lua_getfield(L, 1, "animation");
108 p.animation = read_animation_definition(L, -1);
109 lua_pop(L, 1);
110
111 p.texture = getstringfield_default(L, 1, "texture", p.texture);
112 p.glow = getintfield_default(L, 1, "glow", p.glow);
113
114 lua_getfield(L, 1, "node");
115 if (lua_istable(L, -1))
116 p.node = readnode(L, -1, getGameDef(L)->ndef());
117 lua_pop(L, 1);
118
119 p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile);
120
121 playername = getstringfield_default(L, 1, "playername", "");
122 }
123
124 getServer(L)->spawnParticle(playername, p);
125 return 1;
126 }
127
128 // add_particlespawner({amount=, time=,
129 // minpos=, maxpos=,
130 // minvel=, maxvel=,
131 // minacc=, maxacc=,
132 // minexptime=, maxexptime=,
133 // minsize=, maxsize=,
134 // collisiondetection=,
135 // collision_removal=,
136 // object_collision=,
137 // vertical=,
138 // texture=,
139 // player=})
140 // minpos/maxpos/minvel/maxvel/minacc/maxacc = {x=num, y=num, z=num}
141 // minexptime/maxexptime = num (seconds)
142 // minsize/maxsize = num
143 // collisiondetection = bool
144 // collision_removal = bool
145 // object_collision = bool
146 // vertical = bool
147 // texture = e.g."default_wood.png"
148 // animation = TileAnimation definition
149 // glow = num
l_add_particlespawner(lua_State * L)150 int ModApiParticles::l_add_particlespawner(lua_State *L)
151 {
152 NO_MAP_LOCK_REQUIRED;
153
154 // Get parameters
155 ParticleSpawnerParameters p;
156 ServerActiveObject *attached = NULL;
157 std::string playername;
158
159 if (lua_gettop(L) > 1) //deprecated
160 {
161 log_deprecated(L, "Deprecated add_particlespawner call with "
162 "individual parameters instead of definition");
163 p.amount = luaL_checknumber(L, 1);
164 p.time = luaL_checknumber(L, 2);
165 p.minpos = check_v3f(L, 3);
166 p.maxpos = check_v3f(L, 4);
167 p.minvel = check_v3f(L, 5);
168 p.maxvel = check_v3f(L, 6);
169 p.minacc = check_v3f(L, 7);
170 p.maxacc = check_v3f(L, 8);
171 p.minexptime = luaL_checknumber(L, 9);
172 p.maxexptime = luaL_checknumber(L, 10);
173 p.minsize = luaL_checknumber(L, 11);
174 p.maxsize = luaL_checknumber(L, 12);
175 p.collisiondetection = readParam<bool>(L, 13);
176 p.texture = luaL_checkstring(L, 14);
177 if (lua_gettop(L) == 15) // only spawn for a single player
178 playername = luaL_checkstring(L, 15);
179 }
180 else if (lua_istable(L, 1))
181 {
182 p.amount = getintfield_default(L, 1, "amount", p.amount);
183 p.time = getfloatfield_default(L, 1, "time", p.time);
184
185 lua_getfield(L, 1, "minpos");
186 if (lua_istable(L, -1))
187 p.minpos = check_v3f(L, -1);
188 lua_pop(L, 1);
189
190 lua_getfield(L, 1, "maxpos");
191 if (lua_istable(L, -1))
192 p.maxpos = check_v3f(L, -1);
193 lua_pop(L, 1);
194
195 lua_getfield(L, 1, "minvel");
196 if (lua_istable(L, -1))
197 p.minvel = check_v3f(L, -1);
198 lua_pop(L, 1);
199
200 lua_getfield(L, 1, "maxvel");
201 if (lua_istable(L, -1))
202 p.maxvel = check_v3f(L, -1);
203 lua_pop(L, 1);
204
205 lua_getfield(L, 1, "minacc");
206 if (lua_istable(L, -1))
207 p.minacc = check_v3f(L, -1);
208 lua_pop(L, 1);
209
210 lua_getfield(L, 1, "maxacc");
211 if (lua_istable(L, -1))
212 p.maxacc = check_v3f(L, -1);
213 lua_pop(L, 1);
214
215 p.minexptime = getfloatfield_default(L, 1, "minexptime", p.minexptime);
216 p.maxexptime = getfloatfield_default(L, 1, "maxexptime", p.maxexptime);
217 p.minsize = getfloatfield_default(L, 1, "minsize", p.minsize);
218 p.maxsize = getfloatfield_default(L, 1, "maxsize", p.maxsize);
219 p.collisiondetection = getboolfield_default(L, 1,
220 "collisiondetection", p.collisiondetection);
221 p.collision_removal = getboolfield_default(L, 1,
222 "collision_removal", p.collision_removal);
223 p.object_collision = getboolfield_default(L, 1,
224 "object_collision", p.object_collision);
225
226 lua_getfield(L, 1, "animation");
227 p.animation = read_animation_definition(L, -1);
228 lua_pop(L, 1);
229
230 lua_getfield(L, 1, "attached");
231 if (!lua_isnil(L, -1)) {
232 ObjectRef *ref = ObjectRef::checkobject(L, -1);
233 lua_pop(L, 1);
234 attached = ObjectRef::getobject(ref);
235 }
236
237 p.vertical = getboolfield_default(L, 1, "vertical", p.vertical);
238 p.texture = getstringfield_default(L, 1, "texture", p.texture);
239 playername = getstringfield_default(L, 1, "playername", "");
240 p.glow = getintfield_default(L, 1, "glow", p.glow);
241
242 lua_getfield(L, 1, "node");
243 if (lua_istable(L, -1))
244 p.node = readnode(L, -1, getGameDef(L)->ndef());
245 lua_pop(L, 1);
246
247 p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile);
248 }
249
250 u32 id = getServer(L)->addParticleSpawner(p, attached, playername);
251 lua_pushnumber(L, id);
252
253 return 1;
254 }
255
256 // delete_particlespawner(id, player)
257 // player (string) is optional
l_delete_particlespawner(lua_State * L)258 int ModApiParticles::l_delete_particlespawner(lua_State *L)
259 {
260 NO_MAP_LOCK_REQUIRED;
261
262 // Get parameters
263 u32 id = luaL_checknumber(L, 1);
264 std::string playername;
265 if (lua_gettop(L) == 2) {
266 playername = luaL_checkstring(L, 2);
267 }
268
269 getServer(L)->deleteParticleSpawner(playername, id);
270 return 1;
271 }
272
Initialize(lua_State * L,int top)273 void ModApiParticles::Initialize(lua_State *L, int top)
274 {
275 API_FCT(add_particle);
276 API_FCT(add_particlespawner);
277 API_FCT(delete_particlespawner);
278 }
279
280