Dayz Explorer 1.28.160049
Loading...
Searching...
No Matches
particle.c
Go to the documentation of this file.
1
6class Particle : ParticleBase
7{
13 protected int m_ParticleID;
15 protected float m_Lifetime;
17 protected bool m_IsRepeat;
19 private bool m_MarkedForDeletion;
21
27 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
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 {
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) );
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 {
206 }
207
215 override bool PlayParticleEx(int particle_id = -1, int flags = 0)
216 {
217 if ( particle_id > -1 )
218 {
220 }
221
223
224 UpdateState();
225
226 return true;
227 }
228
233 void Play(int particle_id = -1)
234 {
236 }
237
245 override bool StopParticle(int flags = 0)
246 {
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
286 {
288 }
289
298 {
299 return m_ParticleID;
300 }
301
311
317 {
318 return m_ParentObject;
319 }
320
326 {
328 {
330 }
331
332 return false;
333 }
334
341 {
343 {
345 }
346
347 return 0;
348 }
349
354 bool IsRepeat()
355 {
357 {
358 bool repeat = false;
359
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
381 {
382 float lifetime_return = 0;
383
385 {
386 float lifetime_min = 0;
387 float lifetime_random = 0;
388 float effect_time = 0;
389
390 float lifetime_sum = 0;
391
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
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 {
509 }
510 else
511 {
513
514 if ( GetParticleCount() == 0 )
515 {
516 m_MarkedForDeletion = true;
517 OnToDelete();
519 }
520 }
521 }
522 else
523 {
524 if ( m_MarkedForDeletion )
525 {
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
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
663 float GetParameterOriginal(int emitter, int parameter)
664 {
665 if (!m_ParticleEffect)
666 return 0;
667
668 float value;
669 GetParticleParmOriginal(m_ParticleEffect, emitter, parameter, value);
670 return value;
671 }
672
678 void ScaleParticleParamFromOriginal(int parameter_id, float coef )
679 {
680 if (!m_ParticleEffect)
681 return;
682
684 for (int i = 0; i < emitors; ++i)
685 {
686 float value;
687 GetParticleParmOriginal(m_ParticleEffect, i, parameter_id, value);
688 SetParticleParm(m_ParticleEffect, i, parameter_id, value * coef);
689 }
690 }
691
697 void ScaleParticleParam(int parameter_id, float coef )
698 {
699 if (!m_ParticleEffect)
700 return;
701
703 for (int i = 0; i < emitors; ++i)
704 {
705 float value;
706 GetParticleParm(m_ParticleEffect, i, parameter_id, value);
707 SetParticleParm(m_ParticleEffect, i, parameter_id, value * coef);
708 }
709 }
710
717 void IncrementParticleParamFromOriginal(int parameter_id, float value )
718 {
719 if (!m_ParticleEffect)
720 return;
721
723 for (int i = 0; i < emitors; ++i)
724 {
725 float param;
726 GetParticleParmOriginal(m_ParticleEffect, i, parameter_id, param);
727 SetParticleParm(m_ParticleEffect, i, parameter_id, param + value);
728 }
729 }
730
737 void IncrementParticleParam(int parameter_id, float value )
738 {
739 if (!m_ParticleEffect)
740 return;
741
743 for (int i = 0; i < emitors; ++i)
744 {
745 float param;
746 GetParticleParm(m_ParticleEffect, i, parameter_id, param);
747 SetParticleParm(m_ParticleEffect, i, parameter_id, param + value);
748 }
749 }
750
752
753
754
759
763 bool IsWiggling()
764 {
765 return m_RandomizeOri && m_RandomizeOri.IsRunning();
766 }
767
775 void SetWiggle(float random_angle, float random_interval)
776 {
777 if ( random_angle != 0 || random_interval != 0 )
778 {
779 m_MaxOriWiggle = random_angle;
780 m_MaxOriInterval = random_interval;
781
782 if ( !m_RandomizeOri )
783 m_RandomizeOri = new Timer( CALL_CATEGORY_GAMEPLAY );
784
785 if ( !m_RandomizeOri.IsRunning() ) // Makes sure the timer is NOT running already
786 m_RandomizeOri.Run( Math.RandomFloat(0, m_MaxOriInterval) , this, "RandomizeOrientation", null, false);
787 }
788 else
789 {
790 StopWiggle();
791 }
792 }
793
797 void StopWiggle()
798 {
799 if ( m_RandomizeOri )
800 {
801 m_RandomizeOri.Stop();
802 }
803
804 m_MaxOriWiggle = 0;
805 m_MaxOriInterval = 0;
806 }
807
811 void RandomizeOrientation()
812 {
813 m_WiggleProcessing = true;
814
815 if (m_ParentObject)
816 {
817 if ( !m_RandomizeOri.IsRunning() )
818 {
819 m_RandomizeOri.Run( Math.RandomFloat(0, m_MaxOriInterval) , this, "RandomizeOrientation", NULL, false);
820 }
821
822 Object old_parent = m_ParentObject;
823 AddAsChild( null );
824 AddAsChild( old_parent, m_DefaultPos, m_DefaultOri + RandWiggleVector() );
825 }
826
827 m_WiggleProcessing = false;
828 }
829
834 {
836 }
837
841 protected float RandWiggleFloat()
842 {
843 return Math.RandomFloatInclusive(-m_MaxOriWiggle, m_MaxOriWiggle);
844 }
845
847}
const int ECE_LOCAL
Definition enmath.c:7
Legacy way of using particles in the game.
Definition particle.c:7
bool m_IsRepeat
Whether this particle repeats.
Definition particle.c:17
static Particle Create(int particle_id, Object parent_obj, vector local_pos="0 0 0", vector local_ori="0 0 0")
Legacy function for backwards compatibility.
Definition particle.c:104
float GetMaxLifetime()
Returns the approx. max lifetime.
Definition particle.c:380
void ParticleInit()
Purely here so that it can be emptied in ParticleSource.
Definition particle.c:67
override bool StopParticle(int flags=0)
Method to tell the particle to stop playing.
Definition particle.c:245
void Play(int particle_id=-1)
Legacy function for backwards compatibility with 1.01 and below.
Definition particle.c:233
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)
Creates a particle emitter, attaches it on the given object and activates it.
Definition particle.c:152
Object m_ParticleEffect
The child object which contains the actual particle.
Definition particle.c:50
bool HasActiveParticle()
Returns if there is any particle active.
Definition particle.c:325
static Particle CreateInWorld(int particle_id, vector global_pos, vector global_ori="0 0 0", bool force_world_rotation=false)
Creates a particle emitter on the given position.
Definition particle.c:117
Object GetParticleParent()
Returns the parent of this Particle if there is one.
Definition particle.c:316
int GetParticleCount()
Returns the total count of active particles in all emitors.
Definition particle.c:340
static Particle PlayInWorld(int particle_id, vector global_pos)
Creates a particle emitter on the given position and activates it.
Definition particle.c:174
void SetSource(int particle_id)
Sets particle id.
Definition particle.c:285
override void PlayParticle(int particle_id=-1)
Method to tell the particle to start playing.
Definition particle.c:203
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)
Creates a particle emitter and attaches it on the given object.
Definition particle.c:88
override bool PlayParticleEx(int particle_id=-1, int flags=0)
Method to tell the particle to start playing.
Definition particle.c:215
static Particle Play(int particle_id, vector global_pos)
Legacy function for backwards compatibility with 1.01 and below.
Definition particle.c:185
int GetParticleID()
Gets particle id.
Definition particle.c:297
int m_PreviousFrame
DEPRECATED.
Definition particle.c:53
float m_Lifetime
Approx. remaining lifetime of particle.
Definition particle.c:15
vector RandWiggleVector()
Helper to get a randomized wiggle vector.
Definition particle.c:833
Object m_ParentObject
Parent Object the Particle is child of.
Definition particle.c:48
int m_ParticleID
ID from ParticleList if assigned.
Definition particle.c:13
bool IsRepeat()
Returns whether there is a repeating particle.
Definition particle.c:354
void UpdateState()
Creates/Destroys ParticleEffect child according to current state.
Definition particle.c:425
static Particle Play(int particle_id, Object parent_obj, vector local_pos="0 0 0", vector local_ori="0 0 0")
Legacy function for backwards compatibility with 1.01 and below.
Definition particle.c:163
float RandWiggleFloat()
Helper to get a randomized wiggle float value.
Definition particle.c:841
static Particle Create(int particle_id, vector global_pos, vector global_ori="0 0 0")
Legacy function for backwards compatibility with 1.01 and below.
Definition particle.c:129
void Stop()
Legacy function for backwards compatibility with 1.14 and below.
Definition particle.c:266
Object GetDirectParticleEffect()
Returns direct particle effect entity which is usually handled by this class 'Particle' if there is o...
Definition particle.c:307
bool m_IsPlaying
Whether the Effect is currently playing.
Definition effect.c:37
proto native CGame GetGame()
void Error(string err)
Messagebox with error message.
Definition endebug.c:90
enum ShapeType ErrorEx
proto native void SetPosition(vector position)
Set the world position of the Effect.
Definition effect.c:463
proto native void SetFlags(ShapeFlags flags)
EntityEvent
Entity events for event-mask, or throwing event from code.
Definition enentity.c:45
EntityFlags
Entity flags.
Definition enentity.c:115
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
proto void SetParticleParm(notnull IEntity ent, int emitor, EmitorParam parameter, void value)
bool ParticleHasActive(IEntity ent)
Definition envisual.c:210
proto void GetParticleParmOriginal(notnull IEntity ent, int emitor, EmitorParam parameter, out void value)
int ParticleGetCount(IEntity ent)
Definition envisual.c:205
proto int GetParticleEmitorCount(notnull IEntity ent)
EmitorParam
Definition envisual.c:114
proto void GetParticleParm(notnull IEntity ent, int emitor, EmitorParam parameter, out void value)
class JsonUndergroundAreaTriggerData GetPosition
const int CALL_CATEGORY_GAMEPLAY
Definition tools.c:10
proto native vobject GetObject(string name)
Loads object from data, or gets it from cache. Object must be released when not used.
proto native void ReleaseObject(vobject object, int flag=0)
void OnParticleStart()
Event when the particle starts.
void OnParticleEnd()
Event when the particle ends.
void OnParticleStop()
Event when the particle stops.
int particle_id