DayZ Scripts
v1.21.156300 ยท Jun 20, 2023
 
Loading...
Searching...
No Matches
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
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
18 const string UNDERGROUND_LIGHTING = "dz\\data\\lighting\\lighting_underground.txt";
20
22 private PPERUndergroundAcco m_Requester;
23 private PPERequester_CameraNV m_NVRequester;
24 private ref set<UndergroundTrigger> m_InsideTriggers = new set<UndergroundTrigger>();
25
26 private float m_EyeAccoTarget = 1;
28 private float m_EyeAcco = 1;
29 private float m_LightingLerpTarget;
30 private float m_LightingLerp;
32
33 private UndergroundTrigger m_TransitionalTrigger;
34
36 {
38 m_Player = player;
39 m_NVRequester = PPERequester_CameraNV.Cast(PPERequesterBank.GetRequester( PPERequesterBank.REQ_CAMERANV));
40 }
41
43 {
44 if (GetGame())
45 {
51 }
52 }
53
54 private 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
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 private void ProcessEyeAcco(float timeSlice)
176 {
178 bool reachedTarget = CalculateEyeAcco(timeSlice);
179 ApplyEyeAcco();
180 if(reachedTarget && !m_Player.m_UndergroundPresence)
181 {
182 GetRequester().Stop();
183 m_NVRequester.SetUndergroundExposureCoef(1.0);
184 m_Player.KillUndergroundHandler();
185 }
186
187 }
188
189 private void ProcessLighting(float timeSlice)
190 {
191 #ifdef DEVELOPER
192 if (!DiagMenu.GetBool(DiagMenuIDs.UNDERGROUND_DISABLE_DARKENING) )
193 {
195 }
196 else
197 {
199 }
200 #else
202 #endif
203 }
204
205 private void ProcessSound(float timeSlice)
206 {
208 if (m_AmbientSound)
209 {
211 //Print(m_AmbientSound.GetSoundVolume());
212 }
213 }
214
215 void Tick(float timeSlice)
216 {
217 if (!m_Player.IsAlive())
218 return;
219
220 ProcessEyeAcco(timeSlice);
221 ProcessLighting(timeSlice);
222 ProcessSound(timeSlice);
223
224 #ifdef DIAG_DEVELOPER
225 if ( DiagMenu.GetBool(DiagMenuIDs.UNDERGROUND_SHOW_BREADCRUMB) )
226 {
227 DisplayDebugInfo(GetGame().GetWorld().GetEyeAccom(), m_LightingLerp);
228 }
229 #endif
230
231 }
232
233 private void ApplyEyeAcco()
234 {
235 #ifdef DIAG_DEVELOPER
236 if (!DiagMenu.GetBool(DiagMenuIDs.UNDERGROUND_DISABLE_DARKENING) )
237 {
238 GetRequester().SetEyeAccommodation(m_EyeAcco);
239 }
240 else
241 {
242 GetRequester().SetEyeAccommodation(1);
243 }
244 #else
245 GetRequester().SetEyeAccommodation(m_EyeAcco);
246 #endif
247
248 float undergrounNVExposureCoef = m_EyeAcco;
249 if (m_LightingLerp >= 1.0 || GetDayZGame().GetWorld().IsNight())
250 {
251 undergrounNVExposureCoef = 1.0;
252 }
253 m_NVRequester.SetUndergroundExposureCoef(undergrounNVExposureCoef);
254 }
255
256 private bool CalculateEyeAcco(float timeSlice)
257 {
258 if (m_TransitionalTrigger || !m_Player.m_UndergroundPresence || (m_EyeAccoTarget == 1))
259 {
260 float accoDiff = m_EyeAccoTarget - m_EyeAcco;
261 float increase = accoDiff * m_AccoInterpolationSpeed * timeSlice;
262 m_EyeAcco += increase;
263 if (Math.AbsFloat(accoDiff) < 0.01)
264 {
266 return true;
267 }
268 }
269 else
270 {
272 }
273 return false;
274 }
275
276
277
279 {
280 EUndergroundTriggerType bestType = EUndergroundTriggerType.UNDEFINED;
282 UndergroundTrigger bestTrigger;
283 m_EyeAccoTarget = 1;
285
286 foreach (auto t:m_InsideTriggers)
287 {
288 if (t.m_Type > bestType)
289 {
290 bestTrigger = t;
291 bestType = t.m_Type;
292 }
293 }
294 //Print(m_InsideTriggers.Count());
295 //Print(bestType);
296 if (bestTrigger)
297 {
298 if (bestTrigger.m_Type == EUndergroundTriggerType.TRANSITIONING)
299 {
300 m_TransitionalTrigger = bestTrigger;
301 }
302 m_EyeAccoTarget = bestTrigger.m_Accommodation;
303 if (bestTrigger.m_InterpolationSpeed != -1 && bestTrigger.m_InterpolationSpeed != 0)
304 m_AccoInterpolationSpeed = bestTrigger.m_InterpolationSpeed;
305 }
306
307 SetUndergroundPresence(bestTrigger);
308 }
309
310
311 private void SetUndergroundPresence(UndergroundTrigger trigger)
312 {
314 EUndergroundPresence oldPresence = m_Player.m_UndergroundPresence;
315
316 if (trigger)
317 {
318 if (trigger.m_Type == EUndergroundTriggerType.OUTER)
319 {
320 newPresence = EUndergroundPresence.OUTER;
321 }
322 else if (trigger.m_Type == EUndergroundTriggerType.TRANSITIONING)
323 {
324 newPresence = EUndergroundPresence.TRANSITIONING;
325 }
326 else if (trigger.m_Type == EUndergroundTriggerType.INNER)
327 {
328 newPresence = EUndergroundPresence.FULL;
329 }
330 }
331
332 if (newPresence != oldPresence)//was there a change ?
333 {
334 OnUndergroundPresenceUpdate(newPresence,oldPresence);
335 m_Player.SetUnderground(newPresence);
336 }
337
338
339 }
340
341 private void EnableLights(bool enable)
342 {
343 foreach (ScriptedLightBase light:ScriptedLightBase.m_NightTimeOnlyLights)
344 {
345 light.SetVisibleDuringDaylight(enable);
346 }
347 }
348
350
352 {
354 return;
355 float value01 = m_AnimTimerLightBlend.GetValue();
356 float result = Easing.EaseInQuint(value01);
357 m_LightingLerp = result;
358
359 }
360
362 {
364 return;
365 float value01 = m_AnimTimerLightBlend.GetValue();
366 float result = Easing.EaseOutCubic(value01);
367 m_LightingLerp = result;
368 }
369
370
372 {
373 //Print("-----> On Undeground Presence update " + EnumTools.EnumToString(EUndergroundPresence, newPresence) + " " + EnumTools.EnumToString(EUndergroundPresence, oldPresence));
374 if (newPresence > EUndergroundPresence.NONE)
375 {
376 if (oldPresence == EUndergroundPresence.NONE)
377 {
378 EnableLights(true);
379 }
380 if (newPresence > EUndergroundPresence.OUTER && oldPresence <= EUndergroundPresence.OUTER)
381 {
383 m_Player.PlaySoundSetLoop(m_AmbientSound, "Underground_SoundSet",3,3);
384 }
385 if (newPresence == EUndergroundPresence.FULL)
386 {
388 m_AnimTimerLightBlend.Run(1, this, "OnUpdateTimerIn", "OnUpdateTimerEnd",0, false, LIGHT_BLEND_SPEED_IN);
389 }
390 }
391 if (newPresence < EUndergroundPresence.FULL && oldPresence == EUndergroundPresence.FULL)
392 {
394 m_AnimTimerLightBlend.Run(0, this, "OnUpdateTimerOut", "OnUpdateTimerEnd",m_LightingLerp, false, LIGHT_BLEND_SPEED_OUT);
395 }
396 if (newPresence <= EUndergroundPresence.OUTER && oldPresence > EUndergroundPresence.OUTER)
397 {
399 if (m_AmbientSound)
400 m_Player.StopSoundSet(m_AmbientSound);
401 }
402 if (newPresence == EUndergroundPresence.NONE && oldPresence >= EUndergroundPresence.OUTER)
403 {
405 EnableLights(false);
406 }
407 }
408
409 #ifdef DIAG_DEVELOPER
410 protected void DisplayDebugInfo(float acco, float lighting)
411 {
412 if (acco < 0.0001)
413 acco = 0;
414 DbgUI.Begin(String("Underground Areas"), 20, 20);
415 DbgUI.Text(String("Eye Accomodation: " + acco.ToString()));
416 DbgUI.Text(String("Lighting lerp: " + lighting.ToString()));
417 DbgUI.End();
418 }
419 #endif
420}
DayZGame GetDayZGame()
Definition DayZGame.c:3656
PhxInteractionLayers
Definition DayZPhysics.c:2
DiagMenuIDs
Definition EDiagMenuIDs.c:2
DayZPlayer m_Player
Definition Hand_Events.c:42
void ProcessSound()
void Tick()
void UndergroundHandlerClient(PlayerBase player)
const float DEFAULT_INTERPOLATION_SPEED
const float DISTANCE_CUTOFF
private ref set< UndergroundTrigger > m_InsideTriggers
private void CalculateEyeAccoTarget()
private void OnUndergroundPresenceUpdate(EUndergroundPresence newPresence, EUndergroundPresence oldPresence)
void OnTriggerLeave(UndergroundTrigger trigger)
const float ACCO_MODIFIER
private float m_LightingLerpTarget
private EffectSound m_AmbientSound
enum EUndergroundPresence LIGHT_BLEND_SPEED_IN
private bool CalculateEyeAcco(float timeSlice)
private ref AnimationTimer m_AnimTimerLightBlend
void OnUpdateTimerEnd()
private void OnTriggerInsiderUpdate()
private PPERequester_CameraNV m_NVRequester
const float RATIO_CUTOFF
private UndergroundTrigger m_TransitionalTrigger
private void SetUndergroundPresence(UndergroundTrigger trigger)
private float m_EyeAccoTarget
const float LIGHT_BLEND_SPEED_OUT
void ~UndergroundHandlerClient()
private void ApplyEyeAcco()
void OnTriggerEnter(UndergroundTrigger trigger)
void OnUpdateTimerIn()
void OnUpdateTimerOut()
private float m_EyeAcco
private PPERUndergroundAcco m_Requester
private void EnableLights(bool enable)
const string UNDERGROUND_LIGHTING
private float m_LightingLerp
private PPERUndergroundAcco GetRequester()
private void ProcessLighting(float timeSlice)
private float m_AccoInterpolationSpeed
const float MAX_RATIO
private void ProcessEyeAcco(float timeSlice)
AnimationTimer class. This timer is for animating float value. usage:
Definition tools.c:640
void Run(float targetVal, Managed obj, string updateFunc, string finishedFunc, float startingVal=0, bool loop=false, float speed=1.0, Param params=null, int category=CALL_CATEGORY_SYSTEM)
Definition tools.c:660
float GetValue()
Returns actual animated value.
Definition tools.c:678
proto native DayZPlayer GetPlayer()
proto native World GetWorld()
proto native Weather GetWeather()
Returns weather controller object.
static proto bool RayCastBullet(vector begPos, vector endPos, PhxInteractionLayers layerMask, Object ignoreObj, out Object hitObject, out vector hitPosition, out vector hitNormal, out float hitFraction)
Definition DbgUI.c:60
Definition Debug.c:14
static Shape DrawLine(vector from, vector to, int color=0xFFFFFFFF, int flags=0)
Definition Debug.c:361
static Shape DrawSphere(vector pos, float size=1, int color=0x1fff7f7f, ShapeFlags flags=ShapeFlags.TRANSP|ShapeFlags.NOOUTLINE)
Definition Debug.c:306
Input value between 0 and 1, returns value adjusted by easing, no automatic clamping of input(do your...
Definition Easing.c:3
static float EaseInQuint(float t)
Definition Easing.c:78
static float EaseOutCubic(float t)
Definition Easing.c:42
Wrapper class for managing sound through SEffectManager.
Definition EffectSound.c:5
void SetSoundVolume(float volume)
Set the RELATIVE volume for the sound.
override void Stop()
Stops sound.
Definition EnMath.c:7
proto native void SuppressLightningSimulation(bool state)
enables/disables thunderbolt simulation on client (together with sounds)
proto native void SetUserLightingLerp(float val)
proto native void LoadUserLightingCfg(string path, string name)
proto native void SetExplicitVolumeFactor_EnvSounds2D(float factor, float fadeTime)
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
proto string ToString()
static proto native float Distance(vector v1, vector v2)
Returns the distance between tips of two 3D vectors.
proto native CGame GetGame()
const int COLOR_RED
Definition constants.c:64
ShapeFlags
Definition EnDebug.c:126
static proto native void Begin(string windowTitle, float x=0, float y=0)
static proto native void Text(string label)
static proto native void End()
static proto bool GetBool(int id, bool reverse=false)
Get value as bool from the given script id.
string String(string s)
Helper for passing string expression to functions with void parameter. Example: Print(String("Hello "...
Definition EnScript.c:339
static proto float AbsFloat(float f)
Returns absolute value.
int ARGB(int a, int r, int g, int b)
Definition proto.c:322