1
0

ClumsySystem.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using Content.Shared.CCVar;
  2. using Content.Shared.Chemistry.Hypospray.Events;
  3. using Content.Shared.Climbing.Components;
  4. using Content.Shared.Climbing.Events;
  5. using Content.Shared.Damage;
  6. using Content.Shared.IdentityManagement;
  7. using Content.Shared.Medical;
  8. using Content.Shared.Popups;
  9. using Content.Shared.Stunnable;
  10. using Content.Shared.Weapons.Ranged.Events;
  11. using Robust.Shared.Audio.Systems;
  12. using Robust.Shared.Configuration;
  13. using Robust.Shared.Random;
  14. using Robust.Shared.Timing;
  15. namespace Content.Shared.Clumsy;
  16. public sealed class ClumsySystem : EntitySystem
  17. {
  18. [Dependency] private readonly IRobustRandom _random = default!;
  19. [Dependency] private readonly SharedStunSystem _stun = default!;
  20. [Dependency] private readonly SharedAudioSystem _audio = default!;
  21. [Dependency] private readonly SharedPopupSystem _popup = default!;
  22. [Dependency] private readonly DamageableSystem _damageable = default!;
  23. [Dependency] private readonly IGameTiming _timing = default!;
  24. [Dependency] private readonly IConfigurationManager _cfg = default!;
  25. public override void Initialize()
  26. {
  27. SubscribeLocalEvent<ClumsyComponent, SelfBeforeHyposprayInjectsEvent>(BeforeHyposprayEvent);
  28. SubscribeLocalEvent<ClumsyComponent, SelfBeforeDefibrillatorZapsEvent>(BeforeDefibrillatorZapsEvent);
  29. SubscribeLocalEvent<ClumsyComponent, SelfBeforeGunShotEvent>(BeforeGunShotEvent);
  30. SubscribeLocalEvent<ClumsyComponent, SelfBeforeClimbEvent>(OnBeforeClimbEvent);
  31. }
  32. // If you add more clumsy interactions add them in this section!
  33. #region Clumsy interaction events
  34. private void BeforeHyposprayEvent(Entity<ClumsyComponent> ent, ref SelfBeforeHyposprayInjectsEvent args)
  35. {
  36. // Clumsy people sometimes inject themselves! Apparently syringes are clumsy proof...
  37. // checks if ClumsyHypo is false, if so, skips.
  38. if (!ent.Comp.ClumsyHypo)
  39. return;
  40. if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
  41. return;
  42. args.TargetGettingInjected = args.EntityUsingHypospray;
  43. args.InjectMessageOverride = "hypospray-component-inject-self-clumsy-message";
  44. _audio.PlayPvs(ent.Comp.ClumsySound, ent);
  45. }
  46. private void BeforeDefibrillatorZapsEvent(Entity<ClumsyComponent> ent, ref SelfBeforeDefibrillatorZapsEvent args)
  47. {
  48. // Clumsy people sometimes defib themselves!
  49. // checks if ClumsyDefib is false, if so, skips.
  50. if (!ent.Comp.ClumsyDefib)
  51. return;
  52. if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
  53. return;
  54. args.DefibTarget = args.EntityUsingDefib;
  55. _audio.PlayPvs(ent.Comp.ClumsySound, ent);
  56. }
  57. private void BeforeGunShotEvent(Entity<ClumsyComponent> ent, ref SelfBeforeGunShotEvent args)
  58. {
  59. // Clumsy people sometimes can't shoot :(
  60. // checks if ClumsyGuns is false, if so, skips.
  61. if (!ent.Comp.ClumsyGuns)
  62. return;
  63. if (args.Gun.Comp.ClumsyProof)
  64. return;
  65. if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
  66. return;
  67. if (ent.Comp.GunShootFailDamage != null)
  68. _damageable.TryChangeDamage(ent, ent.Comp.GunShootFailDamage, origin: ent);
  69. _stun.TryParalyze(ent, ent.Comp.GunShootFailStunTime, true);
  70. // Apply salt to the wound ("Honk!") (No idea what this comment means)
  71. _audio.PlayPvs(ent.Comp.GunShootFailSound, ent);
  72. _audio.PlayPvs(ent.Comp.ClumsySound, ent);
  73. _popup.PopupEntity(Loc.GetString("gun-clumsy"), ent, ent);
  74. args.Cancel();
  75. }
  76. private void OnBeforeClimbEvent(Entity<ClumsyComponent> ent, ref SelfBeforeClimbEvent args)
  77. {
  78. // checks if ClumsyVaulting is false, if so, skips.
  79. if (!ent.Comp.ClumsyVaulting)
  80. return;
  81. // This event is called in shared, thats why it has all the extra prediction stuff.
  82. var rand = new System.Random((int)_timing.CurTick.Value);
  83. // If someone is putting you on the table, always get past the guard.
  84. if (!_cfg.GetCVar(CCVars.GameTableBonk) && args.PuttingOnTable == ent.Owner && !rand.Prob(ent.Comp.ClumsyDefaultCheck))
  85. return;
  86. HitHeadClumsy(ent, args.BeingClimbedOn);
  87. _audio.PlayPredicted(ent.Comp.ClumsySound, ent, ent);
  88. _audio.PlayPredicted(ent.Comp.TableBonkSound, ent, ent);
  89. var gettingPutOnTableName = Identity.Entity(args.GettingPutOnTable, EntityManager);
  90. var puttingOnTableName = Identity.Entity(args.PuttingOnTable, EntityManager);
  91. if (args.PuttingOnTable == ent.Owner)
  92. {
  93. // You are slamming yourself onto the table.
  94. _popup.PopupPredicted(
  95. Loc.GetString(ent.Comp.VaulingFailedMessageSelf, ("bonkable", args.BeingClimbedOn)),
  96. Loc.GetString(ent.Comp.VaulingFailedMessageOthers, ("victim", gettingPutOnTableName), ("bonkable", args.BeingClimbedOn)),
  97. ent,
  98. ent);
  99. }
  100. else
  101. {
  102. // Someone else slamed you onto the table.
  103. // This is only run in server so you need to use popup entity.
  104. _popup.PopupPredicted(
  105. Loc.GetString(ent.Comp.VaulingFailedMessageForced,
  106. ("bonker", puttingOnTableName),
  107. ("victim", gettingPutOnTableName),
  108. ("bonkable", args.BeingClimbedOn)),
  109. ent,
  110. null);
  111. }
  112. args.Cancel();
  113. }
  114. #endregion
  115. #region Helper functions
  116. /// <summary>
  117. /// "Hits" an entites head against the given table.
  118. /// </summary>
  119. // Oh this fucntion is public le- NO!! This is only public for the one admin command if you use this anywhere else I will cry.
  120. public void HitHeadClumsy(Entity<ClumsyComponent> target, EntityUid table)
  121. {
  122. var stunTime = target.Comp.ClumsyDefaultStunTime;
  123. if (TryComp<BonkableComponent>(table, out var bonkComp))
  124. {
  125. stunTime = bonkComp.BonkTime;
  126. if (bonkComp.BonkDamage != null)
  127. _damageable.TryChangeDamage(target, bonkComp.BonkDamage, true);
  128. }
  129. _stun.TryParalyze(target, stunTime, true);
  130. }
  131. #endregion
  132. }