shockhandler.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. class ShockHandler
  2. {
  3. protected const float UPDATE_THRESHOLD = 3; //NOTE : The lower, the more precise but the more synchronization
  4. const float VALUE_CHECK_INTERVAL = 0.95; //in seconds
  5. private const int INTENSITY_FACTOR = 1; //How intense the vignette effect will be, the higher the value, the stronger the effect
  6. private const int VIGNETTE_INTENSITY_MAX = 1; //Max BASE intensity of the vignette effect (w/o. bobbing). 0..2, where 2 is full screen coverage
  7. private const int VIGNETTE_INTENSITY_MAX_TOTAL = 2; //Max TOTAL intensity of the vignette effect (w. bobbing). 0..2, where 2 is full screen coverage
  8. private const float SMOOTHING_MAX_INCR = 0.05; //max smoothing change INCREASE per update
  9. private const float SMOOTHING_MAX_DECR = 0.01; //max smoothing change DECREASE per update
  10. //bobbing constants
  11. private const float PULSE_PERIOD = 0.5; //The time it takes for pulse to do a full cycle
  12. private const float PULSE_AMPLITUDE = 0.05; //This is a multiplier, keep below 1 or expect the unexpected
  13. protected float m_Shock;
  14. protected float m_LastEffectIntensityValue; //for interpolation only
  15. protected float m_ShockValueMax;
  16. protected float m_CumulatedShock; //! works ok on server, but does nothing for client. See deprecated stuff.
  17. private float m_TimeSinceLastTick = VALUE_CHECK_INTERVAL + 1;
  18. private float m_ShockMultiplier = 1;
  19. private float m_PrevVignette; //Previous shock-adjecent value (some normalization required). Client sets it only on regular ShockHandler update!
  20. //bobbing effect
  21. private float m_PulseTimer;
  22. //PPE
  23. PPERequester_TunnelVisionEffects m_Requester;
  24. protected ref Param1<float> m_Param;
  25. protected PlayerBase m_Player;
  26. void ShockHandler(PlayerBase player)
  27. {
  28. m_Player = player;
  29. m_Player.m_CurrentShock = m_Player.GetMaxHealth("", "Shock");
  30. m_ShockValueMax = m_Player.GetMaxHealth("", "Shock");
  31. m_PrevVignette = m_Player.m_CurrentShock / m_ShockValueMax; //Equivalent to divided by 100
  32. m_Requester = PPERequester_TunnelVisionEffects.Cast(PPERequesterBank.GetRequester(PPERequester_TunnelVisionEffects));
  33. m_Param = new Param1<float>(0);
  34. //loegacy stuff
  35. m_ShockValueThreshold = m_ShockValueMax * 0.95;
  36. }
  37. void Update(float deltaT)
  38. {
  39. m_TimeSinceLastTick += deltaT;
  40. m_PulseTimer += deltaT;
  41. //periodical update, just in case
  42. if (m_TimeSinceLastTick > VALUE_CHECK_INTERVAL)
  43. {
  44. if (GetGame().IsClient())
  45. {
  46. //ShockHitEffect(m_PrevVignette * m_ShockValueMax);
  47. m_PrevVignette = m_Player.m_CurrentShock / m_ShockValueMax;
  48. }
  49. CheckValue(false);
  50. m_TimeSinceLastTick = 0;
  51. }
  52. if (GetGame().IsClient())
  53. {
  54. float valAdjusted = BaseEffectIntensityCalc();
  55. if (valAdjusted <= 0)
  56. {
  57. if (m_Requester.IsRequesterRunning())
  58. m_Requester.Stop();
  59. return;
  60. }
  61. //Print("dbgShock | valAdjusted: " + valAdjusted);
  62. //Add bobbing to create pulsing effect
  63. valAdjusted = AddEffectBobbing(valAdjusted);
  64. m_Param.param1 = valAdjusted;
  65. m_Requester.Start(m_Param);
  66. }
  67. }
  68. float GetCurrentShock()
  69. {
  70. return m_Player.m_CurrentShock;
  71. }
  72. float GetShock()
  73. {
  74. return m_Shock;
  75. }
  76. void SetShock(float dealtShock)
  77. {
  78. m_Shock += dealtShock;
  79. CheckValue(false);
  80. }
  81. //Inflict shock damage
  82. private void DealShock()
  83. {
  84. if (GetGame().IsServer())
  85. m_Player.GiveShock(-m_CumulatedShock);
  86. }
  87. //Passing a value of FALSE will only check the values, a value of TRUE will force a synchronization (don't use too often)
  88. void CheckValue(bool forceUpdate)
  89. {
  90. m_CumulatedShock += m_Shock; // increment on both client and server
  91. if (forceUpdate)
  92. m_PrevVignette = NormalizeShockVal(m_Player.m_CurrentShock);
  93. if (GetGame().IsServer())
  94. {
  95. if (m_CumulatedShock >= UPDATE_THRESHOLD || forceUpdate)
  96. {
  97. m_CumulatedShock *= m_ShockMultiplier;
  98. DealShock();
  99. m_CumulatedShock = 0;
  100. m_Shock = 0;
  101. Synchronize();
  102. }
  103. m_Player.m_CurrentShock = m_Player.GetHealth("", "Shock");
  104. }
  105. }
  106. protected void Synchronize()
  107. {
  108. DayZPlayerSyncJunctures.SendShock(m_Player, m_Player.m_CurrentShock);
  109. }
  110. protected float BaseEffectIntensityCalc()
  111. {
  112. float effectIntensity = 1 - Easing.EaseInQuart(NormalizeShockVal(m_Player.m_CurrentShock));
  113. //smoothing
  114. if (effectIntensity != m_LastEffectIntensityValue)
  115. effectIntensity = Math.Clamp(effectIntensity,m_LastEffectIntensityValue - SMOOTHING_MAX_DECR, m_LastEffectIntensityValue + SMOOTHING_MAX_INCR);
  116. m_LastEffectIntensityValue = effectIntensity;
  117. return effectIntensity;
  118. }
  119. //! adds bobbing, also clamps to valid range
  120. protected float AddEffectBobbing(float baseVal)
  121. {
  122. float ret = baseVal;
  123. float bobbingVal = 0.0;
  124. if (m_Player.m_CurrentShock > m_ShockValueMax * 0.8)
  125. bobbingVal = MiscGameplayFunctions.Bobbing(PULSE_PERIOD, PULSE_AMPLITUDE, m_PulseTimer);
  126. ret += bobbingVal;
  127. ret = Math.Clamp(ret,0,VIGNETTE_INTENSITY_MAX_TOTAL);
  128. return ret;
  129. }
  130. float SetMultiplier(float mult)
  131. {
  132. m_ShockMultiplier = mult;
  133. return m_ShockMultiplier;
  134. }
  135. private float NormalizeShockVal(float shock)
  136. {
  137. float base = m_ShockValueMax * INTENSITY_FACTOR;
  138. float normShock = shock / base;
  139. return normShock;
  140. }
  141. private float LerpVignette(float x, float y, float deltaT)
  142. {
  143. float output;
  144. output = Math.Lerp(x, y, deltaT);
  145. return output;
  146. }
  147. ///////////////////////////
  148. //Deprecated stuff below//
  149. /////////////////////////
  150. private const int LIGHT_SHOCK_HIT = 33; //!Deprecated
  151. private const int MID_SHOCK_HIT = 67; //!Deprecated
  152. private const int HEAVY_SHOCK_HIT = 100; //!Deprecated
  153. protected float m_ShockValueThreshold; //!Deprecated
  154. private float m_LerpRes; //!Deprecated
  155. //!Deprecated
  156. private void ShockHitEffect(float compareBase)
  157. {
  158. float shockDifference = compareBase - m_Player.m_CurrentShock;
  159. if (shockDifference >= UPDATE_THRESHOLD)
  160. {
  161. if (m_CumulatedShock < 25)
  162. m_Player.SpawnShockEffect(MiscGameplayFunctions.Normalize(LIGHT_SHOCK_HIT, 100));
  163. else if (m_CumulatedShock < 50)
  164. m_Player.SpawnShockEffect(MiscGameplayFunctions.Normalize(MID_SHOCK_HIT, 100));
  165. else
  166. m_Player.SpawnShockEffect(MiscGameplayFunctions.Normalize(HEAVY_SHOCK_HIT, 100));
  167. }
  168. }
  169. };