Dayz Explorer 1.28.160049
Loading...
Searching...
No Matches
fireworkslauncher.c
Go to the documentation of this file.
2{
3 void ExplosionLight()
4 {
5 SetVisibleDuringDaylight(true);
6 SetRadiusTo(60);
7 SetBrightnessTo(0.05);
8 SetFlareVisible(false);
9 SetAmbientColor(1.0, 1.0, 1.0);
10 SetDiffuseColor(1.0, 1.0, 1.0);
11 SetLifetime(2.1);
12 //SetDisableShadowsWithinRadius(-1);
13 SetFadeOutTime(1);
14 m_FadeInTime = 0.25;
15 SetFlickerSpeed(7);
16 //SetFlickerAmplitude(0.5);
17 SetFlickerAmplitudeMax(3);
18 SetFlickerAmplitudeMin(0);
19 SetCastShadow( false );
20 }
21}
22//-----------------------------------------------------------------------------------------------
23class FireworksLauncherClientEventBase
24{
25 void OnFired();
26}
27//-----------------------------------------------------------------------------------------------
28class FireworksLauncherClientEvent : FireworksLauncherClientEventBase
29{
30 protected ref Timer m_Timer = new Timer();
32 protected int m_Index;
38 protected vector m_ShotDir;
41 protected string m_Color;
44 #ifdef DEVELOPER
45 Shape m_ShotTrajectory;
46 #endif
47
48
49 // -----------------------------
50 // ------- Tweaking Start-------
51 // -----------------------------
52
53 protected int GetSoundDelay()
54 {
55 return 0;
56 }
57
58 protected int GetLightDelay()
59 {
60 return 0;
61 }
62
63 protected float GetExplosionDistance()
64 {
65 return Math.RandomFloatInclusive(35,40);
66 }
67
68 protected float GetShotDispersionAngle()
69 {
70 return Math.RandomFloatInclusive(-25,25);//this is rotated 360 degrees around the UP vector too
71 }
72
73 protected string GetExplosionSoundSet()
74 {
75 return "FireworksLauncher_Explosion_SoundSet";
76 }
77
78 protected float GetExplosionDelay()
79 {
80 return Math.RandomFloatInclusive(1.5,1.75);
81 }
82
83 // -----------------------------
84 // ------- Tweaking End --------
85 // -----------------------------
86
87
89 {
90 m_Item = item;
91 m_Index = index;
92
93 int colorSequenceLastIndex = m_Item.GetColorSequence().Length() - 1;
94 int coloreSequenceIndex = m_Index - 1;//shot index(m_Index) starts at 1
95
96 if (colorSequenceLastIndex >= coloreSequenceIndex)
97 {
98 m_Color = m_Item.GetColorSequence().Get(coloreSequenceIndex);
99 }
100 else
101 {
102 Debug.LogError("Failed to obtain color from color sequence");
103 m_Color = "B";
104 }
105 }
106
116
117 override protected void OnFired()
118 {
119 m_Timer.Run(GetExplosionDelay(), this, "OnExplode", null);
120 m_Item.PlaySoundSet( m_FireSound, "FireworksLauncher_Shot_SoundSet", 0, 0 );
121 m_ParticleShot = ParticleManager.GetInstance().PlayInWorld(ParticleList.FIREWORKS_SHOT, GetShotPos());
122 m_ParticleShot.SetYawPitchRoll(Vector(Math.RandomFloatInclusive(0,360),GetShotDispersionAngle(),0));
123
124 m_ParticleAfterBurnEnd = ParticleManager.GetInstance().PlayInWorld(ParticleList.FIREWORKS_AFTERBURN_END, GetShotPos());
126 m_ParticleAfterBurnEnd.SetOwner(this);
127 m_ShotDir = m_ParticleShot.GetDirectionUp();
128
129 #ifdef DEVELOPER
130 vector pts[2];
131 pts[0] = GetShotPos();
133 //m_ShotTrajectory = Shape.CreateLines(COLOR_RED, ShapeFlags.TRANSP|ShapeFlags.NOOUTLINE|ShapeFlags.NOZBUFFER, pts, 2);
134 #endif
135 }
136
137 protected vector GetShotPos()
138 {
139 vector memPos;
140 string memName = "Shot_" + m_Index;
141
142 if (m_Item.MemoryPointExists(memName))
143 {
144 memPos = m_Item.GetMemoryPointPos(memName);
145 memPos = m_Item.ModelToWorld(memPos);
146 }
147 else
148 {
149 memPos = m_Item.GetPosition();//fallback to item's location
150 Debug.LogError("Missing shot memory point on Fireworks");
151 }
152 return memPos;
153 }
154
159
161 {
162 if (!m_ExplosionPos)
163 {
165 }
166 return m_ExplosionPos;
167 }
168
170 {
171 return 4;
172 }
173
174
175 protected void OnExplode()
176 {
177 #ifdef DEVELOPER
178 if (m_ShotTrajectory)
179 {
180 m_ShotTrajectory.Destroy();
181 m_ShotTrajectory = null;
182 }
183 #endif
185
186 GetGame().GetCallQueue( CALL_CATEGORY_SYSTEM ).CallLater( PlayExplosionSound, GetSoundDelay(), false);
187 GetGame().GetCallQueue( CALL_CATEGORY_SYSTEM ).CallLater( SpawnLight, GetLightDelay(), false);
189
191
192 }
193
195 {
197 {
200 }
201 }
202
203 protected void SpawnSecondaryExplosion()
204 {
205 FireworksLauncherClientEventSecondary evnt = new FireworksLauncherClientEventSecondary(m_Item,m_Index);
206 evnt.Init(GetExplosionPosition());
207 evnt.OnExplode();
208 m_Events.Insert(evnt);
210 }
211
213 {
214 return Math.RandomIntInclusive(100,250);
215 }
216
218 {
219 switch (m_Color)
220 {
221 case "R":
222 return ParticleList.FIREWORKS_EXPLOSION_RED;
223 case "G":
224 return ParticleList.FIREWORKS_EXPLOSION_GREEN;
225 case "B":
226 return ParticleList.FIREWORKS_EXPLOSION_BLUE;
227 case "Y":
228 return ParticleList.FIREWORKS_EXPLOSION_YELLOW;
229 case "P":
230 return ParticleList.FIREWORKS_EXPLOSION_PINK;
231 default:
232 ErrorEx("Incorrect explosion particle color in the sequence");
233 }
234 return ParticleList.FIREWORKS_EXPLOSION_RED;
235 }
236
237 protected void SetupLight(PointLightBase light)
238 {
239 switch (m_Color)
240 {
241 case "R":
242 light.SetDiffuseColor(255,51,51);
243 light.SetAmbientColor(255,51,51);
244
245 break;
246 case "G":
247 light.SetDiffuseColor(0,255,128);
248 light.SetAmbientColor(0,255,128);
249 break;
250 case "B":
251 light.SetDiffuseColor(51,153,255);
252 light.SetAmbientColor(51,153,255);
253 break;
254 case "Y":
255 light.SetDiffuseColor(255,255,51);
256 light.SetAmbientColor(255,255,51);
257 break;
258 case "P":
259 light.SetDiffuseColor(255,102,255);
260 light.SetAmbientColor(255,102,255);
261 break;
262 default:
263 ErrorEx("Incorrect explosion particle color in the sequence");
264 }
265 }
266
272
273 protected void PlayExplosionSound()
274 {
275 if (m_FireSound)
276 {
278 }
279 m_Item.PlaySoundSet( m_ExplosionSound, GetExplosionSoundSet(), 0, 0 );
280 }
281}
282//------------------------------------------------------------------------------------
283
284class FireworksLauncherClientEventSecondary : FireworksLauncherClientEvent
285{
286 protected vector m_ShotPos;
287
288 override protected vector GetExplosionPosition()
289 {
290 return GetShotPos() + m_ShotDir * GetExplosionDistance();
291 }
292
293 void Init(vector pos)
294 {
295 m_ShotPos = pos;
296 m_ShotDir[0] = Math.RandomFloatInclusive(-1,1);
297 m_ShotDir[1] = Math.RandomFloatInclusive(-1,1);
298 m_ShotDir[2] = Math.RandomFloatInclusive(-1,1);
299 m_ShotDir.Normalize();
300 }
301 override protected vector GetShotPos()
302 {
303 return m_ShotPos;
304 }
305
306 override protected float GetExplosionDistance()
307 {
308 return Math.RandomFloatInclusive(10,15);
309 }
310
311 override void OnExplode()
312 {
313 GetGame().GetCallQueue( CALL_CATEGORY_SYSTEM ).CallLater( PlayExplosionSound, GetSoundDelay(), false);
314 GetGame().GetCallQueue( CALL_CATEGORY_SYSTEM ).CallLater( SpawnLight, GetLightDelay(), false);
316 }
317}
318
319class FireworksLauncher: FireworksBase
320{
321 int m_Index;//counts the shots
322 int m_IndexPrev;//counts the shots
323 int m_ColorSequenceIndex;
324 ref Timer m_TimerFuse;
326 EffectSound m_FuseSoundStart;
327 EffectSound m_FuseSound;
328 ParticleSource m_ParticleFuse;
329 ParticleSource m_ParticleAfterBurnEnd;
330 ref array<string> m_ColorSequence;
331
332 void FireworksLauncher()
333 {
334 m_ColorSequence = new array<string>();
336 RegisterNetSyncVariableInt("m_State", 0, EnumTools.GetLastEnumValue(EFireworksState));
337 RegisterNetSyncVariableInt("m_Index", 0, GetMaxShots());
338 RegisterNetSyncVariableInt("m_RandomSeed", 0, 1023);
339 int lastIndex = m_ColorSequence.Count() - 1;
340 RegisterNetSyncVariableInt("m_ColorSequenceIndex", 0, lastIndex);
341 m_RandomSeed = Math.RandomInt(0,1023);
342 m_ColorSequenceIndex = Math.RandomIntInclusive(0, lastIndex);
343 }
344
345 void ~FireworksLauncher()
346 {
347 SEffectManager.DestroyEffect(m_FuseSound);
348 SEffectManager.DestroyEffect(m_FuseSoundStart);
349 }
350
351 override bool IsDeployable()
352 {
353 return true;
354 }
355
357 override float GetDeployTime()
358 {
359 return 2;
360 }
361
362 protected void SetupColorSequences()
363 {
364 m_ColorSequence.Insert("RGBYPBRGBRGBYPBRGBRGBYPBRGBPBRGBRGBY");
365 m_ColorSequence.Insert("PGPYPBYPYPBYYPBRPYPBYYPBRGBPBRGRGBRB");
366 m_ColorSequence.Insert("YPBRPYPBYYPBRGBPBRGRGBRBGRPBRGBRYPBY");
367 m_ColorSequence.Insert("YRBGPRYPGRYBGRGRGBRBBYPYPBYRYPGRYGRP");
368 m_ColorSequence.Insert("BGRYPYRPBYYPYRBGPRYPGBYPBRGBPBRGBRGB");
369 m_ColorSequence.Insert("RYGRPBRGBYPBRRPBRGBBRBBYPYPRGBRGBRPY");
370 m_ColorSequence.Insert("GBRGBYRGBYPBRRPBRBYRYPGPYPRGBRGBRPYG");
371 m_ColorSequence.Insert("RYPBYYPBRGBYPBRGBRBGBPBRGRGBRBGRYPYR");
372 m_ColorSequence.Insert("PBRGBYPBRGBRBGBPBRGRGBRBGRYPYRRYPBYY");
373 m_ColorSequence.Insert("RGRGBRBBYPYPBYRYPGRYGRPYRBGPRYPGRYBG");
374 m_ColorSequence.Insert("RBYRYPGPYPRGBRGBRPYGGBRGBYRGBYPBRRPB");
375 m_ColorSequence.Insert("PRGBRGBRPYGGBRRBYRYPGPYGBYRGBYPBRRPB");
376 }
377
379 {
380 if (m_ColorSequence.IsValidIndex(m_ColorSequenceIndex))
381 {
382 return m_ColorSequence.Get(m_ColorSequenceIndex);
383 }
384 else
385 {
386 ErrorEx("Failed to obtain color sequence");
387 return "RYPBYYPBRGBYPBRGBRBGBPBRGRGBRBGRYPYR";
388 }
389 }
390
391
392 override protected void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
393 {
394 super.OnPlacementComplete(player, position, orientation);
395 if (GetGame().IsServer())
396 {
397 if (GetState() == EFireworksState.DEFAULT)
398 {
400 }
401 }
402 }
403
404 override protected float GetMaxAllowedWetness()
405 {
406 return GameConstants.STATE_WET;
407 }
408
409
410 override protected float GetEventDelay()
411 {
412 return Math.RandomFloatInclusive(3,3.35);
413 }
414
415 protected string GetFuseSoundSet()
416 {
417 return "FireworksLauncher_Ignition_Loop_SoundSet";
418 }
419
420 protected int GetMaxShots()
421 {
422 return 16;
423 }
424
425 protected float GetFuseDelay()
426 {
427 return 3;
428 }
429
430 protected string GetAmmoType()
431 {
432 return "Fireworks_Ammo";
433 }
434
435 protected int GetDamageType()
436 {
437 return DamageType.EXPLOSION;
438 }
439
440
441 override protected void OnStateChangedServer(EFireworksState currentState)
442 {
443 switch (currentState)
444 {
445 case EFireworksState.PLACED:
446 break
447 case EFireworksState.IGNITED:
449 break
450 case EFireworksState.FIRING:
451 HideSelection("cover");
453 break
454 case EFireworksState.FINISHED:
455 HideSelection("cover");//when loading from storage
456 break
457 default: {};
458 }
459 }
460
461 override protected void OnStateChangedClient(EFireworksState currentState)
462 {
463 switch (currentState)
464 {
465 case EFireworksState.IGNITED:
467 break
468 case EFireworksState.PLACED:
469 break
470 case EFireworksState.FIRING:
472 break
473 default: {};
474 }
475 }
476
478 override void OnIgnitedThis( EntityAI fire_source)
479 {
480 super.OnIgnitedThis(fire_source);
481 if (m_Events)
482 {
483 m_Events.Clear();
484 }
485 m_Index = 0;
486
487 if (m_TimerEvent)
488 {
489 m_TimerEvent.Stop();
490 }
491 }
492
493 override protected bool CanPutInCargo( EntityAI parent )
494 {
495 return (GetState() == EFireworksState.DEFAULT) || (GetState() == EFireworksState.PLACED) || (GetState() == EFireworksState.FINISHED);
496 }
497
498 override protected bool CanPutIntoHands( EntityAI parent )
499 {
500 return (GetState() == EFireworksState.DEFAULT) || (GetState() == EFireworksState.PLACED) || (GetState() == EFireworksState.FINISHED);
501 }
502
503 protected void OnFuseIgnitedServer()
504 {
505 int state = EFireworksState.FIRING;
506 GetGame().GetCallQueue( CALL_CATEGORY_SYSTEM ).CallLater( SetState, GetFuseDelay()*1000, false, state);
507 }
508
509 protected void OnFuseIgnitedClient()
510 {
511 m_ParticleFuse = ParticleManager.GetInstance().PlayInWorld(ParticleList.FIREWORKS_FUSE, GetPosition() + "0 0.15 0");
512 if (m_ParticleFuse)
513 m_ParticleFuse.SetOwner(this);
514 PlaySoundSet( m_FuseSoundStart, "FireworksLauncher_Ignition_Start_SoundSet", 0, 0 );
515 vector fuseStart;
516 vector fuseEnd;
517
518 if (MemoryPointExists("Fuse_Start"))
519 {
520 fuseStart = GetMemoryPointPos("Fuse_Start");
521 fuseStart = ModelToWorld(fuseStart);
522 }
523 if (MemoryPointExists("Fuse_End"))
524 {
525 fuseEnd = GetMemoryPointPos("Fuse_End");
526 fuseEnd = ModelToWorld(fuseEnd);
527 }
528
529 vector fuseDir = fuseEnd - fuseStart;
530 vector fuseOrientation[4];
531 vector ori = fuseDir.VectorToAngles();
532 m_ParticleFuse.SetOrientation(ori);
533 m_ParticleFuse.SetPosition(fuseStart);
534
535 PlaySoundSetLoop( m_FuseSound, GetFuseSoundSet(), 0, 0 );
536 }
537
538 protected void OnFiringStartServer()
539 {
540 OnEventServer(0);
541 }
542
543 protected void OnFiringStartClient()
544 {
545 if (m_ParticleFuse)
546 {
547 m_ParticleFuse.StopParticle(StopParticleFlags.IMMEDIATE);
548 }
549 if (m_FuseSound)
550 {
551 m_FuseSound.Stop();
552 }
553 }
554
555 protected void OnFiringStop()
556 {
557 SetHealth01("","",0);
558 }
559
561 protected void RestartEventTimer()
562 {
563 if (!m_TimerEvent)
564 {
565 m_TimerEvent = new Timer();
566 }
567 m_TimerEvent.Run(GetEventDelay(), this, "OnEventServer", new Param1<int>(0));
568 }
569
570
571 override protected bool IsIgnited()
572 {
573 return GetState()==EFireworksState.IGNITED;
574 }
575
576 override protected bool CanIgniteItem(EntityAI ignite_target = NULL)
577 {
578 return false;
579 }
580
581
582
584 override protected void OnEventServer(int type)
585 {
586 m_Index++;
587 DamageSystem.ExplosionDamage(this, NULL, GetAmmoType(), GetPosition(), GetDamageType());
588
589 SetSynchDirty();
590 if (m_Index > GetMaxShots())
591 {
592 m_Index = GetMaxShots();
593 m_TimerEvent = null;
594 SetState(EFireworksState.FINISHED);
595 }
596 else
597 {
599 }
600 }
601
602 protected void OnIndexChangedClient()
603 {
604 if (!m_Events)
605 {
607 }
608 if (m_Index != 0 && m_State == EFireworksState.FIRING)//can only be true when restarting the device during debug calls
609 {
610 FireworksLauncherClientEventBase fireEvent = SpawnEvent();
611 m_Events.Insert(fireEvent);
612 }
613 }
614
615 protected FireworksLauncherClientEventBase SpawnEvent()
616 {
617 FireworksLauncherClientEventBase evnt = new FireworksLauncherClientEvent(this,m_Index);
618 evnt.OnFired();
619 return evnt;
620 }
621
622 override protected void OnVariablesSynchronized()
623 {
624 super.OnVariablesSynchronized();
625 //Print("index: " + m_Index);
626 if (m_Index != m_IndexPrev)
627 {
628 Math.Randomize(m_RandomSeed+m_Index);
630 m_IndexPrev = m_Index;
631 }
632 }
633
634 override protected void OnStoreSave(ParamsWriteContext ctx)
635 {
636 super.OnStoreSave(ctx);
637 ctx.Write(m_Index);
638 ctx.Write(m_State);
639 }
640
641
642 override protected bool OnStoreLoad( ParamsReadContext ctx, int version )
643 {
644 if (!super.OnStoreLoad(ctx, version))
645 {
646 return false;
647 }
648
649 if (version >= 130)
650 {
651 if (!ctx.Read(m_Index))
652 {
653 return false;
654 }
655
656 if (!ctx.Read(m_State))
657 {
658 return false;
659 }
660
662 }
663 return true;
664 }
665
666 override string GetDeploySoundset()
667 {
668 return "placeFireworks_SoundSet";
669 }
670
671 override string GetLoopDeploySoundset()
672 {
673 return "fireworks_deploy_SoundSet";
674 }
675
676 #ifdef DEVELOPER
677 override protected string GetDebugText()
678 {
679 string debug_output;
680
681 if( GetGame().IsDedicatedServer())
682 {
683 debug_output+= EnumTools.EnumToString(EFireworksState, m_State) +"\n";
684 debug_output+= "m_Index:" + m_Index +"\n";
685 }
686 else
687 {
688
689 }
690 return debug_output;
691 }
692
693 #endif
694}
Definition debug.c:2
Wrapper class for managing sound through SEffectManager.
Definition effectsound.c:5
override void Stop()
Stops sound.
void FireworksLauncherClientEvent(FireworksLauncher item, int index)
ref array< ref FireworksLauncherClientEventBase > m_Events
void SetupLight(PointLightBase light)
void RestartEventTimer()
Starts event timer.
void OnStateChangedServer(EFireworksState currentState)
override string GetLoopDeploySoundset()
override string GetDeploySoundset()
void OnEventServer(int type)
Called periodically but only after the entity gets ignited.
FireworksLauncherClientEventBase SpawnEvent()
bool CanIgniteItem(EntityAI ignite_target=NULL)
void OnPlacementComplete(Man player, vector position="0 0 0", vector orientation="0 0 0")
void OnStoreSave(ParamsWriteContext ctx)
bool OnStoreLoad(ParamsReadContext ctx, int version)
bool CanPutInCargo(EntityAI parent)
bool CanPutIntoHands(EntityAI parent)
override void OnIgnitedThis(EntityAI fire_source)
Executed on Server when some item ignited this one.
void OnStateChangedClient(EFireworksState currentState)
Definition enmath.c:7
static Particle PlayInWorld(int particle_id, vector global_pos)
Creates a particle emitter on the given position and activates it.
Definition particle.c:174
Entity which has the particle instance as an ObjectComponent.
static override Particle PlayInWorld(int particle_id, vector global_pos)
Creates a particle emitter on the given position and activates it.
Manager class for managing Effect (EffectParticle, EffectSound)
static void DestroyEffect(Effect effect)
Unregisters, stops and frees the Effect.
Serialization general interface. Serializer API works with:
Definition serializer.c:56
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
DamageType
exposed from C++ (do not change)
override Widget Init()
Definition dayzgame.c:127
Particle m_ParticleExplosion
particle
ref Timer m_TimerEvent
EFireworksState
int m_RandomSeed
ExplosionLight PointLightBase OnFired()
FireworksLauncherClientEvent m_ShotPos
proto native CGame GetGame()
enum ShapeType ErrorEx
class DiagMenu Shape
don't call destructor directly. Use Destroy() instead
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
class JsonUndergroundAreaTriggerData GetPosition
const int CALL_CATEGORY_SYSTEM
Definition tools.c:8
string GetDebugText()
enum EObjectTemperatureState m_State
void ParticleManager(ParticleManagerSettings settings)
Constructor (ctor)
void SetState(bool state)