Dayz Explorer  1.24.157551 (v105080)
Dayz Code Explorer by Zeroy
particle.c
Go to the documentation of this file.
1 
7 {
12  protected int m_ParticleID;
15  protected float m_Lifetime;
17  protected bool m_IsRepeat;
19  private bool m_MarkedForDeletion;
21 
26  bool m_WiggleProcessing;
29  bool m_ForceOrientationRelativeToWorld;
31  vector m_DefaultOri;
33  vector m_DefaultPos;
35  vector m_DefaultWorldOri;
37  vector m_DefaultWorldPos;
38 
40  float m_MaxOriWiggle;
42  float m_MaxOriInterval;
44  ref Timer m_RandomizeOri;
46 
48  protected Object m_ParentObject;
50  protected Object m_ParticleEffect;
51 
53  protected int m_PreviousFrame;
55  private vector m_GlobalPosPreviousFrame;
57  static private const int MAX_EMITORS = 30;
58 
59 
61  void Particle()
62  {
63  ParticleInit();
64  }
65 
67  protected void ParticleInit()
68  {
69  SetFlags(EntityFlags.VISIBLE, true);
70  SetEventMask(EntityEvent.INIT);
71  SetEventMask(EntityEvent.FRAME);
72  }
73 
78 
88  static Particle CreateOnObject( int particle_id, Object parent_obj, vector local_pos = "0 0 0", vector local_ori = "0 0 0", bool force_world_rotation = false )
89  {
90  if (!parent_obj)
91  Error("ERROR when creating a particle! Parameter parent_obj is NULL!");
92 
93  vector global_pos = parent_obj.GetPosition();
94  Particle p = CreateInWorld(particle_id, global_pos, Vector(0,0,0), force_world_rotation);
95  p.AddAsChild(parent_obj, local_pos, local_ori, force_world_rotation);
96  p.m_DefaultOri = local_ori;
97 
98  return p;
99  }
100 
104  static Particle Create( int particle_id, Object parent_obj, vector local_pos = "0 0 0", vector local_ori = "0 0 0" )
105  {
106  return CreateOnObject( particle_id, parent_obj, local_pos, local_ori);
107  }
108 
117  static Particle CreateInWorld( int particle_id, vector global_pos, vector global_ori = "0 0 0", bool force_world_rotation = false )
118  {
119  Particle p = Particle.Cast( GetGame().CreateObjectEx("Particle", global_pos, ECE_LOCAL) );
120  p.SetSource(particle_id);
121  p.SetOrientation(global_ori);
122  p.m_ForceOrientationRelativeToWorld = force_world_rotation;
123  return p;
124  }
125 
129  static Particle Create( int particle_id, vector global_pos, vector global_ori = "0 0 0" )
130  {
131  return CreateInWorld( particle_id, global_pos, global_ori );
132  }
133 
135 
136 
137 
142 
152  static Particle PlayOnObject( int particle_id, Object parent_obj, vector local_pos = "0 0 0", vector local_ori = "0 0 0", bool force_world_rotation = false )
153  {
154  Particle p = CreateOnObject(particle_id, parent_obj, local_pos, local_ori, force_world_rotation);
155  p.PlayParticle();
156 
157  return p;
158  }
159 
163  static Particle Play( int particle_id, Object parent_obj, vector local_pos = "0 0 0", vector local_ori = "0 0 0" )
164  {
165  return PlayOnObject( particle_id, parent_obj, local_pos, local_ori);
166  }
167 
174  static Particle PlayInWorld( int particle_id, vector global_pos)
175  {
176  Particle p = CreateInWorld(particle_id, global_pos);
177  p.PlayParticle();
178 
179  return p;
180  }
181 
185  static Particle Play( int particle_id, vector global_pos)
186  {
187  return PlayInWorld( particle_id, global_pos);
188  }
189 
191 
192 
193 
198 
203  override void PlayParticle(int particle_id = -1)
204  {
205  PlayParticleEx(particle_id, 0);
206  }
207 
215  override bool PlayParticleEx(int particle_id = -1, int flags = 0)
216  {
217  if ( particle_id > -1 )
218  {
219  SetSource(particle_id);
220  }
221 
222  OnParticleStart();
223 
224  UpdateState();
225 
226  return true;
227  }
228 
233  void Play(int particle_id = -1)
234  {
235  PlayParticle(particle_id);
236  }
237 
245  override bool StopParticle(int flags = 0)
246  {
247  OnParticleStop();
248 
249  // Without the following we might get an error when a particle parent is despawned client-side.
250  Object parent = Object.Cast( GetParent() );
251  if ( parent && !ToDelete())
252  {
253  vector world_pos = GetPosition();
254  parent.RemoveChild(this);
255  SetPosition(world_pos);
256  }
257 
258  UpdateState();
259 
260  return true;
261  }
262 
266  void Stop()
267  {
268  StopParticle();
269  }
270 
272 
273 
274 
279 
285  void SetSource(int particle_id)
286  {
287  m_ParticleID = particle_id;
288  }
289 
297  int GetParticleID()
298  {
299  return m_ParticleID;
300  }
301 
307  Object GetDirectParticleEffect()
308  {
309  return m_ParticleEffect;
310  }
311 
316  Object GetParticleParent()
317  {
318  return m_ParentObject;
319  }
320 
325  bool HasActiveParticle()
326  {
327  if (m_ParticleEffect)
328  {
329  return ParticleHasActive(m_ParticleEffect);
330  }
331 
332  return false;
333  }
334 
340  int GetParticleCount()
341  {
342  if (m_ParticleEffect)
343  {
344  return ParticleGetCount(m_ParticleEffect);
345  }
346 
347  return 0;
348  }
349 
354  bool IsRepeat()
355  {
356  if (m_ParticleEffect)
357  {
358  bool repeat = false;
359 
360  int emitors = GetParticleEmitorCount(m_ParticleEffect);
361 
362  for (int i = 0; i < emitors; ++i)
363  {
364  GetParticleParm(m_ParticleEffect, i, EmitorParam.REPEAT, repeat);
365 
366  if (repeat)
367  {
368  return true;
369  }
370  }
371  }
372 
373  return false;
374  }
375 
380  float GetMaxLifetime()
381  {
382  float lifetime_return = 0;
383 
384  if (m_ParticleEffect)
385  {
386  float lifetime_min = 0;
387  float lifetime_random = 0;
388  float effect_time = 0;
389 
390  float lifetime_sum = 0;
391 
392  int emitors = GetParticleEmitorCount(m_ParticleEffect);
393 
394  for (int i = 0; i < emitors; ++i)
395  {
396  GetParticleParm(m_ParticleEffect, i, EmitorParam.LIFETIME, lifetime_min);
397  GetParticleParm(m_ParticleEffect, i, EmitorParam.LIFETIME_RND, lifetime_random);
398  GetParticleParm(m_ParticleEffect, i, EmitorParam.EFFECT_TIME, effect_time);
399 
400  lifetime_sum = lifetime_min + lifetime_random + effect_time;
401 
402  if ( lifetime_sum > lifetime_return )
403  {
404  lifetime_return = lifetime_sum;
405  }
406  }
407  }
408 
409  return lifetime_return;
410  }
411 
413 
414 
415 
420 
425  protected void UpdateState()
426  {
427  if ( m_IsPlaying == false && m_ParticleEffect)
428  {
429  DestroyParticleEffect();
430  }
431  else if ( m_IsPlaying == true && m_ParticleEffect == null )
432  {
433  CreateParticleEffect();
434  }
435  }
436 
440  private void CreateParticleEffect()
441  {
442  if ( !GetGame().IsServer() || !GetGame().IsMultiplayer() )
443  {
444  string fullPath = ParticleList.GetParticleFullPath(m_ParticleID);
445  if (fullPath == "")
446  {
447  ErrorEx("Could not play Particle as there is no valid particle id assigned.");
448  m_IsPlaying = false;
449  return;
450  }
451 
452  if ( m_ParticleEffect == null )
453  {
454  m_ParticleEffect = GetGame().CreateObjectEx("#particlesourceenf", vector.Zero, ECE_LOCAL); // particle source must be lowercase!
455  }
456 
457  AddChild(m_ParticleEffect, -1, m_ForceOrientationRelativeToWorld);
458 
459  vobject vobj = GetObject( fullPath );
460  m_ParticleEffect.SetObject(vobj, "");
461  ReleaseObject(vobj);
462 
463  m_IsRepeat = IsRepeat();
464  m_Lifetime = GetMaxLifetime();
465  }
466  }
467 
474  private void DestroyParticleEffect()
475  {
476  if ( m_ParticleEffect && GetGame() )
477  {
478  SetParameter(-1, EmitorParam.LIFETIME, 0);
479  SetParameter(-1, EmitorParam.LIFETIME_RND, 0);
480  SetParameter(-1, EmitorParam.REPEAT, 0);
481 
482  m_IsRepeat = false;
483  }
484  }
485 
489  override void EOnFrame(IEntity other, float timeSlice)
490  {
491  m_Lifetime -= timeSlice;
492  OnCheckAutoDelete();
493  }
494 
498  void OnCheckAutoDelete()
499  {
500  if (m_Lifetime <= 0)
501  {
502  if (!m_MarkedForDeletion)
503  {
504  m_IsRepeat = IsRepeat(); // It is possible that the REPEAT flag was changed during lifetime, so it needs to be checked again.
505 
506  if ( m_IsRepeat )
507  {
508  m_Lifetime = GetMaxLifetime();
509  }
510  else
511  {
512  OnParticleStop();
513 
514  if ( GetParticleCount() == 0 )
515  {
516  m_MarkedForDeletion = true;
517  OnToDelete();
518  OnParticleEnd();
519  }
520  }
521  }
522  else
523  {
524  if ( m_MarkedForDeletion )
525  {
526  if (m_ParticleEffect)
527  {
528  m_ParticleEffect.Delete();
529  m_ParticleEffect = null;
530  }
531 
532  Delete();
533  }
534  }
535  }
536  }
537 
541  private void OnToDelete()
542  {
543 
544  }
545 
547 
548 
549 
554 
563  void AddAsChild(Object parent, vector local_pos = "0 0 0", vector local_ori = "0 0 0", bool force_rotation_to_world = false)
564  {
565  if (ToDelete())
566  return;
567 
568  if (parent)
569  {
570  // AddAsChild method is sometimes called from a timer.
571  // Due to that it is necesarry to use ToDelete() here to check if the parent object is flagged for deletion or not on client,
572  // because sometimes this code is executed before the parent's destructor from where this would normally be handled.
573  if (!parent.ToDelete())
574  {
575  SetPosition(local_pos);
576  SetOrientation(local_ori);
577  m_ParentObject = parent;
578  m_DefaultPos = local_pos;
579  m_ForceOrientationRelativeToWorld = force_rotation_to_world;
580 
581  if (m_ParticleEffect)
582  AddChild(m_ParticleEffect, -1, m_ForceOrientationRelativeToWorld);
583 
584  parent.AddChild(this, -1, false);
585  }
586  }
587  else
588  {
589  if (m_ParentObject && !m_ParentObject.ToDelete())
590  {
591  m_ParentObject.RemoveChild(this, true);
592  m_ParentObject = null;
593  }
594  }
595  }
596 
598 
599 
600 
605 
611  void SetParticleParam(int parameter_id, float value )
612  {
613  if (!m_ParticleEffect)
614  return;
615 
616  SetParticleParm(m_ParticleEffect, -1, parameter_id, value);
617  }
618 
625  void SetParameter(int emitter, int parameter, float value)
626  {
627  if (!m_ParticleEffect)
628  return;
629 
630  SetParticleParm(m_ParticleEffect, emitter, parameter, value);
631  }
632 
639  void GetParameter(int emitter, int parameter, out float value)
640  {
641  if (!m_ParticleEffect)
642  return;
643 
644  GetParticleParm(m_ParticleEffect, emitter, parameter, value);
645  }
646 
653  float GetParameterEx(int emitter, int parameter)
654  {
655  if (!m_ParticleEffect)
656  return 0;
657 
658  float value;
659  GetParticleParm(m_ParticleEffect, emitter, parameter, value);
660  return value;
661  }
662 
668  void ScaleParticleParamFromOriginal(int parameter_id, float coef )
669  {
670  if (!m_ParticleEffect)
671  return;
672 
673  int emitors = GetParticleEmitorCount(m_ParticleEffect);
674  for (int i = 0; i < emitors; ++i)
675  {
676  float value;
677  GetParticleParmOriginal(m_ParticleEffect, i, parameter_id, value);
678  SetParticleParm(m_ParticleEffect, i, parameter_id, value * coef);
679  }
680  }
681 
687  void ScaleParticleParam(int parameter_id, float coef )
688  {
689  if (!m_ParticleEffect)
690  return;
691 
692  int emitors = GetParticleEmitorCount(m_ParticleEffect);
693  for (int i = 0; i < emitors; ++i)
694  {
695  float value;
696  GetParticleParm(m_ParticleEffect, i, parameter_id, value);
697  SetParticleParm(m_ParticleEffect, i, parameter_id, value * coef);
698  }
699  }
700 
707  void IncrementParticleParamFromOriginal(int parameter_id, float value )
708  {
709  if (!m_ParticleEffect)
710  return;
711 
712  int emitors = GetParticleEmitorCount(m_ParticleEffect);
713  for (int i = 0; i < emitors; ++i)
714  {
715  float param;
716  GetParticleParmOriginal(m_ParticleEffect, i, parameter_id, param);
717  SetParticleParm(m_ParticleEffect, i, parameter_id, param + value);
718  }
719  }
720 
727  void IncrementParticleParam(int parameter_id, float value )
728  {
729  if (!m_ParticleEffect)
730  return;
731 
732  int emitors = GetParticleEmitorCount(m_ParticleEffect);
733  for (int i = 0; i < emitors; ++i)
734  {
735  float param;
736  GetParticleParm(m_ParticleEffect, i, parameter_id, param);
737  SetParticleParm(m_ParticleEffect, i, parameter_id, param + value);
738  }
739  }
740 
742 
743 
744 
749 
753  bool IsWiggling()
754  {
755  return m_RandomizeOri && m_RandomizeOri.IsRunning();
756  }
757 
765  void SetWiggle(float random_angle, float random_interval)
766  {
767  if ( random_angle != 0 || random_interval != 0 )
768  {
769  m_MaxOriWiggle = random_angle;
770  m_MaxOriInterval = random_interval;
771 
772  if ( !m_RandomizeOri )
773  m_RandomizeOri = new Timer( CALL_CATEGORY_GAMEPLAY );
774 
775  if ( !m_RandomizeOri.IsRunning() ) // Makes sure the timer is NOT running already
776  m_RandomizeOri.Run( Math.RandomFloat(0, m_MaxOriInterval) , this, "RandomizeOrientation", null, false);
777  }
778  else
779  {
780  StopWiggle();
781  }
782  }
783 
787  void StopWiggle()
788  {
789  if ( m_RandomizeOri )
790  {
791  m_RandomizeOri.Stop();
792  }
793 
794  m_MaxOriWiggle = 0;
795  m_MaxOriInterval = 0;
796  }
797 
801  void RandomizeOrientation()
802  {
803  m_WiggleProcessing = true;
804 
805  if (m_ParentObject)
806  {
807  if ( !m_RandomizeOri.IsRunning() )
808  {
809  m_RandomizeOri.Run( Math.RandomFloat(0, m_MaxOriInterval) , this, "RandomizeOrientation", NULL, false);
810  }
811 
812  Object old_parent = m_ParentObject;
813  AddAsChild( null );
814  AddAsChild( old_parent, m_DefaultPos, m_DefaultOri + RandWiggleVector() );
815  }
816 
817  m_WiggleProcessing = false;
818  }
819 
823  protected vector RandWiggleVector()
824  {
825  return Vector( RandWiggleFloat(), RandWiggleFloat(), RandWiggleFloat() );
826  }
827 
831  protected float RandWiggleFloat()
832  {
833  return Math.RandomFloatInclusive(-m_MaxOriWiggle, m_MaxOriWiggle);
834  }
835 
837 }
GetGame
proto native CGame GetGame()
m_IsPlaying
protected bool m_IsPlaying
Whether the Effect is currently playing.
Definition: effect.c:37
Error
void Error(string err)
Messagebox with error message.
Definition: endebug.c:90
particle_id
int particle_id
Definition: smokesimulation.c:3
CALL_CATEGORY_GAMEPLAY
const int CALL_CATEGORY_GAMEPLAY
Definition: tools.c:10
ParticleBase
void ParticleBase()
ctor
Definition: particlebase.c:71
Particle
Legacy way of using particles in the game.
Definition: particle.c:6
EntityFlags
EntityFlags
Entity flags.
Definition: enentity.c:114
vobject
Definition: proto.c:48
ReleaseObject
proto native void ReleaseObject(vobject object, int flag=0)
OnParticleStart
protected void OnParticleStart()
Event when the particle starts.
Definition: particlebase.c:179
m_Lifetime
class MuzzleFlashLight extends PointLightBase m_Lifetime
GetParticleEmitorCount
proto int GetParticleEmitorCount(notnull IEntity ent)
m_ParentObject
protected Object m_ParentObject
Cached parent.
Definition: effect.c:39
EmitorParam
EmitorParam
Definition: envisual.c:113
OnParticleEnd
protected void OnParticleEnd()
Event when the particle ends.
Definition: particlebase.c:206
ErrorEx
enum ShapeType ErrorEx
IEntity
Definition: enentity.c:164
ParticleHasActive
bool ParticleHasActive(IEntity ent)
Definition: envisual.c:210
GetParticleParmOriginal
proto void GetParticleParmOriginal(notnull IEntity ent, int emitor, EmitorParam parameter, out void value)
GetPosition
class JsonUndergroundAreaTriggerData GetPosition
Definition: undergroundarealoader.c:9
ParticleList
Definition: particlelist.c:11
vector
Definition: enconvert.c:105
OnParticleStop
protected void OnParticleStop()
Event when the particle stops.
Definition: particlebase.c:188
Object
Definition: objecttyped.c:1
SetFlags
proto native void SetFlags(ShapeFlags flags)
SetPosition
proto native void SetPosition(vector position)
Set the world position of the Effect.
Definition: effect.c:436
GetObject
proto native vobject GetObject(string name)
Loads object from data, or gets it from cache. Object must be released when not used.
ParticleGetCount
int ParticleGetCount(IEntity ent)
Definition: envisual.c:205
SetParticleParm
proto void SetParticleParm(notnull IEntity ent, int emitor, EmitorParam parameter, void value)
AddChild
proto native void AddChild(Widget child, bool immedUpdate=true)
GetParent
proto native Widget GetParent()
Get parent of the Effect.
Definition: effect.c:405
Timer
Definition: dayzplayerimplement.c:62
ECE_LOCAL
const int ECE_LOCAL
Definition: centraleconomy.c:24
GetParticleParm
proto void GetParticleParm(notnull IEntity ent, int emitor, EmitorParam parameter, out void value)
Math
Definition: enmath.c:6
EntityEvent
EntityEvent
Entity events for event-mask, or throwing event from code.
Definition: enentity.c:44
Vector
proto native vector Vector(float x, float y, float z)
Vector constructor from components.