1
0

RoundstartStationVariationRuleSystem.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. using System.Linq;
  2. using Content.Server.GameTicking.Rules.Components;
  3. using Content.Server.Shuttles.Systems;
  4. using Content.Server.Station.Components;
  5. using Content.Server.Station.Events;
  6. using Content.Shared.GameTicking.Components;
  7. using Content.Shared.Storage;
  8. using Robust.Shared.Prototypes;
  9. using Robust.Shared.Random;
  10. namespace Content.Server.GameTicking.Rules;
  11. /// <inheritdoc cref="RoundstartStationVariationRuleComponent"/>
  12. public sealed class RoundstartStationVariationRuleSystem : GameRuleSystem<RoundstartStationVariationRuleComponent>
  13. {
  14. [Dependency] private readonly IRobustRandom _random = default!;
  15. public override void Initialize()
  16. {
  17. base.Initialize();
  18. SubscribeLocalEvent<StationPostInitEvent>(OnStationPostInit, after: new []{typeof(ShuttleSystem)});
  19. }
  20. protected override void Added(EntityUid uid, RoundstartStationVariationRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
  21. {
  22. var spawns = EntitySpawnCollection.GetSpawns(component.Rules, _random);
  23. foreach (var rule in spawns)
  24. {
  25. GameTicker.AddGameRule(rule);
  26. }
  27. }
  28. private void OnStationPostInit(ref StationPostInitEvent ev)
  29. {
  30. // as long as one is running
  31. if (!GameTicker.IsGameRuleAdded<RoundstartStationVariationRuleComponent>())
  32. return;
  33. // this is unlikely, but could theoretically happen if it was saved and reloaded, so check anyway
  34. if (HasComp<StationVariationHasRunComponent>(ev.Station))
  35. return;
  36. Log.Info($"Running variation rules for station {ToPrettyString(ev.Station)}");
  37. // raise the event on any passes that have been added
  38. var passEv = new StationVariationPassEvent(ev.Station);
  39. var passQuery = EntityQueryEnumerator<StationVariationPassRuleComponent, GameRuleComponent>();
  40. while (passQuery.MoveNext(out var uid, out _, out _))
  41. {
  42. // TODO: for some reason, ending a game rule just gives it a marker comp,
  43. // and doesnt delete it
  44. // so we have to check here that it isnt an ended game rule (which could happen if a preset failed to start
  45. // or it was ended before station maps spawned etc etc etc)
  46. if (HasComp<EndedGameRuleComponent>(uid))
  47. continue;
  48. RaiseLocalEvent(uid, ref passEv);
  49. }
  50. EnsureComp<StationVariationHasRunComponent>(ev.Station);
  51. }
  52. }
  53. /// <summary>
  54. /// Raised directed on game rule entities which are added and marked as <see cref="StationVariationPassRuleComponent"/>
  55. /// when a new station is initialized that should be varied.
  56. /// </summary>
  57. /// <param name="Station">The new station that was added, and its config & grids.</param>
  58. [ByRefEvent]
  59. public readonly record struct StationVariationPassEvent(Entity<StationDataComponent> Station);