geyserarea.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. enum EGeyserState
  2. {
  3. DORMANT = 0,
  4. ERUPTION_SOON = 1, // bubbling
  5. ERUPTING_PRIMARY = 2, // main particle
  6. ERUPTING_SECONDARY = 4 // secondary tall particle
  7. }
  8. class GeyserArea : EffectArea
  9. {
  10. protected const int UPDATE_RATE = 1000; // ms
  11. protected const float PRE_ERUPTION_DURATION = 5; // length of the pre eruption phase in seconds
  12. protected int m_TimeElapsed; // seconds
  13. protected float m_RandomizedInterval; // randomized interval to 80% - 120% of the set value
  14. protected float m_RandomizedDuration; // randomized duration to 80% - 120% of the set value
  15. protected GeyserTrigger m_GeyserTrigger;
  16. override void EEDelete( EntityAI parent )
  17. {
  18. if (GetGame().IsClient() && m_GeyserTrigger)
  19. m_GeyserTrigger.StopEffects();
  20. super.EEDelete( parent );
  21. }
  22. override void InitZoneServer()
  23. {
  24. super.InitZoneServer();
  25. if ( m_TriggerType != "" )
  26. {
  27. CreateTrigger( m_Position, m_Radius );
  28. m_GeyserTrigger = GeyserTrigger.Cast(m_Trigger);
  29. }
  30. GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(TickState, UPDATE_RATE, true);
  31. m_RandomizedInterval = Math.RandomInt(m_EffectInterval * 0.8, m_EffectInterval * 1.2);
  32. }
  33. void TickState()
  34. {
  35. m_TimeElapsed += UPDATE_RATE * 0.001;
  36. if (m_GeyserTrigger.GetGeyserState() == EGeyserState.DORMANT)
  37. {
  38. if (m_TimeElapsed > m_RandomizedInterval)
  39. {
  40. m_TimeElapsed = 0;
  41. m_RandomizedDuration = Math.RandomInt(m_EffectDuration * 0.8, m_EffectDuration * 1.2);
  42. m_GeyserTrigger.AddGeyserState(EGeyserState.ERUPTION_SOON);
  43. }
  44. }
  45. else
  46. {
  47. if (m_GeyserTrigger.GetGeyserState() & EGeyserState.ERUPTION_SOON)
  48. {
  49. if (m_TimeElapsed > PRE_ERUPTION_DURATION)
  50. {
  51. m_GeyserTrigger.RemoveGeyserState(EGeyserState.ERUPTION_SOON);
  52. m_GeyserTrigger.AddGeyserState(EGeyserState.ERUPTING_PRIMARY);
  53. KillEntitiesInArea();
  54. return;
  55. }
  56. }
  57. if (m_GeyserTrigger.GetGeyserState() & EGeyserState.ERUPTING_PRIMARY)
  58. {
  59. if (m_TimeElapsed > m_RandomizedDuration)
  60. {
  61. m_TimeElapsed = 0;
  62. m_RandomizedInterval = Math.RandomInt(m_EffectInterval * 0.8, m_EffectInterval * 1.2);
  63. m_GeyserTrigger.RemoveGeyserState(EGeyserState.ERUPTING_PRIMARY | EGeyserState.ERUPTING_SECONDARY);
  64. return;
  65. }
  66. if (m_GeyserTrigger.GetGeyserState() & EGeyserState.ERUPTING_SECONDARY)
  67. {
  68. if (Math.RandomBool()) // 50% chance to end secondary eruption every update
  69. m_GeyserTrigger.RemoveGeyserState(EGeyserState.ERUPTING_SECONDARY);
  70. }
  71. else if (Math.RandomBool()) // 50% chance to start secondary eruption every update
  72. m_GeyserTrigger.AddGeyserState(EGeyserState.ERUPTING_SECONDARY);
  73. }
  74. }
  75. }
  76. void KillEntitiesInArea()
  77. {
  78. array<Object> nearestObjects = new array<Object>();
  79. GetGame().GetObjectsAtPosition(m_Position, m_Radius, nearestObjects, null);
  80. foreach (Object obj : nearestObjects)
  81. {
  82. EntityAI entity = EntityAI.Cast(obj);
  83. if (entity)
  84. entity.ProcessDirectDamage(DamageType.CUSTOM, this, "", "HeatDamage", "0 0 0", 1000);
  85. }
  86. }
  87. }