injuryhandler.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. class InjuryHandlerThresholds
  2. {
  3. const float WORN = 0.5;
  4. const float DAMAGED = 0.3;
  5. const float BADLY_DAMAGED = 0.2;
  6. const float RUINED = 0.1;
  7. };
  8. class InjuryAnimValues
  9. {
  10. const float LVL0 = 0;
  11. const float LVL1 = 0.3;
  12. const float LVL2 = 0.6;
  13. const float LVL3 = 0.8;
  14. const float LVL4 = 1;
  15. };
  16. enum eInjuryHandlerLevels
  17. {
  18. PRISTINE,
  19. WORN,
  20. DAMAGED,
  21. BADLY_DAMAGED,
  22. RUINED,
  23. }
  24. enum eInjuryOverrides
  25. {
  26. //! MUST BE POW2
  27. NONE = 0,
  28. MORPHINE = 1,
  29. PAIN_KILLERS_LVL0 = 2,
  30. PAIN_KILLERS_LVL1 = 4,
  31. BROKEN_LEGS = 8, //New
  32. BROKEN_LEGS_SPLINT = 16, //New
  33. PRONE_ANIM_OVERRIDE = 32, //Prevent non pristine animation when prone
  34. }
  35. class InjuryAnimationHandler
  36. {
  37. const float VALUE_CHECK_INTERVAL = 5;
  38. const float SENSITIVTY_PERCENTAGE = 1; //how much the value needs to change up/down from previous update to trigger a new update(in percent)
  39. ref ScriptInvoker m_ChangedStateInvoker = new ScriptInvoker();
  40. float m_TimeSinceLastTick = VALUE_CHECK_INTERVAL + 1;
  41. float m_LastUpdate;
  42. eInjuryHandlerLevels m_LastHealthUpdate;
  43. float m_HealthMaxValue;
  44. private PlayerBase m_Player; //! owner
  45. private bool m_AnimationChange = false;
  46. private bool m_InjuryAnimEnabled = false;
  47. private float m_InjuryAnimDamageValue = 0;
  48. int m_ForceInjuryAnimMask;
  49. void InjuryAnimationHandler(PlayerBase player)
  50. {
  51. m_Player = player;
  52. m_HealthMaxValue = m_Player.GetMaxHealth("", "Health");
  53. }
  54. bool IsInjuryAnimEnabled()
  55. {
  56. return m_InjuryAnimEnabled;
  57. }
  58. float GetInjuryAnimValue()
  59. {
  60. return m_InjuryAnimDamageValue;
  61. }
  62. ScriptInvoker GetInvoker()
  63. {
  64. return m_ChangedStateInvoker;
  65. }
  66. void Update(float deltaT)
  67. {
  68. if ( m_AnimationChange )
  69. {
  70. m_Player.GetCommandModifier_Additives().SetInjured(m_InjuryAnimDamageValue, m_InjuryAnimEnabled);
  71. m_AnimationChange = false;
  72. }
  73. if ( GetGame().IsClient() )
  74. return;
  75. m_TimeSinceLastTick += deltaT;
  76. if ( m_TimeSinceLastTick > VALUE_CHECK_INTERVAL )
  77. {
  78. CheckValue();
  79. m_TimeSinceLastTick = 0;
  80. }
  81. }
  82. eInjuryHandlerLevels GetOverrideLevel(eInjuryHandlerLevels unchanged_level)
  83. {
  84. eInjuryHandlerLevels override_level = unchanged_level;
  85. //Whatever the case, prone will always use PRISTINE anim level as alternative anim level(s) are not interesting gameplaywise
  86. if ( m_ForceInjuryAnimMask & eInjuryOverrides.PRONE_ANIM_OVERRIDE && override_level > eInjuryHandlerLevels.PRISTINE )
  87. {
  88. override_level = eInjuryHandlerLevels.PRISTINE;
  89. return override_level;
  90. }
  91. if ( m_ForceInjuryAnimMask & eInjuryOverrides.MORPHINE && override_level > eInjuryHandlerLevels.PRISTINE )
  92. {
  93. override_level = eInjuryHandlerLevels.PRISTINE;
  94. }
  95. if ( m_ForceInjuryAnimMask & eInjuryOverrides.PAIN_KILLERS_LVL1 && override_level > eInjuryHandlerLevels.WORN )
  96. {
  97. override_level = eInjuryHandlerLevels.WORN;
  98. }
  99. if ( m_ForceInjuryAnimMask & eInjuryOverrides.PAIN_KILLERS_LVL0 && override_level > eInjuryHandlerLevels.DAMAGED )
  100. {
  101. override_level = eInjuryHandlerLevels.DAMAGED;
  102. }
  103. if ( m_ForceInjuryAnimMask && override_level > eInjuryHandlerLevels.DAMAGED )
  104. {
  105. override_level = eInjuryHandlerLevels.RUINED;
  106. }
  107. //Broken leg overrides
  108. if ( m_ForceInjuryAnimMask & eInjuryOverrides.BROKEN_LEGS_SPLINT && override_level < eInjuryHandlerLevels.DAMAGED )
  109. {
  110. override_level = eInjuryHandlerLevels.DAMAGED;
  111. }
  112. if ( m_ForceInjuryAnimMask & eInjuryOverrides.BROKEN_LEGS && override_level < eInjuryHandlerLevels.RUINED )
  113. {
  114. //Average leg health used to determine which animation to use
  115. float avgLegHealth = m_Player.GetHealth("RightLeg","") + m_Player.GetHealth("LeftLeg","") + m_Player.GetHealth("RightFoot","") + m_Player.GetHealth("LeftFoot","");
  116. avgLegHealth *= 0.25; //divide by 4 to make the average leg health;
  117. if (avgLegHealth <= PlayerConstants.BROKEN_LEGS_LOW_HEALTH_THRESHOLD)
  118. override_level = eInjuryHandlerLevels.RUINED;
  119. else if (avgLegHealth >= PlayerConstants.BROKEN_LEGS_HIGH_HEALTH_THRESHOLD)
  120. override_level = eInjuryHandlerLevels.WORN;
  121. else
  122. override_level = eInjuryHandlerLevels.DAMAGED;
  123. }
  124. return override_level;
  125. }
  126. void CheckValue(bool forceUpdate = false)
  127. {
  128. float health_current_normalized = m_Player.GetHealth("","Health") / m_HealthMaxValue;
  129. eInjuryHandlerLevels injury_level = GetInjuryLevel(health_current_normalized);
  130. if ( m_ForceInjuryAnimMask )
  131. {
  132. injury_level = GetOverrideLevel(injury_level);
  133. }
  134. if ( m_LastHealthUpdate != injury_level || forceUpdate )
  135. {
  136. SendValue(injury_level);
  137. m_ChangedStateInvoker.Invoke(injury_level);
  138. m_LastHealthUpdate = injury_level;
  139. Synchronize(injury_level);
  140. }
  141. }
  142. void Synchronize(eInjuryHandlerLevels level)
  143. {
  144. m_Player.m_HealthLevel = level;
  145. //Print("m_Player.m_HealthLevel:" + m_Player.m_HealthLevel);
  146. m_Player.SetSynchDirty();
  147. }
  148. void SendValue(eInjuryHandlerLevels level)
  149. {
  150. DayZPlayerSyncJunctures.SendInjury(m_Player, true, level);
  151. }
  152. void SetInjuryCommandParams(bool enable, eInjuryHandlerLevels level)
  153. {
  154. m_AnimationChange = true;
  155. m_InjuryAnimEnabled = enable;
  156. m_InjuryAnimDamageValue = GetInjuryValue(level);
  157. }
  158. eInjuryHandlerLevels GetInjuryLevel(float health)
  159. {
  160. if ( health < InjuryHandlerThresholds.RUINED )
  161. {
  162. return eInjuryHandlerLevels.RUINED;
  163. }
  164. if ( health < InjuryHandlerThresholds.BADLY_DAMAGED )
  165. {
  166. return eInjuryHandlerLevels.BADLY_DAMAGED;
  167. }
  168. if ( health < InjuryHandlerThresholds.DAMAGED )
  169. {
  170. return eInjuryHandlerLevels.DAMAGED;
  171. }
  172. if ( health < InjuryHandlerThresholds.WORN )
  173. {
  174. return eInjuryHandlerLevels.WORN;
  175. }
  176. return eInjuryHandlerLevels.PRISTINE;
  177. }
  178. float GetInjuryValue(eInjuryHandlerLevels level)
  179. {
  180. switch ( level )
  181. {
  182. case eInjuryHandlerLevels.RUINED:
  183. {
  184. return InjuryAnimValues.LVL4;
  185. }
  186. case eInjuryHandlerLevels.BADLY_DAMAGED:
  187. {
  188. return InjuryAnimValues.LVL3;
  189. }
  190. case eInjuryHandlerLevels.DAMAGED:
  191. {
  192. return InjuryAnimValues.LVL2;
  193. }
  194. case eInjuryHandlerLevels.WORN:
  195. {
  196. return InjuryAnimValues.LVL1;
  197. }
  198. case eInjuryHandlerLevels.PRISTINE:
  199. {
  200. return InjuryAnimValues.LVL0;
  201. }
  202. default:
  203. Error("Undefined Injury level");
  204. }
  205. return 0;
  206. }
  207. }