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