Minetest 5.10.0-dev
 
Loading...
Searching...
No Matches
l_particleparams.h
Go to the documentation of this file.
1/*
2Minetest
3Copyright (C) 2021 velartrill, Lexi Hale <lexi@hale.su>
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU Lesser General Public License as published by
7the Free Software Foundation; either version 2.1 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU Lesser General Public License for more details.
14
15You should have received a copy of the GNU Lesser General Public License along
16with this program; if not, write to the Free Software Foundation, Inc.,
1751 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18*/
19
20#pragma once
21#include "lua_api/l_particles.h"
22#include "lua_api/l_object.h"
23#include "lua_api/l_internal.h"
24#include "common/c_converter.h"
25#include "common/c_content.h"
26#include "server.h"
27#include "particles.h"
28
30{
31 using namespace ParticleParamTypes;
32
33 template<typename T>
34 inline void readNumericLuaValue(lua_State* L, T& ret)
35 {
36 if (lua_isnil(L,-1))
37 return;
38
39 if (std::is_integral<T>())
40 ret = lua_tointeger(L, -1);
41 else
42 ret = lua_tonumber(L, -1);
43 }
44
45 template <typename T, size_t N>
46 inline void readNumericLuaValue(lua_State* L, Parameter<T,N>& ret)
47 {
49 }
50
51 // these are unfortunately necessary as C++ intentionally disallows function template
52 // specialization and there's no way to make template overloads reliably resolve correctly
53 inline void readLuaValue(lua_State* L, f32Parameter& ret) { readNumericLuaValue(L, ret); }
54 inline void readLuaValue(lua_State* L, f32& ret) { readNumericLuaValue(L, ret); }
55 inline void readLuaValue(lua_State* L, u16& ret) { readNumericLuaValue(L, ret); }
56 inline void readLuaValue(lua_State* L, u8& ret) { readNumericLuaValue(L, ret); }
57
58 inline void readLuaValue(lua_State* L, v3fParameter& ret)
59 {
60 if (lua_isnil(L, -1))
61 return;
62
63 if (lua_isnumber(L, -1)) { // shortcut for uniform vectors
64 auto n = lua_tonumber(L, -1);
65 ret = v3fParameter(n,n,n);
66 } else {
67 ret = (v3fParameter)check_v3f(L, -1);
68 }
69 }
70
71 inline void readLuaValue(lua_State* L, v2fParameter& ret)
72 {
73 if (lua_isnil(L, -1))
74 return;
75
76 if (lua_isnumber(L, -1)) { // shortcut for uniform vectors
77 auto n = lua_tonumber(L, -1);
78 ret = v2fParameter(n,n);
79 } else {
80 ret = (v2fParameter)check_v2f(L, -1);
81 }
82 }
83
84 inline void readLuaValue(lua_State* L, TweenStyle& ret)
85 {
86 if (lua_isnil(L, -1))
87 return;
88
89 static const EnumString opts[] = {
90 {(int)TweenStyle::fwd, "fwd"},
91 {(int)TweenStyle::rev, "rev"},
92 {(int)TweenStyle::pulse, "pulse"},
93 {(int)TweenStyle::flicker, "flicker"},
94 {0, nullptr},
95 };
96
97 luaL_checktype(L, -1, LUA_TSTRING);
98 int v = (int)TweenStyle::fwd;
99 if (!string_to_enum(opts, v, lua_tostring(L, -1))) {
100 throw LuaError("tween style must be one of ('fwd', 'rev', 'pulse', 'flicker')");
101 }
102 ret = (TweenStyle)v;
103 }
104
105 inline void readLuaValue(lua_State* L, AttractorKind& ret)
106 {
107 if (lua_isnil(L, -1))
108 return;
109
110 static const EnumString opts[] = {
111 {(int)AttractorKind::none, "none"},
112 {(int)AttractorKind::point, "point"},
113 {(int)AttractorKind::line, "line"},
114 {(int)AttractorKind::plane, "plane"},
115 {0, nullptr},
116 };
117
118 luaL_checktype(L, -1, LUA_TSTRING);
119 int v = (int)AttractorKind::none;
120 if (!string_to_enum(opts, v, lua_tostring(L, -1))) {
121 throw LuaError("attractor kind must be one of ('none', 'point', 'line', 'plane')");
122 }
123 ret = (AttractorKind)v;
124 }
125
126 inline void readLuaValue(lua_State* L, BlendMode& ret)
127 {
128 if (lua_isnil(L, -1))
129 return;
130
131 static const EnumString opts[] = {
132 {(int)BlendMode::alpha, "alpha"},
133 {(int)BlendMode::add, "add"},
134 {(int)BlendMode::sub, "sub"},
135 {(int)BlendMode::screen, "screen"},
136 {0, nullptr},
137 };
138
139 luaL_checktype(L, -1, LUA_TSTRING);
140 int v = (int)BlendMode::alpha;
141 if (!string_to_enum(opts, v, lua_tostring(L, -1))) {
142 throw LuaError("blend mode must be one of ('alpha', 'add', 'sub', 'screen')");
143 }
144 ret = (BlendMode)v;
145 }
146
147 template <typename T> void
148 readLuaValue(lua_State* L, RangedParameter<T>& field)
149 {
150 if (lua_isnil(L,-1))
151 return;
152 if (!lua_istable(L,-1)) // is this is just a literal value?
153 goto set_uniform;
154
155 lua_getfield(L, -1, "min");
156 // handle convenience syntax for non-range values
157 if (lua_isnil(L,-1)) {
158 lua_pop(L, 1);
159 goto set_uniform;
160 }
161 readLuaValue(L,field.min);
162 lua_pop(L, 1);
163
164 lua_getfield(L, -1, "max");
165 readLuaValue(L,field.max);
166 lua_pop(L, 1);
167
168 lua_getfield(L, -1, "bias");
169 if (!lua_isnil(L,-1))
170 readLuaValue(L,field.bias);
171 lua_pop(L, 1);
172 return;
173
174 set_uniform:
175 readLuaValue(L, field.min);
176 readLuaValue(L, field.max);
177 }
178
179 template <typename T> void
180 readLegacyValue(lua_State* L, const char* name, T& field) {}
181
182 template <typename T> void
183 readLegacyValue(lua_State* L, const char* name, RangedParameter<T>& field)
184 {
185 int tbl = lua_gettop(L);
186 lua_pushliteral(L, "min");
187 lua_pushstring(L, name);
188 lua_concat(L, 2);
189 lua_gettable(L, tbl);
190 if (!lua_isnil(L, -1)) {
191 readLuaValue(L, field.min);
192 }
193 lua_settop(L, tbl);
194
195 lua_pushliteral(L, "max");
196 lua_pushstring(L, name);
197 lua_concat(L, 2);
198 lua_gettable(L, tbl);
199 if (!lua_isnil(L, -1)) {
200 readLuaValue(L, field.max);
201 }
202 lua_settop(L, tbl);
203 }
204
205 template <typename T> void
206 readTweenTable(lua_State* L, const char* name, TweenedParameter<T>& field)
207 {
208 int tbl = lua_gettop(L);
209
210 lua_pushstring(L, name);
211 lua_pushliteral(L, "_tween");
212 lua_concat(L, 2);
213 lua_gettable(L, tbl);
214 if(lua_istable(L, -1)) {
215 int tween = lua_gettop(L);
216 // get the starting value
217 lua_pushinteger(L, 1), lua_gettable(L, tween);
218 readLuaValue(L, field.start);
219 lua_pop(L, 1);
220
221 // get the final value -- use len instead of 2 so that this
222 // gracefully degrades if keyframe support is later added
223 lua_pushinteger(L, (lua_Integer)lua_objlen(L, -1)), lua_gettable(L, tween);
224 readLuaValue(L, field.end);
225 lua_pop(L, 1);
226
227 // get the effect settings
228 lua_getfield(L, -1, "style");
229 if (!lua_isnil(L,-1))
230 readLuaValue(L, field.style);
231 lua_pop(L, 1);
232
233 lua_getfield(L, -1, "reps");
234 if (!lua_isnil(L,-1))
235 readLuaValue(L, field.reps);
236 lua_pop(L, 1);
237
238 lua_getfield(L, -1, "start");
239 if (!lua_isnil(L,-1))
240 readLuaValue(L, field.beginning);
241 lua_pop(L, 1);
242
243 goto done;
244 } else {
245 lua_pop(L,1);
246 }
247 // the table is not present; check for nonanimated values
248
249 lua_getfield(L, tbl, name);
250 if(!lua_isnil(L, -1)) {
251 readLuaValue(L, field.start);
252 lua_settop(L, tbl);
253 goto set_uniform;
254 } else {
255 lua_pop(L,1);
256 }
257
258 // the goto did not trigger, so this table is not present either
259 // check for pre-5.6.0 legacy values
260 readLegacyValue(L, name, field.start);
261
262 set_uniform:
263 field.end = field.start;
264 done:
265 lua_settop(L, tbl); // clean up after ourselves
266 }
267
268 inline u16 readAttachmentID(lua_State* L, const char* name)
269 {
270 u16 id = 0;
271 lua_getfield(L, -1, name);
272 if (!lua_isnil(L, -1)) {
274 if (auto obj = ObjectRef::getobject(ref))
275 id = obj->getId();
276 }
277 lua_pop(L, 1);
278 return id;
279 }
280
281 void readTexValue(lua_State* L, ServerParticleTexture& tex);
282}
bool string_to_enum(const EnumString *spec, int &result, const std::string &str)
Definition c_content.cpp:1344
v2f check_v2f(lua_State *L, int index)
Definition c_converter.cpp:168
v3f check_v3f(lua_State *L, int index)
Definition c_converter.cpp:195
Definition c_types.h:55
static T * checkObject(lua_State *L, int narg)
Definition l_base.h:83
Definition l_object.h:34
static ServerActiveObject * getobject(ObjectRef *ref)
Definition l_object.cpp:49
Definition l_particleparams.h:30
void readNumericLuaValue(lua_State *L, T &ret)
Definition l_particleparams.h:34
u16 readAttachmentID(lua_State *L, const char *name)
Definition l_particleparams.h:268
void readTweenTable(lua_State *L, const char *name, TweenedParameter< T > &field)
Definition l_particleparams.h:206
void readTexValue(lua_State *L, ServerParticleTexture &tex)
Definition l_particles.cpp:29
void readLegacyValue(lua_State *L, const char *name, T &field)
Definition l_particleparams.h:180
void readLuaValue(lua_State *L, f32Parameter &ret)
Definition l_particleparams.h:53
Definition particles.cpp:123
VectorParameter< v3f, 3 > v3fParameter
Definition particles.h:147
TweenStyle
Definition particles.h:205
VectorParameter< v2f, 2 > v2fParameter
Definition particles.h:146
BlendMode
Definition particles.h:251
AttractorKind
Definition particles.h:250
Definition c_types.h:31
Definition particles.h:90
T val
Definition particles.h:94
Definition particles.h:153
T max
Definition particles.h:157
f32 bias
Definition particles.h:158
T min
Definition particles.h:157
Definition particles.h:210
T start
Definition particles.h:218
f32 beginning
Definition particles.h:216
T end
Definition particles.h:218
u16 reps
Definition particles.h:215
TweenStyle style
Definition particles.h:214
Definition particles.h:125
Definition particles.h:277