Dayz Explorer  1.24.157551 (v105080)
Dayz Code Explorer by Zeroy
undergroundhandlerclient.c
Go to the documentation of this file.
2 {
3  NONE,//player is not interacting with underground at any level
4  OUTER,//player is on the outskirts of the underdound, some effects are already in effect, while others might not be
5  TRANSITIONING,//player has entered underground and is in the process of screen darkening transition
6  FULL//the player is now fully entered underground
7 }
8 
10 {
11  const float LIGHT_BLEND_SPEED_IN = 5;
12  const float LIGHT_BLEND_SPEED_OUT = 1.75;
13  const float MAX_RATIO = 0.9;//how much max ratio between 0..1 can a single breadcrumb occupy
14  const float RATIO_CUTOFF = 0;//what's the minimum ratio a breadcrumb needs to have to be considered when calculatiing accommodation
15  const float DISTANCE_CUTOFF = 5;//we ignore breadcrumbs further than this distance
16  const float ACCO_MODIFIER = 1;//when we calculate eye accommodation between 0..1 based on the breadcrumbs values and distances, we multiply the result by this modifier to get the final eye accommodation value
17  const float DEFAULT_INTERPOLATION_SPEED = 7;
18  const string UNDERGROUND_LIGHTING = "dz\\data\\lighting\\lighting_underground.txt";
20 
21  protected PlayerBase m_Player;
22  protected PPERUndergroundAcco m_Requester;
23  protected PPERequester_CameraNV m_NVRequester;
24  protected ref set<UndergroundTrigger> m_InsideTriggers = new set<UndergroundTrigger>();
25 
26  protected float m_EyeAccoTarget = 1;
27  protected float m_AccoInterpolationSpeed;
28  protected float m_EyeAcco = 1;
29  protected float m_LightingLerpTarget;
30  protected float m_LightingLerp;
32 
33  protected UndergroundTrigger m_TransitionalTrigger;
34 
36  {
37  GetGame().GetWorld().LoadUserLightingCfg(UNDERGROUND_LIGHTING, "Underground");
38  m_Player = player;
39  m_NVRequester = PPERequester_CameraNV.Cast(PPERequesterBank.GetRequester( PPERequesterBank.REQ_CAMERANV));
40  }
41 
43  {
44  if (GetGame())
45  {
46  GetGame().GetWorld().SetExplicitVolumeFactor_EnvSounds2D(1, 0.5);
47  GetGame().GetWeather().SuppressLightningSimulation(false);
48  GetGame().GetWorld().SetUserLightingLerp(0);
49  if (m_AmbientSound)
50  m_AmbientSound.Stop();
51  }
52  }
53 
54  protected PPERUndergroundAcco GetRequester()
55  {
56  if (!m_Requester)
57  {
58  m_Requester = PPERUndergroundAcco.Cast(PPERequesterBank.GetRequester( PPERequesterBank.REQ_UNDERGROUND));
59  m_Requester.Start();
60  }
61  return m_Requester;
62  }
63 
64  void OnTriggerEnter(UndergroundTrigger trigger)
65  {
66  m_InsideTriggers.Insert(trigger);
68 
69  }
70 
71  void OnTriggerLeave(UndergroundTrigger trigger)
72  {
73  int index = m_InsideTriggers.Find(trigger);
74  if (index != -1)
75  {
76  m_InsideTriggers.Remove(index);
77  }
79  }
80 
81  protected void CalculateEyeAccoTarget()
82  {
83  if (m_TransitionalTrigger && m_TransitionalTrigger.m_Data.Breadcrumbs.Count() >= 2)
84  {
85  float closestDist = float.MAX;
86  float acco;
87  array<float> distances = new array<float>();
88  array<float> distancesInverted = new array<float>();
89 
90 
91  int excludeMask = 0;
92  foreach (int indx, auto crumb:m_TransitionalTrigger.m_Data.Breadcrumbs)
93  {
94  if (indx > 32)//error handling for exceeding this limit is handled elsewhere
95  break;
96 
97  float dist = vector.Distance(m_Player.GetPosition(), crumb.GetPosition());
98  float crumbRadius = m_TransitionalTrigger.m_Data.Breadcrumbs[indx].Radius;
99  float maxRadiusAllowed = DISTANCE_CUTOFF;
100 
101  if (crumbRadius != -1)
102  {
103  maxRadiusAllowed = crumbRadius;
104  }
105  if (dist > maxRadiusAllowed)
106  {
107  excludeMask = (excludeMask | (1 << indx));
108  }
109  else if (m_TransitionalTrigger.m_Data.Breadcrumbs[indx].UseRaycast)
110  {
111  int idx = m_Player.GetBoneIndexByName("Head");
112  vector rayStart = m_Player.GetBonePositionWS(idx);
113  vector rayEnd = crumb.GetPosition();
114  vector hitPos, hitNormal;
115  float hitFraction;
116  Object hitObj;
117 
118  if (DayZPhysics.RayCastBullet(rayStart, rayEnd,PhxInteractionLayers.TERRAIN | PhxInteractionLayers.ROADWAY| PhxInteractionLayers.BUILDING, null, hitObj, hitPos, hitNormal, hitFraction))
119  {
120  excludeMask = (excludeMask | (1 << indx));
121  }
122  }
123 
124  distances.Insert(dist);
125 
126  #ifdef DIAG_DEVELOPER
127  if ( DiagMenu.GetBool(DiagMenuIDs.UNDERGROUND_SHOW_BREADCRUMB) )
128  {
129  Debug.DrawSphere(crumb.GetPosition(),0.1, COLOR_RED, ShapeFlags.ONCE);
130  }
131  #endif
132  }
133  float baseDst = distances[0];
134  float sum = 0;
135  //Print(excludeMask);
136  foreach (float dst:distances)
137  {
138  if (dst == 0)
139  dst = 0.1;
140  float dstInv = (baseDst / dst) * baseDst;
141  sum += dstInv;
142  distancesInverted.Insert(dstInv);
143  }
144  float sumCheck = 0;
145  float eyeAcco = 0;
146  foreach (int i, float dstInvert:distancesInverted)
147  {
148  /*
149  //Print(m_TransitionalTrigger.m_Data.Breadcrumbs[i].EyeAccommodation);
150  //Print(m_TransitionalTrigger.m_Data.Breadcrumbs.Count());
151  */
152  if ((1 << i) & excludeMask)
153  continue;
154  float ratio = dstInvert / sum;
155  if (ratio > MAX_RATIO)
156  ratio = MAX_RATIO;
157  if (ratio > RATIO_CUTOFF)
158  {
159  #ifdef DIAG_DEVELOPER
160  if (DiagMenu.GetBool(DiagMenuIDs.UNDERGROUND_SHOW_BREADCRUMB) )
161  {
162  float intensity = (1-ratio) * 255;
163  Debug.DrawLine(GetGame().GetPlayer().GetPosition() + "0 1 0", m_TransitionalTrigger.m_Data.Breadcrumbs[i].GetPosition(),ARGB(0,255,intensity,intensity),ShapeFlags.ONCE);
164  }
165  #endif
166  eyeAcco += ratio * m_TransitionalTrigger.m_Data.Breadcrumbs[i].EyeAccommodation;
167 
168  }
169 
170  }
171  m_EyeAccoTarget = eyeAcco * ACCO_MODIFIER;
172  }
173  }
174 
175  protected void ProcessEyeAcco(float timeSlice)
176  {
178  bool reachedTarget = CalculateEyeAcco(timeSlice);
179  ApplyEyeAcco();
180  if(reachedTarget && !m_Player.m_UndergroundPresence)
181  {
182  GetRequester().Stop();
184  //m_NVRequester.SetUndergroundExposureCoef(1.0);
185  m_Player.KillUndergroundHandler();
186  }
187 
188  }
189 
190  protected void ProcessLighting(float timeSlice)
191  {
192  #ifdef DEVELOPER
193  if (!DiagMenu.GetBool(DiagMenuIDs.UNDERGROUND_DISABLE_DARKENING) )
194  {
195  GetGame().GetWorld().SetUserLightingLerp(m_LightingLerp);
196  }
197  else
198  {
199  GetGame().GetWorld().SetUserLightingLerp(0);
200  }
201  #else
202  GetGame().GetWorld().SetUserLightingLerp(m_LightingLerp);
203  #endif
204  }
205 
206  protected void ProcessSound(float timeSlice)
207  {
208  GetGame().GetWorld().SetExplicitVolumeFactor_EnvSounds2D(m_EyeAcco, 0);
209  if (m_AmbientSound)
210  {
211  m_AmbientSound.SetSoundVolume(1-m_EyeAcco);
212  //Print(m_AmbientSound.GetSoundVolume());
213  }
214  else
215  {
216  m_Player.PlaySoundSetLoop(m_AmbientSound, "Underground_SoundSet",3,3);
217  }
218  }
219 
220  void Tick(float timeSlice)
221  {
222  if (!m_Player.IsAlive())
223  return;
224 
225  ProcessEyeAcco(timeSlice);
226  ProcessLighting(timeSlice);
227  ProcessSound(timeSlice);
228 
229  #ifdef DIAG_DEVELOPER
230  if ( DiagMenu.GetBool(DiagMenuIDs.UNDERGROUND_SHOW_BREADCRUMB) )
231  {
232  DisplayDebugInfo(GetGame().GetWorld().GetEyeAccom(), m_LightingLerp);
233  }
234  #endif
235 
236  }
237 
238  protected void ApplyEyeAcco()
239  {
240  #ifdef DIAG_DEVELOPER
241  if (!DiagMenu.GetBool(DiagMenuIDs.UNDERGROUND_DISABLE_DARKENING) )
242  {
243  GetRequester().SetEyeAccommodation(m_EyeAcco);
244  }
245  else
246  {
247  GetRequester().SetEyeAccommodation(1);
248  }
249  #else
250  GetRequester().SetEyeAccommodation(m_EyeAcco);
251  #endif
252 
253  float undergrounNVExposureCoef = m_EyeAcco;
254  if (m_LightingLerp >= 1.0 || GetDayZGame().GetWorld().IsNight())
255  {
256  undergrounNVExposureCoef = 1.0;
257  }
258  //m_NVRequester.SetUndergroundExposureCoef(undergrounNVExposureCoef);
259  UpdateNVGRequester(undergrounNVExposureCoef);
260  }
261 
262  protected void UpdateNVGRequester(float value)
263  {
264  m_NVRequester.SetUndergroundExposureCoef(value);
265  }
266 
267  protected bool CalculateEyeAcco(float timeSlice)
268  {
269  if (m_TransitionalTrigger || !m_Player.m_UndergroundPresence || (m_EyeAccoTarget == 1))
270  {
271  float accoDiff = m_EyeAccoTarget - m_EyeAcco;
272  float increase = accoDiff * m_AccoInterpolationSpeed * timeSlice;
273  m_EyeAcco += increase;
274  if (Math.AbsFloat(accoDiff) < 0.01)
275  {
277  return true;
278  }
279  }
280  else
281  {
283  }
284  return false;
285  }
286 
287 
288 
289  protected void OnTriggerInsiderUpdate()
290  {
291  EUndergroundTriggerType bestType = EUndergroundTriggerType.UNDEFINED;
292  m_TransitionalTrigger = null;
293  UndergroundTrigger bestTrigger;
294  m_EyeAccoTarget = 1;
296 
297  foreach (auto t:m_InsideTriggers)
298  {
299  if (t.m_Type > bestType)
300  {
301  bestTrigger = t;
302  bestType = t.m_Type;
303  }
304  }
305  //Print(m_InsideTriggers.Count());
306  //Print(bestType);
307  if (bestTrigger)
308  {
309  if (bestTrigger.m_Type == EUndergroundTriggerType.TRANSITIONING)
310  {
311  m_TransitionalTrigger = bestTrigger;
312  }
313  m_EyeAccoTarget = bestTrigger.m_Accommodation;
314  if (bestTrigger.m_InterpolationSpeed != -1 && bestTrigger.m_InterpolationSpeed != 0)
315  m_AccoInterpolationSpeed = bestTrigger.m_InterpolationSpeed;
316  }
317 
318  SetUndergroundPresence(bestTrigger);
319  }
320 
321 
322  protected void SetUndergroundPresence(UndergroundTrigger trigger)
323  {
324  EUndergroundPresence newPresence = EUndergroundPresence.NONE;
325  EUndergroundPresence oldPresence = m_Player.m_UndergroundPresence;
326 
327  if (trigger)
328  {
329  if (trigger.m_Type == EUndergroundTriggerType.OUTER)
330  {
331  newPresence = EUndergroundPresence.OUTER;
332  }
333  else if (trigger.m_Type == EUndergroundTriggerType.TRANSITIONING)
334  {
335  newPresence = EUndergroundPresence.TRANSITIONING;
336  }
337  else if (trigger.m_Type == EUndergroundTriggerType.INNER)
338  {
339  newPresence = EUndergroundPresence.FULL;
340  }
341  }
342 
343  if (newPresence != oldPresence)//was there a change ?
344  {
345  OnUndergroundPresenceUpdate(newPresence,oldPresence);
346  m_Player.SetUnderground(newPresence);
347  }
348 
349 
350  }
351 
352  protected void EnableLights(bool enable)
353  {
354  foreach (ScriptedLightBase light:ScriptedLightBase.m_NightTimeOnlyLights)
355  {
356  light.SetVisibleDuringDaylight(enable);
357  }
358  }
359 
360  void OnUpdateTimerEnd();
361 
363  {
365  return;
366  float value01 = m_AnimTimerLightBlend.GetValue();
367  float result = Easing.EaseInQuint(value01);
368  m_LightingLerp = result;
369 
370  }
371 
373  {
375  return;
376  float value01 = m_AnimTimerLightBlend.GetValue();
377  float result = Easing.EaseOutCubic(value01);
378  m_LightingLerp = result;
379  }
380 
381 
383  {
384  //Print("-----> On Undeground Presence update " + EnumTools.EnumToString(EUndergroundPresence, newPresence) + " " + EnumTools.EnumToString(EUndergroundPresence, oldPresence));
385  if (newPresence > EUndergroundPresence.NONE)
386  {
387  if (oldPresence == EUndergroundPresence.NONE)
388  {
389  EnableLights(true);
390  }
391  if (newPresence > EUndergroundPresence.OUTER && oldPresence <= EUndergroundPresence.OUTER)
392  {
393  GetGame().GetWeather().SuppressLightningSimulation(true);
394  m_Player.PlaySoundSetLoop(m_AmbientSound, "Underground_SoundSet",3,3);
395  }
396  if (newPresence == EUndergroundPresence.FULL)
397  {
399  m_AnimTimerLightBlend.Run(1, this, "OnUpdateTimerIn", "OnUpdateTimerEnd",0, false, LIGHT_BLEND_SPEED_IN);
400  }
401  }
402  if (newPresence < EUndergroundPresence.FULL && oldPresence == EUndergroundPresence.FULL)
403  {
405  m_AnimTimerLightBlend.Run(0, this, "OnUpdateTimerOut", "OnUpdateTimerEnd",m_LightingLerp, false, LIGHT_BLEND_SPEED_OUT);
406  }
407  if (newPresence <= EUndergroundPresence.OUTER && oldPresence > EUndergroundPresence.OUTER)
408  {
409  GetGame().GetWeather().SuppressLightningSimulation(false);
410  if (m_AmbientSound)
411  m_Player.StopSoundSet(m_AmbientSound);
412  }
413  if (newPresence == EUndergroundPresence.NONE && oldPresence >= EUndergroundPresence.OUTER)
414  {
415  GetGame().GetWorld().SetUserLightingLerp(0);
416  EnableLights(false);
417  }
418  }
419 
420  #ifdef DIAG_DEVELOPER
421  protected void DisplayDebugInfo(float acco, float lighting)
422  {
423  if (acco < 0.0001)
424  acco = 0;
425  DbgUI.Begin(String("Underground Areas"), 20, 20);
426  DbgUI.Text(String("Eye Accomodation: " + acco.ToString()));
427  DbgUI.Text(String("Lighting lerp: " + lighting.ToString()));
428  DbgUI.End();
429  }
430  #endif
431 }
MAX_RATIO
const float MAX_RATIO
Definition: undergroundhandlerclient.c:13
GetGame
proto native CGame GetGame()
m_LightingLerp
protected float m_LightingLerp
Definition: undergroundhandlerclient.c:30
m_Requester
protected PPERUndergroundAcco m_Requester
Definition: undergroundhandlerclient.c:22
m_NVRequester
protected PPERequester_CameraNV m_NVRequester
Definition: undergroundhandlerclient.c:23
DISTANCE_CUTOFF
const float DISTANCE_CUTOFF
Definition: undergroundhandlerclient.c:15
DbgUI
Definition: dbgui.c:59
m_EyeAccoTarget
protected float m_EyeAccoTarget
Definition: undergroundhandlerclient.c:26
String
string String(string s)
Helper for passing string expression to functions with void parameter. Example: Print(String("Hello "...
Definition: enscript.c:339
ApplyEyeAcco
protected void ApplyEyeAcco()
Definition: undergroundhandlerclient.c:238
GetDayZGame
DayZGame GetDayZGame()
Definition: dayzgame.c:3729
DiagMenu
Definition: endebug.c:232
CalculateEyeAccoTarget
protected void CalculateEyeAccoTarget()
Definition: undergroundhandlerclient.c:81
OnUpdateTimerEnd
void OnUpdateTimerEnd()
AnimationTimer
AnimationTimer class. This timer is for animating float value. usage:
Definition: tools.c:652
m_AmbientSound
protected EffectSound m_AmbientSound
Definition: undergroundhandlerclient.c:31
DEFAULT_INTERPOLATION_SPEED
const float DEFAULT_INTERPOLATION_SPEED
Definition: undergroundhandlerclient.c:17
UndergroundHandlerClient
void UndergroundHandlerClient(PlayerBase player)
Definition: undergroundhandlerclient.c:35
RATIO_CUTOFF
const float RATIO_CUTOFF
Definition: undergroundhandlerclient.c:14
ProcessSound
protected void ProcessSound(float timeSlice)
Definition: undergroundhandlerclient.c:206
m_AnimTimerLightBlend
protected ref AnimationTimer m_AnimTimerLightBlend
Definition: undergroundhandlerclient.c:19
Easing
Input value between 0 and 1, returns value adjusted by easing, no automatic clamping of input(do your...
Definition: easing.c:2
OnUpdateTimerIn
void OnUpdateTimerIn()
Definition: undergroundhandlerclient.c:362
DiagMenuIDs
DiagMenuIDs
Definition: ediagmenuids.c:1
EffectSound
Wrapper class for managing sound through SEffectManager.
Definition: effectsound.c:4
PlayerBase
Definition: playerbaseclient.c:1
vector
Definition: enconvert.c:105
LIGHT_BLEND_SPEED_OUT
const float LIGHT_BLEND_SPEED_OUT
Definition: undergroundhandlerclient.c:12
ShapeFlags
ShapeFlags
Definition: endebug.c:125
Object
Definition: objecttyped.c:1
ScriptedLightBase
Definition: pointlightbase.c:1
FULL
@ FULL
Definition: undergroundhandlerclient.c:6
m_Player
protected PlayerBase m_Player
Definition: undergroundhandlerclient.c:21
m_TransitionalTrigger
protected UndergroundTrigger m_TransitionalTrigger
Definition: undergroundhandlerclient.c:33
OUTER
@ OUTER
Definition: undergroundhandlerclient.c:4
NONE
@ NONE
Definition: undergroundhandlerclient.c:3
LIGHT_BLEND_SPEED_IN
enum EUndergroundPresence LIGHT_BLEND_SPEED_IN
Tick
void Tick(float timeSlice)
Definition: undergroundhandlerclient.c:220
COLOR_RED
const int COLOR_RED
Definition: constants.c:64
array< float >
ProcessLighting
protected void ProcessLighting(float timeSlice)
Definition: undergroundhandlerclient.c:190
UpdateNVGRequester
protected void UpdateNVGRequester(float value)
Definition: undergroundhandlerclient.c:262
Debug
Definition: debug.c:13
DayZPhysics
Definition: dayzphysics.c:123
m_EyeAcco
protected float m_EyeAcco
Definition: undergroundhandlerclient.c:28
OnTriggerEnter
void OnTriggerEnter(UndergroundTrigger trigger)
Definition: undergroundhandlerclient.c:64
SetUndergroundPresence
protected void SetUndergroundPresence(UndergroundTrigger trigger)
Definition: undergroundhandlerclient.c:322
CalculateEyeAcco
protected bool CalculateEyeAcco(float timeSlice)
Definition: undergroundhandlerclient.c:267
m_InsideTriggers
protected ref set< UndergroundTrigger > m_InsideTriggers
Definition: undergroundhandlerclient.c:24
m_LightingLerpTarget
protected float m_LightingLerpTarget
Definition: undergroundhandlerclient.c:29
~UndergroundHandlerClient
void ~UndergroundHandlerClient()
Definition: undergroundhandlerclient.c:42
UNDERGROUND_LIGHTING
const string UNDERGROUND_LIGHTING
Definition: undergroundhandlerclient.c:18
m_AccoInterpolationSpeed
protected float m_AccoInterpolationSpeed
Definition: undergroundhandlerclient.c:27
EnableLights
protected void EnableLights(bool enable)
Definition: undergroundhandlerclient.c:352
Math
Definition: enmath.c:6
TRANSITIONING
@ TRANSITIONING
Definition: undergroundhandlerclient.c:5
ProcessEyeAcco
protected void ProcessEyeAcco(float timeSlice)
Definition: undergroundhandlerclient.c:175
OnUpdateTimerOut
void OnUpdateTimerOut()
Definition: undergroundhandlerclient.c:372
EUndergroundPresence
EUndergroundPresence
Definition: undergroundhandlerclient.c:1
OnUndergroundPresenceUpdate
protected void OnUndergroundPresenceUpdate(EUndergroundPresence newPresence, EUndergroundPresence oldPresence)
Definition: undergroundhandlerclient.c:382
OnTriggerInsiderUpdate
protected void OnTriggerInsiderUpdate()
Definition: undergroundhandlerclient.c:289
ARGB
int ARGB(int a, int r, int g, int b)
Definition: proto.c:322
PhxInteractionLayers
PhxInteractionLayers
Definition: dayzphysics.c:1
ACCO_MODIFIER
const float ACCO_MODIFIER
Definition: undergroundhandlerclient.c:16
OnTriggerLeave
void OnTriggerLeave(UndergroundTrigger trigger)
Definition: undergroundhandlerclient.c:71
GetRequester
protected PPERUndergroundAcco GetRequester()
Definition: undergroundhandlerclient.c:54