SuperBonkSystem.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. using Content.Server.Administration.Components;
  2. using Content.Shared.Climbing.Components;
  3. using Content.Shared.Clumsy;
  4. using Content.Shared.Mobs;
  5. using Content.Shared.Mobs.Components;
  6. using Robust.Shared.Audio.Systems;
  7. namespace Content.Server.Administration.Systems;
  8. public sealed class SuperBonkSystem : EntitySystem
  9. {
  10. [Dependency] private readonly SharedTransformSystem _transformSystem = default!;
  11. [Dependency] private readonly ClumsySystem _clumsySystem = default!;
  12. [Dependency] private readonly SharedAudioSystem _audioSystem = default!;
  13. public override void Initialize()
  14. {
  15. base.Initialize();
  16. SubscribeLocalEvent<SuperBonkComponent, MobStateChangedEvent>(OnMobStateChanged);
  17. SubscribeLocalEvent<SuperBonkComponent, ComponentShutdown>(OnBonkShutdown);
  18. }
  19. public void StartSuperBonk(EntityUid target, float delay = 0.1f, bool stopWhenDead = false)
  20. {
  21. //The other check in the code to stop when the target dies does not work if the target is already dead.
  22. if (stopWhenDead && TryComp<MobStateComponent>(target, out var mState))
  23. {
  24. if (mState.CurrentState == MobState.Dead)
  25. return;
  26. }
  27. var hadClumsy = EnsureComp<ClumsyComponent>(target, out _);
  28. var tables = EntityQueryEnumerator<BonkableComponent>();
  29. var bonks = new Dictionary<EntityUid, BonkableComponent>();
  30. // This is done so we don't crash if something like a new table is spawned.
  31. while (tables.MoveNext(out var uid, out var comp))
  32. {
  33. bonks.Add(uid, comp);
  34. }
  35. var sComp = new SuperBonkComponent
  36. {
  37. Target = target,
  38. Tables = bonks.GetEnumerator(),
  39. RemoveClumsy = !hadClumsy,
  40. StopWhenDead = stopWhenDead,
  41. };
  42. AddComp(target, sComp);
  43. }
  44. public override void Update(float frameTime)
  45. {
  46. base.Update(frameTime);
  47. var comps = EntityQueryEnumerator<SuperBonkComponent>();
  48. while (comps.MoveNext(out var uid, out var comp))
  49. {
  50. comp.TimeRemaining -= frameTime;
  51. if (!(comp.TimeRemaining <= 0))
  52. continue;
  53. Bonk(comp);
  54. if (!(comp.Tables.MoveNext()))
  55. {
  56. RemComp<SuperBonkComponent>(comp.Target);
  57. continue;
  58. }
  59. comp.TimeRemaining = comp.InitialTime;
  60. }
  61. }
  62. private void Bonk(SuperBonkComponent comp)
  63. {
  64. var uid = comp.Tables.Current.Key;
  65. // It would be very weird for something without a transform component to have a bonk component
  66. // but just in case because I don't want to crash the server.
  67. if (!HasComp<TransformComponent>(uid) || !TryComp<ClumsyComponent>(comp.Target, out var clumsyComp))
  68. return;
  69. _transformSystem.SetCoordinates(comp.Target, Transform(uid).Coordinates);
  70. _clumsySystem.HitHeadClumsy((comp.Target, clumsyComp), uid);
  71. _audioSystem.PlayPvs(clumsyComp.TableBonkSound, comp.Target);
  72. }
  73. private void OnMobStateChanged(EntityUid uid, SuperBonkComponent comp, MobStateChangedEvent args)
  74. {
  75. if (comp.StopWhenDead && args.NewMobState == MobState.Dead)
  76. {
  77. RemComp<SuperBonkComponent>(uid);
  78. }
  79. }
  80. private void OnBonkShutdown(EntityUid uid, SuperBonkComponent comp, ComponentShutdown ev)
  81. {
  82. if (comp.RemoveClumsy)
  83. RemComp<ClumsyComponent>(comp.Target);
  84. }
  85. }