Dayz Explorer 1.29.162510
Loading...
Searching...
No Matches
land_underground_waterreservoir.c
Go to the documentation of this file.
1class WaterLevelSettings
2{
3 int WaterLevel;
4 float Duration;
5
6 void WaterLevelSettings(int pWaterLevel, float pDuration)
7 {
8 WaterLevel = pWaterLevel;
9 Duration = pDuration;
10 }
11}
12
14{
16 float Duration;
17
18 void PressureLevelSettings(int pPressureLevel, float pDuration)
19 {
20 PressureLevel = pPressureLevel;
21 Duration = pDuration;
22 }
23}
24
26{
27 float WaterHeight;
28 float RemainingDuration;
29}
30
31class Land_Underground_WaterReservoir : BuildingBase
32{
33 protected const string OBJECT_NAME_WATER_PLANE = "Land_Underground_WaterReservoir_Water";
34
35 protected const int WL_MIN = 0;
36 protected const int WL_ABOVE_PIPES = 1;
37 protected const int WL_AVERAGE = 2;
38 protected const int WL_MAX = 3;
39
40 protected const int PL_MIN = 0;
41 protected const int PL_AVERAGE = 1;
42 protected const int PL_MAX = 2;
43
44 protected const int VALVES_COUNT = 2;
45 protected const int VALVE_INDEX_DRAIN = 0;
46 protected const int VALVE_INDEX_FILL = 1;
47
48 protected const int PIPES_BROKEN_COUNT = 2;
49 protected const int PIPE_INDEX_BROKEN1 = 0;
50 protected const int PIPE_INDEX_BROKEN2 = 1;
51
52 protected const string ANIM_PHASE_VALVE_GAUGE_DRAIN = "ValveGauge1";
53 protected const string ANIM_PHASE_VALVE_GAUGE_FILL = "ValveGauge2";
54 protected const string ANIM_PHASE_VALVE_DRAIN = "Valve1";
55 protected const string ANIM_PHASE_VALVE_FILL = "Valve2";
56 protected const string VALVE_NAME_DRAIN = "valve1";
57 protected const string VALVE_NAME_FILL = "valve2";
58 protected const string PIPE_NAME_BROKEN1 = "pipe_broken_1";
59 protected const string PIPE_NAME_BROKEN2 = "pipe_broken_2";
60 protected const string PIPE_NAME_LEAKING_DRAIN = "pipe_leaking_1";
61 protected const string PIPE_NAME_LEAKING_FILL = "pipe_leaking_2";
62
63 protected const string SOUND_NAME_PIPE_CREAKING = "WaterObjectUndergroundPipeCreaking_SoundSet";
64 protected const string SOUND_NAME_VALVE_MANIPULATION = "WaterObjectUndergroundValve_SoundSet";
65 protected const string SOUND_NAME_PIPE_SPRINKLING_START = "WaterObjectUndergroundPipeSprinkling_Start_SoundSet";
66 protected const string SOUND_NAME_PIPE_SPRINKLING_END = "WaterObjectUndergroundPipeSprinkling_End_SoundSet";
67 protected const string SOUND_NAME_PIPE_SPRINKLING_LOOP1 = "WaterObjectUndergroundPipeSprinkling_Loop1_SoundSet";
68 protected const string SOUND_NAME_PIPE_SPRINKLING_LOOP2 = "WaterObjectUndergroundPipeSprinkling_Loop2_SoundSet";
69 protected const string SOUND_NAME_UPIPE_SPRINKLING_START = "WaterObjectUndergroundUnderwaterPipe_Start_SoundSet";
70 protected const string SOUND_NAME_UPIPE_SPRINKLING_END = "WaterObjectUndergroundUnderwaterPipe_End_SoundSet";
71 protected const string SOUND_NAME_UPIPE_SPRINKLING_LOOP = "WaterObjectUndergroundUnderwaterPipe_Loop_SoundSet";
72 protected const string SOUND_NAME_WATER_FILL_LOOP = "WaterObjectUndergroundUnderwaterFill_Loop_SoundSet";
73 protected const string SOUND_NAME_WATER_DRAIN_LOOP = "WaterObjectUndergroundUnderwaterEmpty_Loop_SoundSet";
74
75 protected const int PARTICLE_DRAIN_PIPE_MAX_PRESSURE = ParticleList.WATER_SPILLING;
76 protected const int PARTICLE_FILL_PIPE_MAX_PRESSURE = ParticleList.WATER_SPILLING;
77 protected const int PARTICLE_FILL_PIPE_JET = ParticleList.WATER_JET;
78 protected const int PARTICLE_FILL_PIPE_JET_WEAK = ParticleList.WATER_JET_WEAK;
79
88
94
95 protected static const string WATER_LEVEL_MAX = "water_level_max";
96 protected static const string WATER_LEVEL_AVERAGE = "water_level_average";
97 protected static const string WATER_LEVEL_ABOVE_PIPES = "water_level_above_pipes";
98 protected static const string WATER_LEVEL_MIN = "water_level_min";
99
100 protected const int WATER_LEVELS_COUNT = 4;
101 protected const string WATER_LEVELS[WATER_LEVELS_COUNT] = {
102 WATER_LEVEL_MAX,
103 WATER_LEVEL_AVERAGE,
104 WATER_LEVEL_ABOVE_PIPES,
105 WATER_LEVEL_MIN
106 };
107
108 protected int m_ValveStatesPacked;
115 protected int m_WaterLevelActual;
116 protected int m_WaterLevelPrev;
121 protected int m_LastActiveValve;
122
126
131
134
135 protected bool m_PipeUnderwaterSoundRunning
137
139
140 protected const int PIPE_CREAKING_MIN_TIME_DELAY_MS = 10000;
141 protected const int PIPE_CREAKING_MAX_TIME_DELAY_MS = 15000;
142 protected const int PIPE_CREAKING_SOUND_LOCATIONS_COUNT = 4;
144 "pipe_creaking_sound_pos_1",
145 "pipe_creaking_sound_pos_2",
146 "pipe_creaking_sound_pos_3",
147 "pipe_creaking_sound_pos_4"
148 };
149
152
153
154 private ref Timer m_TempHotfixTimer;
155 private const float TEMP_HOTIX_TIMESLICE = 0.01;
156
157 void Land_Underground_WaterReservoir()
158 {
159 SetEventMask(EntityEvent.POSTSIMULATE);
160
161 Init();
162 }
163
164 void ~Land_Underground_WaterReservoir()
165 {
168
169 if (m_TempHotfixTimer)
170 {
171 m_TempHotfixTimer.Stop();
172 m_TempHotfixTimer = null;
173 }
174 }
175
176 override void EOnPostSimulate(IEntity other, float timeSlice)
177 {
178 #ifndef SERVER
181 #endif
182
183 if (!g_Game.IsServer())
184 {
185 return;
186 }
187
188 int valve;
189 float waterHeight, pressureLevel;
190 WaterLevelSettings wlStageSettings, wlStageSettingsPrev;
191 PressureLevelSettings plStageSettings, plStageSettingsPrev;
192
195 for (valve = 0; valve < VALVES_COUNT; ++valve)
196 {
197 if (m_LastActiveValve != INDEX_NOT_FOUND && m_LastActiveValve != valve && m_ValveStates[valve] == true)
198 {
199 wlStageSettings = ActualWaterLevelStageSettings(valve);
200 m_WaterLevelSnapshot = new WaterLevelSnapshot();
202 m_WaterLevelSnapshot.RemainingDuration = Math.Clamp(wlStageSettings.Duration - m_WaterLevelTimesAccumulated[valve], 0, wlStageSettings.Duration);
203 m_ValveStates[valve] = false;
204 m_PressureDeanimationRequests[valve] = true;
205 break;
206 }
207 }
208
210 for (valve = 0; valve < VALVES_COUNT; ++valve)
211 {
212 if (m_ValveStates[valve] == true)
213 {
214 wlStageSettingsPrev = PreviousWaterLevelStageSettings(valve);
215 wlStageSettings = ActualWaterLevelStageSettings(valve);
216
218 if (wlStageSettings.Duration == -1.0)
219 {
220 m_ValveStates[valve] = false;
224 return;
225 }
226
227 float adjustedWaterHeight = WaterLevelToHeight(wlStageSettingsPrev.WaterLevel);
228 float adjustedDuration = wlStageSettings.Duration;
230 {
231 adjustedWaterHeight = m_WaterLevelSnapshot.WaterHeight;
232 adjustedDuration = wlStageSettings.Duration + m_WaterLevelSnapshot.RemainingDuration;
233 }
234
235 if (m_WaterLevelTimesAccumulated[valve] <= adjustedDuration)
236 {
237 float start = adjustedWaterHeight;
238 float target = WaterLevelToHeight(wlStageSettings.WaterLevel);
239 waterHeight = Math.Lerp(start, target, Easing.EaseInOutSine(m_WaterLevelTimesAccumulated[valve] / adjustedDuration));
240 SetWaterLevelHeight(waterHeight);
241 }
242 else
243 {
247 SetSynchDirty();
248 }
249 m_WaterLevelTimesAccumulated[valve] = m_WaterLevelTimesAccumulated[valve] + AdjustTime(TEMP_HOTIX_TIMESLICE);
250 }
251 else
252 {
255 }
256 }
257
258 int allValvesStates = 0;
259
261 for (valve = 0; valve < VALVES_COUNT; ++valve)
262 {
263 if (m_PressureAnimationRequests[valve] == true)
264 {
265 bool hasToBeDeanimated = m_PressureAnimationRequests[valve] == m_PressureDeanimationRequests[valve];
266 plStageSettingsPrev = PreviousPressureLevelStageSettings(valve, hasToBeDeanimated);
267 plStageSettings = ActualPressureLevelStageSettings(valve, hasToBeDeanimated);
268
270 if (plStageSettings.Duration == -1.0)
271 {
273 m_PressureAnimationRequests[valve] = false;
275 return;
276 }
277
278 if (m_PressureTimesAccumulated[valve] <= plStageSettings.Duration)
279 {
280 float plStart = PressureLevelToValue(plStageSettingsPrev.PressureLevel);
281 float plTarget = PressureLevelToValue(plStageSettings.PressureLevel);
282 pressureLevel = Math.Lerp(plStart, plTarget, m_PressureTimesAccumulated[valve] / plStageSettings.Duration);
283 SetValvePressureLevelGauge(valve, pressureLevel);
284 }
285 else
286 {
289 if (hasToBeDeanimated && IsValvePressureLevelGaugeAtBase(valve))
290 {
291 m_PressureDeanimationRequests[valve] = false;
293 }
294 else
295 {
297 SetSynchDirty();
298 }
299 }
300
301 m_PressureTimesAccumulated[valve] = m_PressureTimesAccumulated[valve] + AdjustTime(TEMP_HOTIX_TIMESLICE);
302 }
303 else
304 {
306 }
307
308
309 allValvesStates += m_PressureAnimationRequests[valve];
310 if (allValvesStates == false)
311 {
313 }
314 }
315 }
316
317 override void OnVariablesSynchronized()
318 {
319 super.OnVariablesSynchronized();
320
322
325
326 if (m_ValveManipulatedIndex == -1)
328 }
329
330 override void SetActions()
331 {
332 super.SetActions();
333
335 }
336
337 override bool HasTurnableValveBehavior()
338 {
339 return true;
340 }
341
342 protected void Init()
343 {
358
361
365
369
371 int i = 0;
372 for (i = 0; i < VALVES_COUNT; ++i)
373 {
374 m_ValveNames.Insert("none");
375 m_ValveStates.Insert(false);
376 m_PressureAnimationRequests.Insert(false);
377 m_PressureDeanimationRequests.Insert(false);
380 m_PipeSounds.Insert(null);
381 m_ValveParticles.Insert(null);
382 }
383
384 for (i = 0; i < PIPES_BROKEN_COUNT; ++i)
385 {
386 m_PipeBrokenParticles.Insert(null);
387 }
388
389 RegisterNetSyncVariableInt("m_ValveStatesPacked", 0);
390 RegisterNetSyncVariableInt("m_ValveManipulatedIndex", -1, VALVES_COUNT - 1);
391 RegisterNetSyncVariableInt("m_WaterLevelActual", WL_MIN, WL_MAX);
392 RegisterNetSyncVariableInt("m_WaterLevelPrev", WL_MIN, WL_MAX);
393
394 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(LateInit, 250);
395
397 m_TempHotfixTimer = new Timer();
398 m_TempHotfixTimer.Run(TEMP_HOTIX_TIMESLICE, this, "EOnPostSimulate", null, true);
399 }
400
401 protected void LateInit()
402 {
405
407
409
410 m_WaterLevelDefault = m_WaterLevelsAvailable[WATER_LEVEL_AVERAGE];
411
412 if (g_Game.IsServer())
413 {
415 m_SpawnedWaterObject.SetOrientation(GetOrientation());
417 }
418
419 g_Game.RegisterNetworkStaticObject(this);
420 SetSynchDirty();
421 }
422
424 {
430
436
440
446
452
456 }
457
458 override bool IsValveTurnable(int pValveIndex)
459 {
460 return !IsValveActive(pValveIndex) && IsValvePressureLevelGaugeAtBase(pValveIndex);
461 }
462
463 protected bool IsAnyValveActive()
464 {
465 for (int i = 0; i < m_ValveStates.Count(); ++i)
466 {
467 if (m_ValveStates[i])
468 {
469 return true;
470 }
471 }
472
473 return false;
474 }
475
476 protected bool IsValveActive(int pValveIndex)
477 {
478 return pValveIndex >= 0 && pValveIndex <= VALVES_COUNT && m_ValveStates[pValveIndex];
479 }
480
481 override int GetTurnableValveIndex(int pComponentIndex)
482 {
483 string targetedValveName = GetActionComponentName(pComponentIndex);
484 for (int i = 0; i < m_ValveNames.Count(); ++i)
485 {
486 if (m_ValveNames[i] == targetedValveName)
487 {
488 return i;
489 }
490 }
491
492 return INDEX_NOT_FOUND;
493 }
494
495 void OnValveManipulationStart(int pValveIndex)
496 {
497 if (g_Game.IsServer())
498 {
499 AnimateValve(pValveIndex, 1);
500 m_ValveManipulatedIndex = pValveIndex;
501 SetSynchDirty();
502 }
503 }
504
505 void OnValveManipulationEnd(int pValveIndex)
506 {
507 if (g_Game.IsServer())
508 {
509 switch (pValveIndex)
510 {
512 m_ValveStates[pValveIndex] = true;
513 m_PressureAnimationRequests[pValveIndex] = true;
516 SetLastActiveValve(pValveIndex);
517 AnimateValve(pValveIndex, 0);
518 break;
519 case VALVE_INDEX_FILL:
520 m_ValveStates[pValveIndex] = true;
521 m_PressureAnimationRequests[pValveIndex] = true;
524 AnimateValve(pValveIndex, 0);
525 SetLastActiveValve(pValveIndex);
526 break;
527 }
528
530 }
531 }
532
533 void OnValveManipulationCanceled(int pValveIndex)
534 {
535 if (g_Game.IsServer())
536 {
537 AnimateValve(pValveIndex, 0);
539 SetSynchDirty();
540 }
541 }
542
546 {
547 vector posPoint, dirPoint = vector.Zero;
548
549 switch (pValveIndex)
550 {
552 posPoint = GetMemoryPointPosition(string.Format("%1_align_pos", VALVE_NAME_DRAIN));
553 dirPoint = GetMemoryPointPosition(string.Format("%1_align_dir", VALVE_NAME_DRAIN));
554 break;
555 case VALVE_INDEX_FILL:
556 posPoint = GetMemoryPointPosition(string.Format("%1_align_pos", VALVE_NAME_FILL));
557 dirPoint = GetMemoryPointPosition(string.Format("%1_align_dir", VALVE_NAME_FILL));
558 break;
559 }
560
561 array<vector> valvePositions = new array<vector>();
562 valvePositions.Insert(posPoint);
563 valvePositions.Insert(dirPoint);
564
565 return valvePositions;
566 }
567
568 protected void SetLastActiveValve(int pValveIndex)
569 {
570 m_LastActiveValve = pValveIndex;
571 }
572
573 protected void SetWaterLevelHeight(float pHeight)
574 {
575 if (g_Game && g_Game.IsServer())
576 {
578 m_WaterLevelHeightActual = pHeight;
580
582 {
583 m_SpawnedWaterObject.SetPosition(pos);
584 }
585 }
586 }
587
588 protected void RegisterValve(string pCompName, int pIndex)
589 {
590 m_ValveNames.Set(pIndex, pCompName);
591 m_ValveStates.Set(pIndex, false);
592 m_PressureAnimationRequests.Set(pIndex, 0);
593 m_PressureDeanimationRequests.Set(pIndex, 0);
594 m_WaterLevelTimesAccumulated.Set(pIndex, 0);
595 m_PressureTimesAccumulated.Set(pIndex, false);
596 m_PipeSounds.Set(pIndex, null);
597 }
598
600 {
602 for (int i = 0; i < WATER_LEVELS_COUNT; ++i)
603 {
604 if (MemoryPointExists(WATER_LEVELS[i]))
605 {
606 if (!m_WaterLevelsAvailable.Contains(WATER_LEVELS[i]))
607 {
608 m_WaterLevelsAvailable.Insert(WATER_LEVELS[i], ModelToWorld(GetMemoryPointPos(WATER_LEVELS[i])));
609 }
610 }
611 }
612 }
613
614 protected float WaterLevelToHeight(int pWaterLevel)
615 {
616 switch (pWaterLevel)
617 {
618 case WL_MIN:
619 return m_WaterLevelsAvailable[WATER_LEVEL_MIN][1];
620 case WL_ABOVE_PIPES:
621 return m_WaterLevelsAvailable[WATER_LEVEL_ABOVE_PIPES][1];
622 case WL_AVERAGE:
623 return m_WaterLevelsAvailable[WATER_LEVEL_AVERAGE][1];
624 case WL_MAX:
625 return m_WaterLevelsAvailable[WATER_LEVEL_MAX][1];
626 }
627
628 return 0;
629 }
630
631 protected int HeightToWaterLevel(float pHeight)
632 {
633 if (pHeight <= m_WaterLevelsAvailable[WATER_LEVEL_MIN][1])
634 {
635 return WL_MIN;
636 }
637 else if (pHeight > m_WaterLevelsAvailable[WATER_LEVEL_MIN][1] && pHeight <= m_WaterLevelsAvailable[WATER_LEVEL_ABOVE_PIPES][1])
638 {
639 return WL_ABOVE_PIPES;
640 }
641 else if (pHeight > m_WaterLevelsAvailable[WATER_LEVEL_ABOVE_PIPES][1] && pHeight <= m_WaterLevelsAvailable[WATER_LEVEL_AVERAGE][1])
642 {
643 return WL_AVERAGE;
644 }
645 else if (pHeight < m_WaterLevelsAvailable[WATER_LEVEL_MAX][1] && pHeight >= m_WaterLevelsAvailable[WATER_LEVEL_AVERAGE][1])
646 {
647 return WL_AVERAGE;
648 }
649
650 return WL_MAX;
651 }
652
653 protected float PressureLevelToValue(int pPressureLevel)
654 {
655 switch (pPressureLevel)
656 {
657 case PL_MIN:
658 return 0.0;
659 case PL_AVERAGE:
660 return 0.5;
661 case PL_MAX:
662 return 1.0;
663 }
664
665 return 0.0;
666 }
667
669 {
670 WaterLevelSettings wlStageSettings;
671
672 switch (pValveIndex)
673 {
676 {
678 }
679 else
680 {
682 }
683 break;
684 case VALVE_INDEX_FILL:
686 {
688 }
689 else
690 {
692 }
693 break;
694 }
695
696 m_WaterLevelPrev = wlStageSettings.WaterLevel;
697 SetSynchDirty();
698
699 return wlStageSettings;
700 }
701
703 {
704 WaterLevelSettings wlStageSettings;
705
706 switch (pValveIndex)
707 {
710 break;
711 case VALVE_INDEX_FILL:
713 break;
714 }
715
716 return wlStageSettings;
717 }
718
719 protected void AdvanceToNextWaterLevelStageSettings(int pValveIndex)
720 {
721 switch (pValveIndex)
722 {
725 {
727 }
728 else
729 {
731 }
732 break;
733 case VALVE_INDEX_FILL:
735 {
737 }
738 else
739 {
741 }
742 break;
743 }
744 }
745
746 protected PressureLevelSettings PreviousPressureLevelStageSettings(int pValveIndex, bool pDeanimationRequest = false)
747 {
748 PressureLevelSettings plStageSettings;
749
750 switch (pValveIndex)
751 {
753 if (pDeanimationRequest)
754 {
755 plStageSettings = m_FillValvePressureDeanimationSettings[0];
756 return plStageSettings;
757 }
758
760 {
762 }
763 else
764 {
766 }
767 break;
768 case VALVE_INDEX_FILL:
769 if (pDeanimationRequest)
770 {
771 plStageSettings = m_FillValvePressureDeanimationSettings[0];
772 return plStageSettings;
773 }
774
776 {
778 }
779 else
780 {
782 }
783 break;
784 }
785
786 return plStageSettings;
787 }
788
789 protected PressureLevelSettings ActualPressureLevelStageSettings(int pValveIndex, bool pDeanimationRequest = false)
790 {
791 PressureLevelSettings plStageSettings;
792
793 switch (pValveIndex)
794 {
796 if (pDeanimationRequest)
797 {
798 plStageSettings = m_DrainValvePressureDeanimationSettings[1];
799 return plStageSettings;
800 }
801
803 break;
804 case VALVE_INDEX_FILL:
805 if (pDeanimationRequest)
806 {
807 plStageSettings = m_FillValvePressureDeanimationSettings[1];
808 return plStageSettings;
809 }
810
812 break;
813 }
814
815 return plStageSettings;
816 }
817
818 protected void AdvanceToNextPressureLevelStageSettings(int pValveIndex)
819 {
820 switch (pValveIndex)
821 {
824 {
826 }
827 else
828 {
830 }
831 break;
832 case VALVE_INDEX_FILL:
834 {
836 }
837 else
838 {
840 }
841 break;
842 }
843 }
844
845 protected void SetDefaultPressureLevelStageSettings(int pValveIndex)
846 {
847 switch (pValveIndex)
848 {
851 break;
852 case VALVE_INDEX_FILL:
854 break;
855 }
856 }
857
858 protected void AnimateValve(int pValveIndex, float pPhase)
859 {
860 switch (pValveIndex)
861 {
863 SetAnimationPhase(ANIM_PHASE_VALVE_DRAIN, pPhase);
864 break;
865 case VALVE_INDEX_FILL:
866 SetAnimationPhase(ANIM_PHASE_VALVE_FILL, pPhase);
867 break;
868 }
869 }
870
871 protected void SetValvePressureLevelGauge(int pValveIndex, float pValue)
872 {
873 switch (pValveIndex)
874 {
876 SetAnimationPhase(ANIM_PHASE_VALVE_GAUGE_DRAIN, pValue);
877 break;
878 case VALVE_INDEX_FILL:
879 SetAnimationPhase(ANIM_PHASE_VALVE_GAUGE_FILL, pValue);
880 break;
881 }
882 }
883
884 protected float GetValvePressureLevelGauge(int pValveIndex)
885 {
886 switch (pValveIndex)
887 {
889 return GetAnimationPhase(ANIM_PHASE_VALVE_GAUGE_DRAIN);
890 break;
891 case VALVE_INDEX_FILL:
892 return GetAnimationPhase(ANIM_PHASE_VALVE_GAUGE_FILL);
893 break;
894 }
895
896 return 0;
897 }
898
899 protected bool IsValvePressureLevelGaugeAtBase(int pValveIndex)
900 {
901 switch (pValveIndex)
902 {
904 return GetValvePressureLevelGauge(pValveIndex) <= 0.01;
905 break;
906 case VALVE_INDEX_FILL:
907 return GetValvePressureLevelGauge(pValveIndex) >= 0.99;
908 break;
909 }
910
911 return 0.0;
912 }
913
914 protected float AdjustTime(float originalTime)
915 {
916 #ifdef DIAG_DEVELOPER
917 float timeAccel = 1;
918 if (FeatureTimeAccel.GetFeatureTimeAccelEnabled(ETimeAccelCategories.UNDERGROUND_RESERVOIR))
919 {
920 timeAccel = FeatureTimeAccel.GetFeatureTimeAccelValue();
921 return originalTime * timeAccel;
922 }
923 #endif
924 return originalTime;
925 }
926
927 protected vector GetMemoryPointPosition(string pMemoryPoint)
928 {
929 vector pos = vector.Zero;
930
931 if (MemoryPointExists(pMemoryPoint))
932 {
933 pos = GetMemoryPointPos(pMemoryPoint);
934 pos = ModelToWorld(pos);
935 }
936 else
937 {
938 ErrorEx(string.Format("Memory point %1 not found, falling back to vector.Zero", pMemoryPoint));
939 }
940
941 return pos;
942 }
943
951
964
966 {
967 if (IsAnyValveActive())
968 {
970 {
973 g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(PlayPipeCreakingSoundOnLocation, randomDelay, false);
974 }
975 }
976 else
977 {
979 {
980 StopSoundSet(m_PipeCreakingSounds);
982 }
983 }
984 }
985
987 {
988 if (!m_PipeSounds || m_PipeSounds.Count() == 0)
989 {
990 return;
991 }
992
993 EffectSound snd;
994
995 EffectSound sndDrain, sndFill;
996 float drainPressureLevel = GetValvePressureLevelGauge(VALVE_INDEX_DRAIN);
997 if (drainPressureLevel >= 0.4 && drainPressureLevel < 0.8)
998 {
999 if (m_PipeSounds[VALVE_INDEX_DRAIN] == null)
1000 {
1001 PlaySoundSetAtMemoryPoint(sndDrain, SOUND_NAME_PIPE_SPRINKLING_START, VALVE_NAME_DRAIN, false, 0.0, 0.5);
1002 m_PipeSounds[VALVE_INDEX_DRAIN] = sndDrain;
1004 StopSoundSet(snd);
1006 PlaySoundSetAtMemoryPointLooped(sndDrain, SOUND_NAME_PIPE_SPRINKLING_LOOP1, VALVE_NAME_DRAIN, 0.5, 0.5);
1007 m_PipeSounds[VALVE_INDEX_DRAIN] = sndDrain;
1008 }
1009 }
1010
1011 if (drainPressureLevel < 0.4)
1012 {
1013 if (m_PipeSounds[VALVE_INDEX_DRAIN] != null)
1014 {
1016 StopSoundSet(snd);
1018 }
1019 }
1020
1022
1023 float fillPressureLevel = GetValvePressureLevelGauge(VALVE_INDEX_FILL);
1024 if (fillPressureLevel >= 0.4)
1025 {
1026 if (m_PipeSounds[VALVE_INDEX_FILL] == null)
1027 {
1028 PlaySoundSetAtMemoryPoint(sndFill, SOUND_NAME_PIPE_SPRINKLING_START, VALVE_NAME_FILL, false, 0.0, 0.5);
1030 StopSoundSet(snd);
1032 PlaySoundSetAtMemoryPointLooped(sndFill, SOUND_NAME_PIPE_SPRINKLING_LOOP2, VALVE_NAME_FILL, 0.5, 0.5);
1033 m_PipeSounds[VALVE_INDEX_FILL] = sndFill;
1034 }
1035 }
1036
1037 if (fillPressureLevel < 0.4)
1038 {
1039 if (m_PipeSounds[VALVE_INDEX_FILL] != null)
1040 {
1042 StopSoundSet(snd);
1044 }
1045 }
1046 }
1047
1049 {
1052 {
1054 {
1055 if (m_PipeUnderwaterSound == null)
1056 {
1057 PlaySoundSetAtMemoryPoint(m_PipeUnderwaterSound, SOUND_NAME_UPIPE_SPRINKLING_START, PIPE_NAME_BROKEN1, false, 0.0, 0.5);
1058 StopSoundSet(m_PipeUnderwaterSound);
1059 m_PipeUnderwaterSound = null;
1060 m_PipeUnderwaterSoundRunning = PlaySoundSetAtMemoryPointLooped(m_PipeUnderwaterSound, SOUND_NAME_UPIPE_SPRINKLING_LOOP, PIPE_NAME_BROKEN1, 0.0, 0.5);
1061 }
1062 }
1064 {
1066 {
1067 StopSoundSet(m_PipeUnderwaterSound);
1068 if (m_PipeUnderwaterSoundRunning)
1069 {
1070 PlaySoundSetAtMemoryPoint(m_PipeUnderwaterSound, SOUND_NAME_UPIPE_SPRINKLING_END, PIPE_NAME_BROKEN1, false, 0.0, 0.5);
1071 m_PipeUnderwaterSoundRunning = false;
1072 }
1073 }
1074 }
1075 }
1076 }
1077
1079 {
1081 {
1082 if (m_WaterLevelMovementSound == null)
1083 {
1084 PlaySoundSetAtMemoryPointLooped(m_WaterLevelMovementSound, SOUND_NAME_WATER_DRAIN_LOOP, PIPE_NAME_BROKEN1, 0.0, 0.5);
1085 }
1086 }
1088 {
1089 if (m_WaterLevelMovementSound == null)
1090 {
1091 PlaySoundSetAtMemoryPointLooped(m_WaterLevelMovementSound, SOUND_NAME_WATER_FILL_LOOP, PIPE_NAME_BROKEN1, 0.0, 0.5);
1092 }
1093 }
1095 {
1097 {
1098 StopSoundSet(m_WaterLevelMovementSound);
1099 }
1100 }
1101 }
1102
1108
1110 {
1112 int index = Math.RandomInt(0, PIPE_CREAKING_SOUND_LOCATIONS_COUNT);
1114 }
1115
1116 protected void HandleVisualEffects()
1117 {
1119 {
1121 {
1123 }
1124 }
1125
1127 {
1129 {
1130 m_ValveParticles[VALVE_INDEX_DRAIN].StopParticle();
1132 }
1133 }
1134
1136 {
1138 {
1140 }
1141 }
1142
1144 {
1146 {
1147 m_ValveParticles[VALVE_INDEX_FILL].StopParticle();
1149 }
1150 }
1151
1152
1155 {
1157 {
1159 {
1161 }
1162
1165 {
1168 }
1169 }
1170 }
1171
1174 {
1176 {
1178 }
1179 }
1180
1182 {
1183 for (int pipe = 0; pipe < m_PipeBrokenParticles.Count(); ++pipe)
1184 {
1185 if (m_PipeBrokenParticles[pipe])
1186 {
1187 m_PipeBrokenParticles[pipe].StopParticle();
1188 m_PipeBrokenParticles[pipe] = null;
1189 }
1190 }
1191 }
1192 }
1193
1194 protected void CleanVisualEffects()
1195 {
1196 for (int valve = 0; valve < VALVES_COUNT; ++valve)
1197 {
1198 if (m_ValveParticles[valve])
1199 {
1200 m_ValveParticles[valve].StopParticle();
1201 m_ValveParticles[valve] = null;
1202 }
1203 }
1204
1205 for (int pipe = 0; pipe < m_PipeBrokenParticles.Count(); ++pipe)
1206 {
1207 if (m_PipeBrokenParticles[pipe])
1208 {
1209 m_PipeBrokenParticles[pipe].StopParticle();
1210 m_PipeBrokenParticles[pipe] = null;
1211 }
1212 }
1213 }
1214
1215
1216
1239
1240 protected void SyncValveVariables()
1241 {
1242 if (g_Game)
1243 {
1246 {
1248 SetSynchDirty();
1249 }
1250 }
1251 }
1252
1254 {
1255 int packedBits = 0;
1256
1257 for (int i = 0; i < pStates.Count(); ++i)
1258 {
1259 if (pStates[i] == true)
1260 {
1261 packedBits |= 1 << i;
1262 }
1263 }
1264
1265 return packedBits;
1266 }
1267
1268 protected array<bool> UnpackBitsToArrayOfBoolStates(int pPackedBits, int pArrayLength)
1269 {
1270 array<bool> unpackedBools = new array<bool>();
1271 for (int i = 0; i < pArrayLength; ++i)
1272 {
1273 if ((pPackedBits & 1 << i) != 0)
1274 {
1275 unpackedBools.Insert(true);
1276 }
1277 else
1278 {
1279 unpackedBools.Insert(false);
1280 }
1281 }
1282
1283 return unpackedBools;
1284 }
1285
1286#ifdef DEVELOPER
1287 override protected string GetDebugText()
1288 {
1289 string debug_output = "";
1290 debug_output += string.Format("\nm_WaterLevelActual: %1", m_WaterLevelActual);
1291 debug_output += string.Format("\nm_WaterLevelPrev: %1", m_WaterLevelPrev);
1292 debug_output += string.Format("\nm_ValveManipulatedIndex: %1", m_ValveManipulatedIndex);
1293
1294 int valve;
1295 for (valve = 0; valve < VALVES_COUNT; ++valve)
1296 {
1297 debug_output += string.Format("\nvalve %1 state:%2 | pressure req: %2", valve, m_ValveStates[valve], m_PressureAnimationRequests[valve]);
1298 }
1299
1300 return debug_output;
1301 }
1302
1303 override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
1304 {
1305 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SPECIALIZED_ACTION1, "Reset state", FadeColors.LIGHT_GREY));
1306 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SPECIALIZED_ACTION2, "Drain", FadeColors.LIGHT_GREY));
1307 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SPECIALIZED_ACTION3, "Fill", FadeColors.LIGHT_GREY));
1308 outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
1309
1310 super.GetDebugActions(outputList);
1311 }
1312
1313 override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
1314 {
1315 if (super.OnAction(action_id, player, ctx))
1316 return true;
1317 if (g_Game.IsServer() || !g_Game.IsMultiplayer())
1318 {
1319 if (action_id == EActions.SPECIALIZED_ACTION1)
1320 {
1321 ResetState();
1326 }
1327 else if (action_id == EActions.SPECIALIZED_ACTION2)
1328 {
1329 ResetState();
1335 }
1336 else if (action_id == EActions.SPECIALIZED_ACTION3)
1337 {
1338 ResetState();
1344 SetSynchDirty();
1345 }
1346 }
1347 return false;
1348 }
1349
1350
1351#endif
1352}
1353
Param4< int, int, string, int > TSelectableActionInfoWithColor
Definition entityai.c:104
ActionTurnValveUndergroundReservoirCB ActionTurnValveCB ActionTurnValveUndergroundReservoir()
void AddAction(typename actionName)
void SetActions()
vector GetOrientation()
const int ECE_CREATEPHYSICS
Wrapper class for managing sound through SEffectManager.
Definition effectsound.c:5
Definition enmath.c:7
Manager class for managing Effect (EffectParticle, EffectSound).
static bool DestroySound(EffectSound sound_effect)
Legacy, backwards compatibility.
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
override void OnVariablesSynchronized()
override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
Definition dayzanimal.c:136
override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
Definition dayzanimal.c:125
DayZGame g_Game
Definition dayzgame.c:3942
override Widget Init()
Definition dayzgame.c:127
EActions
Definition eactions.c:2
const int INDEX_NOT_FOUND
Definition gameplay.c:13
Serializer ParamsReadContext
Definition gameplay.c:15
enum ShapeType ErrorEx
EntityEvent
Entity events for event-mask, or throwing event from code.
Definition enentity.c:45
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
const int SAT_DEBUG_ACTION
Definition constants.c:457
const int CALL_CATEGORY_SYSTEM
Definition tools.c:8
ref ParticleSourceArray m_PipeBrokenParticles
ref array< ref PressureLevelSettings > m_DrainValvePressureDeanimationSettings
float m_WaterLevelHeightActual
void RegisterValve(string pCompName, int pIndex)
const int PIPE_INDEX_BROKEN1
ref ParticleSourceArray m_ValveParticles
ref map< string, vector > m_WaterLevelsAvailable
const string SOUND_NAME_PIPE_SPRINKLING_START
void SetDefaultPressureLevelStageSettings(int pValveIndex)
bool IsValvePressureLevelGaugeAtBase(int pValveIndex)
void HandleSoundEffectsWaterLevelMovementSounds()
const string SOUND_NAME_PIPE_CREAKING
ref array< ref PressureLevelSettings > m_FillValvePressureStageSettings
const string ANIM_PHASE_VALVE_GAUGE_FILL
const int PARTICLE_FILL_PIPE_JET
PressureLevelSettings ActualPressureLevelStageSettings(int pValveIndex, bool pDeanimationRequest=false)
ref array< ref PressureLevelSettings > m_FillValvePressureDeanimationSettings
const string SOUND_NAME_WATER_FILL_LOOP
const int PARTICLE_FILL_PIPE_MAX_PRESSURE
ref array< ref WaterLevelSettings > m_DrainValveWaterStageSettings
valve/pipe stages for water and pressure levels
int m_DrainValvePressureLevelStageIndex
ref array< ref WaterLevelSettings > m_FillValveWaterStageSettings
for deanimation purposes
ref EffectSound m_WaterLevelMovementSound
const string VALVE_NAME_FILL
const string WATER_LEVELS[WATER_LEVELS_COUNT]
void PlayPipeCreakingSoundOnLocation()
ref array< bool > m_PressureDeanimationRequests
const string PIPE_NAME_BROKEN1
const string ANIM_PHASE_VALVE_FILL
WaterLevelSettings ActualWaterLevelStageSettings(int pValveIndex)
void OnValveManipulationStart(int pValveIndex)
void SetLastActiveValve(int pValveIndex)
void HandleSoundEffectsUnderwaterPipeSounds()
const string PIPE_NAME_LEAKING_DRAIN
const int VALVES_COUNT
const int PARTICLE_DRAIN_PIPE_MAX_PRESSURE
class WaterLevelSettings PressureLevel
const string SOUND_NAME_PIPE_SPRINKLING_LOOP2
void AdvanceToNextPressureLevelStageSettings(int pValveIndex)
bool m_ValveManipulationSoundRequested
VFX/SFX.
ref array< ref PressureLevelSettings > m_DrainValvePressureStageSettings
const string SOUND_NAME_VALVE_MANIPULATION
const int VALVE_INDEX_DRAIN
const string ANIM_PHASE_VALVE_DRAIN
PressureLevelSettings PreviousPressureLevelStageSettings(int pValveIndex, bool pDeanimationRequest=false)
const string SOUND_NAME_WATER_DRAIN_LOOP
int PackArrayOfBoolStatesIntoBits(array< bool > pStates)
void SetWaterLevelHeight(float pHeight)
void OnValveManipulationEnd(int pValveIndex)
ref array< bool > m_ValveStates
void SetValvePressureLevelGauge(int pValveIndex, float pValue)
ref array< string > m_ValveNames
array< bool > UnpackBitsToArrayOfBoolStates(int pPackedBits, int pArrayLength)
float WaterLevelToHeight(int pWaterLevel)
array< vector > GetValveAligningPointsWS(int pValveIndex)
void HandleSoundEffectsPipeCreaking()
ref EffectSound m_ValveManipulationSound
const string PIPE_NAME_LEAKING_FILL
float GetValvePressureLevelGauge(int pValveIndex)
const int PIPE_CREAKING_SOUND_LOCATIONS_COUNT
const int PIPE_INDEX_BROKEN2
main broken pipe
void OnValveManipulationCanceled(int pValveIndex)
bool m_PipeCreakingSoundRequested
ref array< float > m_PressureTimesAccumulated
WaterLevelSettings PreviousWaterLevelStageSettings(int pValveIndex)
const int WATER_LEVELS_COUNT
bool IsValveActive(int pValveIndex)
ref array< EffectSound > m_PipeSounds
override bool IsValveTurnable(int pValveIndex)
const int PARTICLE_FILL_PIPE_JET_WEAK
const string PIPE_CREAKING_SOUND_LOCATIONS[PIPE_CREAKING_SOUND_LOCATIONS_COUNT]
void AdvanceToNextWaterLevelStageSettings(int pValveIndex)
const string VALVE_NAME_DRAIN
const int PIPE_CREAKING_MIN_TIME_DELAY_MS
float PressureLevelToValue(int pPressureLevel)
const int VALVE_INDEX_FILL
void HandleSoundEffectsPipeSprinkling()
const string SOUND_NAME_PIPE_SPRINKLING_LOOP1
ref WaterLevelSnapshot m_WaterLevelSnapshot
for deanimation purposes
int m_DrainValveWaterLevelStageIndex
pointing to specific stage for each valve/pipe
const int PIPES_BROKEN_COUNT
int m_FillValveWaterLevelStageIndex
override int GetTurnableValveIndex(int pComponentIndex)
const int WL_AVERAGE
float AdjustTime(float originalTime)
const string SOUND_NAME_UPIPE_SPRINKLING_START
const string PIPE_NAME_BROKEN2
const string SOUND_NAME_UPIPE_SPRINKLING_END
int HeightToWaterLevel(float pHeight)
ref array< float > m_WaterLevelTimesAccumulated
void TranslateMemoryPointsToWaterLevels()
int m_FillValvePressureLevelStageIndex
Object m_SpawnedWaterObject
void AnimateValve(int pValveIndex, float pPhase)
ref EffectSound m_PipeUnderwaterSound
ref array< bool > m_PressureAnimationRequests
class WaterLevelSnapshot OBJECT_NAME_WATER_PLANE
const string SOUND_NAME_PIPE_SPRINKLING_END
const int WL_ABOVE_PIPES
const string SOUND_NAME_UPIPE_SPRINKLING_LOOP
ref EffectSound m_PipeCreakingSounds
const string ANIM_PHASE_VALVE_GAUGE_DRAIN
tighter broken pipe
void PlayValveManipulationSound()
void PressureLevelSettings(int pPressureLevel, float pDuration)
const int PIPE_CREAKING_MAX_TIME_DELAY_MS
void ConfigureValvesAndGaugesCourse()
vector GetMemoryPointPosition(string pMemoryPoint)
const int PL_AVERAGE
string GetDebugText()
void ParticleManager(ParticleManagerSettings settings)
Constructor (ctor).
array< ParticleSource > ParticleSourceArray