bleedingindicator.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. //! indicator wrapper for a specific bleeding source.
  2. class BleedingIndicator extends Managed
  3. {
  4. protected bool m_Initialized;
  5. protected bool m_Terminating = false; //doesn't spawn more drops and ends when the last one does
  6. protected bool m_EndNow = false;
  7. protected bool m_IsRunning = false;
  8. protected int m_DropSpawnsQueued;
  9. protected int m_ActiveDropsCount;
  10. protected int m_Severity;
  11. protected int m_SourceID; //pairs this with the 'BleedingSource' bit/ID
  12. protected GameplayEffectsDataBleeding m_ParentMetaData;
  13. protected array<float> m_DropProbabilityArray;
  14. protected float m_AverageFrequency; //average drops per interval. NOT changeable on the fly, just a helper value!
  15. protected float m_SequenceTick;
  16. protected float m_SequenceDuration;
  17. protected float m_TimeElapsedTotal;
  18. protected float m_TimeElapsedSequence;
  19. protected float m_LastDropSpawnTime; //relative to the TOTAL time, not the sequence!
  20. protected float m_DropSpawnMinDelay;
  21. protected float m_DropSpawnMaxDelay;
  22. protected int m_CurrentDropProbabilityStep;
  23. protected int m_DropProbabilityRollsCount;
  24. protected vector m_BasePosition;
  25. ref set<ref BleedingIndicatorDropData> m_ActiveDrops;
  26. ref set<int> m_CleanupQueue;
  27. void BleedingIndicator(int source_ID, int severity, GameplayEffectsDataBleeding parent)
  28. {
  29. m_Initialized = false;
  30. m_SourceID = source_ID;
  31. m_Severity = severity;
  32. m_ParentMetaData = parent;
  33. m_CurrentDropProbabilityStep = 0;
  34. m_ActiveDrops = new set<ref BleedingIndicatorDropData>;
  35. m_CleanupQueue = new set<int>;
  36. m_DropProbabilityArray = m_ParentMetaData.GetProbabilities(m_Severity);
  37. m_DropProbabilityRollsCount = m_DropProbabilityArray.Count();
  38. switch (m_Severity)
  39. {
  40. case BleedingIndicationConstants.INDICATOR_SEVERITY_LOW:
  41. {
  42. m_SequenceDuration = BleedingIndicationConstants.SEQUENCE_DURATION_LOW;
  43. m_AverageFrequency = BleedingIndicationConstants.SEQUENCE_DROP_AVERAGE_LOW;
  44. m_DropSpawnMinDelay = BleedingIndicationConstants.SEQUENCE_DROP_DELAY_MIN_LOW;
  45. m_DropSpawnMaxDelay = BleedingIndicationConstants.SEQUENCE_DROP_DELAY_MAX_LOW;
  46. break;
  47. }
  48. case BleedingIndicationConstants.INDICATOR_SEVERITY_MEDIUM:
  49. {
  50. m_SequenceDuration = BleedingIndicationConstants.SEQUENCE_DURATION_MEDIUM;
  51. m_AverageFrequency = BleedingIndicationConstants.SEQUENCE_DROP_AVERAGE_MEDIUM;
  52. m_DropSpawnMinDelay = BleedingIndicationConstants.SEQUENCE_DROP_DELAY_MIN_MEDIUM;
  53. m_DropSpawnMaxDelay = BleedingIndicationConstants.SEQUENCE_DROP_DELAY_MAX_MEDIUM;
  54. break;
  55. }
  56. case BleedingIndicationConstants.INDICATOR_SEVERITY_HIGH:
  57. {
  58. m_SequenceDuration = BleedingIndicationConstants.SEQUENCE_DURATION_HIGH;
  59. m_AverageFrequency = BleedingIndicationConstants.SEQUENCE_DROP_AVERAGE_HIGH;
  60. m_DropSpawnMinDelay = BleedingIndicationConstants.SEQUENCE_DROP_DELAY_MIN_HIGH;
  61. m_DropSpawnMaxDelay = BleedingIndicationConstants.SEQUENCE_DROP_DELAY_MAX_HIGH;
  62. break;
  63. }
  64. default:
  65. {
  66. m_AverageFrequency = BleedingIndicationConstants.SEQUENCE_DROP_AVERAGE_LOW;
  67. m_DropSpawnMinDelay = BleedingIndicationConstants.SEQUENCE_DROP_DELAY_MIN_LOW;
  68. m_DropSpawnMaxDelay = BleedingIndicationConstants.SEQUENCE_DROP_DELAY_MAX_LOW;
  69. Debug.Log("Unknown severity value!");
  70. }
  71. #ifdef DIAG_DEVELOPER
  72. if (DbgBleedingIndicationStaticInfo.m_DbgUseOverrideValues)
  73. {
  74. m_SequenceDuration = DbgBleedingIndicationStaticInfo.m_DbgSequenceDuration;
  75. m_DropSpawnMinDelay = DbgBleedingIndicationStaticInfo.m_DbgDropMinDelay;
  76. m_DropSpawnMaxDelay = DbgBleedingIndicationStaticInfo.m_DbgDropMaxDelay;
  77. }
  78. #endif
  79. }
  80. m_TimeElapsedTotal = 0;
  81. m_TimeElapsedSequence = 0;
  82. }
  83. void InitIndicator(vector position)
  84. {
  85. m_BasePosition = position;
  86. ResetIndicator();
  87. m_Initialized = true;
  88. }
  89. void StopIndicator(bool instant = false)
  90. {
  91. if (!m_Terminating)
  92. {
  93. m_IsRunning = false;
  94. if (instant)
  95. {
  96. m_EndNow = true;
  97. }
  98. m_Terminating = true;
  99. }
  100. }
  101. protected void StartRunningDrops()
  102. {
  103. m_ActiveDropsCount = 0;
  104. m_IsRunning = true;
  105. TrySpawnNextDrop();
  106. m_DropSpawnsQueued = 0;
  107. m_CurrentDropProbabilityStep = (int)(m_DropProbabilityRollsCount - (m_DropProbabilityRollsCount / m_AverageFrequency));
  108. }
  109. //! Are any drops currently being animated?
  110. protected bool IsRunningDrops()
  111. {
  112. return m_ActiveDropsCount > 0;
  113. }
  114. void TrySpawnNextDrop()
  115. {
  116. ImageWidget dropImage;
  117. if (Class.CastTo(dropImage,m_ParentMetaData.GetNextDropImage()) && !dropImage.IsVisible()) //IsVisible false means the drop is free to be used
  118. {
  119. BleedingIndicatorDropData data = new BleedingIndicatorDropData(dropImage,m_Severity);
  120. data.SetBasePosition(m_BasePosition);
  121. data.StartDrop();
  122. m_ActiveDrops.Insert(data);
  123. m_ActiveDropsCount++;
  124. }
  125. m_LastDropSpawnTime = m_TimeElapsedTotal;
  126. m_DropSpawnsQueued--;
  127. }
  128. protected void ResetSequence()
  129. {
  130. m_CurrentDropProbabilityStep = 0;
  131. m_TimeElapsedSequence = 0;
  132. m_DropSpawnsQueued = 0;
  133. }
  134. void ResetIndicator()
  135. {
  136. m_Terminating = false;
  137. m_EndNow = false;
  138. m_TimeElapsedTotal = 0;
  139. m_CurrentDropProbabilityStep = 0;
  140. m_TimeElapsedSequence = 0;
  141. m_LastDropSpawnTime = 0;
  142. m_DropSpawnsQueued = 0;
  143. }
  144. void Update(float timeSlice)
  145. {
  146. if ( !m_Initialized )
  147. {
  148. return;
  149. }
  150. #ifdef DIAG_DEVELOPER
  151. if (DbgBleedingIndicationStaticInfo.m_DbgUseOverrideValues)
  152. {
  153. m_SequenceDuration = DbgBleedingIndicationStaticInfo.m_DbgSequenceDuration;
  154. }
  155. #endif
  156. m_SequenceTick = m_SequenceDuration / m_DropProbabilityRollsCount;
  157. //run drops, if possible
  158. if (!m_Terminating)
  159. {
  160. if (m_IsRunning)
  161. {
  162. if (m_TimeElapsedSequence > (m_SequenceTick * m_CurrentDropProbabilityStep))
  163. {
  164. if (m_CurrentDropProbabilityStep < m_DropProbabilityRollsCount)
  165. {
  166. float rnd = Math.RandomFloat01();
  167. if (rnd < m_DropProbabilityArray[m_CurrentDropProbabilityStep])
  168. {
  169. m_DropSpawnsQueued++;
  170. }
  171. m_CurrentDropProbabilityStep++;
  172. }
  173. }
  174. float sinceLastDrop = m_TimeElapsedTotal - m_LastDropSpawnTime;
  175. if (m_TimeElapsedSequence > m_SequenceDuration)
  176. {
  177. ResetSequence();
  178. }
  179. else if (m_DropSpawnsQueued > 0) //spawn queued drop
  180. {
  181. if (sinceLastDrop >= m_DropSpawnMinDelay)
  182. {
  183. TrySpawnNextDrop();
  184. }
  185. }
  186. else if (sinceLastDrop > m_DropSpawnMaxDelay)
  187. {
  188. TrySpawnNextDrop(); //guaranteed drop
  189. m_CurrentDropProbabilityStep++; //substitutes a regular roll..
  190. }
  191. }
  192. else //1st drop ignores delay
  193. {
  194. StartRunningDrops();
  195. }
  196. }
  197. for (int i = 0; i < m_ActiveDropsCount; i++)
  198. {
  199. if (!m_EndNow)
  200. {
  201. //Simulate drops
  202. m_ActiveDrops[i].Update(timeSlice);
  203. }
  204. else
  205. {
  206. m_ActiveDrops[i].StopDrop();
  207. }
  208. if (!m_ActiveDrops[i].IsRunning())
  209. {
  210. m_CleanupQueue.Insert(i);
  211. }
  212. }
  213. //Cleanup drops
  214. for (i = m_CleanupQueue.Count() - 1; i >= 0; i--)
  215. {
  216. m_ActiveDrops.Remove(m_CleanupQueue[i]);
  217. m_ActiveDropsCount--;
  218. }
  219. m_CleanupQueue.Clear();
  220. if (m_Terminating && !IsRunningDrops())
  221. {
  222. m_EndNow = true;
  223. }
  224. m_TimeElapsedTotal += timeSlice;
  225. m_TimeElapsedSequence += timeSlice;
  226. }
  227. bool GetEndNow()
  228. {
  229. return m_EndNow;
  230. }
  231. int GetSeverity()
  232. {
  233. return m_Severity;
  234. }
  235. }