1
0

DragonRiftSystem.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using Content.Server.Chat.Systems;
  2. using Content.Server.NPC;
  3. using Content.Server.NPC.Systems;
  4. using Content.Server.Pinpointer;
  5. using Content.Shared.Damage;
  6. using Content.Shared.Dragon;
  7. using Content.Shared.Examine;
  8. using Content.Shared.Sprite;
  9. using Robust.Shared.GameObjects;
  10. using Robust.Shared.Map;
  11. using Robust.Shared.Player;
  12. using Robust.Shared.Serialization.Manager;
  13. using System.Numerics;
  14. using Robust.Shared.Audio;
  15. using Robust.Shared.Audio.Systems;
  16. using Robust.Shared.Utility;
  17. namespace Content.Server.Dragon;
  18. /// <summary>
  19. /// Handles events for rift entities and rift updating.
  20. /// </summary>
  21. public sealed class DragonRiftSystem : EntitySystem
  22. {
  23. [Dependency] private readonly ChatSystem _chat = default!;
  24. [Dependency] private readonly DragonSystem _dragon = default!;
  25. [Dependency] private readonly ISerializationManager _serManager = default!;
  26. [Dependency] private readonly NavMapSystem _navMap = default!;
  27. [Dependency] private readonly NPCSystem _npc = default!;
  28. [Dependency] private readonly SharedAudioSystem _audio = default!;
  29. public override void Initialize()
  30. {
  31. base.Initialize();
  32. SubscribeLocalEvent<DragonRiftComponent, ExaminedEvent>(OnExamined);
  33. SubscribeLocalEvent<DragonRiftComponent, AnchorStateChangedEvent>(OnAnchorChange);
  34. SubscribeLocalEvent<DragonRiftComponent, ComponentShutdown>(OnShutdown);
  35. }
  36. public override void Update(float frameTime)
  37. {
  38. base.Update(frameTime);
  39. var query = EntityQueryEnumerator<DragonRiftComponent, TransformComponent>();
  40. while (query.MoveNext(out var uid, out var comp, out var xform))
  41. {
  42. if (comp.State != DragonRiftState.Finished && comp.Accumulator >= comp.MaxAccumulator)
  43. {
  44. // TODO: When we get autocall you can buff if the rift finishes / 3 rifts are up
  45. // for now they just keep 3 rifts up.
  46. if (comp.Dragon != null)
  47. _dragon.RiftCharged(comp.Dragon.Value);
  48. comp.Accumulator = comp.MaxAccumulator;
  49. RemComp<DamageableComponent>(uid);
  50. comp.State = DragonRiftState.Finished;
  51. Dirty(uid, comp);
  52. }
  53. else if (comp.State != DragonRiftState.Finished)
  54. {
  55. comp.Accumulator += frameTime;
  56. }
  57. comp.SpawnAccumulator += frameTime;
  58. if (comp.State < DragonRiftState.AlmostFinished && comp.Accumulator > comp.MaxAccumulator / 2f)
  59. {
  60. comp.State = DragonRiftState.AlmostFinished;
  61. Dirty(uid, comp);
  62. var msg = Loc.GetString("carp-rift-warning",
  63. ("location", FormattedMessage.RemoveMarkupOrThrow(_navMap.GetNearestBeaconString((uid, xform)))));
  64. _chat.DispatchGlobalAnnouncement(msg, playSound: false, colorOverride: Color.Red);
  65. _audio.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), true);
  66. _navMap.SetBeaconEnabled(uid, true);
  67. }
  68. if (comp.SpawnAccumulator > comp.SpawnCooldown)
  69. {
  70. comp.SpawnAccumulator -= comp.SpawnCooldown;
  71. var ent = Spawn(comp.SpawnPrototype, xform.Coordinates);
  72. // Update their look to match the leader.
  73. if (TryComp<RandomSpriteComponent>(comp.Dragon, out var randomSprite))
  74. {
  75. var spawnedSprite = EnsureComp<RandomSpriteComponent>(ent);
  76. _serManager.CopyTo(randomSprite, ref spawnedSprite, notNullableOverride: true);
  77. Dirty(ent, spawnedSprite);
  78. }
  79. if (comp.Dragon != null)
  80. _npc.SetBlackboard(ent, NPCBlackboard.FollowTarget, new EntityCoordinates(comp.Dragon.Value, Vector2.Zero));
  81. }
  82. }
  83. }
  84. private void OnExamined(EntityUid uid, DragonRiftComponent component, ExaminedEvent args)
  85. {
  86. args.PushMarkup(Loc.GetString("carp-rift-examine", ("percentage", MathF.Round(component.Accumulator / component.MaxAccumulator * 100))));
  87. }
  88. private void OnAnchorChange(EntityUid uid, DragonRiftComponent component, ref AnchorStateChangedEvent args)
  89. {
  90. if (!args.Anchored && component.State == DragonRiftState.Charging)
  91. {
  92. QueueDel(uid);
  93. }
  94. }
  95. private void OnShutdown(EntityUid uid, DragonRiftComponent comp, ComponentShutdown args)
  96. {
  97. if (!TryComp<DragonComponent>(comp.Dragon, out var dragon) || dragon.Weakened)
  98. return;
  99. _dragon.RiftDestroyed(comp.Dragon.Value, dragon);
  100. }
  101. }