trap_tripwire.c 10 KB

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