trap_landmine.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. enum SoundTypeMine
  2. {
  3. DISARMING = 0
  4. }
  5. class LandMineTrap extends TrapBase
  6. {
  7. protected ref EffectSound m_TimerLoopSound;
  8. protected ref EffectSound m_SafetyPinSound;
  9. protected ref EffectSound m_DisarmingLoopSound;
  10. protected ref Timer m_DeleteTimer;
  11. private const int BROKEN_LEG_PROB = 90;
  12. private const int BLEED_SOURCE_PROB = 50;
  13. private const int MAX_BLEED_SOURCE = 1;
  14. void LandMineTrap()
  15. {
  16. m_DefectRate = 15;
  17. m_DamagePlayers = 0; //How much damage player gets when caught
  18. m_InitWaitTime = 10; //After this time after deployment, the trap is activated
  19. m_InfoActivationTime = string.Format("#STR_LandMineTrap0%1#STR_LandMineTrap1", m_InitWaitTime.ToString());
  20. m_AddDeactivationDefect = true;
  21. //Order is important and must match clothing array in DamageClothing method
  22. m_ClothingDmg = new array<int>;
  23. m_ClothingDmg.Insert(60); //Trousers
  24. m_ClothingDmg.Insert(100); //BackPack
  25. m_ClothingDmg.Insert(40); //Vest
  26. m_ClothingDmg.Insert(10); //HeadGear
  27. m_ClothingDmg.Insert(10); //Mask
  28. m_ClothingDmg.Insert(40); //Body
  29. m_ClothingDmg.Insert(50); //Feet
  30. m_ClothingDmg.Insert(5); //Gloves
  31. }
  32. void ~LandMineTrap()
  33. {
  34. SEffectManager.DestroyEffect(m_TimerLoopSound);
  35. SEffectManager.DestroyEffect(m_DisarmingLoopSound);
  36. }
  37. override void StartActivate(PlayerBase player)
  38. {
  39. super.StartActivate(player);
  40. if (!GetGame().IsDedicatedServer())
  41. {
  42. if (m_SafetyPinSound)
  43. {
  44. m_SafetyPinSound = SEffectManager.PlaySound("landmine_safetyPin_SoundSet", GetPosition(), 0, 0, false);
  45. m_SafetyPinSound.SetAutodestroy(true);
  46. }
  47. if (!m_TimerLoopSound)
  48. m_TimerLoopSound = SEffectManager.PlaySound("landmine_timer2_SoundSet", GetPosition(), 0, 0, true);
  49. }
  50. }
  51. override void OnActivatedByItem(notnull ItemBase item)
  52. {
  53. SetHealth("", "", 0.0);
  54. DeleteThis();
  55. }
  56. override void OnActivate()
  57. {
  58. if (!GetGame().IsDedicatedServer())
  59. {
  60. if (m_TimerLoopSound)
  61. {
  62. m_TimerLoopSound.SetAutodestroy(true);
  63. m_TimerLoopSound.SoundStop();
  64. }
  65. if (GetGame().GetPlayer())
  66. {
  67. PlaySoundActivate();
  68. }
  69. }
  70. }
  71. override bool CanExplodeInFire()
  72. {
  73. return true;
  74. }
  75. override void OnUpdate(EntityAI victim)
  76. {
  77. if (victim && victim.IsInherited(CarScript))
  78. {
  79. EntityAI wheel = GetClosestCarWheel(victim);
  80. if (wheel)
  81. {
  82. OnServerSteppedOn(wheel, "");
  83. }
  84. }
  85. }
  86. override void OnSteppedOn(EntityAI victim)
  87. {
  88. int i;
  89. if (GetGame().IsServer() && victim)
  90. {
  91. if (!victim.GetAllowDamage())
  92. {
  93. return;
  94. }
  95. if (victim.IsInherited(CarScript))
  96. {
  97. //! CarScript specific reaction on LandMineTrap
  98. Param1<EntityAI> params = new Param1<EntityAI>(victim);
  99. m_UpdateTimer.Run(UPDATE_TIMER_INTERVAL, this, "OnUpdate", params, true);
  100. return;
  101. }
  102. else
  103. {
  104. //Check if we have a player
  105. PlayerBase victim_PB = PlayerBase.Cast(victim);
  106. if (victim_PB && victim_PB.IsAlive())
  107. {
  108. int randNum; //value used for probability evaluation
  109. randNum = Math.RandomInt(0, 100);
  110. if (randNum <= BROKEN_LEG_PROB)
  111. {
  112. float damage = victim_PB.GetMaxHealth("RightLeg", ""); //deal 100% damage to break legs
  113. victim_PB.DamageAllLegs( damage );
  114. }
  115. randNum = Math.RandomInt(0, 100);
  116. if (randNum < BLEED_SOURCE_PROB)
  117. {
  118. for (i = 0; i < MAX_BLEED_SOURCE; i++)
  119. {
  120. //We add two bleeding sources max to lower half
  121. randNum = Math.RandomIntInclusive(0, PlayerBase.m_BleedingSourcesLow.Count() - 1);
  122. victim_PB.m_BleedingManagerServer.AttemptAddBleedingSourceBySelection(PlayerBase.m_BleedingSourcesLow[randNum]);
  123. }
  124. }
  125. DamageClothing(victim_PB);
  126. }
  127. else
  128. {
  129. ItemBase victim_IB = ItemBase.Cast(victim);
  130. if (victim_IB)
  131. {
  132. MiscGameplayFunctions.DealAbsoluteDmg(victim_IB, DAMAGE_TRIGGER_MINE);
  133. }
  134. }
  135. Explode(DamageType.EXPLOSION);
  136. }
  137. DeleteThis();
  138. }
  139. super.OnSteppedOn(victim);
  140. }
  141. override void OnSteppedOut(EntityAI victim)
  142. {
  143. if (victim.IsInherited(CarScript))
  144. {
  145. if (m_UpdateTimer && m_UpdateTimer.IsRunning())
  146. {
  147. m_UpdateTimer.Stop();
  148. }
  149. }
  150. }
  151. protected void OnServerSteppedOn(Object obj, string damageZone)
  152. {
  153. if (obj.IsInherited(CarWheel))
  154. {
  155. obj.ProcessDirectDamage(DamageType.CLOSE_COMBAT, this, "", "LandMineExplosion_CarWheel", "0 0 0", 1);
  156. Explode(DamageType.EXPLOSION);
  157. if (m_UpdateTimer.IsRunning())
  158. m_UpdateTimer.Stop();
  159. }
  160. SetInactive(false);
  161. Synch(EntityAI.Cast(obj));
  162. }
  163. void DeleteThis()
  164. {
  165. m_DeleteTimer = new Timer(CALL_CATEGORY_SYSTEM);
  166. m_DeleteTimer.Run(1, this, "DeleteSafe");
  167. }
  168. override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
  169. {
  170. super.OnItemLocationChanged(old_owner, new_owner);
  171. }
  172. override void EEKilled(Object killer)
  173. {
  174. super.EEKilled(killer);
  175. Explode(DamageType.EXPLOSION);
  176. }
  177. void PlaySoundActivate()
  178. {
  179. if (!GetGame().IsDedicatedServer())
  180. {
  181. EffectSound sound = SEffectManager.PlaySound("landmineActivate_SoundSet", GetPosition(), 0, 0, false);
  182. sound.SetAutodestroy(true);
  183. }
  184. }
  185. override void Explode(int damageType, string ammoType = "")
  186. {
  187. if (ammoType == "")
  188. {
  189. ammoType = ConfigGetString("ammoType");
  190. }
  191. if (ammoType == "")
  192. {
  193. ammoType = "Dummy_Heavy";
  194. }
  195. if ( GetGame().IsServer() )
  196. {
  197. SynchExplosion();
  198. vector offset = Vector(0, 0.1, 0); //Vertical offset applied to landmine explosion (in meters)
  199. DamageSystem.ExplosionDamage(this, NULL, ammoType, GetPosition() + offset, damageType); //Offset explosion on Y axis
  200. DeleteThis();
  201. }
  202. }
  203. override bool CanBeDisarmed()
  204. {
  205. return true;
  206. }
  207. override void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
  208. {
  209. super.OnRPC(sender, rpc_type, ctx);
  210. Param1<bool> p = new Param1<bool>(false);
  211. if (!ctx.Read(p))
  212. return;
  213. bool play = p.param1;
  214. switch (rpc_type)
  215. {
  216. case SoundTypeMine.DISARMING:
  217. if (play)
  218. PlayDisarmingLoopSound();
  219. else
  220. StopDisarmingLoopSound();
  221. break;
  222. }
  223. }
  224. void PlayDisarmingLoopSound()
  225. {
  226. if (!m_DisarmingLoopSound || !m_DisarmingLoopSound.IsSoundPlaying())
  227. {
  228. m_DisarmingLoopSound = SEffectManager.PlaySound("landmine_deploy_SoundSet", GetPosition());
  229. }
  230. }
  231. void StopDisarmingLoopSound()
  232. {
  233. m_DisarmingLoopSound.SoundStop();
  234. }
  235. //================================================================
  236. // ADVANCED PLACEMENT
  237. //================================================================
  238. override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
  239. {
  240. super.OnPlacementComplete(player, position, orientation);
  241. if (GetGame().IsServer())
  242. {
  243. PlayerBase player_PB = PlayerBase.Cast(player);
  244. StartActivate(player_PB);
  245. }
  246. }
  247. override bool IsDeployable()
  248. {
  249. return true;
  250. }
  251. override string GetLoopDeploySoundset()
  252. {
  253. return "landmine_deploy_SoundSet";
  254. }
  255. override void SetActions()
  256. {
  257. super.SetActions();
  258. AddAction(ActionAttach);
  259. AddAction(ActionDetach);
  260. AddAction(ActionTogglePlaceObject);
  261. AddAction(ActionDeployObject);
  262. }
  263. #ifdef DEVELOPER
  264. //================================================================
  265. // DEBUG
  266. //================================================================
  267. //Debug menu Spawn Ground Special
  268. override void OnDebugSpawn()
  269. {
  270. StartActivate(null);
  271. }
  272. override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
  273. {
  274. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ACTIVATE_ENTITY, "Activate", FadeColors.LIGHT_GREY));
  275. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DEACTIVATE_ENTITY, "Deactivate", FadeColors.LIGHT_GREY));
  276. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.LIGHT_GREY));
  277. super.GetDebugActions(outputList);
  278. }
  279. override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
  280. {
  281. if (super.OnAction(action_id, player, ctx))
  282. return true;
  283. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  284. {
  285. if (action_id == EActions.ACTIVATE_ENTITY)
  286. {
  287. StartActivate(null);
  288. }
  289. else if (action_id == EActions.DEACTIVATE_ENTITY)
  290. {
  291. SetInactive();
  292. }
  293. }
  294. return false;
  295. }
  296. #endif
  297. }