grenade_base.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. enum EGrenadeType
  2. {
  3. FRAGMENTATION = 0,
  4. CHEMICAL,
  5. ILLUMINATING,
  6. NON_LETHAL
  7. }
  8. //! For backward compatibility
  9. class GrenadeLight : ExplosiveLight {}
  10. class FlashGrenadeLight : PointLightBase
  11. {
  12. protected static float m_DefaultBrightness = 50;
  13. protected static float m_DefaultRadius = 20;
  14. void FlashGrenadeLight()
  15. {
  16. SetVisibleDuringDaylight(true);
  17. SetRadiusTo(m_DefaultRadius);
  18. SetBrightnessTo(m_DefaultBrightness);
  19. SetFlareVisible(false);
  20. SetAmbientColor(1.0, 1.0, 1.0);
  21. SetDiffuseColor(1.0, 1.0, 1.0);
  22. SetLifetime(0.35);
  23. SetDisableShadowsWithinRadius(-1);
  24. }
  25. }
  26. class Grenade_Base : ExplosivesBase
  27. {
  28. protected const float DEFAULT_FUSE_DELAY = 10;
  29. protected ref Timer m_FuseTimer;
  30. protected float m_FuseDelay;
  31. protected float m_RemainingFuseTime;
  32. protected bool m_Pinned;
  33. protected bool m_Pinnable;
  34. //protected bool m_Explodable; //! DEPRECATED; not used anywhere
  35. protected EGrenadeType m_GrenadeType;
  36. void Pin()
  37. {
  38. if (!m_Pinned && m_Pinnable)
  39. {
  40. OnPin();
  41. }
  42. }
  43. void Unpin()
  44. {
  45. if (m_Pinned)
  46. {
  47. OnUnpin();
  48. }
  49. }
  50. //! DEPRECATED use OnActivatedByItem
  51. override void OnActivatedByTripWire();
  52. override void OnActivatedByItem(notnull ItemBase item)
  53. {
  54. if (item == this)
  55. {
  56. OnActivateFinished();
  57. return;
  58. }
  59. Unpin();
  60. }
  61. bool IsPinned()
  62. {
  63. return m_Pinned;
  64. }
  65. bool IsPinnable()
  66. {
  67. //! cannot be pinned once the fuse has started
  68. if (m_FuseTimer.IsRunning())
  69. {
  70. return false;
  71. }
  72. return m_Pinnable;
  73. }
  74. void ActivateImmediate()
  75. {
  76. OnActivateImmediate();
  77. }
  78. void ActivateRandomTime()
  79. {
  80. float delay = Math.RandomFloat(1, 20);
  81. delay *= 1000; //! to millis
  82. GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(ActivateImmediate, delay, false);
  83. }
  84. void SetPinnable(bool state)
  85. {
  86. m_Pinnable = state;
  87. }
  88. void SetFuseDelay(float delay)
  89. {
  90. m_FuseDelay = delay;
  91. }
  92. void SetGrenadeType(EGrenadeType type)
  93. {
  94. m_GrenadeType = type;
  95. }
  96. EGrenadeType GetGrenadeType()
  97. {
  98. return m_GrenadeType;
  99. }
  100. protected void Activate()
  101. {
  102. if (!m_FuseTimer.IsRunning())
  103. {
  104. //! run only the remaining part (already unpinned and pinned)
  105. if (m_RemainingFuseTime > 0)
  106. {
  107. //Debug.Log(string.Format("Grenade activated num of seconds to explosion: %1", m_RemainingFuseTime));
  108. m_FuseTimer.Run(m_RemainingFuseTime, this, "OnActivateFinished");
  109. }
  110. else
  111. {
  112. //Debug.Log(string.Format("Grenade activated num of seconds to explosion: %1", m_FuseDelay));
  113. m_FuseTimer.Run(m_FuseDelay, this, "OnActivateFinished");
  114. }
  115. }
  116. }
  117. protected void Deactivate()
  118. {
  119. if (m_FuseTimer.IsRunning())
  120. {
  121. m_RemainingFuseTime = m_FuseTimer.GetRemaining();
  122. m_FuseTimer.Stop();
  123. OnDeactivate();
  124. }
  125. }
  126. protected override void InitiateExplosion()
  127. {
  128. switch (GetGrenadeType())
  129. {
  130. case EGrenadeType.FRAGMENTATION:
  131. case EGrenadeType.ILLUMINATING:
  132. for (int i = 0; i < m_AmmoTypes.Count(); i++)
  133. {
  134. Explode(DamageType.EXPLOSION, m_AmmoTypes[i]);
  135. }
  136. break;
  137. case EGrenadeType.CHEMICAL:
  138. case EGrenadeType.NON_LETHAL:
  139. break;
  140. }
  141. OnExplode();
  142. }
  143. //! DEPRECATED - for backward compatibility only
  144. protected void ExplodeGrenade(EGrenadeType grenade_type)
  145. {
  146. InitiateExplosion();
  147. }
  148. protected void OnPin()
  149. {
  150. m_Pinned = true;
  151. if (GetGame().IsServer())
  152. {
  153. ForceFarBubble(false);
  154. SetSynchDirty();
  155. }
  156. Deactivate();
  157. }
  158. protected void OnUnpin()
  159. {
  160. m_Pinned = false;
  161. if (GetGame().IsServer())
  162. {
  163. ForceFarBubble(true);
  164. SetSynchDirty();
  165. }
  166. OnActivateStarted();
  167. }
  168. protected void OnActivateStarted();
  169. protected void OnActivateFinished()
  170. {
  171. if (GetGame().IsServer())
  172. {
  173. SetHealth("", "", 0.0); // causes explosion when grenade is destroyed
  174. SetTakeable(false);
  175. }
  176. }
  177. protected void OnActivateImmediate()
  178. {
  179. if (GetGame().IsServer())
  180. {
  181. SetHealth("", "", 0.0); // causes explosion when grenade is destroyed
  182. SetTakeable(false);
  183. }
  184. }
  185. protected void OnDeactivate();
  186. override void OnStoreSave(ParamsWriteContext ctx)
  187. {
  188. super.OnStoreSave(ctx);
  189. if (GetGame().SaveVersion() >= 107)
  190. {
  191. ctx.Write(m_Pinned);
  192. }
  193. }
  194. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  195. {
  196. if (!super.OnStoreLoad(ctx, version))
  197. return false;
  198. bool pinned;
  199. if (version >= 107)
  200. {
  201. if (!ctx.Read(pinned))
  202. {
  203. return false;
  204. }
  205. m_Pinned = pinned;
  206. }
  207. return true;
  208. }
  209. override bool CanBeArmed()
  210. {
  211. return false;
  212. }
  213. override bool CanBeDisarmed()
  214. {
  215. return false;
  216. }
  217. override bool CanExplodeInFire()
  218. {
  219. return true;
  220. }
  221. override void SetActions()
  222. {
  223. super.SetActions();
  224. AddAction(ActionUnpin);
  225. AddAction(ActionPin);
  226. }
  227. override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
  228. {
  229. super.EEItemLocationChanged(oldLoc, newLoc);
  230. //! activate grenade when it leaves player hands (safety handle released)
  231. if (newLoc.GetType() != InventoryLocationType.HANDS && !IsPinned())
  232. {
  233. Activate();
  234. }
  235. }
  236. override void OnWasAttached(EntityAI parent, int slot_id)
  237. {
  238. super.OnWasAttached(parent, slot_id);
  239. if (parent.IsAnyInherited({TrapBase,ImprovisedExplosive}))
  240. {
  241. Deactivate();
  242. }
  243. }
  244. void Grenade_Base()
  245. {
  246. m_Pinned = true;
  247. m_FuseTimer = new Timer;
  248. m_RemainingFuseTime = -1;
  249. SetPinnable(true);
  250. SetFuseDelay(DEFAULT_FUSE_DELAY);
  251. SetGrenadeType(EGrenadeType.FRAGMENTATION);
  252. RegisterNetSyncVariableBool("m_Pinned");
  253. }
  254. override void InitSpecificsExplosionEffectForSurface()
  255. {
  256. AddExplosionEffectForSurface("Hit_Snow", ParticleList.EXPLOSION_GRENADE_SNOW);
  257. AddExplosionEffectForSurface("Hit_Ice", ParticleList.EXPLOSION_GRENADE_ICE);
  258. }
  259. }