DayZ 1.30
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
ScriptedSandstormController.c
См. документацию.
1/*
2 This class implements scripted functionality over the Sandstorm controller.
3 Note that certain functionality may be limited to server-only or client-only!
4*/
6{
7 private static const float MAX_SURFACE_DISTANCE = 2.0;
8 private static const float MAX_SURFACE_DISTANCE_INVERSE = 1.0 / MAX_SURFACE_DISTANCE;
9 private const float SURFACE_TRANSITION_DISTANCE = 10.0;
10 private static const float SURFACE_TRANSITION_FRACTION = 1.0 / MAX_SURFACE_DISTANCE;
11
12 private const float SURFACE_INTENSITY_MIN = 0;
13 private const float SURFACE_INTENSITY_MAX = 1.0;
14
15 private static const float INTERIOR_TRANSITION_DURATION = 1.5; // 1.5 seconds transition
16 private const float INTERIOR_TRANSITION_MIN = 0;
17 private const float INTERIOR_TRANSITION_MAX = 1.0;
19
20 private const ref array<typename> EXCLUDED_SHELTER_TYPES = {CrashBase, Plant};
21
23
25 private float m_StormEffectTimer;
26
29
30 private void ScriptedSandstormController() { /*Disallowed in scripts, leave to native.*/ }
31 private void ~ScriptedSandstormController() { /*Disallowed in scripts, leave to native.*/ }
32
33 private PlayerSandstormData GetPlayerData(string playerId)
34 {
35 if (!m_PlayerData.Contains(playerId))
36 {
37 m_PlayerData.Set(playerId, new PlayerSandstormData());
38 }
39 return m_PlayerData.Get(playerId);
40 }
41
43 {
44 if (!player)
45 return NULL;
46
47 PlayerSandstormData playerData;
48 PlayerIdentity identity = player.GetIdentity();
49 if (g_Game.IsMultiplayer() || g_Game.IsDedicatedServer())
50 {
51 if (!identity)
52 return NULL;
53
54 playerData = GetPlayerData(identity.GetId());
55 }
56 else // singleplayer override
57 {
58 playerData = GetPlayerData("-1");
59 }
60
61 if (!playerData)
62 {
63 if (g_Game.IsMultiplayer() || g_Game.IsDedicatedServer())
64 {
65 ErrorEx("Could not get players sandstorm data! Player UID= [" + identity.GetId() + "]", ErrorExSeverity.ERROR);
66 }
67 else
68 {
69 ErrorEx("Could not get players sandstorm data! Player UID=[-1]", ErrorExSeverity.ERROR);
70 }
71 }
72
73 return playerData;
74 }
75
76 void CleanupDisconnectedPlayer(string playerId)
77 {
78 if (m_PlayerData.Contains(playerId))
79 {
80 m_PlayerData.Remove(playerId);
81 }
82 }
83
85 {
86 array<Man> players = new array<Man>();
87 array<string> playerUIDs = new array<string>();
88
89 if (g_Game.IsMultiplayer() || g_Game.IsDedicatedServer())
90 {
91 g_Game.GetPlayers(players);
92 foreach(Man player: players)
93 {
94 if (!player)
95 continue;
96
97 PlayerIdentity identity = player.GetIdentity();
98 if (!identity)
99 continue;
100
101 string playerUIDToAdd = identity.GetId();
102 if (playerUIDs.Find(playerUIDToAdd) == -1)
103 playerUIDs.Insert(playerUIDToAdd);
104 }
105 }
106 else // singleplayer override
107 {
108 playerUIDs.Insert("-1");
109 }
110
112 for (int i = m_PlayerData.Count() - 1; i >=0; --i)
113 {
114 string playerUIDToRemove = m_PlayerData.GetKey(i);
115 if (playerUIDs.Find(playerUIDToRemove) == -1)
116 {
117 m_PlayerData.RemoveElement(i);
118 }
119 }
120
121 playerUIDs.Clear();
122 }
123
124 // Lerps 'intensity' between its outside value and 0 based on whether the player is
125 // currently in a shielding state and how far through the transition they are.
126 // progress = 0 -> no change (still fully outside / just entered)
127 // progress = 1 -> fully sheltered (intensity = 0) when entering,
128 // or fully exposed (intensity = outside) when leaving.
129 protected void ApplyShelterFade(inout float intensity, bool isCurrentlySheltered, float transitionProgress)
130 {
131 if (isCurrentlySheltered)
132 {
133 intensity = Math.Lerp(intensity, 0.0, transitionProgress);
134 }
135 else
136 {
137 intensity = Math.Lerp(0.0, intensity, transitionProgress);
138 }
139 }
140
141 // Get local sandstorm intensity value for player
142 override float GetIntensityForPlayer(Man player)
143 {
144 super.GetIntensityForPlayer(player);
145
146 if (!player)
147 return 0.0;
148
149 PlayerBase playerPB = PlayerBase.Cast(player);
150 if (!playerPB)
151 return 0.0;
152
153 vector headPosition = MiscGameplayFunctions.GetPlayerHeadPosition(playerPB);
154 float baseIntensity = GetIntensity(headPosition);
155 if (baseIntensity <= 0.0)
156 return 0.0;
157
158 // Get player-specific data
159 PlayerSandstormData playerData = GetPlayerSandstormData(playerPB);
160 if (!playerData)
161 return 0.0;
162
163 // Apply intensity modifiers in sequence - each can modify the result
164 float modifiedIntensity = baseIntensity;
165
166 // Apply underground modifier first (highest priority)
167 ApplyUndergroundModifier(modifiedIntensity, playerPB, playerData);
168
169 // If not underground, apply building modifier
170 if (modifiedIntensity > 0.0)
171 ApplyBuildingCheckModifier(modifiedIntensity, playerPB, playerData);
172
173 // If not underground or in building, apply vehicle modifier
174 if (modifiedIntensity > 0.0)
175 ApplyVehicleModifier(modifiedIntensity, playerPB, playerData);
176
177 return modifiedIntensity;
178 }
179
180 private void ApplyUndergroundModifier(inout float intensity, PlayerBase player, PlayerSandstormData playerData)
181 {
182 HumanCommandVehicle vehicleCommand = player.GetCommand_Vehicle();
183 if (vehicleCommand)
184 return;
185
186 bool isUnderground = false;
187 EUndergroundPresence presence = player.GetUndergroundPresence();
188 if (presence == EUndergroundPresence.TRANSITIONING || presence == EUndergroundPresence.FULL)
189 isUnderground = true;
190
191 float currentTime = g_Game.GetTime();
192 float elapsedTime = currentTime - playerData.m_UndergroundTransitionTimer;
194
195 ApplyShelterFade(intensity, isUnderground, transitionProgress);
196 ApplySurfaceDistanceModifier(intensity, player);
197 }
198
199 private void ApplySurfaceDistanceModifier(inout float intensity, PlayerBase player)
200 {
201 vector playerPos = player.GetPosition();
202 //float surfaceHeight = GetInterpolatedSurfaceY(playerPos[0], playerPos[2]);
203 float surfaceHeight = g_Game.SurfaceY(playerPos[0], playerPos[2]);
204
205 if (playerPos[1] < surfaceHeight)
206 {
207 float depthBelowSurface = surfaceHeight - playerPos[1];
208 float fade = Math.Clamp(depthBelowSurface * MAX_SURFACE_DISTANCE_INVERSE, 0, 1.0);
209 intensity *= (1.0 - fade);
210 }
211 }
212
213 private void ApplyBuildingCheckModifier(inout float intensity, PlayerBase player, PlayerSandstormData playerData)
214 {
215 if (!player)
216 return;
217
218 if (intensity <= 0)
219 return;
220
221 Object roofHitObj;
222 bool isUnderRoof = MiscGameplayFunctions.IsUnder(player, EXCLUDED_SHELTER_TYPES, roofHitObj, GameConstants.ROOF_CHECK_RAYCAST_DIST, ObjIntersectIFire);
223 bool isInInterior = player.IsSoundInsideBuilding();
224
225 //ErrorEx(string.Format("Under roof=%1 | In Interior=%2", isUnderRoof, isInInterior), ErrorExSeverity.INFO);
226
227 // Determine if player is currently "inside"
228 bool isCurrentlyInside = (isUnderRoof && isInInterior);
229 bool wasInside = (playerData.GetWasUnderRoof() && playerData.GetWasInInterior());
230 float currentTime = g_Game.GetTime();
231
232 // Initialize transition ONLY if building state actually changed
233 if (isCurrentlyInside != wasInside)
234 {
235 playerData.m_InteriorTransitionTimer = currentTime; // Only reset timer on state change
236 playerData.SetWasUnderRoof(isUnderRoof);
237 playerData.SetWasInInterior(isInInterior);
238 }
239
240 // If not inside and never was inside, no modification needed
241 if (!isCurrentlyInside && !wasInside)
242 return;
243
244 float elapsedTime = currentTime - playerData.m_InteriorTransitionTimer;
246
247 ApplyShelterFade(intensity, isCurrentlyInside, transitionProgress);
248 }
249
250 private void ApplyVehicleModifier(inout float intensity, PlayerBase player, PlayerSandstormData playerData)
251 {
252 if (!player)
253 return;
254
255 if (intensity <= 0)
256 return;
257
258 HumanCommandVehicle vehicleCommand = player.GetCommand_Vehicle();
259 if (!vehicleCommand)
260 return;
261
262 Transport transport = vehicleCommand.GetTransport();
263
264 // no transport or not in Car transport
265 if (!transport || transport && !transport.IsAnyInherited({Car}))
266 return;
267
268 bool isInVehicle = transport != null;
269 float currentTime = g_Game.GetTime();
270
271 // Initialize transition if vehicle state changed
272 if (isInVehicle != playerData.GetWasInVehicle())
273 {
274 playerData.m_VehicleTransitionTimer = currentTime;
275 playerData.SetWasInVehicle(isInVehicle);
276 }
277
278 float elapsedTime = currentTime - playerData.m_VehicleTransitionTimer;
280
281 ApplyShelterFade(intensity, isInVehicle, transitionProgress);
282 }
283
284 // Helper function to interpolate SurfaceY values
285 /*private float GetInterpolatedSurfaceY(float x, float z, float sampleRadius = 2.0)
286 {
287 float totalHeight = 0;
288 int validSamples = 0;
289
290 // Sample in a 3x3 grid around the point
291 for (int i = -1; i <= 1; i++)
292 {
293 for (int j = -1; j <= 1; j++)
294 {
295 float sampleX = x + (i * sampleRadius);
296 float sampleZ = z + (j * sampleRadius);
297 float height = g_Game.SurfaceY(sampleX, sampleZ);
298
299 totalHeight += height;
300 validSamples++;
301 }
302 }
303
304 return totalHeight / validSamples;
305 }*/
306
310 override void OnStart(bool continuedSession, bool calledByWeather = false)
311 {
312 super.OnStart(calledByWeather, continuedSession);
313
314 // Server is not interested in local effects like post-processing.
315 if (!g_Game || g_Game.IsDedicatedServer())
316 return;
317
318 // Clients may start their post processing effects as soon as the sandstorm starts - this may also be during join in progress so set the intensity accordingly as well.
319 m_PPESandstormRequester = PPERequester_SandstormEffect.Cast(PPERequesterBank.GetRequester(PPERequesterBank.REQ_SANDSTORMEFFECT));
320
321 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
322 if (player && m_PPESandstormRequester)
323 {
324 float localIntensity = GetIntensityForPlayer(player);
325 m_PPESandstormRequester.SetTargetIntensity(localIntensity);
327 }
328
330 m_OnSandstormStartSI.Invoke();
331 }
332
336 override void OnUpdate(float deltaTime)
337 {
338 super.OnUpdate(deltaTime);
339
340 // Server is not interested in local effects like post-processing.
341 if (!g_Game || g_Game.IsDedicatedServer())
342 return;
343
344 // Clients may update their post-processing effect and its properties
345 // on a per-tick basis, to represent the actual state closely
346 PlayerBase player = PlayerBase.Cast(g_Game.GetPlayer());
347 if (player && m_PPESandstormRequester)
348 {
349 float localIntensity = GetIntensityForPlayer(player);
350 m_PPESandstormRequester.SetTargetIntensity(localIntensity);
351 }
352 }
353
357 override void OnStop(bool calledByWeather = false)
358 {
359 super.OnStop(calledByWeather);
360
361 // Server is not interested in local effects like post-processing.
362 if (!g_Game || g_Game.IsDedicatedServer())
363 return;
364
365 // Clients may reset their post processing to default state
367 {
368 m_PPESandstormRequester.SetTargetIntensity(0);
370 }
371
373 m_OnSandstormStopSI.Invoke();
374 }
375
380
385}
DayZGame g_Game
Определения DayZGame.c:4074
EUndergroundPresence
Определения UndergroundHandlerClient.c:2
Определения Wreck_Chinook.c:2
proto native Transport GetTransport()
Определения human.c:712
Определения EnMath.c:7
Определения ObjectTyped.c:2
Определения PlayerBaseClient.c:2
proto string GetId()
unique id of player (hashed steamID, database Xbox id...) can be used in database or logs
The class that will be instanced (moddable)
Определения gameplay.c:389
bool GetWasInVehicle()
Определения PlayerSandstormData.c:28
float m_UndergroundTransitionTimer
Определения PlayerSandstormData.c:12
bool GetWasUnderRoof()
Определения PlayerSandstormData.c:38
void SetWasInInterior(bool value)
Определения PlayerSandstormData.c:53
void SetWasInVehicle(bool value)
Определения PlayerSandstormData.c:33
float m_VehicleTransitionTimer
Определения PlayerSandstormData.c:10
bool GetWasInInterior()
Определения PlayerSandstormData.c:48
void SetWasUnderRoof(bool value)
Определения PlayerSandstormData.c:43
float m_InteriorTransitionTimer
Определения PlayerSandstormData.c:11
proto native float GetIntensity(vector worldPosition)
Returns the intensity of the sandstorm at a given position in world space. The sandstorm must be acti...
void SandstormController()
Creation of SandstormController is disallowed in scripts. Retrieve current instance using Weather::Ge...
Определения Sandstorm.c:12
ScriptInvoker Class provide list of callbacks usage:
Определения 2_GameLib/DayZ/tools.c:116
ScriptInvoker GetSandstormStopSI()
Определения ScriptedSandstormController.c:381
const float SURFACE_INTENSITY_MIN
Определения ScriptedSandstormController.c:12
ref ScriptInvoker m_OnSandstormStopSI
Определения ScriptedSandstormController.c:28
static const float MAX_SURFACE_DISTANCE
Определения ScriptedSandstormController.c:7
PlayerSandstormData GetPlayerData(string playerId)
Определения ScriptedSandstormController.c:33
const ref array< typename > EXCLUDED_SHELTER_TYPES
Определения ScriptedSandstormController.c:20
PlayerSandstormData GetPlayerSandstormData(PlayerBase player)
Определения ScriptedSandstormController.c:42
static const float MAX_SURFACE_DISTANCE_INVERSE
Определения ScriptedSandstormController.c:8
void ApplyShelterFade(inout float intensity, bool isCurrentlySheltered, float transitionProgress)
Определения ScriptedSandstormController.c:129
ref ScriptInvoker m_OnSandstormStartSI
Определения ScriptedSandstormController.c:27
void ApplyUndergroundModifier(inout float intensity, PlayerBase player, PlayerSandstormData playerData)
Определения ScriptedSandstormController.c:180
const float SURFACE_TRANSITION_DISTANCE
Определения ScriptedSandstormController.c:9
override float GetIntensityForPlayer(Man player)
Определения ScriptedSandstormController.c:142
override void OnStop(bool calledByWeather=false)
Определения ScriptedSandstormController.c:357
static const float SURFACE_TRANSITION_FRACTION
Определения ScriptedSandstormController.c:10
const float INTERIOR_TRANSITION_MAX
Определения ScriptedSandstormController.c:17
void ApplySurfaceDistanceModifier(inout float intensity, PlayerBase player)
Определения ScriptedSandstormController.c:199
void CleanupDisconnectedPlayer(string playerId)
Определения ScriptedSandstormController.c:76
override void OnStart(bool continuedSession, bool calledByWeather=false)
Определения ScriptedSandstormController.c:310
static const float INTERIOR_TRANSITION_DURATION
Определения ScriptedSandstormController.c:15
const float INTERIOR_TRANSITION_MIN
Определения ScriptedSandstormController.c:16
static const float INTERIOR_TRANSITION_DURATON_FRACTION
Определения ScriptedSandstormController.c:18
const float SURFACE_INTENSITY_MAX
Определения ScriptedSandstormController.c:13
override void OnUpdate(float deltaTime)
Определения ScriptedSandstormController.c:336
void ApplyBuildingCheckModifier(inout float intensity, PlayerBase player, PlayerSandstormData playerData)
Определения ScriptedSandstormController.c:213
ref PPERequester_SandstormEffect m_PPESandstormRequester
Определения ScriptedSandstormController.c:24
void ApplyVehicleModifier(inout float intensity, PlayerBase player, PlayerSandstormData playerData)
Определения ScriptedSandstormController.c:250
ref map< string, ref PlayerSandstormData > m_PlayerData
Определения ScriptedSandstormController.c:22
ScriptInvoker GetSandstormStartSI()
Определения ScriptedSandstormController.c:376
Native class for boats - handles physics simulation.
Определения Boat.c:29
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
Определения Transport.c:70
Определения EnConvert.c:119
ErrorExSeverity
Определения EnDebug.c:62
enum ShapeType ErrorEx
const float ROOF_CHECK_RAYCAST_DIST
Определения 3_Game/DayZ/constants.c:1072
static proto float Lerp(float a, float b, float time)
Linearly interpolates between 'a' and 'b' given 'time'.
static proto float Clamp(float value, float min, float max)
Clamps 'value' to 'min' if it is lower than 'min', or to 'max' if it is higher than 'max'.