trap_tripwire.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. // Wire type is used in the case of decrafting to give back the correct base Ingredient
  2. enum eWireMaterial
  3. {
  4. WIRE = 0,
  5. BARBED_WIRE = 1,
  6. ROPE = 2
  7. }
  8. class TripwireTrap : TrapBase
  9. {
  10. // Current state of the tripwire
  11. static const int FOLDED = 3;
  12. static const int DEPLOYED = 2;
  13. static const int TRIGGERED = 1;
  14. int m_State = FOLDED;
  15. private int m_WireMaterial;
  16. protected bool m_ResultOfAdvancedPlacing;
  17. protected vector m_TriggerPosition;
  18. protected vector m_TriggerOrientation;
  19. void TripwireTrap()
  20. {
  21. m_DamagePlayers = 0; //How much damage player gets when caught
  22. m_InitWaitTime = 0.0; //After this time after deployment, the trap is activated
  23. m_DefectRate = 15;
  24. m_NeedActivation = false;
  25. m_AnimationPhaseGrounded = "inventory";
  26. m_AnimationPhaseSet = "placing";
  27. m_AnimationPhaseTriggered = "triggered";
  28. m_InfoActivationTime = string.Format("#STR_TripwireTrap0%1#STR_TripwireTrap1", m_InitWaitTime.ToString()); // nefunguje dynamicke vyrazy mimo funkcii
  29. RegisterNetSyncVariableInt("m_State");
  30. }
  31. override void OnStoreSave(ParamsWriteContext ctx)
  32. {
  33. super.OnStoreSave(ctx);
  34. ctx.Write( m_State );
  35. }
  36. //----------------------------------------------------------------
  37. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  38. {
  39. if ( !super.OnStoreLoad(ctx, version) )
  40. return false;
  41. int state = FOLDED;
  42. if ( !ctx.Read( state ) )
  43. state = FOLDED;
  44. SetState( state );
  45. RefreshState();
  46. return true;
  47. }
  48. override void CreateTrigger()
  49. {
  50. m_TrapTrigger = TripWireTrigger.Cast(GetGame().CreateObjectEx("TripWireTrigger", GetPosition(), SPAWN_FLAGS));
  51. vector mins = "-0.75 0.3 -0.01";
  52. vector maxs = "0.75 0.32 0.01";
  53. m_TrapTrigger.SetOrientation(GetOrientation());
  54. m_TrapTrigger.SetExtents(mins, maxs);
  55. m_TrapTrigger.SetParentObject(this);
  56. GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Call(DeferredEnableTrigger);
  57. }
  58. override void OnSteppedOn(EntityAI victim)
  59. {
  60. if (!victim)
  61. {
  62. return;
  63. }
  64. if (!victim.GetAllowDamage())
  65. {
  66. return;
  67. }
  68. // We must deal some damage, here 5 shock as melee damage in order to trigger hit animation
  69. if (GetGame().IsServer())
  70. {
  71. victim.ProcessDirectDamage(DamageType.CLOSE_COMBAT, this, "", "TripWireHit", "0 0 0", 1);
  72. SetState(TRIGGERED);
  73. SetInactive(false);
  74. }
  75. // We play the trap trigger sound
  76. #ifndef SERVER
  77. EffectSound sound = SEffectManager.PlaySound("TripwireTrap_Trigger_SoundSet", GetPosition());
  78. sound.SetAutodestroy(true);
  79. #endif
  80. }
  81. override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
  82. {
  83. super.OnItemLocationChanged(old_owner, new_owner);
  84. PlayerBase player = PlayerBase.Cast(new_owner);
  85. if (player)
  86. {
  87. StartDeactivate(player);
  88. return;
  89. }
  90. }
  91. override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
  92. {
  93. super.EEItemLocationChanged(oldLoc, newLoc);
  94. if (m_ResultOfAdvancedPlacing)
  95. {
  96. if (oldLoc.GetType() == InventoryLocationType.GROUND && newLoc.GetType() == InventoryLocationType.GROUND)
  97. {
  98. SetActive();
  99. m_TrapTrigger.SetPosition(m_TriggerPosition);
  100. m_TrapTrigger.SetOrientation(m_TriggerOrientation);
  101. }
  102. m_ResultOfAdvancedPlacing = false;
  103. }
  104. if (oldLoc.GetType() == InventoryLocationType.GROUND && newLoc.GetType() == InventoryLocationType.CARGO)
  105. {
  106. SetInactive();
  107. DeleteTrigger();
  108. SetState(FOLDED);
  109. RefreshState();
  110. }
  111. }
  112. override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
  113. {
  114. super.EEHealthLevelChanged(oldLevel, newLevel, zone);
  115. if (GetGame().IsServer())
  116. {
  117. if (newLevel == GameConstants.STATE_RUINED)
  118. {
  119. SetState(TRIGGERED);
  120. RefreshState();
  121. }
  122. }
  123. }
  124. override void SetInactive(bool stop_timer = true)
  125. {
  126. super.SetInactive(stop_timer);
  127. // de-attach attachments after "activating them"
  128. for (int att = 0; att < GetInventory().AttachmentCount(); att++)
  129. {
  130. ItemBase attachment = ItemBase.Cast(GetInventory().GetAttachmentFromIndex(att));
  131. if (attachment)
  132. {
  133. if (attachment.IsLockedInSlot())
  134. {
  135. attachment.UnlockFromParent();
  136. }
  137. attachment.OnActivatedByItem(this);
  138. GetInventory().DropEntity(InventoryMode.SERVER, this, attachment);
  139. }
  140. }
  141. }
  142. void SetState(int state_ID)
  143. {
  144. m_State = state_ID;
  145. }
  146. int GetState()
  147. {
  148. return m_State;
  149. }
  150. void SetWireType( int wireType )
  151. {
  152. m_WireMaterial = wireType;
  153. }
  154. int GetWireType()
  155. {
  156. return m_WireMaterial;
  157. }
  158. override void RefreshState()
  159. {
  160. super.RefreshState();
  161. if (GetState() == FOLDED)
  162. {
  163. FoldTripWire();
  164. }
  165. }
  166. override void SetupTrapPlayer( PlayerBase player, bool set_position = true )
  167. {
  168. super.SetupTrapPlayer( player, set_position );
  169. SetState(DEPLOYED);
  170. }
  171. override void StartDeactivate(PlayerBase player)
  172. {
  173. super.StartDeactivate(player);
  174. DeleteTrigger();
  175. SetState(FOLDED);
  176. }
  177. // We do not want players to attach charges before trap is deployed
  178. override bool CanReceiveAttachment( EntityAI attachment, int slotId )
  179. {
  180. if ( GetState() != DEPLOYED )
  181. return false;
  182. return super.CanReceiveAttachment( attachment, slotId );
  183. }
  184. // As players cannot attch charges, we do not display the attachment slot before it is necessary
  185. override bool CanDisplayAttachmentSlot( int slot_id )
  186. {
  187. if ( GetState() != DEPLOYED )
  188. return false;
  189. return super.CanDisplayAttachmentSlot( slot_id );
  190. }
  191. override void EEItemAttached(EntityAI item, string slot_name)
  192. {
  193. super.EEItemAttached(item, slot_name);
  194. SetTakeable(false);
  195. }
  196. override void EEItemDetached(EntityAI item, string slot_name)
  197. {
  198. super.EEItemDetached(item, slot_name);
  199. SetTakeable(false);
  200. }
  201. override void EEKilled(Object killer)
  202. {
  203. if (m_TrapTrigger)
  204. {
  205. StartDeactivate(null);
  206. }
  207. super.EEKilled(killer);
  208. }
  209. // We reset the animation phases to see the tripwire as folded
  210. void FoldTripWire()
  211. {
  212. if ( m_AnimationPhaseGrounded != "" )
  213. {
  214. SetAnimationPhase( m_AnimationPhaseSet, 1 );
  215. if ( m_AnimationPhaseTriggered != m_AnimationPhaseGrounded )
  216. {
  217. SetAnimationPhase( m_AnimationPhaseTriggered, 1 );
  218. }
  219. SetAnimationPhase( m_AnimationPhaseGrounded, 0 );
  220. }
  221. }
  222. override void OnInventoryEnter( Man player )
  223. {
  224. SetState( FOLDED );
  225. }
  226. #ifdef PLATFORM_WINDOWS
  227. // How one sees the tripwire when in vicinity
  228. override int GetViewIndex()
  229. {
  230. if ( MemoryPointExists( "invView2" ) )
  231. {
  232. InventoryLocation il = new InventoryLocation;
  233. GetInventory().GetCurrentInventoryLocation( il );
  234. InventoryLocationType type = il.GetType();
  235. switch ( type )
  236. {
  237. case InventoryLocationType.CARGO:
  238. {
  239. return 0;
  240. }
  241. case InventoryLocationType.ATTACHMENT:
  242. {
  243. return 1;
  244. }
  245. case InventoryLocationType.HANDS:
  246. {
  247. return 0;
  248. }
  249. case InventoryLocationType.GROUND:
  250. {
  251. // Different view index depending on deployment state
  252. if ( GetState() == DEPLOYED )
  253. return 1;
  254. else if ( GetState() == TRIGGERED )
  255. return 2;
  256. // When folded
  257. return 0;
  258. }
  259. case InventoryLocationType.PROXYCARGO:
  260. {
  261. return 0;
  262. }
  263. default:
  264. {
  265. if ( GetState() == DEPLOYED )
  266. return 1;
  267. else if ( GetState() == TRIGGERED )
  268. return 2;
  269. // When folded
  270. return 0;
  271. }
  272. }
  273. }
  274. return 0;
  275. }
  276. #endif
  277. //================================================================
  278. // ADVANCED PLACEMENT
  279. //================================================================
  280. // On placement complete, set state, play sound, create trigger and synch to client
  281. override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
  282. {
  283. if (GetGame().IsServer())
  284. {
  285. SetState(DEPLOYED);
  286. m_TriggerPosition = position;
  287. m_TriggerOrientation = orientation;
  288. m_ResultOfAdvancedPlacing = true;
  289. }
  290. super.OnPlacementComplete(player, position, orientation);
  291. }
  292. override void OnPlacementCancelled(Man player)
  293. {
  294. super.OnPlacementCancelled(player);
  295. SetState(FOLDED);
  296. m_ResultOfAdvancedPlacing = false;
  297. }
  298. override bool IsDeployable()
  299. {
  300. return true;
  301. }
  302. // Tripwire cannot be taken if deployed with attachment
  303. override bool IsTakeable()
  304. {
  305. return GetState() != DEPLOYED || (GetInventory().AttachmentCount() == 0 && GetState() == DEPLOYED);
  306. }
  307. override string GetDeploySoundset()
  308. {
  309. return "tripwire_deploy_SoundSet";
  310. }
  311. override string GetLoopDeploySoundset()
  312. {
  313. return "tripwiretrap_deploy_SoundSet";
  314. }
  315. override void SetActions()
  316. {
  317. super.SetActions();
  318. AddAction(ActionTogglePlaceObject);
  319. AddAction(ActionDeployObject);
  320. }
  321. // ====================================
  322. // =========== DEPRECATED ===========
  323. // ====================================
  324. void UpdateProxySelections()
  325. {
  326. if ( GetInventory().AttachmentCount() > 0)
  327. {
  328. ItemBase attachment = ItemBase.Cast( GetInventory().GetAttachmentFromIndex(0) );
  329. if ( attachment )
  330. {
  331. // Hide all proxies
  332. for (int i = 1; i <= 3; i++)
  333. {
  334. HideSelection("s" + i + "_charge");
  335. }
  336. // Now show the one we need to see
  337. string proxy_to_show = string.Format("s%1_charge", GetState() );
  338. //Print(proxy_to_show);
  339. ShowSelection( proxy_to_show );
  340. }
  341. }
  342. }
  343. #ifdef DEVELOPER
  344. //================================================================
  345. // DEBUG
  346. //================================================================
  347. //Debug menu Spawn Ground Special
  348. override void OnDebugSpawn()
  349. {
  350. SetState(DEPLOYED);
  351. StartActivate(null);
  352. }
  353. override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
  354. {
  355. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ACTIVATE_ENTITY, "Activate", FadeColors.LIGHT_GREY));
  356. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DEACTIVATE_ENTITY, "Deactivate", FadeColors.LIGHT_GREY));
  357. outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.LIGHT_GREY));
  358. super.GetDebugActions(outputList);
  359. }
  360. override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
  361. {
  362. if (super.OnAction(action_id, player, ctx))
  363. return true;
  364. if (GetGame().IsServer() || !GetGame().IsMultiplayer())
  365. {
  366. if (action_id == EActions.ACTIVATE_ENTITY)
  367. {
  368. StartActivate(null);
  369. }
  370. else if (action_id == EActions.DEACTIVATE_ENTITY)
  371. {
  372. SetInactive();
  373. }
  374. }
  375. return false;
  376. }
  377. #endif
  378. }
  379. class TripwireTrapDeployed : TripwireTrap
  380. {
  381. }