44#include " particle.h"
55#include " vecmath.h"
66#include " object.h"
7+ #include " model.h"
8+ #include " particle/ParticleManager.h"
9+ #include " particle/ParticleEffect.h"
710
811namespace scripting {
912namespace api {
@@ -20,6 +23,18 @@ bool particle_h::isValid() const {
2023 return !part.expired ();
2124}
2225
26+ particle_source_h::particle_source_h (particle::ParticleSource* source_p, uint32_t sourceValidityCounter_p) {
27+ this ->source = source_p;
28+ this ->sourceValidityCounter = sourceValidityCounter_p;
29+ }
30+
31+ particle::ParticleSource* particle_source_h::Get () const {
32+ return isValid () ? this ->source : nullptr ;
33+ }
34+
35+ bool particle_source_h::isValid () const {
36+ return particle::ParticleManager::get ()->getSourceValidityCounter () == sourceValidityCounter;
37+ }
2338
2439// **********HANDLE: Particle
2540ADE_OBJ (l_Particle, particle_h, " particle" , " Handle to a particle" );
@@ -214,6 +229,230 @@ ADE_FUNC_DEPRECATED(setColor, l_Particle, "number r, number g, number b", "Sets
214229}
215230
216231
232+ ADE_OBJ (l_ParticleEffect, ::particle::ParticleEffectHandle, " particle_effect" , " Handle to a tabled particle effect" );
233+
234+ ADE_FUNC (getName, l_ParticleEffect, nullptr , " Returns the name under which this effect is stored" , " string" , " the name of the particle effect, or an empty string for an invalid handle" )
235+ {
236+ ::particle::ParticleEffectHandle ph;
237+ if (!ade_get_args (L, " o" , l_ParticleEffect.Get (&ph)))
238+ return ade_set_error (L, " s" , " " );
239+
240+ if (!ph.isValid ())
241+ return ade_set_error (L, " s" , " " );
242+
243+ const auto & particle_effect = particle::ParticleManager::get ()->getEffect (ph);
244+ if (particle_effect.empty ())
245+ return ade_set_error (L, " s" , " " );
246+
247+ return ade_set_args (L, " s" , particle_effect.front ().getName ().c_str ());
248+ }
249+
250+ ADE_FUNC (createSource, l_ParticleEffect, nullptr , " Creates a new particle source, spawning particles as per this particle effect" , " particle_source" , " the particle source, or nil for an invalid handle" )
251+ {
252+ ::particle::ParticleEffectHandle ph;
253+ if (!ade_get_args (L, " o" , l_ParticleEffect.Get (&ph)))
254+ return ADE_RETURN_NIL ;
255+
256+ if (!ph.isValid ())
257+ return ADE_RETURN_NIL ;
258+
259+ auto source = particle::ParticleManager::get ()->createSource (ph);
260+ return ade_set_args (L, " o" , l_ParticleSource.Set (particle_source_h (source, particle::ParticleManager::get ()->getSourceValidityCounter ())));
261+ }
262+
263+ ADE_OBJ (l_ParticleSource, particle_source_h, " particle_source" , " Handle to a particle source. Only valid immediately after acquiring." );
264+
265+ ADE_FUNC (setNormal, l_ParticleSource, " vector normal" , " Sets the normal vector of this particle source." , nullptr , nullptr )
266+ {
267+ particle_source_h ps;
268+ vec3d normal;
269+ if (!ade_get_args (L, " oo" , l_ParticleSource.Get (&ps), l_Vector.Get (&normal)))
270+ return ADE_RETURN_NIL ;
271+
272+ particle::ParticleSource* psp = ps.Get ();
273+ if (psp == nullptr )
274+ return ADE_RETURN_NIL ;
275+
276+ vm_vec_normalize_safe (&normal);
277+ psp->setNormal (normal);
278+
279+ return ADE_RETURN_NIL ;
280+ }
281+
282+ ADE_FUNC (setTriggerRadius, l_ParticleSource, " number triggerRadius" , " Sets the trigger radius of this particle source." , nullptr , nullptr )
283+ {
284+ particle_source_h ps;
285+ float trigger;
286+ if (!ade_get_args (L, " of" , l_ParticleSource.Get (&ps), &trigger))
287+ return ADE_RETURN_NIL ;
288+
289+ particle::ParticleSource* psp = ps.Get ();
290+ if (psp == nullptr )
291+ return ADE_RETURN_NIL ;
292+
293+ psp->setTriggerRadius (trigger);
294+
295+ return ADE_RETURN_NIL ;
296+ }
297+
298+ ADE_FUNC (setTriggerVelocity, l_ParticleSource, " number triggerVelocity" , " Sets the trigger velocity of this particle source." , nullptr , nullptr )
299+ {
300+ particle_source_h ps;
301+ float trigger;
302+ if (!ade_get_args (L, " of" , l_ParticleSource.Get (&ps), &trigger))
303+ return ADE_RETURN_NIL ;
304+
305+ particle::ParticleSource* psp = ps.Get ();
306+ if (psp == nullptr )
307+ return ADE_RETURN_NIL ;
308+
309+ psp->setTriggerVelocity (trigger);
310+
311+ return ADE_RETURN_NIL ;
312+ }
313+
314+ ADE_FUNC (createOnCoordinates, l_ParticleSource, " vector position, orientation orientation, [vector velocity = zero_vector, orientation orientationOverride = identity, boolean orientationOverrideIsRelative = true]" , " Actually spawns this particle source at the specified position." , " boolean" , " returns true if the source was successfully created, false otherwise" )
315+ {
316+ particle_source_h ps;
317+ vec3d position;
318+ matrix_h orientation;
319+ vec3d velocity = ZERO_VECTOR ;
320+ matrix_h orientationOverride (&vmd_identity_matrix);
321+ bool orientationOverrideRelative = true ;
322+
323+ if (!ade_get_args (L, " ooo|oob" , l_ParticleSource.Get (&ps), l_Vector.Get (&position), l_Matrix.Get (&orientation), l_Vector.Get (&velocity), l_Matrix.Get (&orientationOverride), &orientationOverrideRelative))
324+ return ade_set_args (L, " b" , false );
325+
326+ particle::ParticleSource* psp = ps.Get ();
327+ if (psp == nullptr )
328+ return ade_set_args (L, " b" , false );
329+
330+ psp->setHost (std::make_unique<EffectHostVector>(position, *orientation.GetMatrix (), velocity, *orientationOverride.GetMatrix (), orientationOverrideRelative));
331+ psp->finishCreation ();
332+
333+ return ade_set_args (L, " b" , true );
334+ }
335+
336+ ADE_FUNC (createOnObject, l_ParticleSource, " object object, vector offset, [orientation orientationOverride = identity, boolean orientationOverrideIsRelative = true]" , " Actually spawns this particle source, attached to the specified object." , " boolean" , " returns true if the source was successfully created, false otherwise" )
337+ {
338+ particle_source_h ps;
339+ object_h objh;
340+ vec3d position;
341+ matrix_h orientationOverride (&vmd_identity_matrix);
342+ bool orientationOverrideRelative = true ;
343+
344+ if (!ade_get_args (L, " ooo|ob" , l_ParticleSource.Get (&ps), l_Object.Get (&objh), l_Vector.Get (&position), l_Matrix.Get (&orientationOverride), &orientationOverrideRelative))
345+ return ade_set_args (L, " b" , false );
346+
347+ if (!objh.isValid ())
348+ return ade_set_args (L, " b" , false );
349+
350+ particle::ParticleSource* psp = ps.Get ();
351+ if (psp == nullptr )
352+ return ade_set_args (L, " b" , false );
353+
354+ psp->setHost (std::make_unique<EffectHostObject>(objh.objp (), position, *orientationOverride.GetMatrix (), orientationOverrideRelative));
355+ psp->finishCreation ();
356+
357+ return ade_set_args (L, " b" , true );
358+ }
359+
360+ ADE_FUNC (createOnSubmodel, l_ParticleSource, " object object, submodel submodel, vector offset, [orientation orientationOverride = identity, boolean orientationOverrideIsRelative = true]" , " Actually spawns this particle source, attached to the specified submodel." , " boolean" , " returns true if the source was successfully created, false otherwise" )
361+ {
362+ particle_source_h ps;
363+ object_h objh;
364+ submodel_h subobjh;
365+ vec3d position;
366+ matrix_h orientationOverride (&vmd_identity_matrix);
367+ bool orientationOverrideRelative = true ;
368+
369+ if (!ade_get_args (L, " oooo|ob" , l_ParticleSource.Get (&ps), l_Object.Get (&objh), l_Submodel.Get (&subobjh), l_Vector.Get (&position), l_Matrix.Get (&orientationOverride), &orientationOverrideRelative))
370+ return ade_set_args (L, " b" , false );
371+
372+ if (!(subobjh.isValid () && objh.isValid ()))
373+ return ade_set_args (L, " b" , false );
374+
375+ particle::ParticleSource* psp = ps.Get ();
376+ if (psp == nullptr )
377+ return ade_set_args (L, " b" , false );
378+
379+ psp->setHost (std::make_unique<EffectHostSubmodel>(objh.objp (), subobjh.GetSubmodelIndex (), position, *orientationOverride.GetMatrix (), orientationOverrideRelative));
380+ psp->finishCreation ();
381+
382+ return ade_set_args (L, " b" , true );
383+ }
384+
385+ ADE_FUNC (createOnTurret, l_ParticleSource, " object object, submodel submodel, number firepoint, [orientation orientationOverride = identity, boolean orientationOverrideIsRelative = true]" , " Actually spawns this particle source, attached to the specified turret firepoint." , " boolean" , " returns true if the source was successfully created, false otherwise" )
386+ {
387+ particle_source_h ps;
388+ object_h objh;
389+ submodel_h subobjh;
390+ int firepoint;
391+ matrix_h orientationOverride (&vmd_identity_matrix);
392+ bool orientationOverrideRelative = true ;
393+
394+ if (!ade_get_args (L, " oooi|ob" , l_ParticleSource.Get (&ps), l_Object.Get (&objh), l_Submodel.Get (&subobjh), &firepoint, l_Matrix.Get (&orientationOverride), &orientationOverrideRelative))
395+ return ade_set_args (L, " b" , false );
396+
397+ if (!(subobjh.isValid () && objh.isValid ()))
398+ return ade_set_args (L, " b" , false );
399+
400+ particle::ParticleSource* psp = ps.Get ();
401+ if (psp == nullptr )
402+ return ade_set_args (L, " b" , false );
403+
404+ psp->setHost (std::make_unique<EffectHostTurret>(objh.objp (), subobjh.GetSubmodelIndex (), firepoint, *orientationOverride.GetMatrix (), orientationOverrideRelative));
405+ psp->finishCreation ();
406+
407+ return ade_set_args (L, " b" , true );
408+ }
409+
410+ ADE_FUNC (createOnBeam, l_ParticleSource, " object object, submodel submodel, number firepoint, [orientation orientationOverride = identity, boolean orientationOverrideIsRelative = true]" , " Actually spawns this particle source along the length of the beam." , " boolean" , " returns true if the source was successfully created, false otherwise" )
411+ {
412+ particle_source_h ps;
413+ object_h objh;
414+ matrix_h orientationOverride (&vmd_identity_matrix);
415+ bool orientationOverrideRelative = true ;
416+
417+ if (!ade_get_args (L, " ooo|ob" , l_ParticleSource.Get (&ps), l_Object.Get (&objh), l_Matrix.Get (&orientationOverride), &orientationOverrideRelative))
418+ return ade_set_args (L, " b" , false );
419+
420+ if (!objh.isValid () || objh.objp ()->type != OBJ_BEAM )
421+ return ade_set_args (L, " b" , false );
422+
423+ particle::ParticleSource* psp = ps.Get ();
424+ if (psp == nullptr )
425+ return ade_set_args (L, " b" , false );
426+
427+ psp->setHost (std::make_unique<EffectHostBeam>(objh.objp (), *orientationOverride.GetMatrix (), orientationOverrideRelative));
428+ psp->finishCreation ();
429+
430+ return ade_set_args (L, " b" , true );
431+ }
432+
433+ ADE_FUNC (createOnParticle, l_ParticleSource, " particle particle, [orientation orientationOverride = identity, boolean orientationOverrideIsRelative = true]" , " Actually spawns this particle source, attached to the specified persistent particle." , " boolean" , " returns true if the source was successfully created, false otherwise" )
434+ {
435+ particle_source_h ps;
436+ particle_h particle;
437+ matrix_h orientationOverride (&vmd_identity_matrix);
438+ bool orientationOverrideRelative = true ;
439+
440+ if (!ade_get_args (L, " ooo|ob" , l_ParticleSource.Get (&ps), l_Particle.Get (&particle), l_Matrix.Get (&orientationOverride), &orientationOverrideRelative))
441+ return ade_set_args (L, " b" , false );
442+
443+ if (!particle.isValid ())
444+ return ade_set_args (L, " b" , false );
445+
446+ particle::ParticleSource* psp = ps.Get ();
447+ if (psp == nullptr )
448+ return ade_set_args (L, " b" , false );
449+
450+ psp->setHost (std::make_unique<EffectHostParticle>(particle.Get (), *orientationOverride.GetMatrix (), orientationOverrideRelative));
451+ psp->finishCreation ();
452+
453+ return ade_set_args (L, " b" , true );
454+ }
455+
217456}
218457}
219458
0 commit comments