@@ -48,8 +48,6 @@ ParticleEffect::ParticleEffect(SCP_string name)
4848 m_manual_offset (std::nullopt ),
4949 m_manual_velocity_offset(std::nullopt ),
5050 m_particleTrail(ParticleEffectHandle::invalid()),
51- m_size_lifetime_curve(-1 ),
52- m_vel_lifetime_curve (-1 ),
5351 m_particleChance(1 .f),
5452 m_distanceCulled(-1 .f)
5553 {}
@@ -119,8 +117,6 @@ ParticleEffect::ParticleEffect(SCP_string name,
119117 m_manual_offset(offsetLocal),
120118 m_manual_velocity_offset(velocityOffsetLocal),
121119 m_particleTrail(particleTrail),
122- m_size_lifetime_curve(-1 ),
123- m_vel_lifetime_curve (-1 ),
124120 m_particleChance(particleChance),
125121 m_distanceCulled(distanceCulled) {}
126122
@@ -268,11 +264,11 @@ auto ParticleEffect::processSourceInternal(float interp, const ParticleSource& s
268264 for (uint i = 0 ; i < num_spawn; ++i) {
269265 float particleFraction = static_cast <float >(i) / static_cast <float >(num_spawn);
270266
271- particle_info info;
267+ particle info;
272268
273269 info.reverse = m_reverseAnimation;
274270 info.pos = pos;
275- info.vel = velParent;
271+ info.velocity = velParent;
276272
277273 if (m_parent_local) {
278274 info.attached_objnum = parent;
@@ -284,9 +280,9 @@ auto ParticleEffect::processSourceInternal(float interp, const ParticleSource& s
284280 }
285281
286282 if (m_vel_inherit_absolute)
287- vm_vec_normalize_safe (&info.vel , true );
283+ vm_vec_normalize_safe (&info.velocity , true );
288284
289- info.vel *= (m_ignore_velocity_inherit_if_has_parent && parent >= 0 ) ? 0 .f : m_vel_inherit.next () * inheritVelocityMultiplier;
285+ info.velocity *= (m_ignore_velocity_inherit_if_has_parent && parent >= 0 ) ? 0 .f : m_vel_inherit.next () * inheritVelocityMultiplier;
290286
291287 vec3d localVelocity = velNoise;
292288 vec3d localPos = posNoise;
@@ -325,32 +321,43 @@ auto ParticleEffect::processSourceInternal(float interp, const ParticleSource& s
325321 m_velocity_directional_scaling == VelocityScaling::DOT ? dot : 1 .f / std::max (0 .001f , dot));
326322 }
327323
328- info.vel += localVelocity;
329- info.pos += localPos + info.vel * (interp * f2fl (Frametime));
324+ info.velocity += localVelocity;
325+ info.pos += localPos + info.velocity * (interp * f2fl (Frametime));
330326
331327 info.bitmap = m_bitmap_list[m_bitmap_range.next ()];
332328
333329 if (m_parentScale)
334330 // if we were spawned by a particle, parentRadius is the parent's radius and m_radius is a factor of that
335- info.rad = parentRadius * m_radius.next () * radiusMultiplier;
331+ info.radius = parentRadius * m_radius.next () * radiusMultiplier;
336332 else
337- info.rad = m_radius.next () * radiusMultiplier;
333+ info.radius = m_radius.next () * radiusMultiplier;
338334
339335 info.length = m_length.next () * lengthMultiplier;
340- if (m_hasLifetime) {
341- if (m_parentLifetime)
342- // if we were spawned by a particle, parentLifetime is the parent's remaining lifetime and m_lifetime is a factor of that
343- info.lifetime = parentLifetime * m_lifetime.next () * lifetimeMultiplier;
344- else
345- info.lifetime = m_lifetime.next () * lifetimeMultiplier;
346336
347- info.lifetime_from_animation = m_keep_anim_length_if_available;
337+ int fps = 1 ;
338+ if (info.nframes < 0 ) {
339+ Assertion (bm_is_valid (info.bitmap ), " Invalid bitmap handle passed to particle create." );
340+ bm_get_info (info.bitmap , nullptr , nullptr , nullptr , &info.nframes , &fps);
341+ }
342+
343+ if (m_hasLifetime) {
344+ if (m_keep_anim_length_if_available && info.nframes > 1 ) {
345+ // Recalculate max life for ani's
346+ info.max_life = i2fl (info.nframes ) / i2fl (fps);
347+ }
348+ else {
349+ if (m_parentLifetime)
350+ // if we were spawned by a particle, parentLifetime is the parent's remaining lifetime and m_lifetime is a factor of that
351+ info.max_life = parentLifetime * m_lifetime.next () * lifetimeMultiplier;
352+ else
353+ info.max_life = m_lifetime.next () * lifetimeMultiplier;
354+ }
348355 }
349356
350- info.starting_age = interp * f2fl (Frametime);
351-
352- info.size_lifetime_curve = m_size_lifetime_curve ;
353- info.vel_lifetime_curve = m_vel_lifetime_curve ;
357+ info.age = interp * f2fl (Frametime);
358+ info. looping = false ;
359+ info.angle = frand_range ( 0 . 0f , PI2) ;
360+ info.parent_effect = m_self ;
354361
355362 switch (m_rotation_type) {
356363 case RotationType::DEFAULT:
@@ -367,7 +374,7 @@ auto ParticleEffect::processSourceInternal(float interp, const ParticleSource& s
367374 }
368375
369376 if (m_particleTrail.isValid ()) {
370- auto part = createPersistent (& info);
377+ auto part = createPersistent (std::move ( info) );
371378
372379 if constexpr (isPersistent)
373380 createdParticles.push_back (part);
@@ -381,12 +388,12 @@ auto ParticleEffect::processSourceInternal(float interp, const ParticleSource& s
381388 }
382389 } else {
383390 if constexpr (isPersistent){
384- auto part = createPersistent (& info);
391+ auto part = createPersistent (std::move ( info) );
385392 createdParticles.push_back (part);
386393 }
387394 else {
388395 // We don't have a trail so we don't need a persistent particle
389- create (& info);
396+ create (std::move ( info) );
390397 }
391398 }
392399 }
0 commit comments