DayZ 1.30
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
Environment.c
См. документацию.
1#ifdef DIAG_DEVELOPER
2//#define CHECK_SHADOW_VIZ
3#endif
4
15
16enum EEnvironmentSoakingCategories
17{
18 PARENT_LIQUID = 0, // how much wetness will be transfered into child item from parent containing liquid
19 PARENT_WET = 1 // how much wetness will be transfered into child item from wet parent
20}
21
22enum EEnvironmentDryingCategories
23{
24 PLAYER = 0, // Player (Environment)
25 GROUND, = 1, // Ground (CE Update)
26 PLAYER_HEATSOURCE, = 2, // Player (Near any temperature source)
27 GROUND_HEATSOURCE = 3 // Ground (Universal Temperature Source)
28}
29
30class EnvironmentSnapshotData
31{
32 float m_ClothingHeatComfort;
33 float m_TargetHeatComfort;
34}
35
36class EnvironmentDrynessData
37{
38 bool m_UseTemperatureSources = false;
39 float m_TemperatureSourceDistance = 1.0;
40}
41
42class EnvironmentEntityData
43{
44 int m_SlotId
45
46 bool m_HasTemperature;
47
48 float m_Temperature;
49 float m_HeatComfort;
50 float m_Wetness;
51
52 ref InventoryLocation m_InventoryLocation = new InventoryLocation();
53
56}
57
58class ShadowDetectionCollisionCallback : CollisionOverlapCallback
59{
60 override bool OnContact(IEntity other, Contact contact)
61 {
62 if (other)
63 return true;
64
65 return false;
66 }
67}
72class Environment
73{
74 const float RAIN_LIMIT_LOW = 0.05;
75
76 protected const float SNOWFALL_LIMIT_LOW = 0.5;
77 protected const float SNOWFALL_WIND_COMBINED_THRESHOLD = 1.3;
78
79 protected const float HC_EXPOSED_HEAD_TO_SUN = 1.2;
80
81 const float WATER_LEVEL_HIGH = 1.5;
82 const float WATER_LEVEL_MID = 1.2;
83 const float WATER_LEVEL_LOW = 0.5;
84 const float WATER_LEVEL_NONE = 0.15;
85
86 protected float m_WetDryTick; //ticks passed since last clothing wetting or drying
87 protected float m_ItemsWetnessMax;
88 protected float m_RoofCheckTimer; // keeps info about tick time
89 protected float m_ShadowCheckTimer;
90
91 //player
92 protected PlayerBase m_Player;
93 protected float m_PlayerHeightPos; // y position of player above water level (meters)
94 protected float m_PlayerSpeed; // 1-3 speed of player movement
95 protected float m_PlayerTemperature; //34-44
96 protected float m_PlayerHeat; //3-9 heatcomfort generated by entites movement
97 protected float m_HeatComfort;
98 protected float m_TargetHeatComfort;
99 protected float m_TargetHeatComfortRaw;
100
101 //environment
102 protected float m_Rain = 0; // 0-1 amount of rain
103 protected float m_Snowfall = 0; // 0-1 amount of rain
104 protected float m_Wind = 0; // strength of wind
105 protected float m_Fog = 0; // 0-1 how foggy it is
106 protected float m_DayOrNight = 0; // 0-1 day(0) or night(1)
107 protected float m_Clouds = 0; // 0-1 how cloudy it is
108 protected float m_EnvironmentTemperature; //temperature of environment player is in
109 protected float m_Time = 0;
110 protected string m_SurfaceType;
111 protected int m_DayTime; // WorldDataDayTime
112 protected int m_LiquidType;
113
114 //item temperatures
115 protected float m_ItemTemperatureCoef;
116
117 //
118 protected float m_WaterLevel;
119 protected bool m_IsUnderRoof;
120 private bool m_IsUnderRoofBuilding;
121 protected bool m_IsInWater;
122 protected bool m_IsTempSet;
123 protected bool m_ShadowPresence;
124 //
125 protected float m_HeatBufferTimer;
126 protected float m_HeatBufferCapPrevious;
127
128 protected ref array<int> m_SlotIdsComplete;
129 protected ref array<int> m_SlotIdsUpper;
130 protected ref array<int> m_SlotIdsBottom;
131 protected ref array<int> m_SlotIdsLower;
132
133 protected ref array<int> m_HeadParts;
134 protected ref array<int> m_BodyParts;
135 protected ref array<int> m_FeetParts;
136
137 protected WorldData m_WorldData;
138
139 protected bool m_HasTemperatureSources;
140 protected float m_UTSAverageTemperature;
141 protected ref array<UTemperatureSource> m_UTemperatureSources;
142 protected ref SimpleMovingAverage<float> m_UTSAverageTemperatureBuffer;
143 protected ref SimpleMovingAverage<float> m_AverageHeatComfortBuffer;
144
145 protected int m_HeatComfortBehaviorCategory;
146
147 private bool m_Initialized;
148
149 #ifdef DIAG_DEVELOPER
150 bool m_Debug = false;
151 #endif
152
153 #ifdef ENABLE_LOGGING
154 bool m_DebugLogDryWet = false;
155 bool m_DebugLogItemHeat = false;
156 #endif
157
158 protected ref map<ItemBase, ref EnvironmentEntityData> m_EnvironmentEntityDataCache;
159
160 void Environment(PlayerBase pPlayer)
161 {
162 m_Player = pPlayer;
163 }
164
165 void Init()
166 {
167 m_PlayerSpeed = 0.0;
168 m_WetDryTick = 0.0;
169 m_RoofCheckTimer = 0.0;
170 m_WaterLevel = 0.0;
171 m_HeatComfort = m_Player.GetStatHeatComfort().Get();
172 m_WorldData = g_Game.GetMission().GetWorldData();
173 m_EnvironmentTemperature = m_WorldData.GetBaseEnvTemperatureAtObject(m_Player);
174
175 m_IsUnderRoof = false;
176 m_IsInWater = false;
177 m_SurfaceType = "cp_dirt";
178
179 m_HeatBufferTimer = 0.0;
180
181 m_UTSAverageTemperature = 0.0;
182 m_UTemperatureSources = new array<UTemperatureSource>();
183 m_UTSAverageTemperatureBuffer = new SimpleMovingAverage<float>(10, 0.0);
184 m_AverageHeatComfortBuffer = new SimpleMovingAverage<float>(20, m_HeatComfort);
185
187 m_SlotIdsComplete = new array<int>();
188 m_SlotIdsComplete = {
189 InventorySlots.HEADGEAR,
190 InventorySlots.MASK,
191 InventorySlots.EYEWEAR,
192 InventorySlots.GLOVES,
193 InventorySlots.ARMBAND,
194 InventorySlots.BODY,
195 InventorySlots.HIPS,
196 InventorySlots.VEST,
197 InventorySlots.BACK,
198 InventorySlots.LEGS,
199 InventorySlots.FEET,
200 InventorySlots.HANDS
201 };
203 m_SlotIdsUpper = new array<int>();
204 m_SlotIdsUpper = {
205 InventorySlots.GLOVES,
206 InventorySlots.ARMBAND,
207 InventorySlots.BODY,
208 InventorySlots.HIPS,
209 InventorySlots.VEST,
210 InventorySlots.BACK,
211 InventorySlots.LEGS,
212 InventorySlots.FEET,
213 InventorySlots.HANDS
214 };
216 m_SlotIdsBottom = new array<int>();
217 m_SlotIdsBottom = {
218 InventorySlots.HIPS,
219 InventorySlots.LEGS,
220 InventorySlots.FEET,
221 InventorySlots.HANDS
222 };
224 m_SlotIdsLower = new array<int>();
225 m_SlotIdsLower = {
226 InventorySlots.FEET,
227 };
228
231 m_HeadParts = new array<int>();
232 m_HeadParts = {
233 InventorySlots.HEADGEAR,
234 InventorySlots.MASK,
235 };
236
237 m_BodyParts = new array<int>();
238 m_BodyParts = {
239 InventorySlots.GLOVES,
240 InventorySlots.HIPS,
241 InventorySlots.BODY,
242 InventorySlots.BACK,
243 InventorySlots.VEST,
244 InventorySlots.MELEE,
245 InventorySlots.SHOULDER
246 };
247
248 m_FeetParts = new array<int>();
249 m_FeetParts = {
250 InventorySlots.LEGS,
251 InventorySlots.FEET,
252 };
253
254 m_HeatComfortBehaviorCategory = EEnvironmentHeatcomfortBehaviorCategory.DEFAULT;
255 m_EnvironmentSnapshot = new EnvironmentSnapshotData();
256
257 m_TargetHeatComfortRaw = 0.0;
258
259 m_EnvironmentEntityDataCache = new map<ItemBase, ref EnvironmentEntityData>();
260
261 m_Initialized = true;
262 }
263
264 // --------------------------------------------------------------------------------
265
266 protected void CachePlayerInventoryItemAttributes()
267 {
268 m_EnvironmentEntityDataCache.Clear();
269
270 EnvironmentEntityData bodyPartItemData;
271 GameInventory itemInventory;
272 GameInventory playerInventory = m_Player.GetInventory();
273
274 ItemBase itemInHands = m_Player.GetItemInHands();
275 if (itemInHands)
276 {
277 bodyPartItemData = new EnvironmentEntityData();
278 itemInventory = itemInHands.GetInventory();
279 itemInventory.GetCurrentInventoryLocation(bodyPartItemData.m_InventoryLocation);
280 bodyPartItemData.m_SlotId = bodyPartItemData.m_InventoryLocation.GetSlot();
281 bodyPartItemData.m_Wetness = itemInHands.GetWet();
282
283 bodyPartItemData.m_Attachments = ProcessAttachmentAttributes(itemInventory);
284 bodyPartItemData.m_Cargo = ProcessCargoAttributes(itemInventory);
285
286 m_EnvironmentEntityDataCache.Set(itemInHands, bodyPartItemData);
287 }
288
289 int attCount = playerInventory.AttachmentCount();
290 for (int attIdx = 0; attIdx < attCount; ++attIdx)
291 {
292 EntityAI bodyPartItem = playerInventory.GetAttachmentFromIndex(attIdx);
293 if (bodyPartItem.IsClothing())
294 {
295 bodyPartItemData = new EnvironmentEntityData();
296 ItemBase item = ItemBase.Cast(bodyPartItem);
297 itemInventory = item.GetInventory();
298 itemInventory.GetCurrentInventoryLocation(bodyPartItemData.m_InventoryLocation);
299 bodyPartItemData.m_SlotId = bodyPartItemData.m_InventoryLocation.GetSlot();
300 bodyPartItemData.m_Wetness = item.GetWet();
301
302 bodyPartItemData.m_Attachments = ProcessAttachmentAttributes(itemInventory);
303 bodyPartItemData.m_Cargo = ProcessCargoAttributes(itemInventory);
304
305 m_EnvironmentEntityDataCache.Set(ItemBase.Cast(bodyPartItem), bodyPartItemData);
306 }
307 }
308 }
309
310 // --------------------------------------------------------------------------------
311
312 private map<ItemBase, ref EnvironmentEntityData> ProcessAttachmentAttributes(GameInventory parentItemInventory)
313 {
315 int inventoryAttCount = parentItemInventory.AttachmentCount();
316 if (inventoryAttCount > 0)
317 {
318 for (int inAttIdx = 0; inAttIdx < inventoryAttCount; ++inAttIdx)
319 {
320 EntityAI inAttachment = parentItemInventory.GetAttachmentFromIndex(inAttIdx);
321 ItemBase attachmentItem = ItemBase.Cast(inAttachment);
322 EnvironmentEntityData bodyPartAttachmentData = new EnvironmentEntityData();
323 if (attachmentItem)
324 {
325 GameInventory attachmentInventory = attachmentItem.GetInventory();
326 attachmentInventory.GetCurrentInventoryLocation(bodyPartAttachmentData.m_InventoryLocation);
327 if (attachmentItem.CanHaveTemperature())
328 {
329 bodyPartAttachmentData.m_HasTemperature = true;
330 bodyPartAttachmentData.m_Temperature = attachmentItem.GetTemperature();
331 if (bodyPartAttachmentData.m_Temperature < GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_LOWER_LIMIT || bodyPartAttachmentData.m_Temperature > GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_UPPER_LIMIT)
332 bodyPartAttachmentData.m_HeatComfort = NormalizedTemperature(bodyPartAttachmentData.m_Temperature) * attachmentItem.GetQuantityNormalizedScripted() * attachmentItem.GetTemperaturePerQuantityWeight();
333
334 }
335
336 bodyPartAttachmentData.m_Wetness = attachmentItem.GetWet();
337 outData.Set(attachmentItem, bodyPartAttachmentData);
338 }
339 }
340 }
341
342 return outData;
343 }
344
345 // --------------------------------------------------------------------------------
346
347 private map<ItemBase, ref EnvironmentEntityData> ProcessCargoAttributes(GameInventory parentItemInventory)
348 {
350
351 CargoBase inventoryItemCargo = parentItemInventory.GetCargo();
352 if (inventoryItemCargo)
353 {
354 int inventoryItemCount = inventoryItemCargo.GetItemCount();
355 if (inventoryItemCount > 0)
356 {
357 for (int j = 0; j < inventoryItemCount; ++j)
358 {
359 ItemBase cargoItem = ItemBase.Cast(inventoryItemCargo.GetItem(j));
360 EnvironmentEntityData bodyPartCargoData = new EnvironmentEntityData();
361 if (cargoItem)
362 {
363 GameInventory cargoInventory = cargoItem.GetInventory();
364 cargoInventory.GetCurrentInventoryLocation(bodyPartCargoData.m_InventoryLocation);
365
366 if (cargoItem.CanHaveTemperature())
367 {
368 bodyPartCargoData.m_HasTemperature = true;
369 bodyPartCargoData.m_Temperature = cargoItem.GetTemperature();
370 if (bodyPartCargoData.m_Temperature < GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_LOWER_LIMIT || bodyPartCargoData.m_Temperature > GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_UPPER_LIMIT)
371 bodyPartCargoData.m_HeatComfort = NormalizedTemperature(bodyPartCargoData.m_Temperature) * cargoItem.GetQuantityNormalizedScripted() * cargoItem.GetTemperaturePerQuantityWeight();
372
373 }
374
375 bodyPartCargoData.m_Wetness = cargoItem.GetWet();
376 outData.Set(cargoItem, bodyPartCargoData);
377 }
378 }
379 }
380 }
381
382 return outData;
383 }
384
385 // --------------------------------------------------------------------------------
386
390 void Update(float pDelta)
391 {
392 if (m_Player && m_Initialized)
393 {
394 m_RoofCheckTimer += pDelta;
396 if ( m_RoofCheckTimer >= GameConstants.ENVIRO_TICK_ROOF_RC_CHECK )
397 {
398 if (!IsInsideBuilding())
399 CheckUnderRoof();
400 else
401 m_IsUnderRoof = true;
402
403 m_RoofCheckTimer = 0;
404 }
405
406 m_ShadowCheckTimer += pDelta;
407 if (m_ShadowCheckTimer >= GameConstants.ENVIRO_TICK_SHADOW_RC_CHECK)
408 {
409 if (IsInsideBuilding())
410 m_ShadowPresence = true;
411 else
412 CheckShadowPresence();
413
414 m_ShadowCheckTimer = 0;
415 }
416
417 m_Time += pDelta;
418 if (m_Time >= GameConstants.ENVIRO_TICK_RATE)
419 {
420 CachePlayerInventoryItemAttributes();
421
422 m_Time = 0;
423 m_WetDryTick++; // Sets whether it is time to add wetness to items and clothing
424
426 CheckWaterContact(m_WaterLevel);
427 CollectAndSetPlayerData();
428 CollectAndSetEnvironmentData();
429
430 GatherTemperatureSources();
431 ProcessTemperatureSources();
432
434 ProcessItemsTemperature(m_HeadParts);
435 ProcessItemsTemperature(m_BodyParts);
436 ProcessItemsTemperature(m_FeetParts);
437 ProcessItemsInHandsTemperature();
438
440 if (DetermineHeatcomfortBehavior())
441 SetHeatcomfortDirectly();
442 else
443 ProcessHeatComfort();
444
446 if (m_WetDryTick >= GameConstants.ENVIRO_TICKS_TO_WETNESS_CALCULATION)
447 {
448 if (IsWaterContact())
449 {
450 ProcessWetnessByWaterLevel(m_WaterLevel);
451 }
452 else if ((IsRaining() || (IsSnowing() && MiscGameplayFunctions.GetCombinedSnowfallWindValue() > SNOWFALL_WIND_COMBINED_THRESHOLD)) && !IsInsideBuilding() && !IsUnderRoof() && !IsChildOfType({Car}))
453 {
454 ProcessItemsWetness(m_SlotIdsComplete);
455 }
456 else
457 {
458 ProcessItemsDryness();
459 }
460
461 PlayerStat<int> wetnessStat = m_Player.GetStatWet();
463 if ((m_ItemsWetnessMax < GameConstants.STATE_WET) && (wetnessStat.Get() == 1))
464 {
465 wetnessStat.Set(0);
466 }
467 else if ((m_ItemsWetnessMax >= GameConstants.STATE_WET) && (wetnessStat.Get() == 0))
468 {
469 wetnessStat.Set(1);
470 }
471
472 m_WetDryTick = 0;
473 m_ItemsWetnessMax = 0;
474 }
475 }
476 }
477 }
478
479 // --------------------------------------------------------------------------------
480
484 bool IsTemperatureSet()
485 {
486 return m_IsTempSet;
487 }
488
493 protected float GetPlayerHeat()
494 {
495 float heat = m_PlayerSpeed * GameConstants.ENVIRO_DEFAULT_ENTITY_HEAT;
496 return heat;
497 }
498
503 bool IsUnderRoof()
504 {
505 return m_IsUnderRoof;
506 }
507
511 bool IsInsideBuilding()
512 {
513 return m_Player.IsSoundInsideBuilding();
514 }
515
519 bool IsInShadow()
520 {
521 return m_ShadowPresence;
522 }
523
527 protected bool IsWaterContact()
528 {
529 return m_IsInWater;
530 }
531
536 private bool IsChildOfType(array<typename> typenames)
537 {
538 Object parent = Object.Cast(m_Player.GetParent());
539 if (parent)
540 return parent.IsAnyInherited(typenames);
541
542 return false;
543 }
544
549 private bool IsUnderRoofBuilding()
550 {
551 return m_IsUnderRoofBuilding;
552 }
553
557 protected bool IsRaining()
558 {
559 return m_Rain > RAIN_LIMIT_LOW;
560 }
561
565 protected bool IsSnowing()
566 {
567 return m_Snowfall > SNOWFALL_LIMIT_LOW;
568 }
569
575 protected bool DetermineHeatcomfortBehavior()
576 {
577 m_HeatComfortBehaviorCategory = EEnvironmentHeatcomfortBehaviorCategory.DEFAULT;
578 m_TargetHeatComfortRaw = 0.0;
579
580 if (IsChildOfType({Car}))
581 {
582 CarScript car = CarScript.Cast(m_Player.GetParent());
583 if (car && car.EngineIsOn())
584 {
585 m_HeatComfortBehaviorCategory = EEnvironmentHeatcomfortBehaviorCategory.CAR_ENGINE_ON;
586 return true;
587 }
588
589 return false;
590 }
591
592 float speed;
593
594 if (IsChildOfType({Motorbike}))
595 {
596 Motorbike motorbike = Motorbike.Cast(m_Player.GetParent());
597 if (motorbike)
598 {
599 speed = Math.Round(Math.AbsFloat(motorbike.GetSpeedometerAbsolute()));
600 if (speed > GameConstants.ENVIRO_HEATCOMFORT_MOTORBIKE_SPEED_MIN)
601 {
602 m_HeatComfortBehaviorCategory = EEnvironmentHeatcomfortBehaviorCategory.MOTORBIKE;
603 return true;
604 }
605 }
606
607 return false;
608 }
609
610 if (IsChildOfType({Boat}))
611 {
612 Boat boat = Boat.Cast(m_Player.GetParent());
613 if (boat)
614 {
615 speed = Math.Round(Math.AbsFloat(boat.GetSpeedometerAbsolute()));
616 if (speed > GameConstants.ENVIRO_HEATCOMFORT_BOAT_SPEED_MIN)
617 {
618 m_HeatComfortBehaviorCategory = EEnvironmentHeatcomfortBehaviorCategory.BOAT;
619 return true;
620 }
621 }
622
623 return false;
624 }
625
626 return false;
627 }
628
629 // --------------------------------------------------------------------------------
630
634 protected void CheckUnderRoof()
635 {
637 if (IsChildOfType({Transport}))
638 {
639 m_IsUnderRoof = false;
640 m_IsUnderRoofBuilding = false;
641 return;
642 }
643
644 float hitFraction;
645 vector hitPosition, hitNormal;
646 vector from = m_Player.GetPosition();
647 vector to = from + "0 25 0";
648 Object hitObject;
649
650 PhxInteractionLayers collisionLayerMask = PhxInteractionLayers.ITEM_LARGE;
651 collisionLayerMask |= PhxInteractionLayers.BUILDING;
652 collisionLayerMask |= PhxInteractionLayers.VEHICLE;
653
654 m_IsUnderRoof = DayZPhysics.RayCastBullet(from, to, collisionLayerMask, null, hitObject, hitPosition, hitNormal, hitFraction);
655
656 m_IsUnderRoofBuilding = hitObject && hitObject.IsInherited(House);
657 }
658
659 // --------------------------------------------------------------------------------
660
665 protected void CheckShadowPresence()
666 {
667 if (IsInsideBuilding() || m_IsUnderRoof || m_IsUnderRoofBuilding)
668 {
669 m_ShadowPresence = true;
670 return;
671 }
672
673 if (IsChildOfType({Car}))
674 {
675 m_ShadowPresence = true;
676 return;
677 }
678
679 // TODO@RR move the class consts
680 float length = 50.0;
681 float radius = 0.05;
682
683 vector playerHeadPosition = MiscGameplayFunctions.GetPlayerHeadPosition(m_Player);
684
685 vector to = playerHeadPosition + -g_Game.GetWorld().GetSunOrMoonDirection() * length;
686
687 // Compute direction and distance
688 vector dir = (to - playerHeadPosition).Normalized();
689
690 // align the Y axis of the matrix to point from 'playerHeadPosition' to 'to'
691 vector up = dir; // Y axis of the matrix
692 vector forward = vector.Up; // arbitrary "up" to cross from
693 if (Math.AbsFloat(vector.Dot(forward, up)) > 0.99)
694 forward = vector.Aside; // when parallel
695
696 vector right = forward.Cross(up).Normalized(); // X axis
697 vector back = up.Cross(right).Normalized(); // Z axis
698
699 vector transform[4];
700 transform[0] = right;
701 transform[1] = up;
702 transform[2] = back;
703 transform[3] = (playerHeadPosition + to) * 0.5;
704
705 #ifdef CHECK_SHADOW_VIZ
706 Debug.DrawLine(playerHeadPosition, to, 0xff00ff00, ShapeFlags.ONCE);
707 Shape cylinder = Debug.DrawCylinder(transform[3], radius, length, ARGB(255, 0, 255, 0), ShapeFlags.ONCE|ShapeFlags.TRANSP);
708 cylinder.SetMatrix(transform);
709 #endif
710
711 PhxInteractionLayers collisionLayerMask;
712 collisionLayerMask |= PhxInteractionLayers.ITEM_LARGE;
713 collisionLayerMask |= PhxInteractionLayers.BUILDING;
714 collisionLayerMask |= PhxInteractionLayers.VEHICLE;
715 collisionLayerMask |= PhxInteractionLayers.TERRAIN;
716 collisionLayerMask |= PhxInteractionLayers.ROADWAY;
717
718 ShadowDetectionCollisionCallback callback = new ShadowDetectionCollisionCallback();
719 m_ShadowPresence = DayZPhysics.CapsuleOverlapBullet(transform, radius, length, collisionLayerMask, callback);
720 }
721
722 // --------------------------------------------------------------------------------
723
730 protected void CheckWaterContact(out float pWaterLevel)
731 {
732 m_IsInWater = false;
733
734 if (m_Player.PhysicsGetLinkedEntity() || IsChildOfType({Transport}))
735 {
736 m_Player.SetInWater(m_IsInWater);
737 return;
738 }
739
740 string surfType;
741 int liquidType;
742
743 if (m_Player.IsSwimming())
744 {
745 g_Game.SurfaceUnderObjectByBoneCorrectedLiquid(m_Player, SurfaceAnimationBone.RightFrontLimb, surfType, liquidType);
746 m_SurfaceType = surfType;
747 m_LiquidType = liquidType;
748
749 m_IsInWater = true;
750 m_Player.SetInWater(m_IsInWater);
751
752 HumanMovementState hms = new HumanMovementState();
753 m_Player.GetMovementState(hms);
754
755 pWaterLevel = WATER_LEVEL_MID;
756 if (hms.m_iMovement >= DayZPlayerConstants.MOVEMENTIDX_WALK)
757 pWaterLevel = WATER_LEVEL_HIGH;
758
759 return;
760 }
761
763 {
764 pWaterLevel = 0.0;
765 m_IsInWater = false;
766
767 return;
768 }
769
771 if (IsUnderRoofBuilding())
772 {
773 m_IsInWater = false;
774 return;
775 }
776
777 string impact;
778 g_Game.SurfaceUnderObjectExCorrectedLiquid(m_Player, surfType, impact, liquidType);
779
780 switch (liquidType)
781 {
782 case LIQUID_SALTWATER:
783 case LIQUID_WATER:
787 case LIQUID_HOTWATER:
788 pWaterLevel = Math.Max(m_Player.GetCurrentWaterLevel(), 0.0);
789 m_IsInWater = true;
790 break;
791 }
792
794 m_Player.SetInWater(m_IsInWater);
795
797 m_SurfaceType = surfType;
798 m_LiquidType = liquidType;
799
800 }
801
802 // --------------------------------------------------------------------------------
803
809 float GetWindModifierPerSurface()
810 {
811 if (IsUnderRoofBuilding())
812 return 0.0;
813
814 return g_Game.ConfigGetFloat("CfgSurfaces " + m_SurfaceType + " windModifier");
815 }
816
817 float GetTemperature()
818 {
819 return m_EnvironmentTemperature;
820 }
821
822 float GetTargetHeatComfort()
823 {
824 return m_TargetHeatComfort;
825 }
826
827 // --------------------------------------------------------------------------------
828
837 protected float GetEnvironmentTemperature()
838 {
839 float temperature = m_WorldData.GetTemperature(m_Player, EEnvironmentTemperatureComponent.ALTITUDE | EEnvironmentTemperatureComponent.OVERCAST);
840
841 if (IsWaterContact())
842 {
843 float waterBodyTemperature = m_WorldData.GetLiquidTypeEnviroTemperature(m_LiquidType);
844 temperature = waterBodyTemperature - m_WorldData.m_WaterContactTemperatureModifier;
845
846 return temperature;
847 }
848
849 if (IsInsideBuilding() || m_IsUnderRoofBuilding)
850 {
851 temperature += m_WorldData.m_TemperatureInsideBuildingsModifier;
852 }
853 else if (IsChildOfType({Car}))
854 {
855 temperature += Math.AbsFloat(temperature * GameConstants.ENVIRO_TEMPERATURE_INSIDE_VEHICLE_COEF);
856 return temperature;
857 }
858 else if (IsUnderRoof() && !m_IsUnderRoofBuilding)
859 {
861 temperature += WindEffectTemperatureValue(temperature) * GetWindModifierPerSurface() * GameConstants.ENVIRO_TEMPERATURE_UNDERROOF_COEF;
862 }
863 else
864 {
866 temperature += m_WorldData.GetTemperatureComponentValue(temperature, EEnvironmentTemperatureComponent.WIND) * GetWindModifierPerSurface();
867
868 if (!IsInShadow())
869 {
870 if (WorldDataDaytime.IsInRange(m_DayTime, m_WorldData.m_TemperatureUnderSunModifier.GetKeyArray()))
871 temperature += m_WorldData.GetSunEffectOnTemperature(m_DayTime) * HeadGearProtectionAgainstSun();
872 }
873 }
874
875 float temperaturesDiff = temperature - m_UTSAverageTemperature;
876 if (temperaturesDiff * (temperaturesDiff - temperature) > 0.0)
877 temperature = m_UTSAverageTemperature;
878
879 return temperature;
880 }
881
882 // --------------------------------------------------------------------------------
883
889 float GetWetDelta()
890 {
891 float wetDelta = 0;
892 if ( IsWaterContact() )
893 {
895 if (m_WaterLevel >= WATER_LEVEL_HIGH)
896 {
897 wetDelta = 1;
898 }
899 else if (m_WaterLevel >= WATER_LEVEL_MID && m_WaterLevel < WATER_LEVEL_HIGH)
900 {
901 wetDelta = 0.66;
902 }
903 else if (m_WaterLevel >= WATER_LEVEL_LOW && m_WaterLevel < WATER_LEVEL_MID)
904 {
905 wetDelta = 0.66;
906 }
907 else if (m_WaterLevel >= WATER_LEVEL_NONE && m_WaterLevel < WATER_LEVEL_LOW)
908 {
909 wetDelta = 0.33;
910 }
911 }
912 else if (!IsInsideBuilding() && !IsUnderRoof() && !IsChildOfType({Car}))
913 {
914 if (IsRaining())
915 wetDelta = GameConstants.ENVIRO_WET_INCREMENT * GameConstants.ENVIRO_TICKS_TO_WETNESS_CALCULATION * (m_Rain) * (1 + (GameConstants.ENVIRO_WIND_EFFECT * m_Wind));
916
917 if (IsSnowing() && MiscGameplayFunctions.GetCombinedSnowfallWindValue() > SNOWFALL_WIND_COMBINED_THRESHOLD)
918 wetDelta = GameConstants.ENVIRO_WET_INCREMENT * GameConstants.ENVIRO_TICKS_TO_WETNESS_CALCULATION * (m_Snowfall - SNOWFALL_LIMIT_LOW) * GameConstants.ENVIRO_SNOW_WET_COEF * (1 + (GameConstants.ENVIRO_WIND_EFFECT * m_Wind));
919 }
920 else
921 {
923 float tempEffect = Math.Max(m_PlayerHeat + GetEnvironmentTemperature(), 1.0);
924
925 float weatherEffect = ((1 - (m_Fog * GameConstants.ENVIRO_FOG_DRY_EFFECT))) * (1 - (m_Clouds * GameConstants.ENVIRO_CLOUD_DRY_EFFECT));
926 if (weatherEffect <= 0)
927 {
928 weatherEffect = 1.0;
929 }
930
931 wetDelta = -(GameConstants.ENVIRO_DRY_INCREMENT * weatherEffect * tempEffect);
932 if (!IsInsideBuilding())
933 {
934 wetDelta *= 1 + (GameConstants.ENVIRO_WIND_EFFECT * m_Wind);
935 }
936 }
937
938 return wetDelta;
939 }
940
941 // --------------------------------------------------------------------------------
942
949 protected void CollectAndSetPlayerData()
950 {
951 vector playerPos = m_Player.GetPosition();
952 m_PlayerHeightPos = playerPos[1];
953
954 m_PlayerSpeed = 0.0;
955
956 HumanCommandMove hcm = m_Player.GetCommand_Move();
957 if (hcm)
958 m_PlayerSpeed = hcm.GetCurrentMovementSpeed();
959
960 m_PlayerHeat = GetPlayerHeat();
961
962 }
963
964 // Each tick updates current environment member variables
968 protected void CollectAndSetEnvironmentData()
969 {
970 Weather weather = g_Game.GetWeather();
971 m_Rain = weather.GetRain().GetActual();
972 m_Snowfall = weather.GetSnowfall().GetActual();
973 m_DayTime = g_Game.GetMission().GetWorldData().GetDaytime();
974 m_DayOrNight = m_DayTime;
975 m_Fog = weather.GetFog().GetActual();
976 m_Clouds = weather.GetOvercast().GetActual();
977 m_Wind = weather.GetWindMagnitude().GetActual();
978
979 SetEnvironmentTemperature();
980 SetAreaGenericColdness();
981 }
982
983 // --------------------------------------------------------------------------------
984
985 void SetEnvironmentTemperature()
986 {
987 m_IsTempSet = true;
988 m_EnvironmentTemperature = GetEnvironmentTemperature();
989 }
990
994 void SetAreaGenericColdness()
995 {
996 float heigthCorrectedTemp = m_WorldData.GetBaseEnvTemperatureAtObject(m_Player);
997 m_Player.SetInColdArea(heigthCorrectedTemp <= GameConstants.COLD_AREA_TEMPERATURE_THRESHOLD);
998 }
999
1004 protected void ProcessWetnessByWaterLevel(float pWaterLevel)
1005 {
1006 if (pWaterLevel >= WATER_LEVEL_HIGH)
1007 ProcessItemsWetness(m_SlotIdsComplete);
1008 else if (pWaterLevel >= WATER_LEVEL_MID && pWaterLevel < WATER_LEVEL_HIGH)
1009 ProcessItemsWetness(m_SlotIdsUpper);
1010 else if (pWaterLevel >= WATER_LEVEL_LOW && pWaterLevel < WATER_LEVEL_MID)
1011 ProcessItemsWetness(m_SlotIdsBottom);
1012 else if (pWaterLevel >= WATER_LEVEL_NONE && pWaterLevel < WATER_LEVEL_LOW)
1013 ProcessItemsWetness(m_SlotIdsLower);
1014 }
1015
1016 // --------------------------------------------------------------------------------
1017
1022 protected void ProcessItemsWetness(array<int> pSlotIds)
1023 {
1024 #ifdef ENABLE_LOGGING
1025 LogDryWetProcess(string.Format("Environment :: ProcessItemsWetness (update interval=%1s)", GameConstants.ENVIRO_TICK_RATE));
1026 #endif
1027
1028 foreach (ItemBase item, EnvironmentEntityData attributes : m_EnvironmentEntityDataCache)
1029 {
1030 if (pSlotIds.Find(attributes.m_SlotId) != INDEX_NOT_FOUND )
1031 ApplyWetnessToItem(item);
1032 }
1033
1034 #ifdef ENABLE_LOGGING
1035 LogDryWetProcess("==========");
1036 #endif
1037 }
1038
1039 //protected void ApplyWetnessToItem(ItemBase pItem)
1040 protected void ApplyWetnessToItem(ItemBase pItem, EnvironmentEntityData itemAttributes = null)
1041 {
1042 EnvironmentEntityData itemData;
1043 if (pItem && !itemAttributes)
1044 itemData = m_EnvironmentEntityDataCache.Get(pItem);
1045 else if (pItem && itemAttributes)
1046 itemData = itemAttributes;
1047
1048 if (itemData)
1049 {
1050 ItemBase parentItem;
1051 bool isParentWet = false;
1052 bool parentContainsLiquid = false;
1053
1054 if (itemData.m_InventoryLocation != null)
1055 {
1056 EntityAI parent = itemData.m_InventoryLocation.GetParent();
1057 if (parent)
1058 {
1059 parentItem = ItemBase.Cast(parent);
1060 if (parentItem)
1061 {
1062 if (parentItem.GetWet() >= GameConstants.STATE_SOAKING_WET)
1063 isParentWet = true;
1064
1065 if ((parentItem.GetLiquidType() != 0) && (parentItem.GetQuantity() > 0))
1066 parentContainsLiquid = true;
1067 }
1068 else
1069 isParentWet = true;
1070
1071 if ((itemData.m_Wetness > m_ItemsWetnessMax) && (parent == m_Player))
1072 m_ItemsWetnessMax = itemData.m_Wetness;
1073 }
1074 }
1075
1076 if (isParentWet || parentContainsLiquid)
1077 {
1078 float soakingCoef = 0;
1079 if (parentContainsLiquid)
1080 {
1081 soakingCoef = pItem.GetSoakingIncrement(EEnvironmentSoakingCategories.PARENT_LIQUID);
1082 #ifdef ENABLE_LOGGING
1083 LogDryWetProcess(string.Format("%1 (soak coef=%2/s, current wetness=%3) [parent contains liquid]", pItem.GetDisplayName(), soakingCoef / GameConstants.ENVIRO_TICK_RATE, pItem.GetWet()), parentItem != null);
1084 #endif
1085 }
1086 else if (isParentWet && parentItem)
1087 {
1088 if (itemData.m_Wetness < parentItem.GetWet())
1089 soakingCoef = GetWetDelta();
1090
1091 #ifdef ENABLE_LOGGING
1092 LogDryWetProcess(string.Format("%1 (soak coef=%2/s, current wetness=%3) [parent wet]", pItem.GetDisplayName(), soakingCoef / GameConstants.ENVIRO_TICK_RATE, pItem.GetWet()), parentItem != null);
1093 #endif
1094 }
1095 else
1096 {
1097 soakingCoef = GetWetDelta();
1098 #ifdef ENABLE_LOGGING
1099 LogDryWetProcess(string.Format("%1 (soak coef=%2/s, current wetness=%3) [normal]", pItem.GetDisplayName(), soakingCoef / GameConstants.ENVIRO_TICK_RATE, pItem.GetWet()), parentItem != null);
1100 #endif
1101 }
1102
1103 pItem.AddWet(soakingCoef);
1104
1105 if (itemData.m_Attachments.Count() > 0)
1106 ApplyWetnessToItem(itemData.m_Attachments);
1107 if (itemData.m_Cargo.Count() > 0)
1108 ApplyWetnessToItem(itemData.m_Cargo);
1109 }
1110 }
1111 }
1112
1113 // --------------------------------------------------------------------------------
1114
1115 private void ApplyWetnessToItem(notnull map<ItemBase, ref EnvironmentEntityData> itemDataCached)
1116 {
1117 foreach (ItemBase item, EnvironmentEntityData itemAttributes : itemDataCached)
1118 ApplyWetnessToItem(item, itemAttributes);
1119 }
1120
1121 // --------------------------------------------------------------------------------
1122
1126 protected void ProcessItemsDryness()
1127 {
1128 #ifdef ENABLE_LOGGING
1129 LogDryWetProcess(string.Format("Environment :: ProcessItemsDryness (update interval=%1s)", GameConstants.ENVIRO_TICK_RATE));
1130 #endif
1131 EnvironmentDrynessData drynessData = new EnvironmentDrynessData();
1132 drynessData.m_UseTemperatureSources = m_HasTemperatureSources;
1133
1134 if (m_HasTemperatureSources)
1135 {
1136 float distance = vector.Distance(m_UTemperatureSources[0].GetPosition(), m_Player.GetPosition());
1137 distance = Math.Max(distance, 0.1);
1138 drynessData.m_TemperatureSourceDistance = distance;
1139 #ifdef ENABLE_LOGGING
1140 LogDryWetProcess(string.Format("distance to heatsource: %1 m", distance));
1141 #endif
1142 }
1143
1144 foreach (ItemBase item, EnvironmentEntityData attributes : m_EnvironmentEntityDataCache)
1145 ApplyDrynessToItemEx(item, drynessData);
1146
1147 #ifdef ENABLE_LOGGING
1148 LogDryWetProcess("==========");
1149 #endif
1150 }
1151
1152 protected void ApplyDrynessToItem(ItemBase pItem)
1153 {
1154 EnvironmentDrynessData drynessData = new EnvironmentDrynessData();
1155 ApplyDrynessToItemEx(pItem, drynessData);
1156 }
1157
1158 //protected void ApplyDrynessToItemEx(ItemBase pItem, EnvironmentDrynessData pDrynessData)
1159 protected void ApplyDrynessToItemEx(ItemBase pItem, EnvironmentDrynessData pDrynessData, EnvironmentEntityData itemAttributes = null)
1160 {
1161 EnvironmentEntityData itemData;
1162 if (pItem && !itemAttributes)
1163 itemData = m_EnvironmentEntityDataCache.Get(pItem);
1164 else if (pItem && itemAttributes)
1165 itemData = itemAttributes;
1166
1167 if (itemData)
1168 {
1169 float dryingIncrement = pItem.GetDryingIncrement(EEnvironmentDryingCategories.PLAYER);
1170 if (pDrynessData.m_UseTemperatureSources)
1171 dryingIncrement = pItem.GetDryingIncrement(EEnvironmentDryingCategories.PLAYER_HEATSOURCE);
1172
1173 ItemBase parentItem;
1174 bool isParentWet = false;
1175 bool parentContainsLiquid = false;
1176
1177 if (itemData.m_InventoryLocation != null)
1178 {
1179 EntityAI parent = itemData.m_InventoryLocation.GetParent();
1180 if (parent)
1181 {
1182 parentItem = ItemBase.Cast(parent);
1183 if (parentItem)
1184 {
1185 if (parentItem.GetWet() >= GameConstants.STATE_SOAKING_WET)
1186 isParentWet = true;
1187
1188 if ((parentItem.GetLiquidType() != 0) && (parentItem.GetQuantity() > 0))
1189 parentContainsLiquid = true;
1190 }
1191
1192 if ((itemData.m_Wetness > m_ItemsWetnessMax) && (parent == m_Player))
1193 m_ItemsWetnessMax = itemData.m_Wetness;
1194 }
1195 }
1196
1197 float dryingCoef = 0;
1198 float normalizedTemp = Math.Clamp(Math.InverseLerp(GameConstants.ENVIRO_LOW_TEMP_LIMIT, GameConstants.ENVIRO_HIGH_TEMP_LIMIT, GetEnvironmentTemperature()), 0.0, 2.0);
1199 float temperatureCoef = Math.Clamp(normalizedTemp * normalizedTemp * 10.5, 0.1, 4.0);
1200
1201 if (!isParentWet && !parentContainsLiquid)
1202 {
1203 dryingCoef = (-1 * GameConstants.ENVIRO_TICK_RATE * dryingIncrement * temperatureCoef) / pDrynessData.m_TemperatureSourceDistance;
1204 if (itemData.m_Wetness >= GameConstants.STATE_DAMP)
1205 {
1206 #ifdef ENABLE_LOGGING
1207 LogDryWetProcess(string.Format("%1 (dry coef=%2/s, tempCoef=%3, current wetness=%4) [normal]", pItem.GetDisplayName(), dryingCoef / GameConstants.ENVIRO_TICK_RATE, temperatureCoef, pItem.GetWet()), parentItem != null);
1208 #endif
1209 pItem.AddWet(dryingCoef);
1210 }
1211
1212 if (itemData.m_Attachments.Count() > 0)
1213 ApplyDrynessToItemEx(pDrynessData, itemData.m_Attachments);
1214 if (itemData.m_Cargo.Count() > 0)
1215 ApplyDrynessToItemEx(pDrynessData, itemData.m_Cargo);
1216 }
1217
1218 if (parentContainsLiquid)
1219 {
1221 dryingCoef = (GameConstants.ENVIRO_TICK_RATE * pItem.GetSoakingIncrement(EEnvironmentSoakingCategories.PARENT_LIQUID) * temperatureCoef) / pDrynessData.m_TemperatureSourceDistance;
1222 #ifdef ENABLE_LOGGING
1223 LogDryWetProcess(string.Format("%1 (dry coef=%2/s, tempCoef=%3, current wetness=%4) [parent contains liquid]", pItem.GetDisplayName(), dryingCoef / GameConstants.ENVIRO_TICK_RATE, temperatureCoef, pItem.GetWet()), parentItem != null);
1224 #endif
1225 pItem.AddWet(dryingCoef);
1226 }
1227
1228 if (isParentWet)
1229 {
1231 dryingCoef = (GameConstants.ENVIRO_TICK_RATE * pItem.GetSoakingIncrement(EEnvironmentSoakingCategories.PARENT_WET) * temperatureCoef) / pDrynessData.m_TemperatureSourceDistance;
1232 #ifdef ENABLE_LOGGING
1233 LogDryWetProcess(string.Format("%1 (dry coef=%2/s, tempCoef=%3, current wetness=%4) [parent wet]", pItem.GetDisplayName(), dryingCoef / GameConstants.ENVIRO_TICK_RATE, temperatureCoef, pItem.GetWet()), parentItem != null);
1234 #endif
1235 pItem.AddWet(dryingCoef);
1236 }
1237 }
1238 }
1239
1240 // --------------------------------------------------------------------------------
1241
1242 private void ApplyDrynessToItemEx(EnvironmentDrynessData pDrynessData, notnull map<ItemBase, ref EnvironmentEntityData> itemDataCached)
1243 {
1244 foreach (ItemBase item, EnvironmentEntityData itemAttributes : itemDataCached)
1245 ApplyDrynessToItemEx(item, pDrynessData, itemAttributes);
1246 }
1247
1248 // --------------------------------------------------------------------------------
1249
1253 protected void ProcessHeatComfort()
1254 {
1255 float hcPenaltyTotal
1256
1257 // NEW body parts => splitted
1258 float hcBodyPartTotal, hcBodyPart;
1259 float hBodyPartTotal, hBodyPart;
1260
1261 float heatComfortSum = 0.0;
1262 float heatItems = 0.0;
1263
1264 #ifdef ENABLE_LOGGING
1265 LogItemHeat("====================");
1266 #endif
1267 BodyPartHeatProperties(InventorySlots.HEADGEAR, GameConstants.ENVIRO_HEATCOMFORT_HEADGEAR_WEIGHT, hcBodyPart, hBodyPart);
1268 hcBodyPartTotal += hcBodyPart; hBodyPartTotal += hBodyPart;
1269 BodyPartHeatProperties(InventorySlots.MASK, GameConstants.ENVIRO_HEATCOMFORT_MASK_WEIGHT, hcBodyPart, hBodyPart);
1270 hcBodyPartTotal += hcBodyPart; hBodyPartTotal += hBodyPart;
1271 BodyPartHeatProperties(InventorySlots.VEST, GameConstants.ENVIRO_HEATCOMFORT_VEST_WEIGHT, hcBodyPart, hBodyPart);
1272 hcBodyPartTotal += hcBodyPart; hBodyPartTotal += hBodyPart;
1273 BodyPartHeatProperties(InventorySlots.BODY, GameConstants.ENVIRO_HEATCOMFORT_BODY_WEIGHT, hcBodyPart, hBodyPart);
1274 hcBodyPartTotal += hcBodyPart; hBodyPartTotal += hBodyPart;
1275 BodyPartHeatProperties(InventorySlots.BACK, GameConstants.ENVIRO_HEATCOMFORT_BACK_WEIGHT, hcBodyPart, hBodyPart);
1276 hcBodyPartTotal += hcBodyPart; hBodyPartTotal += hBodyPart;
1277 BodyPartHeatProperties(InventorySlots.GLOVES, GameConstants.ENVIRO_HEATCOMFORT_GLOVES_WEIGHT, hcBodyPart, hBodyPart);
1278 hcBodyPartTotal += hcBodyPart; hBodyPartTotal += hBodyPart;
1279 BodyPartHeatProperties(InventorySlots.LEGS, GameConstants.ENVIRO_HEATCOMFORT_LEGS_WEIGHT, hcBodyPart, hBodyPart);
1280 hcBodyPartTotal += hcBodyPart; hBodyPartTotal += hBodyPart;
1281 BodyPartHeatProperties(InventorySlots.FEET, GameConstants.ENVIRO_HEATCOMFORT_FEET_WEIGHT, hcBodyPart, hBodyPart);
1282 hcBodyPartTotal += hcBodyPart; hBodyPartTotal += hBodyPart;
1283 BodyPartHeatProperties(InventorySlots.HIPS, GameConstants.ENVIRO_HEATCOMFORT_HIPS_WEIGHT, hcBodyPart, hBodyPart);
1284 hcBodyPartTotal += hcBodyPart; hBodyPartTotal += hBodyPart;
1285
1286 hcPenaltyTotal += NakedBodyPartHeatComfortPenalty(InventorySlots.HEADGEAR, GameConstants.ENVIRO_HEATCOMFORT_HEADGEAR_WEIGHT);
1287 hcPenaltyTotal += NakedBodyPartHeatComfortPenalty(InventorySlots.MASK, GameConstants.ENVIRO_HEATCOMFORT_MASK_WEIGHT);
1288 hcPenaltyTotal += NakedBodyPartHeatComfortPenalty(InventorySlots.BODY, GameConstants.ENVIRO_HEATCOMFORT_BODY_WEIGHT);
1289 hcPenaltyTotal += NakedBodyPartHeatComfortPenalty(InventorySlots.GLOVES, GameConstants.ENVIRO_HEATCOMFORT_GLOVES_WEIGHT);
1290 hcPenaltyTotal += NakedBodyPartHeatComfortPenalty(InventorySlots.LEGS, GameConstants.ENVIRO_HEATCOMFORT_LEGS_WEIGHT);
1291 hcPenaltyTotal += NakedBodyPartHeatComfortPenalty(InventorySlots.FEET, GameConstants.ENVIRO_HEATCOMFORT_FEET_WEIGHT);
1292
1293 heatItems = hBodyPartTotal;
1294 heatComfortSum = hcBodyPartTotal;
1295 heatComfortSum += hcPenaltyTotal;
1296
1298 {
1299 if (m_Player.GetStomach().GetStomachVolume() > 0.0)
1300 {
1301 float stomachContentTemperature = m_Player.GetStomach().GetStomachTemperature();
1302 if (stomachContentTemperature < GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_LOWER_LIMIT)
1303 {
1304 stomachContentTemperature = Math.Remap(
1305 -10.0,
1306 GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_LOWER_LIMIT,
1307 -GameConstants.ENVIRO_STOMACH_WEIGHT,
1308 0.0,
1309 stomachContentTemperature,
1310 );
1311 }
1312 else if (stomachContentTemperature > GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_UPPER_LIMIT)
1313 {
1314 stomachContentTemperature = Math.Remap(
1315 GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_UPPER_LIMIT,
1316 70.0,
1317 0.0,
1318 GameConstants.ENVIRO_STOMACH_WEIGHT,
1319 stomachContentTemperature,
1320 );
1321 }
1322 else
1323 stomachContentTemperature = 0.0;
1324
1325 heatComfortSum += stomachContentTemperature * GameConstants.ENVIRO_STOMACH_WEIGHT;
1326 }
1327 }
1328
1329 float targetHeatComfort = (heatComfortSum + heatItems + (m_PlayerHeat / 100)) + EnvTempToCoef(m_EnvironmentTemperature);
1330
1332 m_EnvironmentSnapshot.m_ClothingHeatComfort = hcBodyPartTotal;
1333 m_EnvironmentSnapshot.m_TargetHeatComfort = targetHeatComfort;
1334 ProcessHeatBuffer(m_EnvironmentSnapshot);
1335
1336 if (m_Player.GetModifiersManager().IsModifierActive(eModifiers.MDF_HEATBUFFER))
1337 targetHeatComfort = Math.Clamp(targetHeatComfort, 0.0, m_Player.GetStatHeatComfort().GetMax());
1338 else
1339 targetHeatComfort = Math.Clamp(targetHeatComfort, m_Player.GetStatHeatComfort().GetMin(), m_Player.GetStatHeatComfort().GetMax());
1340
1341 targetHeatComfort = Math.Round(targetHeatComfort * 100) * 0.01;
1342
1343 float dynamicHeatComfort;
1344
1345 {
1346 float direction = 1.0;
1347 if (targetHeatComfort < 0.0)
1348 direction = -1.0;
1349
1350 if (Math.AbsFloat(targetHeatComfort - m_HeatComfort) <= GameConstants.ENVIRO_HEATCOMFORT_MAX_STEP_SIZE)
1351 dynamicHeatComfort = m_AverageHeatComfortBuffer.Add(targetHeatComfort);
1352 else
1353 dynamicHeatComfort = m_AverageHeatComfortBuffer.Add((Math.AbsFloat(targetHeatComfort) - GameConstants.ENVIRO_HEATCOMFORT_MAX_STEP_SIZE) * direction);
1354 }
1355
1356 dynamicHeatComfort = Math.Round(dynamicHeatComfort * 100) * 0.01;
1357
1358 m_HeatComfort = dynamicHeatComfort;
1359
1360 SetTargetHeatComfort(targetHeatComfort);
1361 m_Player.GetStatHeatComfort().Set(m_HeatComfort);
1362 }
1363
1364 protected void SetTargetHeatComfort(float value)
1365 {
1366 m_TargetHeatComfort = Math.Clamp(value, -1.0, 1.0);
1367 }
1368
1369 protected void SetHeatcomfortDirectly()
1370 {
1371 float targetHeatComfort = 0.0;
1372 float dynamicHeatComfort = 0.0;
1373
1374 float speed, normalizedSpeed;
1375 float heatcomfortMax;
1376 float result;
1377
1378 switch (m_HeatComfortBehaviorCategory)
1379 {
1380 case EEnvironmentHeatcomfortBehaviorCategory.CAR_ENGINE_ON:
1381 dynamicHeatComfort = m_AverageHeatComfortBuffer.Add(targetHeatComfort);
1382 m_HeatComfort = dynamicHeatComfort;
1383
1384 SetTargetHeatComfort(targetHeatComfort);
1385 m_Player.GetStatHeatComfort().Set(dynamicHeatComfort);
1386
1387 break;
1388
1390 if (m_TargetHeatComfortRaw == 0.0)
1391 {
1392 ProcessHeatComfort();
1393 m_TargetHeatComfortRaw = m_TargetHeatComfort;
1394 }
1395
1396 targetHeatComfort = m_TargetHeatComfortRaw;
1397 MotorbikeScript motorbike = MotorbikeScript.Cast(m_Player.GetParent());
1398 if (motorbike)
1399 {
1400 speed = Math.Round(Math.AbsFloat(motorbike.GetSpeedometerAbsolute()));
1401 normalizedSpeed = Math.Clamp(speed / (float)(GameConstants.ENVIRO_HEATCOMFORT_MOTORBIKE_SPEED_MAX - GameConstants.ENVIRO_HEATCOMFORT_MOTORBIKE_SPEED_MIN), 0.0, 1.0);
1402
1403 heatcomfortMax = GameConstants.ENVIRO_HEATCOMFORT_MOTORBIKE_TARGET_MAX - motorbike.GetHeatComfortOverride();
1404 result = Easing.EaseInCubic(normalizedSpeed) * heatcomfortMax;
1405 targetHeatComfort = Math.Clamp(result, -1.0, heatcomfortMax);
1406 targetHeatComfort = m_TargetHeatComfortRaw - targetHeatComfort;
1407
1408 dynamicHeatComfort = m_AverageHeatComfortBuffer.Add(targetHeatComfort);
1409 m_HeatComfort = dynamicHeatComfort;
1410
1411 SetTargetHeatComfort(targetHeatComfort);
1412 m_Player.GetStatHeatComfort().Set(dynamicHeatComfort);
1413 }
1414
1415 break;
1416
1418 if (m_TargetHeatComfortRaw == 0.0)
1419 {
1420 ProcessHeatComfort();
1421 m_TargetHeatComfortRaw = m_TargetHeatComfort;
1422 }
1423
1424 targetHeatComfort = m_TargetHeatComfortRaw;
1425 BoatScript boat = BoatScript.Cast(m_Player.GetParent());
1426 if (boat)
1427 {
1428 speed = Math.Round(Math.AbsFloat(boat.GetSpeedometerAbsolute()));
1429 normalizedSpeed = Math.Clamp(speed / (float)(GameConstants.ENVIRO_HEATCOMFORT_BOAT_SPEED_MAX - GameConstants.ENVIRO_HEATCOMFORT_BOAT_SPEED_MIN), 0.0, 1.0);
1430
1431 heatcomfortMax = GameConstants.ENVIRO_HEATCOMFORT_MOTORBIKE_TARGET_MAX - boat.GetHeatComfortOverride();
1432 result = Easing.EaseInCubic(normalizedSpeed) * heatcomfortMax;
1433 targetHeatComfort = Math.Clamp(result, -1.0, heatcomfortMax);
1434 targetHeatComfort = m_TargetHeatComfortRaw - targetHeatComfort;
1435
1436 dynamicHeatComfort = m_AverageHeatComfortBuffer.Add(targetHeatComfort);
1437 m_HeatComfort = dynamicHeatComfort;
1438
1439 SetTargetHeatComfort(targetHeatComfort);
1440 m_Player.GetStatHeatComfort().Set(dynamicHeatComfort);
1441 }
1442
1443 break;
1444 }
1445 }
1446
1447 // --------------------------------------------------------------------------------
1448
1449 protected void ProcessHeatBuffer(EnvironmentSnapshotData data)
1450 {
1451 if (m_HeatComfortBehaviorCategory == EEnvironmentHeatcomfortBehaviorCategory.DEFAULT)
1452 {
1453 float applicableHeatbuffer = GetApplicableHeatbuffer();
1454
1456 float heatBufferCap = Math.InverseLerp(0.0, GameConstants.ENVIRO_HEATCOMFORT_WEIGHT_SUMMARY, data.m_ClothingHeatComfort);
1457 float heatBufferMax = GameConstants.ENVIRO_PLAYER_HEATBUFFER_CAPACITY_MIN + heatBufferCap * (1 - GameConstants.ENVIRO_PLAYER_HEATBUFFER_CAPACITY_MIN);
1458 m_Player.SetHeatBufferDynamicMax(heatBufferMax);
1459
1460 PlayerStat<float> heatBuffer = m_Player.GetStatHeatBuffer();
1461
1463 if (heatBufferCap < m_HeatBufferCapPrevious)
1464 {
1465 float heatBufferValueCorrection = GameConstants.ENVIRO_PLAYER_HEATBUFFER_INCREASE / (heatBufferMax * ((-GameConstants.ENVIRO_PLAYER_HEATBUFFER_TEMP_AFFECT * data.m_TargetHeatComfort) + 1 ));
1466 heatBuffer.Add(-heatBufferValueCorrection);
1467 m_HeatBufferCapPrevious = heatBufferCap;
1468 }
1469
1470 float increaseRate = 0.0;
1471 float decreaseRate = 0.0;
1472
1473 {
1474 increaseRate = GameConstants.ENVIRO_PLAYER_HEATBUFFER_INCREASE / (heatBufferMax * (( -GameConstants.ENVIRO_PLAYER_HEATBUFFER_TEMP_AFFECT * data.m_TargetHeatComfort) + 1 ));
1475 decreaseRate = GameConstants.ENVIRO_PLAYER_HEATBUFFER_DECREASE / (heatBufferMax * (( GameConstants.ENVIRO_PLAYER_HEATBUFFER_TEMP_AFFECT * data.m_TargetHeatComfort) + 1 ));
1476
1477 float decreaseRateByHeatBufferStageCoef = 1;
1478
1479 if (heatBufferMax > HeatBufferMdfr.STAGE_THRESHOLDS[1])
1480 {
1481 float heatBufferMaxInversed = Math.InverseLerp(HeatBufferMdfr.STAGE_THRESHOLDS[1], 1.0, heatBufferMax);
1482 switch (m_Player.GetHeatBufferStage())
1483 {
1484 case 2:
1485 decreaseRateByHeatBufferStageCoef = Math.Lerp(
1486 GameConstants.ENVIRO_PLAYER_HEATBUFFER_STAGE_RATELIMIT[2][0],
1487 GameConstants.ENVIRO_PLAYER_HEATBUFFER_STAGE_RATELIMIT[2][1],
1488 heatBufferMaxInversed,
1489 );
1490 break;
1491 case 1:
1492 decreaseRateByHeatBufferStageCoef = Math.Lerp(
1493 GameConstants.ENVIRO_PLAYER_HEATBUFFER_STAGE_RATELIMIT[1][0],
1494 GameConstants.ENVIRO_PLAYER_HEATBUFFER_STAGE_RATELIMIT[1][1],
1495 heatBufferMaxInversed,
1496 );
1497 break;
1498 }
1499 }
1500 else
1501 {
1502 decreaseRateByHeatBufferStageCoef = GameConstants.ENVIRO_PLAYER_HEATBUFFER_STAGE_RATELIMIT[1][0];
1503 }
1504
1505 decreaseRate *= decreaseRateByHeatBufferStageCoef;
1506
1507 if (m_IsInWater)
1508 decreaseRate *= GameConstants.ENVIRO_PLAYER_HEATBUFFER_WATEREFFECT * m_WaterLevel;
1509 }
1510
1511 if (!m_HasTemperatureSources)
1512 {
1513 if (m_Player.GetModifiersManager().IsModifierActive(eModifiers.MDF_HEATBUFFER))
1514 {
1515 if (m_HeatBufferTimer >= 1.0)
1516 heatBuffer.Add(-decreaseRate);
1517 else
1518 m_HeatBufferTimer = 1.0;
1519 }
1520 else
1521 {
1522 m_HeatBufferTimer = 0.0;
1523 if (applicableHeatbuffer > 0.0)
1524 heatBuffer.Add(-decreaseRate);
1525 else if (applicableHeatbuffer != 0.0 && !m_Player.GetModifiersManager().IsModifierActive(eModifiers.MDF_HEATBUFFER))
1526 heatBuffer.Set(0.0);
1527 }
1528 }
1529 else
1530 {
1531 if (m_HeatComfort > PlayerConstants.THRESHOLD_HEAT_COMFORT_MINUS_WARNING && m_UTSAverageTemperature > 0) // m_UTSAverageTemperature can be negative
1532 {
1533 if (applicableHeatbuffer < heatBufferMax)
1534 {
1535 heatBuffer.Add(increaseRate);
1536 m_HeatBufferCapPrevious = heatBufferCap;
1537 }
1538 }
1539 else if (applicableHeatbuffer > 0.0)
1540 heatBuffer.Add(-decreaseRate);
1541 else if (applicableHeatbuffer != 0.0 && !m_Player.GetModifiersManager().IsModifierActive(eModifiers.MDF_HEATBUFFER))
1542 heatBuffer.Set(0.0);
1543
1544 m_HeatBufferTimer = 0.0;
1545 }
1546 }
1547 }
1548
1549 protected float GetApplicableHeatbuffer()
1550 {
1551 PlayerStat<float> heatBuffer = m_Player.GetStatHeatBuffer();
1552 float applicableHeatbuffer = Math.Round((heatBuffer.Get() / heatBuffer.GetMax()) * 1000) * 0.001;
1553
1554 return applicableHeatbuffer;
1555 }
1556
1557 // --------------------------------------------------------------------------------
1558
1563 protected void ProcessItemsTemperature(array<int> pBodyPartIds)
1564 {
1565 foreach (ItemBase item, EnvironmentEntityData attributes : m_EnvironmentEntityDataCache)
1566 {
1567 if (pBodyPartIds.Find(attributes.m_SlotId) != INDEX_NOT_FOUND)
1568 {
1569 float heatPermCoef = item.GetHeatPermeabilityCoef();
1570 //first handle the item itself, if necessary
1571 if (attributes.m_HasTemperature && !item.IsSelfAdjustingTemperature())
1572 SetProcessedItemTemperature(item, heatPermCoef);
1573
1574 ProcessItemHierarchyRecursive(item, heatPermCoef);
1575 }
1576 }
1577 }
1578
1582 protected void ProcessItemsInHandsTemperature()
1583 {
1584 ItemBase item = m_Player.GetItemInHands();
1585 if (item)
1586 {
1587 float heatPermCoef = item.GetHeatPermeabilityCoef();
1588 //first handle the item itself, if necessary
1589 if (item.CanHaveTemperature() && !item.IsSelfAdjustingTemperature())
1590 SetProcessedItemTemperature(item, heatPermCoef);
1591
1592 ProcessItemHierarchyRecursive(item, heatPermCoef);
1593 }
1594 }
1595
1596 protected void ProcessItemHierarchyRecursive(ItemBase item, float heatPermeabilityCoef = 1.0)
1597 {
1598 float heatPermCoef = heatPermeabilityCoef;
1599
1600 // go through any attachments and cargo, recursive
1601 EnvironmentEntityData itemData;
1602 if (m_EnvironmentEntityDataCache.Find(item, itemData))
1603 {
1604 foreach (ItemBase attachment, EnvironmentEntityData attachmentAttributes : itemData.m_Attachments)
1605 {
1606 heatPermCoef = heatPermeabilityCoef;
1607 heatPermCoef *= attachment.GetHeatPermeabilityCoef();
1608
1609 if (attachmentAttributes.m_HasTemperature && !attachment.IsSelfAdjustingTemperature())
1610 SetProcessedItemTemperature(attachment, heatPermCoef);
1611
1612 ProcessItemHierarchyRecursive(attachment, heatPermCoef);
1613 }
1614
1615 foreach (ItemBase cargo, EnvironmentEntityData cargoAttributes : itemData.m_Cargo)
1616 {
1617 heatPermCoef = heatPermeabilityCoef;
1618 heatPermCoef *= cargo.GetHeatPermeabilityCoef();
1619
1620 if (cargoAttributes.m_HasTemperature && !cargo.IsSelfAdjustingTemperature())
1621 SetProcessedItemTemperature(cargo, heatPermCoef);
1622
1623 ProcessItemHierarchyRecursive(cargo, heatPermCoef);
1624 }
1625 }
1626 }
1627
1628 protected void SetProcessedItemTemperature(ItemBase item, float heatPermeabilityCoef = 1.0)
1629 {
1630 float targetTemperature = GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_MIDDLE;
1631 bool globalCooling = true;
1633 if (m_Player.IsSwimming())
1634 {
1635 SetItemHeatingCoef(GameConstants.TEMP_COEF_SWIMMING);
1636 targetTemperature = m_WorldData.GetLiquidTypeEnviroTemperature(m_LiquidType);
1637 globalCooling = false;
1638 }
1639
1640 if (item.GetTemperature() != targetTemperature || !item.IsFreezeThawProgressFinished())
1641 {
1642 TemperatureDataInterpolated temperatureData = new TemperatureDataInterpolated(
1643 targetTemperature,
1644 ETemperatureAccessTypes.ACCESS_INVENTORY,
1645 GameConstants.ENVIRO_TICK_RATE,
1646 m_ItemTemperatureCoef,
1647 heatPermeabilityCoef,
1648 );
1649 temperatureData.m_UseGlobalCooling = globalCooling;
1650
1651 item.SetTemperatureEx(temperatureData);
1652 }
1653 }
1654
1655 // --------------------------------------------------------------------------------
1656
1657 protected float EnvTempToCoef(float pTemp)
1658 {
1659 return (pTemp - GameConstants.ENVIRO_PLAYER_COMFORT_TEMP) / GameConstants.ENVIRO_TEMP_EFFECT_ON_PLAYER;
1660 }
1661
1669 protected void BodyPartHeatProperties(int pBodyPartId, float pCoef, out float pHeatComfort, out float pHeat)
1670 {
1671 pHeatComfort = 0;
1672 pHeat = 0;
1673
1674 foreach (ItemBase item, EnvironmentEntityData attributes : m_EnvironmentEntityDataCache)
1675 {
1676 if (attributes.m_SlotId == pBodyPartId)
1677 {
1678 #ifdef ENABLE_LOGGING
1679 LogItemHeat(string.Format("BodyPartHeatProperties (%1)", EnumTools.EnumToString(InventorySlots, pBodyPartId)));
1680 #endif
1681
1682 float itemHeatcomfort = 0;
1683 float itemTemperature = 0;
1684
1685 // attachments
1686 foreach (ItemBase attachmentItem, EnvironmentEntityData attachmentAttributes : attributes.m_Attachments)
1687 {
1688 #ifdef ENABLE_LOGGING
1689 LogItemHeat(string.Format("attachments:"), false);
1690 #endif
1691 if (attachmentAttributes.m_HasTemperature)
1692 {
1693 itemTemperature = attachmentAttributes.m_Temperature;
1694 itemHeatcomfort = attachmentAttributes.m_HeatComfort;
1695 #ifdef ENABLE_LOGGING
1696 LogItemHeat(string.Format("%1: temperature=%2 heat=%3", attachmentItem, itemTemperature, pHeat), true);
1697 #endif
1698 pHeat += itemHeatcomfort;
1699 }
1700 }
1701
1702 foreach (ItemBase cargoItem, EnvironmentEntityData cargoAttributes : attributes.m_Cargo)
1703 {
1704 #ifdef ENABLE_LOGGING
1705 LogItemHeat(string.Format("cargo:"), false);
1706 #endif
1707 if (cargoAttributes.m_HasTemperature)
1708 {
1709 itemTemperature = cargoAttributes.m_Temperature;
1710 itemHeatcomfort = cargoAttributes.m_HeatComfort;
1711 #ifdef ENABLE_LOGGING
1712 LogItemHeat(string.Format("%1: temperature=%2 heat=%3", cargoItem, itemTemperature, itemHeatcomfort), true);
1713 #endif
1714 pHeat += itemHeatcomfort;
1715 }
1716 }
1717
1718 pHeatComfort = MiscGameplayFunctions.GetCurrentItemHeatIsolation(item) * pCoef;
1719
1720 #ifdef ENABLE_LOGGING
1721 LogItemHeat(string.Format("overall heat from items=%1 (coef applied)", pHeat));
1722 LogItemHeat("");
1723 #endif
1724
1725 //break;
1726 }
1727 }
1728 }
1729
1736 protected float NakedBodyPartHeatComfortPenalty(int pBodyPartSlotId, float pCoef)
1737 {
1738 float penalty = 0.0;
1739
1740 if (!IsInsideBuilding() && !IsUnderRoof() && !IsChildOfType({Car}) && !IsWaterContact())
1741 {
1742 if (m_Rain > GameConstants.ENVIRO_NAKED_BODY_PENALTY_RAIN_MIN_VALUE || m_Snowfall > GameConstants.ENVIRO_NAKED_BODY_PENALTY_SNOWFALL_MIN_VALUE)
1743 {
1744 if (m_Player.GetInventory().FindAttachment(pBodyPartSlotId))
1745 return penalty;
1746
1747 penalty += GameConstants.ENVIRO_ISOLATION_WETFACTOR_DRENCHED;
1748 penalty *= pCoef;
1749 }
1750 }
1751
1752 return penalty;
1753 }
1754
1755 // --------------------------------------------------------------------------------
1756
1760 protected void GatherTemperatureSources()
1761 {
1762 m_UTemperatureSources.Clear();
1763
1764 // Calculate min and max positions of the box
1765 vector pos = m_Player.GetPosition();
1766 vector minPos = pos - Vector(GameConstants.ENVIRO_TEMP_SOURCES_LOOKUP_RADIUS, GameConstants.ENVIRO_TEMP_SOURCES_LOOKUP_RADIUS / 2, GameConstants.ENVIRO_TEMP_SOURCES_LOOKUP_RADIUS);
1767 vector maxPos = pos + Vector(GameConstants.ENVIRO_TEMP_SOURCES_LOOKUP_RADIUS, GameConstants.ENVIRO_TEMP_SOURCES_LOOKUP_RADIUS / 2, GameConstants.ENVIRO_TEMP_SOURCES_LOOKUP_RADIUS);
1768
1769 array<EntityAI> nearestObjects = {};
1770 DayZPlayerUtils.SceneGetEntitiesInBox(minPos, maxPos, nearestObjects, QueryFlags.DYNAMIC);
1771
1772 foreach (EntityAI nearestEntity : nearestObjects)
1773 {
1774 if (nearestEntity.IsUniversalTemperatureSource() && nearestEntity != m_Player)
1775 {
1777 if (!nearestEntity.GetUniversalTemperatureSource().GetLambda().AffectsPlayer())
1778 continue;
1779
1781 if (vector.DistanceSq(pos, nearestEntity.GetPosition()) > Math.SqrFloat(nearestEntity.GetUniversalTemperatureSource().GetMaxRange()))
1782 continue;
1783
1784 m_UTemperatureSources.Insert(nearestEntity.GetUniversalTemperatureSource());
1785 }
1786 }
1787
1788 ItemBase inHandsItem = m_Player.GetItemInHands();
1789 if (inHandsItem && inHandsItem.IsUniversalTemperatureSource())
1790 m_UTemperatureSources.Insert(inHandsItem.GetUniversalTemperatureSource());
1791 }
1792
1796 protected void ProcessTemperatureSources()
1797 {
1798 int UTScount = m_UTemperatureSources.Count();
1799 if (UTScount == 0)
1800 {
1801 m_HasTemperatureSources = false;
1802 OnTemperatureSourcesLeft();
1803 m_UTSAverageTemperatureBuffer.Add(0.0);
1804 m_UTSAverageTemperature = 0.0;
1805 SetItemHeatingCoef(GameConstants.TEMP_COEF_INVENTORY);
1806
1807 return;
1808 }
1809
1810 TFloatArray utsTemperatures = new TFloatArray();
1811
1812 // get temperature from the source (based on distance), save it for min/max filtering
1813 float itemCoefAverage = 0.0;
1814 foreach (UTemperatureSource tempSource : m_UTemperatureSources)
1815 {
1816 utsTemperatures.Insert(CalcTemperatureFromTemperatureSource(tempSource));
1817 itemCoefAverage += tempSource.GetTemperatureItemCoef();
1818 }
1819 itemCoefAverage /= UTScount;
1820 SetItemHeatingCoef(itemCoefAverage);
1821
1822 float min = MiscGameplayFunctions.GetMinValue(utsTemperatures);
1823 float max = MiscGameplayFunctions.GetMaxValue(utsTemperatures);
1824
1825 if (max > 0 && min < 0)
1826 {
1828 m_UTSAverageTemperature = m_UTSAverageTemperatureBuffer.Add((max + min) * 0.5);
1829 }
1830 else
1831 {
1832 m_UTSAverageTemperature = m_UTSAverageTemperatureBuffer.Add(max);
1833 }
1834
1835 if (m_HasTemperatureSources == false)
1836 OnTemperatureSourcesEnter();
1837
1838 m_HasTemperatureSources = true;
1839 }
1840
1841 protected void SetItemHeatingCoef(float val)
1842 {
1843 m_ItemTemperatureCoef = val;
1844 }
1845
1849 protected void OnTemperatureSourcesEnter();
1850
1854 protected void OnTemperatureSourcesLeft();
1855
1856 float GetUniversalSourcesTemperageAverage()
1857 {
1858 return m_UTSAverageTemperature;
1859 }
1860
1861 float CalcTemperatureFromTemperatureSource(notnull UTemperatureSource uts)
1862 {
1863 float distance = vector.Distance(m_Player.GetPosition(), uts.GetPosition());
1864 distance = Math.Max(distance, 0.1); //min distance cannot be 0 (division by zero)
1865 float temperature = 0;
1866
1868 if (distance > uts.GetFullRange())
1869 {
1870 float distFactor = Math.InverseLerp(uts.GetMaxRange(), uts.GetFullRange(), distance);
1871 temperature = uts.GetTemperatureCap() * distFactor;
1872 }
1873 else
1874 {
1875 temperature = uts.GetTemperatureCap();
1876 }
1877
1878 return temperature;
1879 }
1880
1881 // --------------------------------------------------------------------------------
1882
1884 #ifdef DIAG_DEVELOPER
1885 EnvDebugData GetEnvDebugData()
1886 {
1887 EnvDebugData data = new EnvDebugData();
1888 data.Synch(this, m_Player);
1889 return data;
1890 }
1891
1892 void ShowEnvDebugPlayerInfo(bool enabled)
1893 {
1894 EnvDebugData data = GetEnvDebugData();
1895 DisplayEnvDebugPlayerInfo(enabled, data);
1896 }
1897
1898 static void DisplayEnvDebugPlayerInfo(bool enabled, EnvDebugData data)
1899 {
1900 int windowPosX = 10;
1901 int windowPosY = 200;
1902
1903 Object obj;
1904
1905 DbgUI.Begin("Player stats", windowPosX, windowPosY);
1906 if ( enabled )
1907 {
1908 DbgUI.Text(string.Format("Heat comfort(target): %1", data.m_PlayerData.m_HeatComfortTarget));
1909 DbgUI.Text(string.Format("Heat comfort(dynamic): %1", data.m_PlayerData.m_HeatComfortDynamic));
1910 DbgUI.Text(string.Format("Inside: %1 (%2)", data.m_PlayerData.m_Inside, data.m_PlayerData.m_Surface));
1911 DbgUI.Text(string.Format("Under roof: %1 (%2)", data.m_PlayerData.m_UnderRoof, data.m_PlayerData.m_UnderRoofTimer));
1912 if ( data.m_PlayerData.m_WaterLevel > 0 )
1913 {
1914 DbgUI.Text(string.Format("Water Level: %1", data.m_PlayerData.m_WaterLevel));
1915 }
1916
1917 }
1918 DbgUI.End();
1919
1920 DbgUI.Begin("Weather stats:", windowPosX, windowPosY + 200);
1921 if ( enabled )
1922 {
1923 DbgUI.Text(string.Format("Env temperature (base): %1", data.m_MiscData.m_TemperatureBase));
1924 DbgUI.Text(string.Format("Env temperature (height corrected): %1", data.m_MiscData.m_HeightCorrectedTemperature));
1925 DbgUI.Text(string.Format("Env temperature (modfied): %1", data.m_MiscData.m_TemperatureModified));
1926 DbgUI.Text(string.Format("Wind magnitude(surface mult): %1 (x%2)", data.m_WeatherData.m_Wind, data.m_WeatherData.m_WindModifier));
1927 DbgUI.Text(string.Format("Rain: %1", data.m_WeatherData.m_Rain));
1928 DbgUI.Text(string.Format("Snow: %1", data.m_WeatherData.m_Snowfall));
1929 DbgUI.Text(string.Format("Datetime: %1", WorldDataDaytime.ToString(g_Game.GetMission().GetWorldData().GetDaytime())));
1930 DbgUI.Text(string.Format("Fog: %1", data.m_WeatherData.m_Fog));
1931 DbgUI.Text(string.Format("Clouds: %1", data.m_WeatherData.m_Clouds));
1932 DbgUI.Text(string.Format("Wet delta: %1", data.m_MiscData.m_WetDelta));
1933 }
1934 DbgUI.End();
1935 }
1936
1937 void FillDebugWeatherData(EnvDebugWeatherData data)
1938 {
1939 data.m_Wind = m_Wind;
1940 data.m_WindModifier = GetWindModifierPerSurface();
1941 data.m_Rain = m_Rain;
1942 data.m_Snowfall = m_Snowfall;
1943 data.m_Fog = m_Fog;
1944 data.m_Clouds = m_Clouds;
1945 }
1946 #endif
1947
1948 string GetDebugMessage()
1949 {
1950 string message;
1951 message += "Player stats";
1952 message += "\nHeat comfort(target): " + GetTargetHeatComfort().ToString();
1953 message += "\nHeat comfort(dynamic): " + m_HeatComfort.ToString();
1954
1955 int liquidType;
1956 string impact, surfaceType;
1957 g_Game.SurfaceUnderObjectExCorrectedLiquid(m_Player, surfaceType, impact, liquidType);
1958
1959 bool insideBuilding = IsInsideBuilding();
1960 message += "\nInside: " + insideBuilding.ToString();
1961 message += "\nSurface: " + surfaceType;
1962 message += "\nLiquid: " + liquidType;
1963
1964 string roofCheckRemaining = GetNextRoofCheck().ToString();
1965 string shadowCheckRemaining = GetNextShadowCheck().ToString();
1966 if (insideBuilding)
1967 {
1968 roofCheckRemaining = string.Format("%1, inside override", roofCheckRemaining);
1969 shadowCheckRemaining = string.Format("%1, inside override", shadowCheckRemaining);
1970 }
1971 message += "\nUnder roof: " + m_IsUnderRoof.ToString() + " (" + roofCheckRemaining + ")";
1972 message += "\nIn Shadow: " + IsInShadow().ToString() + " (" + shadowCheckRemaining + ")";
1973
1974 if (IsWaterContact() && m_WaterLevel > WATER_LEVEL_NONE)
1975 {
1976 message += "\nWater Level: " + m_WaterLevel;
1977 }
1978
1979 message += "\n\nWeather stats";
1980 message += "\nEnv temperature (base): " + m_WorldData.GetBaseEnvTemperature().ToString();
1981 message += "\nEnv temperature (height corrected): " + m_WorldData.GetBaseEnvTemperatureAtObject(m_Player);
1982 message += "\nEnv temperature (modified): " + m_EnvironmentTemperature.ToString();
1983 message += "\nWind: " + m_Wind.ToString() + " (x" + GetWindModifierPerSurface() + ")";
1984 message += "\nRain: " + m_Rain.ToString();
1985 message += "\nSnow: " + m_Snowfall.ToString();
1986 message += "\nDaytime: " + WorldDataDaytime.ToString(m_DayTime);
1987 message += "\nFog: " + m_Fog.ToString();
1988 message += "\nClouds: " + m_Clouds.ToString();
1989 message += "\nWet delta: " + GetWetDelta().ToString();
1990
1991 return message;
1992 }
1993
1994 int GetNextRoofCheck()
1995 {
1996 return (GameConstants.ENVIRO_TICK_ROOF_RC_CHECK - m_RoofCheckTimer) + 1;
1997 }
1998
1999 int GetNextShadowCheck()
2000 {
2001 return (GameConstants.ENVIRO_TICK_SHADOW_RC_CHECK - m_ShadowCheckTimer) + 1;
2002 }
2003
2004 float GetWaterLevel()
2005 {
2006 if (IsWaterContact() && m_WaterLevel > WATER_LEVEL_NONE)
2007 {
2008 return m_WaterLevel;
2009 }
2010
2011 return 0.0;
2012 }
2013
2014 private bool IsNeutralTemperature(float temperature, float lowerLimit = GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_LOWER_LIMIT, float upperLimit = GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_UPPER_LIMIT)
2015 {
2016 if (temperature >= lowerLimit && temperature <= upperLimit)
2017 return true;
2018
2019 return false;
2020 }
2021
2022 private float NormalizedTemperature(float temperature, float lowerLimit = GameConstants.ENVIRO_LOW_TEMP_LIMIT, float upperLimit = GameConstants.ENVIRO_HIGH_TEMP_LIMIT)
2023 {
2024 if (temperature >= GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_LOWER_LIMIT && temperature <= GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_UPPER_LIMIT)
2025 return 0.0;
2026
2027 if (temperature < GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_LOWER_LIMIT)
2028 return Math.Clamp(Math.InverseLerp(lowerLimit, GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_LOWER_LIMIT, temperature), -1.0, -0.1);
2029
2030 if (temperature > GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_UPPER_LIMIT)
2031 return Math.Clamp(Math.InverseLerp(GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_UPPER_LIMIT, upperLimit, temperature), 0.1, 1.0);
2032
2033 // neutral zone
2034 return 0.0;
2035 }
2036
2037 private float HeadGearProtectionAgainstSun()
2038 {
2039 float isolation = 0;
2040 GameInventory playerInventory = m_Player.GetInventory();
2041 int attCount = playerInventory.AttachmentCount();
2042 for (int attIdx = 0; attIdx < attCount; ++attIdx)
2043 {
2044 EntityAI attachment = playerInventory.GetAttachmentFromIndex(attIdx);
2045 if (attachment.IsClothing())
2046 {
2047 ItemBase item = ItemBase.Cast(attachment);
2048 int attachmentSlot = attachment.GetInventory().GetSlotId(0);
2049
2050 if (attachmentSlot == InventorySlots.HEADGEAR)
2051 {
2052 isolation = MiscGameplayFunctions.GetCurrentItemHeatIsolation(item);
2053 }
2054 else
2055 {
2056 return HC_EXPOSED_HEAD_TO_SUN;
2057 }
2058 }
2059 }
2060
2061 if (isolation > 0)
2062 return (isolation * HC_EXPOSED_HEAD_TO_SUN) + 0.4;
2063 else
2064 return HC_EXPOSED_HEAD_TO_SUN;
2065 }
2066
2067 #ifdef ENABLE_LOGGING
2068 private void LogDryWetProcess(string message, bool indented = false)
2069 {
2070 if (m_DebugLogDryWet)
2071 {
2072 string indentation = "";
2073 if (indented)
2074 indentation = "|--";
2075
2076 Debug.Log(string.Format("%1 %2", indentation, message));
2077 }
2078 }
2079 #endif
2080
2081 #ifdef ENABLE_LOGGING
2082 private void LogItemHeat(string message, bool indented = false)
2083 {
2084 if (m_DebugLogItemHeat)
2085 {
2086 string indentation = "";
2087 if (indented)
2088 indentation = "|--";
2089
2090 Debug.Log(string.Format("%1 %2", indentation, message));
2091 }
2092 }
2093 #endif
2094
2095 // --------------------------------------------------------------------------------
2096
2098 protected float m_HeatSourceTemp;
2099 protected ref SimpleMovingAverage<float> m_WindAverageBuffer;
2100 protected ref EnvironmentSnapshotData m_EnvironmentSnapshot;
2101
2102 void Init(PlayerBase pPlayer)
2103 {
2104 Init();
2105 }
2106
2107 protected bool OverridenHeatComfort(out float value);
2108 void AddToEnvironmentTemperature(float pTemperature);
2109
2110 protected void ProcessItemsHeat()
2111 {
2112 // for backward combatibility only
2113 ProcessHeatComfort();
2114 }
2115
2116 protected void ProcessWetnessByRain()
2117 {
2118 ProcessItemsWetness(m_SlotIdsComplete);
2119 }
2120
2121 // Returns amount of deg C air temperature should be lowered by, based on player's height above water level
2122 float GetTemperatureHeightCorrection()
2123 {
2124 float temperature_reduction = Math.Max(0, (m_PlayerHeightPos * m_WorldData.m_TemperaturePerHeightReductionModifier));
2125 return temperature_reduction;
2126 }
2127
2129 protected void BodyPartHeatProperties(array<int> pBodyPartIds, float pCoef, out float pHeatComfort, out float pHeat)
2130 {
2131 pHeatComfort = 0;
2132 pHeat = 0;
2133
2134 if (pBodyPartIds.Count() > 0)
2135 {
2136 #ifdef ENABLE_LOGGING
2137 LogItemHeat(string.Format("BodyPartHeatProperties (%1)", EnumTools.EnumToString(InventorySlots, pBodyPartIds[0])));
2138 #endif
2139
2140 int attCount = m_Player.GetInventory().AttachmentCount();
2141 for (int attIdx = 0; attIdx < attCount; ++attIdx)
2142 {
2143 EntityAI attachment = m_Player.GetInventory().GetAttachmentFromIndex(attIdx);
2144 if (attachment.IsClothing())
2145 {
2146 ItemBase item = ItemBase.Cast(attachment);
2147 int attachmentSlot = attachment.GetInventory().GetSlotId(0);
2148
2150 for (int i = 0; i < pBodyPartIds.Count(); ++i)
2151 {
2152 if (attachmentSlot == pBodyPartIds[i])
2153 {
2154 float heatIsoMult = 1.0;
2155 if (attachmentSlot == InventorySlots.BACK)
2156 heatIsoMult = GameConstants.ENVIRO_HEATISOLATION_BACK_WEIGHT;
2157 else if (attachmentSlot == InventorySlots.VEST)
2158 heatIsoMult = GameConstants.ENVIRO_HEATISOLATION_VEST_WEIGHT;
2159
2160 pHeatComfort += heatIsoMult * MiscGameplayFunctions.GetCurrentItemHeatIsolation(item);
2161
2162 float itemHeatcomfort = 0;
2163 float itemTemperature = 0;
2164
2165 // go through any attachments and cargo (only current level, ignore nested containers - they isolate)
2166 int inventoryAttCount = item.GetInventory().AttachmentCount();
2167 if (inventoryAttCount > 0)
2168 {
2169 #ifdef ENABLE_LOGGING
2170 LogItemHeat(string.Format("attachments:"), false);
2171 #endif
2172 for (int inAttIdx = 0; inAttIdx < inventoryAttCount; ++inAttIdx)
2173 {
2174 EntityAI inAttachment = item.GetInventory().GetAttachmentFromIndex(inAttIdx);
2175 ItemBase attachmentItem = ItemBase.Cast(inAttachment);
2176 if (attachmentItem && attachmentItem.CanHaveTemperature())
2177 {
2178 itemTemperature = attachmentItem.GetTemperature();
2179 if (itemTemperature < GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_LOWER_LIMIT || itemTemperature > GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_UPPER_LIMIT)
2180 {
2181 itemHeatcomfort = NormalizedTemperature(itemTemperature) * attachmentItem.GetQuantityNormalizedScripted() * attachmentItem.GetTemperaturePerQuantityWeight();
2182 #ifdef ENABLE_LOGGING
2183 LogItemHeat(string.Format("%1: temperature=%2 heat=%3", attachmentItem, itemTemperature, pHeat), true);
2184 pHeat += itemHeatcomfort;
2185 #endif
2186 }
2187 }
2188 }
2189 }
2190 if (item.GetInventory().GetCargo())
2191 {
2192 int inventoryItemCount = item.GetInventory().GetCargo().GetItemCount();
2193
2194 if (inventoryItemCount > 0)
2195 {
2196 #ifdef ENABLE_LOGGING
2197 LogItemHeat(string.Format("cargo:"), false);
2198 #endif
2199 for (int j = 0; j < inventoryItemCount; ++j)
2200 {
2201 ItemBase inventoryItem = ItemBase.Cast(item.GetInventory().GetCargo().GetItem(j));
2202 if (inventoryItem && inventoryItem.CanHaveTemperature())
2203 {
2204 itemTemperature = inventoryItem.GetTemperature();
2205 if (itemTemperature < GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_LOWER_LIMIT || itemTemperature > GameConstants.ITEM_TEMPERATURE_NEUTRAL_ZONE_UPPER_LIMIT)
2206 {
2207 itemHeatcomfort = NormalizedTemperature(itemTemperature) * inventoryItem.GetQuantityNormalizedScripted() * inventoryItem.GetTemperaturePerQuantityWeight();
2208 #ifdef ENABLE_LOGGING
2209 LogItemHeat(string.Format("%1: temperature=%2 heat=%3", inventoryItem, itemTemperature, itemHeatcomfort), true);
2210 #endif
2211 pHeat += itemHeatcomfort;
2212 }
2213 }
2214 }
2215 }
2216 }
2217 }
2218 }
2219 }
2220 }
2221
2222 pHeatComfort += (pHeatComfort / pBodyPartIds.Count()) * pCoef;
2223
2224 #ifdef ENABLE_LOGGING
2225 LogItemHeat(string.Format("overall heat from items=%1 (coef applied)", pHeat));
2226 LogItemHeat("");
2227 #endif
2228 }
2229 }
2230
2231 protected void SetEnvironmentSnapshotData()
2232 {
2233 EnvironmentSnapshotData data = new EnvironmentSnapshotData();
2234 data.m_TargetHeatComfort = m_TargetHeatComfort;
2235
2236 m_EnvironmentSnapshot = data;
2237 }
2238
2240 protected void ProcessHeatBuffer(float heatComfortCloths)
2241 {
2242 m_EnvironmentSnapshot.m_ClothingHeatComfort = heatComfortCloths;
2243 m_EnvironmentSnapshot.m_TargetHeatComfort = m_TargetHeatComfort;
2244
2245 ProcessHeatBuffer(m_EnvironmentSnapshot);
2246 }
2247
2249 protected float WindEffectTemperatureValue(float temperatureInput)
2250 {
2251 float output = 0.0;
2252
2253 output = (temperatureInput - GameConstants.ENVIRO_WIND_CHILL_LIMIT) / (GameConstants.ENVIRO_WIND_EFFECT_SLOPE - GameConstants.ENVIRO_WIND_CHILL_LIMIT);
2254 output = output * m_Wind * m_WorldData.GetWindCoef();
2255
2256 return -output;
2257 }
2258
2259 float GetDayOrNight()
2260 {
2261 return m_DayTime;
2262 }
2263
2264 protected bool IsInsideVehicle()
2265 {
2266 return IsChildOfType({Car});
2267 }
2268}
2269
2270#ifdef DIAG_DEVELOPER
2271class EnvDebugPlayerData : Param
2272{
2273 float m_HeatComfortDynamic;
2274 float m_HeatComfortTarget;
2275 bool m_Inside;
2276 bool m_InShadow;
2277 string m_Surface;
2278 bool m_UnderRoof;
2279 int m_UnderRoofTimer;
2280 float m_WaterLevel;
2281
2282 void Synch(Environment env, PlayerBase player)
2283 {
2284 m_HeatComfortTarget = env.GetTargetHeatComfort();
2285 m_HeatComfortDynamic = player.GetStatHeatComfort().Get();
2286 m_Inside = env.IsInsideBuilding();
2287 m_InShadow = env.IsInShadow();
2288 m_Surface = player.GetSurfaceType();
2289 m_UnderRoof = env.IsUnderRoof();
2290 m_UnderRoofTimer = env.GetNextRoofCheck();
2291 m_WaterLevel = env.GetWaterLevel();
2292 }
2293
2294 override bool Serialize(Serializer ctx)
2295 {
2296 return (
2297 ctx.Write(m_HeatComfortTarget) && ctx.Write(m_HeatComfortDynamic) && ctx.Write(m_Inside) && ctx.Write(m_InShadow) && ctx.Write(m_Surface) && ctx.Write(m_UnderRoof) && ctx.Write(m_UnderRoofTimer) && ctx.Write(m_WaterLevel));
2298 }
2299
2300 override bool Deserializer(Serializer ctx)
2301 {
2302 return ctx.Read(m_HeatComfortTarget) && ctx.Read(m_HeatComfortDynamic) && ctx.Read(m_Inside) && ctx.Read(m_InShadow) && ctx.Read(m_Surface) && ctx.Read(m_UnderRoof) && ctx.Read(m_UnderRoofTimer) && ctx.Read(m_WaterLevel);
2303 }
2304}
2305
2306class EnvDebugMiscData : Param
2307{
2308 float m_TemperatureBase;
2309 float m_TemperatureModified;
2310 float m_HeightCorrectedTemperature;
2311 float m_WetDelta;
2312
2313 void Synch(Environment env)
2314 {
2315 m_TemperatureBase = g_Game.GetMission().GetWorldData().GetBaseEnvTemperature();
2316 m_TemperatureModified = env.GetTemperature();
2317 m_HeightCorrectedTemperature = m_TemperatureBase - env.GetTemperatureHeightCorrection();
2318 m_WetDelta = env.GetWetDelta();
2319 }
2320
2321 override bool Serialize(Serializer ctx)
2322 {
2323 return ctx.Write(m_TemperatureBase) && ctx.Write(m_TemperatureModified) && ctx.Write(m_HeightCorrectedTemperature) && ctx.Write(m_WetDelta);
2324 }
2325
2326 override bool Deserializer(Serializer ctx)
2327 {
2328 return ctx.Read(m_TemperatureBase) && ctx.Read(m_TemperatureModified) && ctx.Read(m_HeightCorrectedTemperature) && ctx.Read(m_WetDelta);
2329 }
2330}
2331
2332class EnvDebugWeatherData : Param
2333{
2334 float m_Wind;
2335 float m_WindModifier;
2336 float m_Rain;
2337 float m_Snowfall;
2338 float m_Fog;
2339 float m_Clouds;
2340
2341 void Synch(Environment env)
2342 {
2343 env.FillDebugWeatherData(this);
2344 }
2345
2346 override bool Serialize(Serializer ctx)
2347 {
2348 return ctx.Write(m_Wind) && ctx.Write(m_WindModifier) && ctx.Write(m_Rain) && ctx.Write(m_Snowfall) && ctx.Write(m_Fog) && ctx.Write(m_Clouds);
2349 }
2350
2351 override bool Deserializer(Serializer ctx)
2352 {
2353 return ctx.Read(m_Wind) && ctx.Read(m_WindModifier) && ctx.Read(m_Rain) && ctx.Read(m_Snowfall) && ctx.Read(m_Fog) && ctx.Read(m_Clouds);
2354 }
2355}
2356
2357class EnvDebugData : Param
2358{
2359 ref EnvDebugPlayerData m_PlayerData = new EnvDebugPlayerData();
2360 ref EnvDebugMiscData m_MiscData = new EnvDebugMiscData();
2361 ref EnvDebugWeatherData m_WeatherData = new EnvDebugWeatherData();
2362
2363 void Synch(Environment env, PlayerBase player)
2364 {
2365 m_PlayerData.Synch(env, player);
2366 m_MiscData.Synch(env);
2367 m_WeatherData.Synch(env);
2368 }
2369
2370 override bool Serialize(Serializer ctx)
2371 {
2372 return m_PlayerData.Serialize(ctx) && m_MiscData.Serialize(ctx) && m_WeatherData.Serialize(ctx);
2373 }
2374
2375 override bool Deserializer(Serializer ctx)
2376 {
2377 return m_PlayerData.Deserializer(ctx) && m_MiscData.Deserializer(ctx) && m_WeatherData.Deserializer(ctx);
2378 }
2379}
2380#endif
class LogManager EntityAI
void Serialize()
ObtainLiquidActionReciveData m_LiquidType
@ PLAYER
indicates if driver is controlled by player
Определения Boat.c:9
string m_SurfaceType
Определения CCTWaterSurface.c:63
string Debug()
Определения CachedEquipmentStorageBase.c:26
map
Определения ControlsXboxNew.c:4
DayZGame g_Game
Определения DayZGame.c:4074
override Widget Init()
Определения DayZGame.c:127
PhxInteractionLayers
Определения DayZPhysics.c:2
void DayZPlayerUtils()
cannot be instantiated
Определения DayZPlayerUtils.c:465
QueryFlags
Определения DayZPlayerUtils.c:2
float hitFraction
Определения DustKickupEffects.c:23
EEnvironmentTemperatureComponent
enum EEnvironmentHeatcomfortBehaviorCategory PARENT_LIQUID
EEnvironmentHeatcomfortBehaviorCategory
Categories that are changing behavior of Heat comfort processing.
Определения Environment.c:9
@ MOTORBIKE
Определения Environment.c:12
@ BOAT
Определения Environment.c:13
@ CAR_ENGINE_ON
Определения Environment.c:11
class GP5GasMask extends MaskBase ItemBase
DayZPlayer m_Player
Определения Hand_Events.c:42
string m_Surface
Определения ImpactEffects.c:17
@ GROUND
Определения InventoryLocation.c:6
static bool IsUnderRoof(EntityAI entity, float height=GameConstants.ROOF_CHECK_RAYCAST_DIST)
Определения MiscGameplayFunctions.c:1086
void MotorbikeScript()
Определения MotorbikeScript.c:105
void PlayerStat(T min, T max, T init, string label, int flags)
Определения PlayerStatBase.c:43
class PresenceNotifierNoiseEvents windowPosX
dbgUI settings
const int windowPosY
Определения PluginPresenceNotifier.c:77
ETemperatureAccessTypes
Определения TemperatureAccessConstants.c:2
void Synch(EntityAI victim)
keeping "step" here for consistency only
Определения TrapBase.c:290
bool m_Initialized
Определения UiHintPanel.c:317
float m_Temperature
Player HC target(?) value.
Определения UniversalTemperatureSource.c:34
float m_Time
Определения WoundInfection.c:22
float GetHeatComfortOverride()
Определения BoatScript.c:256
proto native int GetItemCount()
proto native EntityAI GetItem(int index)
bool OnContact(IEntity other, Contact contact)
Определения DayZPhysics.c:117
override float GetCurrentWaterLevel()
Определения DayZPlayerImplement.c:353
bool IsClimbingLadder()
Определения DayZPlayerImplement.c:478
bool IsSwimming()
Определения DayZPlayerImplement.c:473
proto native EntityAI GetAttachmentFromIndex(int index)
proto native bool GetCurrentInventoryLocation(out notnull InventoryLocation loc)
returns information about current item location
proto native CargoBase GetCargo()
cargo
proto native int AttachmentCount()
Returns count of attachments attached to this item.
proto native float GetCurrentMovementSpeed()
0,1,2..3 idle, walk, run, sprint
int m_iMovement
current stance (DayZPlayerConstants.STANCEIDX_ERECT, ...), only if the command has a stance
Определения human.c:1184
override bool IsSelfAdjustingTemperature()
Определения PortableGasStove.c:291
bool Deserializer(Serializer ctx)
Определения param.c:18
Base Param Class with no parameters. Used as general purpose parameter overloaded with Param1 to Para...
Определения param.c:12
proto bool Write(void value_out)
proto bool Read(void value_in)
proto native Fog GetFog()
Returns a fog phenomenon object.
proto native WindMagnitude GetWindMagnitude()
Returns a wind magnitude phenomenon object.
proto native Snowfall GetSnowfall()
Returns a snowfall phenomenon object.
proto native Rain GetRain()
Returns a rain phenomenon object.
proto native Overcast GetOvercast()
Returns an overcast phenomenon object.
proto native float GetActual()
float GetTemperature(Object object, EEnvironmentTemperatureComponent properties=EEnvironmentTemperatureComponent.BASE)
Return actual temperature of environment based on provided parameters.
Определения WorldData.c:312
float GetSunEffectOnTemperature(int m_DayTime)
Определения WorldData.c:355
float GetBaseEnvTemperature()
Определения WorldData.c:217
float GetBaseEnvTemperatureAtObject(notnull Object object)
Определения WorldData.c:222
float m_WaterContactTemperatureModifier
Определения WorldData.c:12
float m_TemperaturePerHeightReductionModifier
directly accesible (defined/overriden in Init())
Определения WorldData.c:8
ref map< int, float > m_TemperatureUnderSunModifier
Определения WorldData.c:11
float m_TemperatureInsideBuildingsModifier
how many % of environment temperature can be lowered by clouds
Определения WorldData.c:10
float GetWindCoef()
Определения WorldData.c:297
float GetLiquidTypeEnviroTemperature(int liquidType)
Определения WorldData.c:239
float GetTemperatureComponentValue(float temperatureIn, EEnvironmentTemperatureComponent properties=0)
Return value of queried EEnvironmentTemperatureComponent which can be used in future calculation(s)
Определения WorldData.c:337
string ToString()
Определения EnConvert.c:3
proto string ToString(bool simple=true)
proto vector Normalized()
return normalized vector (keeps orginal vector untouched)
static const vector Aside
Определения EnConvert.c:121
vector Cross(vector v)
Returns cross product of this vector with passed vector.
Определения EnConvert.c:239
static const vector Up
Определения EnConvert.c:120
DayZPlayerConstants
defined in C++
Определения dayzplayer.c:602
eModifiers
Определения eModifiers.c:2
const int INDEX_NOT_FOUND
Определения gameplay.c:13
class LOD Object
@ DEFAULT
Определения DebugTextFlags.c:9
ShapeFlags
Определения EnDebug.c:126
class DiagMenu Shape
don't call destructor directly. Use Destroy() instead
array< float > TFloatArray
Определения EnScript.c:732
const int LIQUID_STILLWATER
Определения 3_Game/DayZ/constants.c:589
const int LIQUID_HOTWATER
Определения 3_Game/DayZ/constants.c:590
const int LIQUID_FRESHWATER
Определения 3_Game/DayZ/constants.c:588
const int LIQUID_WATER
Определения 3_Game/DayZ/constants.c:578
const int LIQUID_RIVERWATER
Определения 3_Game/DayZ/constants.c:579
const int LIQUID_SALTWATER
Определения 3_Game/DayZ/constants.c:587
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
vector GetPosition()
Get the world position of the Effect.
Определения Effect.c:473
static proto string ToString(void var, bool type=false, bool name=false, bool quotes=true)
Return string representation of variable.
static proto string Format(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL)
Gets n-th character from string.
proto native volatile void Update()
Определения PlayerSoundManager.c:125
void HumanCommandMove()
Определения human.c:534
int ARGB(int a, int r, int g, int b)
Определения proto.c:322