DayZ Scripts
v1.21.156300 ยท Jun 20, 2023
 
Loading...
Searching...
No Matches
DayZPlayerImplementFallDamage.c
Go to the documentation of this file.
2{
4 float m_Height;
16}
17
19{
20 static const string FALL_DAMAGE_AMMO_HEALTH = "FallDamageHealth";
21 static const string FALL_DAMAGE_AMMO_SHOCK = "FallDamageShock";
22
23 static const string FALL_DAMAGE_AMMO_HEALTH_ATTACHMENT = "FallDamageHealthAttachment";
24 static const string FALL_DAMAGE_AMMO_HEALTH_OTHER_ATTACHMENTS = "FallDamageHealthOtherAttachments";
25
26 const float HEALTH_HEIGHT_LOW = 5;
27 const float HEALTH_HEIGHT_HIGH = 14;
28
29 private const float SHOCK_HEIGHT_LOW = 3;
30 private const float SHOCK_HEIGHT_HIGH = 12;
31 private const float BROKENLEGS_HEIGHT_LOW = 5;
32 private const float BROKENLEGS_HEIGHT_HIGH = 9;
33
34 private const float GLOVES_HEALTH_HEIGHT_LOW = 5;
35 private const float GLOVES_HEALTH_HEIGHT_HIGH = 15;
36 private const float SHOES_HEALTH_HEIGHT_LOW = 2;
37 private const float SHOES_HEALTH_HEIGHT_HIGH = 15;
38 private const float PANTS_HEALTH_HEIGHT_LOW = 5;
39 private const float PANTS_HEALTH_HEIGHT_HIGH = 16;
40
41 private const float BLEEDINGHANDS_HEIGHT_LOW = 5;
42 private const float BLEEDINGFEET_HEIGHT_LOW = 3;
43 private const float BLEEDINGLEGS_HEIGHT_LOW = 10;
44
45 private const float RANDOM_THRESHOLD_HEALTH_LOW = 0.05;
46 private const float RANDOM_THRESHOLD_HEALTH_HIGH = 0.1;
47 private const float RANDOM_THRESHOLD_LEGS_LOW = 0.05;
48 private const float RANDOM_THRESHOLD_LEGS_HIGH = 0.1;
49 private const float RANDOM_THRESHOLD_ATTACHMENTS_LOW = 0;
50 private const float RANDOM_THRESHOLD_ATTACHMENTS_HIGH = 0.2;
51
52 private const float BLEEDING_CHANCE_HEIGHT_LOW = 3;
53 private const float BLEEDING_CHANCE_HEIGHT_HIGH = 15;
54
55 private static const float BROKENLEGS_HEALTH_DAMAGE_MAX = 125;
56
57 private static const string BLEEDING_HANDS_SELECTIONS[2] = {"LeftForeArmRoll", "RightForeArmRoll"};
58 private static const string BLEEDING_FEET_SELECTIONS[2] = {"LeftFoot", "RightFoot"};
59 private static const string BLEEDING_LEGS_SELECTIONS[2] = {"LeftLeg", "RightLeg"};
60
61 private const int DAMAGE_TYPE_GLOBAL = 0;
62 private const int DAMAGE_TYPE_LEGS = 1;
63 private const int DAMAGE_TYPE_ATTACHMENTS = 2;
64
67
68 #ifdef DIAG_DEVELOPER
69 bool m_Debug = false;
70 private static ref map<string, float> m_AmmoTypeData;
71 #endif
72
74 {
75 m_Player = pPlayer;
77
78 #ifdef DIAG_DEVELOPER
79 PreloadAmmoTypeData();
80 #endif
81 }
82
83 float GetHeight()
84 {
86 }
87
89 {
91 }
92
94 {
95 m_FallDamageData = pData;
96
100
103
107
110
113
116
120
124
128
131
133
134 if (GetGame().IsServer())
135 {
136 PlayerBase playerBase = PlayerBase.Cast(m_Player);
137 if (playerBase)
138 {
140 DamageAttachedGear(playerBase);
142 }
143
144 vector posMS = m_Player.WorldToModel(m_Player.GetPosition());
145
146 m_Player.ProcessDirectDamage(DT_CUSTOM, m_Player, "", FALL_DAMAGE_AMMO_HEALTH, posMS, m_FallDamageData.m_HealthCoef);
147 m_Player.ProcessDirectDamage(DT_CUSTOM, m_Player, "", FALL_DAMAGE_AMMO_SHOCK, posMS, m_FallDamageData.m_ShockCoef);
148
149 if (playerBase)
150 playerBase.ForceUpdateInjuredState();
151 }
152 }
153
154 private float Randomize(int pType, float pValue)
155 {
157
158 int randomizedSign = -1;
159 if (Math.RandomIntInclusive(1, 2) % 2 == 1)
160 randomizedSign = 1;
161
162 float randomizationValue = 0;
163 switch (pType)
164 {
167 break;
168 case DAMAGE_TYPE_LEGS:
170 break;
173 break;
174 }
175
176 return pValue + (randomizedSign * pValue * randomizationValue);
177 }
178
179 private void AttachBleedingToZonesByHeight(notnull PlayerBase pPlayer)
180 {
182
183 int bleedingSelectionIndex;
184 BleedingSourcesManagerServer bleedingManager = pPlayer.GetBleedingManagerServer();
185 if (Math.RandomFloatInclusive(0.0, 1.0) <= m_FallDamageData.m_BleedingChanceCoef && m_FallDamageData.m_BleedingHandsCoef == 1.0 && pPlayer.FindAttachmentBySlotName("Gloves") == null)
186 {
187 bleedingSelectionIndex = Math.RandomInt(0, 2);
188 bleedingManager.AttemptAddBleedingSourceBySelection(BLEEDING_HANDS_SELECTIONS[bleedingSelectionIndex]);
189 }
190
191 if (Math.RandomFloatInclusive(0.0, 1.0) <= m_FallDamageData.m_BleedingChanceCoef && m_FallDamageData.m_BleedingFeetCoef == 1.0 && pPlayer.FindAttachmentBySlotName("Feet") == null)
192 {
193
194 bleedingSelectionIndex = Math.RandomInt(0, 2);
195 bleedingManager.AttemptAddBleedingSourceBySelection(BLEEDING_FEET_SELECTIONS[bleedingSelectionIndex]);
196 }
198 {
199
200 bleedingSelectionIndex = Math.RandomInt(0, 2);
201 bleedingManager.AttemptAddBleedingSourceBySelection(BLEEDING_LEGS_SELECTIONS[bleedingSelectionIndex]);
202 }
203 }
204
205 private void DamageAttachedGear(notnull PlayerBase pPlayer)
206 {
207 EntityAI gloves = pPlayer.FindAttachmentBySlotName("Gloves");
208 if (gloves)
209 gloves.ProcessDirectDamage(DT_CUSTOM, pPlayer, "", FALL_DAMAGE_AMMO_HEALTH_OTHER_ATTACHMENTS, gloves.WorldToModel(gloves.GetPosition()), m_FallDamageData.m_GlovesHealthCoef);
210
211 EntityAI shoes = pPlayer.FindAttachmentBySlotName("Feet");
212 if (shoes)
213 shoes.ProcessDirectDamage(DT_CUSTOM, pPlayer, "", FALL_DAMAGE_AMMO_HEALTH_OTHER_ATTACHMENTS, shoes.WorldToModel(shoes.GetPosition()), m_FallDamageData.m_ShoesHealthCoef);
214
215 EntityAI pants = pPlayer.FindAttachmentBySlotName("Legs");
216 if (pants)
217 pants.ProcessDirectDamage(DT_CUSTOM, pPlayer, "", FALL_DAMAGE_AMMO_HEALTH_ATTACHMENT, pants.WorldToModel(pants.GetPosition()), m_FallDamageData.m_PantsHealthCoef);
218 }
219
220#ifdef DIAG_DEVELOPER
221 FallDamageDebugData GetFallDamageDebugData()
222 {
223 FallDamageDebugData data = new FallDamageDebugData();
224 data.Synch(this);
225
226 return data;
227 }
228
229 void ShowFallDamageDebugInfo(bool enabled)
230 {
231 FallDamageDebugData data = GetFallDamageDebugData();
232 DisplayFallDamageDebugInfo(enabled, data);
233 }
234
235 private static string LandTypeToString(int landType)
236 {
237 switch (landType)
238 {
239 case 1:
240 return "LIGHT";
241 case 2:
242 return "MEDIUM";
243 case 3:
244 return "HEAVY":
245 }
246
247 return "NONE";
248 }
249
250 private void PreloadAmmoTypeData()
251 {
252 if (m_AmmoTypeData == null)
253 m_AmmoTypeData = new ref map<string, float>();
254
255 m_AmmoTypeData.Insert(FALL_DAMAGE_AMMO_HEALTH, GetValuesFromAmmoType(FALL_DAMAGE_AMMO_HEALTH)[0]);
256 m_AmmoTypeData.Insert(FALL_DAMAGE_AMMO_SHOCK, GetValuesFromAmmoType(FALL_DAMAGE_AMMO_SHOCK)[2]);
257 m_AmmoTypeData.Insert(FALL_DAMAGE_AMMO_HEALTH_OTHER_ATTACHMENTS, GetValuesFromAmmoType(FALL_DAMAGE_AMMO_HEALTH_OTHER_ATTACHMENTS)[0]);
258 m_AmmoTypeData.Insert(FALL_DAMAGE_AMMO_HEALTH_ATTACHMENT, GetValuesFromAmmoType(FALL_DAMAGE_AMMO_HEALTH_ATTACHMENT)[0]);
259 }
260
261 private vector GetValuesFromAmmoType(string pAmmoType)
262 {
263 vector values = vector.Zero;
264 values[0] = GetGame().ConfigGetFloat(string.Format("CfgAmmo %1 DamageApplied Health damage", pAmmoType));
265 values[1] = GetGame().ConfigGetFloat(string.Format("CfgAmmo %1 DamageApplied Blood damage", pAmmoType));
266 values[2] = GetGame().ConfigGetFloat(string.Format("CfgAmmo %1 DamageApplied Shock damage", pAmmoType));
267
268 return values;
269 }
270
271 static void DisplayFallDamageDebugInfo(bool enabled, FallDamageDebugData data)
272 {
273 int windowPosX = 10;
274 int windowPosY = 200;
275
276 DbgUI.Begin("Fall Damage (last)", windowPosX, windowPosY);
277 if (enabled)
278 {
279 DbgUI.Text(string.Format("Height:\t%1", Math.Clamp(data.m_Height, 0, float.MAX)));
280 DbgUI.Text(string.Format("Land Type:\t%1 (%2)", data.m_LandType, LandTypeToString(data.m_LandType)));
281 DbgUI.Text("");
282 DbgUI.Text("Health");
283 DbgUI.Text(string.Format(" coef:%1 dmg:%2", data.m_HealthCoef, m_AmmoTypeData[FALL_DAMAGE_AMMO_HEALTH] * data.m_HealthCoef));
284 DbgUI.Text("Shock");
285 DbgUI.Text(string.Format(" coef:%1 dmg:%2", data.m_ShockCoef, m_AmmoTypeData[FALL_DAMAGE_AMMO_SHOCK] * data.m_ShockCoef));
286 DbgUI.Text("Broken Legs:");
287 DbgUI.Text(string.Format(" coef:%1 dmg:%2", data.m_BrokenLegsCoef, BROKENLEGS_HEALTH_DAMAGE_MAX * data.m_BrokenLegsCoef));
288 DbgUI.Text("Gloves damage:");
289 DbgUI.Text(string.Format(" coef:%1 dmg:%2", data.m_GlovesHealthCoef, m_AmmoTypeData[FALL_DAMAGE_AMMO_HEALTH_OTHER_ATTACHMENTS] * data.m_GlovesHealthCoef));
290 DbgUI.Text("Shoes damage:");
291 DbgUI.Text(string.Format(" coef:%1 dmg:%2", data.m_ShoesHealthCoef, m_AmmoTypeData[FALL_DAMAGE_AMMO_HEALTH_OTHER_ATTACHMENTS] * data.m_ShoesHealthCoef));
292 DbgUI.Text("Pants damage:");
293 DbgUI.Text(string.Format(" coef:%1 dmg:%2" , data.m_PantsHealthCoef, m_AmmoTypeData[FALL_DAMAGE_AMMO_HEALTH_ATTACHMENT] * data.m_PantsHealthCoef));
294 DbgUI.Text("Bleeding coefs:");
295 DbgUI.Text(string.Format(" hands:%1", data.m_BleedingHandsCoef));
296 DbgUI.Text(string.Format(" feet:%1", data.m_BleedingFeetCoef));
297 DbgUI.Text(string.Format(" legs:%1", data.m_BleedingLegsCoef));
298 DbgUI.Text(string.Format(" H&F chance:%1", data.m_BleedingChanceCoef));
299
300
301 }
302 DbgUI.End();
303 }
304
305 void FillDebugFallDamageData(FallDamageDebugData data)
306 {
307 data.m_Height = m_FallDamageData.m_Height;
308 data.m_LandType = m_FallDamageData.m_LandType;
309 data.m_HealthCoef = m_FallDamageData.m_HealthCoef;
310 data.m_ShockCoef = m_FallDamageData.m_ShockCoef;
311 data.m_BrokenLegsCoef = m_FallDamageData.m_BrokenLegsCoef;
312 data.m_GlovesHealthCoef = m_FallDamageData.m_GlovesHealthCoef;
313 data.m_ShoesHealthCoef = m_FallDamageData.m_ShoesHealthCoef;
314 data.m_PantsHealthCoef = m_FallDamageData.m_PantsHealthCoef;
315
316 data.m_BleedingHandsCoef = m_FallDamageData.m_BleedingHandsCoef;
317 data.m_BleedingFeetCoef = m_FallDamageData.m_BleedingFeetCoef;
318 data.m_BleedingLegsCoef = m_FallDamageData.m_BleedingLegsCoef;
319 data.m_BleedingChanceCoef = m_FallDamageData.m_BleedingChanceCoef;
320 }
321#endif
322
326 const string FD_AMMO = "FallDamage";
327 const float FD_DMG_FROM_HEIGHT = 2.5;
328 const float FD_MAX_DMG_AT_HEIGHT = 15;
329 const float FD_MAX_HEIGHT_LEG_BREAK = 8;
330
331 void HandleFallDamage(float pHeight);
332 float DamageCoef(float pHeight);
333}
334
335#ifdef DIAG_DEVELOPER
336class FallDamageDebugData : Param
337{
338 int m_LandType;
339 float m_Height;
340 float m_HealthCoef;
341 float m_ShockCoef;
342 float m_BrokenLegsCoef;
343 float m_GlovesHealthCoef;
344 float m_ShoesHealthCoef;
345 float m_PantsHealthCoef;
346 float m_BleedingHandsCoef;
347 float m_BleedingFeetCoef;
348 float m_BleedingLegsCoef;
349 float m_BleedingChanceCoef;
350
351 void Synch(DayZPlayerImplementFallDamage fallDamage)
352 {
353 m_Height = fallDamage.GetHeight();
354 m_LandType = fallDamage.GetLandType();
355
356 fallDamage.FillDebugFallDamageData(this);
357 }
358
359 override bool Serialize(Serializer ctx)
360 {
361 return ctx.Write(m_Height) && ctx.Write(m_LandType) && ctx.Write(m_HealthCoef) && ctx.Write(m_ShockCoef) && ctx.Write(m_BrokenLegsCoef) && ctx.Write(m_GlovesHealthCoef) && ctx.Write(m_ShoesHealthCoef) && ctx.Write(m_PantsHealthCoef) && ctx.Write(m_BleedingHandsCoef) && ctx.Write(m_BleedingFeetCoef) && ctx.Write(m_BleedingLegsCoef);
362 }
363
364 override bool Deserializer(Serializer ctx)
365 {
366 return ctx.Read(m_Height) && ctx.Read(m_LandType) && ctx.Read(m_HealthCoef) && ctx.Read(m_ShockCoef) && ctx.Write(m_BrokenLegsCoef) && ctx.Read(m_GlovesHealthCoef) && ctx.Read(m_ShoesHealthCoef) && ctx.Read(m_PantsHealthCoef) && ctx.Read(m_BleedingHandsCoef) && ctx.Read(m_BleedingFeetCoef) && ctx.Read(m_BleedingLegsCoef);
367 }
368}
369#endif
void Serialize()
Definition Inventory.c:190
class FallDamageData FALL_DAMAGE_AMMO_HEALTH
static private const string BLEEDING_LEGS_SELECTIONS[2]
private const float SHOCK_HEIGHT_HIGH
const float FD_DMG_FROM_HEIGHT
damage will not be taken into account bellow this HeightToDamage
private const float RANDOM_THRESHOLD_HEALTH_LOW
private const float BLEEDINGFEET_HEIGHT_LOW
private const float BLEEDINGLEGS_HEIGHT_LOW
static const string FALL_DAMAGE_AMMO_HEALTH_OTHER_ATTACHMENTS
const float HEALTH_HEIGHT_LOW
private const float SHOES_HEALTH_HEIGHT_LOW
private const float PANTS_HEALTH_HEIGHT_HIGH
void DayZPlayerImplementFallDamage(DayZPlayer pPlayer)
private ref FallDamageData m_FallDamageData
private const float BROKENLEGS_HEIGHT_LOW
private const int DAMAGE_TYPE_ATTACHMENTS
private const float RANDOM_THRESHOLD_LEGS_HIGH
const float FD_MAX_HEIGHT_LEG_BREAK
height where legs break most of the time
const float FD_MAX_DMG_AT_HEIGHT
height where player gets 100% damage
private const float BLEEDING_CHANCE_HEIGHT_LOW
private const float BLEEDINGHANDS_HEIGHT_LOW
static const string FALL_DAMAGE_AMMO_SHOCK
static const string FALL_DAMAGE_AMMO_HEALTH_ATTACHMENT
private void AttachBleedingToZonesByHeight(notnull PlayerBase pPlayer)
private const float GLOVES_HEALTH_HEIGHT_HIGH
private const int DAMAGE_TYPE_GLOBAL
private const float BLEEDING_CHANCE_HEIGHT_HIGH
private void DamageAttachedGear(notnull PlayerBase pPlayer)
static private const float BROKENLEGS_HEALTH_DAMAGE_MAX
private const float RANDOM_THRESHOLD_ATTACHMENTS_HIGH
private const float GLOVES_HEALTH_HEIGHT_LOW
float DamageCoef(float pHeight)
void HandleFallDamage(FallDamageData pData)
const string FD_AMMO
ammo type used for damaging
private const float BROKENLEGS_HEIGHT_HIGH
private const int DAMAGE_TYPE_LEGS
private const float RANDOM_THRESHOLD_HEALTH_HIGH
static private const string BLEEDING_HANDS_SELECTIONS[2]
private float Randomize(int pType, float pValue)
private const float RANDOM_THRESHOLD_ATTACHMENTS_LOW
private const float SHOCK_HEIGHT_LOW
private const float SHOES_HEALTH_HEIGHT_HIGH
private const float PANTS_HEALTH_HEIGHT_LOW
private const float RANDOM_THRESHOLD_LEGS_LOW
static private const string BLEEDING_FEET_SELECTIONS[2]
const float HEALTH_HEIGHT_HIGH
DayZPlayer m_Player
Definition Hand_Events.c:42
static protected int m_Height
float GetTime()
class PresenceNotifierNoiseEvents windowPosX
dbgUI settings
const int windowPosY
protected bool m_Debug
protected void Synch(EntityAI victim)
keeping "step" here for consistency only
Definition TrapBase.c:306
proto native float ConfigGetFloat(string path)
Get float value from config on path.
Definition DbgUI.c:60
Definition EnMath.c:7
Base Param Class with no parameters. Used as general purpose parameter overloaded with Param1 to Para...
Definition param.c:12
bool Deserializer(Serializer ctx)
Definition param.c:18
Serialization general interface. Serializer API works with:
Definition Serializer.c:56
proto bool Write(void value_out)
proto bool Read(void value_in)
static const vector Zero
Definition EnConvert.c:110
proto native CGame GetGame()
static proto native void Begin(string windowTitle, float x=0, float y=0)
static proto native void Text(string label)
static proto native void End()
static proto int RandomInt(int min, int max)
Returns a random int number between and min [inclusive] and max [exclusive].
static proto int Randomize(int seed)
Sets the seed for the random number generator.
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'.
static proto float InverseLerp(float a, float b, float value)
Calculates the linear value that produces the interpolant value within the range [a,...
static float RandomFloatInclusive(float min, float max)
Returns a random float number between and min [inclusive] and max [inclusive].
Definition EnMath.c:86
static int RandomIntInclusive(int min, int max)
Returns a random int number between and min [inclusive] and max [inclusive].
Definition EnMath.c:53