explosivesbase.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. class ExplosiveLight : PointLightBase
  2. {
  3. protected static float m_DefaultBrightness = 10;
  4. protected static float m_DefaultRadius = 30;
  5. void ExplosiveLight()
  6. {
  7. SetVisibleDuringDaylight(false);
  8. SetRadiusTo(m_DefaultRadius);
  9. SetBrightnessTo(m_DefaultBrightness);
  10. SetFlareVisible(false);
  11. SetAmbientColor(1.0, 1.0, 0.3);
  12. SetDiffuseColor(1.0, 1.0, 0.3);
  13. SetLifetime(0.15);
  14. SetDisableShadowsWithinRadius(-1);
  15. }
  16. }
  17. class ExplosivesBase : ItemBase
  18. {
  19. protected const string DEFAULT_AMMO_TYPE = "Explosion_NonLethal";
  20. protected const string ANIM_PHASE_VISIBILITY = "Visibility";
  21. protected bool m_Armed;
  22. protected bool m_Defused;
  23. protected ref array<string> m_AmmoTypes;
  24. protected ref Timer m_DeleteTimer;
  25. //! light
  26. protected ExplosiveLight m_Light;
  27. //! particle
  28. protected Particle m_ParticleExplosion;
  29. protected ref array<ParticleSource> m_ParticleExplosionArr = {};
  30. protected int m_ParticleExplosionId;
  31. protected vector m_ParticlePosition;
  32. protected vector m_ParticleOrientation;
  33. static protected ref map<string, ref map<string, int>> m_TypeToSurfaceParticleIDMap;
  34. void ExplosivesBase()
  35. {
  36. m_DeleteTimer = new Timer();
  37. m_AmmoTypes = new array<string>();
  38. SetAmmoType(DEFAULT_AMMO_TYPE);
  39. SetParticleExplosion(ParticleList.INVALID); //! no effect
  40. SetParticlePosition(WorldToModel(GetPosition()));
  41. SetParticleOrientation(vector.Zero);
  42. RegisterNetSyncVariableBool("m_Armed");
  43. RegisterNetSyncVariableBool("m_Defused");
  44. Init();
  45. }
  46. override bool IsExplosive()
  47. {
  48. return true;
  49. }
  50. override void OnExplosionEffects(Object source, Object directHit, int componentIndex, string surface, vector pos, vector surfNormal, float energyFactor, float explosionFactor, bool isWater, string ammoType)
  51. {
  52. super.OnExplosionEffects(source, directHit, componentIndex, surface, pos, surfNormal, energyFactor, explosionFactor, isWater, ammoType);
  53. if (m_ParticleExplosionId > ParticleList.INVALID)
  54. {
  55. EntityAI parent = this;
  56. if (GetHierarchyParent())
  57. {
  58. parent = GetHierarchyParent();
  59. }
  60. //SEffectManager.CreateParticleServer(pos, new TreeEffecterParameters("TreeEffecter", 1.0, 10 * explosionFactor));
  61. int particleID = GetParticleExplosionID(surface);
  62. ParticleSource p = ParticleManager.GetInstance().PlayOnObject(particleID, parent, m_ParticlePosition, m_ParticleOrientation);
  63. m_ParticleExplosionArr.Insert(p);
  64. m_ParticleExplosion = p;
  65. }
  66. CreateLight();
  67. }
  68. override void EEDelete(EntityAI parent)
  69. {
  70. super.EEDelete(parent);
  71. if (m_ParticleExplosion)
  72. {
  73. foreach (ParticleSource p : m_ParticleExplosionArr)
  74. {
  75. DestroyParticle(p);
  76. }
  77. }
  78. }
  79. override void EEKilled(Object killer)
  80. {
  81. super.EEKilled(killer);
  82. //! should be called only here to avoid multiple explosion calculations, call SetHealth("","",0.0) instead
  83. InitiateExplosion();
  84. UnpairRemote();
  85. }
  86. override void OnCEUpdate()
  87. {
  88. super.OnCEUpdate();
  89. if (!IsRuined() && GetArmed() && GetPairDevice())
  90. {
  91. if (vector.DistanceSq(GetPosition(), GetPairDevice().GetPosition()) <= Math.SqrFloat(UAMaxDistances.EXPLOSIVE_REMOTE_ACTIVATION))
  92. {
  93. UpdateLED(ERemoteDetonatorLEDState.LIT);
  94. return;
  95. }
  96. }
  97. UpdateLED(ERemoteDetonatorLEDState.OFF);
  98. }
  99. override void UnpairRemote()
  100. {
  101. if (GetRemotelyActivatedItemBehaviour())
  102. {
  103. if (GetPairDevice())
  104. {
  105. GetPairDevice().UnpairRemote();
  106. }
  107. GetRemotelyActivatedItemBehaviour().Unpair();
  108. }
  109. }
  110. override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
  111. {
  112. super.OnPlacementComplete(player, position, orientation);
  113. if (GetGame().IsServer())
  114. {
  115. SetOrientation(orientation);
  116. SetPosition(position);
  117. PlaceOnSurface();
  118. }
  119. }
  120. string GetArmSoundset()
  121. {
  122. return string.Empty;
  123. }
  124. string GetDisarmSoundset()
  125. {
  126. return string.Empty;
  127. }
  128. override void InitItemSounds()
  129. {
  130. super.InitItemSounds();
  131. ItemSoundHandler handler = GetItemSoundHandler();
  132. if (GetArmSoundset() != string.Empty)
  133. handler.AddSound(SoundConstants.ITEM_EXPLOSIVE_ARM, GetArmSoundset());
  134. if (GetDisarmSoundset() != string.Empty)
  135. handler.AddSound(SoundConstants.ITEM_EXPLOSIVE_DISARM, GetDisarmSoundset());
  136. }
  137. protected void CreateLight()
  138. {
  139. m_Light = ExplosiveLight.Cast(ScriptedLightBase.CreateLight(ExplosiveLight, GetPosition()));
  140. }
  141. protected void DestroyParticle(Particle p)
  142. {
  143. #ifndef SERVER
  144. if (p != null)
  145. {
  146. p.Stop();
  147. }
  148. #endif
  149. }
  150. protected void InitiateExplosion()
  151. {
  152. int count = m_AmmoTypes.Count();
  153. for (int i = 0; i < count; i++)
  154. {
  155. Explode(DamageType.EXPLOSION, m_AmmoTypes[i]);
  156. }
  157. OnExplode();
  158. }
  159. protected void OnExplode()
  160. {
  161. if (GetGame().IsServer())
  162. {
  163. m_DeleteTimer.Run(0.25, this, "DeleteSafe");
  164. }
  165. }
  166. override void SetActions()
  167. {
  168. super.SetActions();
  169. AddAction(ActionAttach);
  170. AddAction(ActionDetach);
  171. }
  172. override bool IsInventoryVisible()
  173. {
  174. if (!super.IsInventoryVisible())
  175. {
  176. return false;
  177. }
  178. return GetAnimationPhase("Visibility") == 0;
  179. }
  180. override bool IsTakeable()
  181. {
  182. return super.IsTakeable() && GetAnimationPhase("Visibility") == 0;
  183. }
  184. bool IsTimerDetonable()
  185. {
  186. return false;
  187. }
  188. void Arm()
  189. {
  190. SetArmed(true);
  191. OnArmed();
  192. }
  193. void OnArmed();
  194. bool CanBeArmed()
  195. {
  196. return true;
  197. }
  198. void Disarm(bool pWithTool = false)
  199. {
  200. SetArmed(false);
  201. OnDisarmed(pWithTool);
  202. }
  203. void OnBeforeDisarm();
  204. void OnDisarmed(bool pWithTool);
  205. bool CanBeDisarmed()
  206. {
  207. return false;
  208. }
  209. bool GetArmed()
  210. {
  211. return m_Armed;
  212. }
  213. protected void SetArmed(bool state)
  214. {
  215. m_Armed = state;
  216. SetSynchDirty();
  217. }
  218. override bool CanPutInCargo(EntityAI parent)
  219. {
  220. if (!super.CanPutInCargo(parent))
  221. {
  222. return false;
  223. }
  224. return IsTakeable();
  225. }
  226. override bool CanPutIntoHands(EntityAI parent)
  227. {
  228. if (!super.CanPutIntoHands(parent))
  229. {
  230. return false;
  231. }
  232. return IsTakeable();
  233. }
  234. override bool CanRemoveFromHands(EntityAI parent)
  235. {
  236. return IsTakeable();
  237. }
  238. bool GetDefused()
  239. {
  240. return m_Defused;
  241. }
  242. protected void SetDefused(bool state)
  243. {
  244. m_Defused = state;
  245. SetSynchDirty();
  246. }
  247. void SetAmmoType(string pAmmoType)
  248. {
  249. SetAmmoTypes({pAmmoType});
  250. }
  251. void SetAmmoTypes(array<string> pAmmoTypes)
  252. {
  253. m_AmmoTypes.Clear();
  254. m_AmmoTypes = pAmmoTypes;
  255. }
  256. void SetParticleExplosion(int particle)
  257. {
  258. m_ParticleExplosionId = particle;
  259. }
  260. //! set position for smoke particle - needs to be in Local Space
  261. void SetParticlePosition(vector local_pos)
  262. {
  263. m_ParticlePosition = local_pos;
  264. if (GetHierarchyParent())
  265. {
  266. m_ParticlePosition = GetHierarchyParent().WorldToModel(GetPosition());
  267. }
  268. }
  269. void SetParticleOrientation(vector local_ori)
  270. {
  271. m_ParticleOrientation = local_ori;
  272. if (GetHierarchyParent())
  273. {
  274. m_ParticleOrientation = GetHierarchyParent().WorldToModel(GetOrientation());
  275. }
  276. }
  277. override void OnStoreSave(ParamsWriteContext ctx)
  278. {
  279. super.OnStoreSave(ctx);
  280. ctx.Write(m_Armed);
  281. }
  282. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  283. {
  284. if (!super.OnStoreLoad(ctx, version))
  285. return false;
  286. if (version > 129)
  287. {
  288. bool armed = false;
  289. if (!ctx.Read(armed))
  290. {
  291. return false;
  292. }
  293. SetArmed(armed);
  294. }
  295. return true;
  296. }
  297. //! HELPERS
  298. void UpdateLED(int pState);
  299. bool HasLockedTriggerSlots()
  300. {
  301. return false;
  302. }
  303. void LockTriggerSlots();
  304. void UnlockTriggerSlots();
  305. void LockExplosivesSlots();
  306. void UnlockExplosivesSlots();
  307. void Init()
  308. {
  309. #ifndef SERVER
  310. if (!m_TypeToSurfaceParticleIDMap)
  311. {
  312. m_TypeToSurfaceParticleIDMap = new map<string, ref map<string, int>>;
  313. }
  314. if(!m_TypeToSurfaceParticleIDMap.Contains(GetName()))
  315. {
  316. map<string, int> extraSurfaceeffect = new map<string, int>();
  317. m_TypeToSurfaceParticleIDMap.Insert(GetName(), extraSurfaceeffect);
  318. InitSpecificsExplosionEffectForSurface();
  319. }
  320. #endif
  321. }
  322. static void Cleanup()
  323. {
  324. if (m_TypeToSurfaceParticleIDMap)
  325. {
  326. m_TypeToSurfaceParticleIDMap.Clear();
  327. }
  328. }
  329. void InitSpecificsExplosionEffectForSurface()
  330. {
  331. //Here add in override call AddExplosionEffectForSurface for specific explosion on surface
  332. }
  333. void AddExplosionEffectForSurface(string surface, int effectID)
  334. {
  335. map<string, int> extraSurfaceeffect;
  336. m_TypeToSurfaceParticleIDMap.Find(GetName(), extraSurfaceeffect);
  337. extraSurfaceeffect.Insert(surface, effectID);
  338. }
  339. int GetParticleExplosionID(string surface)
  340. {
  341. map<string, int> extraSurfaceeffect;
  342. m_TypeToSurfaceParticleIDMap.Find(GetName(), extraSurfaceeffect);
  343. int particleID;
  344. if (extraSurfaceeffect.Find(surface, particleID))
  345. return particleID;
  346. return m_ParticleExplosionId;
  347. }
  348. }