trap_bear.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. class BearTrap extends TrapBase
  2. {
  3. static const int RAYCAST_SOURCES_COUNT = 5;
  4. // Raycasts start positions:
  5. // Positions are local to model. Vertical offset prevents ground collision.
  6. static const vector m_RaycastSources[RAYCAST_SOURCES_COUNT] = {
  7. "0.0 0.1 0.0", // center
  8. "0.2 0.1 0.2", // north east
  9. "-.2 0.1 0.2", // north west
  10. "0.2 0.1 -0.2", // south east
  11. "-0.2 0.1 -0.2" // south west
  12. };
  13. void BearTrap()
  14. {
  15. m_DamagePlayers = 5; // How much damage player gets when caught
  16. m_DamageOthers = 5; // How much damage other entities(CreatureAI) gets when caught
  17. m_DefectRate = 0;
  18. m_InitWaitTime = 0.0; // After this time after deployment, the trap is activated
  19. m_AnimationPhaseGrounded = "placing";
  20. m_AnimationPhaseSet = "BearTrap_Set";
  21. m_AnimationPhaseTriggered = "placing";
  22. }
  23. override bool CanBeDisarmed()
  24. {
  25. return true;
  26. }
  27. override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
  28. {
  29. super.EEHealthLevelChanged(oldLevel, newLevel, zone);
  30. if (GetGame().IsServer())
  31. {
  32. if (newLevel == GameConstants.STATE_RUINED)
  33. {
  34. SetInactive();
  35. }
  36. }
  37. }
  38. override void CreateTrigger()
  39. {
  40. super.CreateTrigger();
  41. vector mins = "-0.1 -0.05 -0.1";
  42. vector maxs = "0.1 0.4 0.1";
  43. m_TrapTrigger.SetOrientation(GetOrientation());
  44. m_TrapTrigger.SetExtents(mins, maxs);
  45. m_TrapTrigger.SetParentObject(this);
  46. }
  47. override void OnUpdate(EntityAI victim)
  48. {
  49. if (victim && victim.IsInherited(CarScript))
  50. {
  51. EntityAI wheel = GetClosestCarWheel(victim);
  52. if (wheel)
  53. {
  54. OnServerSteppedOn(wheel, "");
  55. }
  56. }
  57. }
  58. override void OnSteppedOn(EntityAI victim)
  59. {
  60. if (GetGame().IsServer() && victim)
  61. {
  62. if (!victim.GetAllowDamage())
  63. return;
  64. if (victim.IsInherited(CarScript))
  65. {
  66. //! CarScript specific reaction on BearTrap
  67. Param1<EntityAI> params = new Param1<EntityAI>(victim);
  68. m_UpdateTimer.Run(UPDATE_TIMER_INTERVAL, this, "OnUpdate", params, true);
  69. return;
  70. }
  71. else
  72. {
  73. foreach (vector raycastSourcePosition: m_RaycastSources)
  74. {
  75. vector raycastStart = ModelToWorld(raycastSourcePosition);
  76. vector raycastEnd = "0 0.5 0" + raycastStart;
  77. RaycastRVParams rayInput = new RaycastRVParams(raycastStart, raycastEnd, this);
  78. rayInput.flags = CollisionFlags.ALLOBJECTS;
  79. rayInput.type = ObjIntersectFire;
  80. rayInput.radius = 0.05;
  81. array<ref RaycastRVResult> results = new array<ref RaycastRVResult>();
  82. if (DayZPhysics.RaycastRVProxy(rayInput, results))
  83. {
  84. foreach (RaycastRVResult result: results)
  85. {
  86. if (result.obj && !result.obj.IsDamageDestroyed() && !result.obj.IsAnyInherited({ItemBase, Plant}))
  87. {
  88. OnServerSteppedOn(result.obj, result.obj.GetDamageZoneNameByComponentIndex(result.component));
  89. return;
  90. }
  91. }
  92. }
  93. }
  94. OnServerSteppedOn(victim, "zone_leg_random");
  95. }
  96. }
  97. else if (!GetGame().IsDedicatedServer()) //! this is also called on client (OnRPC->SnapOn->OnSteppedOn chain)
  98. {
  99. if (victim)
  100. {
  101. if (victim.IsInherited(PlayerBase))
  102. {
  103. victim.SpawnDamageDealtEffect();
  104. }
  105. PlaySoundBiteLeg();
  106. }
  107. }
  108. }
  109. override void OnSteppedOut(EntityAI victim)
  110. {
  111. if (victim.IsInherited(CarScript))
  112. {
  113. if (m_UpdateTimer && m_UpdateTimer.IsRunning())
  114. {
  115. m_UpdateTimer.Stop();
  116. }
  117. }
  118. }
  119. protected void OnServerSteppedOn(Object obj, string damageZone)
  120. {
  121. if (obj.IsInherited(CarWheel))
  122. {
  123. obj.ProcessDirectDamage(DamageType.CLOSE_COMBAT, this, damageZone, "BearTrapHit_CarWheel", "0 0 0", 1);
  124. if (m_UpdateTimer.IsRunning())
  125. {
  126. m_UpdateTimer.Stop();
  127. }
  128. SetInactive(false);
  129. Synch(EntityAI.Cast(obj));
  130. return;
  131. }
  132. if (obj.IsDamageDestroyed())
  133. return;
  134. string zoneUsed = damageZone;
  135. if (damageZone == "zone_leg_random")
  136. {
  137. zoneUsed = "LeftLeg";
  138. if (Math.RandomIntInclusive(0, 1) == 1)
  139. zoneUsed = "RightLeg";
  140. }
  141. //! Generic limp handling
  142. ZombieBase zombie;
  143. if (obj.IsInherited(PlayerBase) || (Class.CastTo(zombie,obj) && !zombie.IsCrawling() && Math.RandomIntInclusive(0, 1) == 1))
  144. {
  145. CauseVictimToStartLimping(obj, "");
  146. }
  147. obj.ProcessDirectDamage(DamageType.CLOSE_COMBAT, this, zoneUsed, "BearTrapHit", "0 0 0", 1);
  148. SetInactive(false);
  149. Synch(EntityAI.Cast(obj));
  150. }
  151. // Causes the player to start limping. This is temporary and should at some point be replaced by broken legs
  152. void CauseVictimToStartLimping(Object obj, string damagedZone)
  153. {
  154. PlayerBase player;
  155. ZombieBase zombie;
  156. if (Class.CastTo(player,obj))
  157. {
  158. player.DamageAllLegs(player.GetMaxHealth() * 2); //reduce legs health (not regular DamageSystem damage, does not transfer!)
  159. }
  160. else if (Class.CastTo(zombie,obj))
  161. {
  162. zombie.SetHealth("LeftLeg", "Health", 0.0);
  163. zombie.SetHealth("RightLeg", "Health", 0.0);
  164. }
  165. }
  166. void PlaySoundBiteLeg()
  167. {
  168. EffectSound sound = SEffectManager.PlaySound("beartrapCloseDamage_SoundSet", GetPosition(), 0, 0, false);
  169. sound.SetAutodestroy(true);
  170. }
  171. void PlaySoundBiteEmpty()
  172. {
  173. EffectSound sound = SEffectManager.PlaySound("beartrapClose_SoundSet", GetPosition(), 0, 0, false);
  174. sound.SetAutodestroy(true);
  175. }
  176. void PlaySoundOpen()
  177. {
  178. EffectSound sound = SEffectManager.PlaySound("beartrapOpen_SoundSet", GetPosition(), 0, 0, false);
  179. sound.SetAutodestroy(true);
  180. }
  181. override void OnActivate()
  182. {
  183. #ifndef SERVER
  184. PlaySoundOpen();
  185. #endif
  186. }
  187. override void OnDisarm()
  188. {
  189. #ifndef SERVER
  190. PlaySoundBiteEmpty();
  191. #endif
  192. }
  193. //================================================================
  194. // ADVANCED PLACEMENT
  195. //================================================================
  196. override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
  197. {
  198. super.OnPlacementComplete(player, position, orientation);
  199. if (GetGame().IsServer())
  200. {
  201. PlayerBase player_PB = PlayerBase.Cast(player);
  202. StartActivate(player_PB);
  203. }
  204. }
  205. override bool IsDeployable()
  206. {
  207. return true;
  208. }
  209. override string GetLoopDeploySoundset()
  210. {
  211. return "beartrap_deploy_SoundSet";
  212. }
  213. override void SetActions()
  214. {
  215. super.SetActions();
  216. AddAction(ActionClapBearTrapWithThisItem);
  217. AddAction(ActionTogglePlaceObject);
  218. AddAction(ActionDeployObject);
  219. }
  220. #ifdef DEVELOPER
  221. //================================================================
  222. // DEBUG
  223. //================================================================
  224. //Debug menu Spawn Ground Special
  225. override void OnDebugSpawn()
  226. {
  227. StartActivate(null);
  228. }
  229. override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
  230. {
  231. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ACTIVATE_ENTITY, "Activate", FadeColors.LIGHT_GREY));
  232. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DEACTIVATE_ENTITY, "Deactivate", FadeColors.LIGHT_GREY));
  233. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.LIGHT_GREY));
  234. super.GetDebugActions(outputList);
  235. }
  236. override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
  237. {
  238. if (super.OnAction(action_id, player, ctx))
  239. return true;
  240. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  241. {
  242. if (action_id == EActions.ACTIVATE_ENTITY)
  243. {
  244. StartActivate(null);
  245. }
  246. else if (action_id == EActions.DEACTIVATE_ENTITY)
  247. {
  248. SetInactive();
  249. }
  250. }
  251. return false;
  252. }
  253. #endif
  254. }