SalvageSystem.Expeditions.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. using System.Linq;
  2. using System.Threading;
  3. using Content.Server.Salvage.Expeditions;
  4. using Content.Server.Salvage.Expeditions.Structure;
  5. using Content.Shared.CCVar;
  6. using Content.Shared.Examine;
  7. using Content.Shared.Random.Helpers;
  8. using Content.Shared.Salvage.Expeditions;
  9. using Robust.Shared.Audio;
  10. using Robust.Shared.CPUJob.JobQueues;
  11. using Robust.Shared.CPUJob.JobQueues.Queues;
  12. using Robust.Shared.GameStates;
  13. using Robust.Shared.Map;
  14. namespace Content.Server.Salvage;
  15. public sealed partial class SalvageSystem
  16. {
  17. /*
  18. * Handles setup / teardown of salvage expeditions.
  19. */
  20. private const int MissionLimit = 3;
  21. private readonly JobQueue _salvageQueue = new();
  22. private readonly List<(SpawnSalvageMissionJob Job, CancellationTokenSource CancelToken)> _salvageJobs = new();
  23. private const double SalvageJobTime = 0.002;
  24. private float _cooldown;
  25. private void InitializeExpeditions()
  26. {
  27. SubscribeLocalEvent<SalvageExpeditionConsoleComponent, ComponentInit>(OnSalvageConsoleInit);
  28. SubscribeLocalEvent<SalvageExpeditionConsoleComponent, EntParentChangedMessage>(OnSalvageConsoleParent);
  29. SubscribeLocalEvent<SalvageExpeditionConsoleComponent, ClaimSalvageMessage>(OnSalvageClaimMessage);
  30. SubscribeLocalEvent<SalvageExpeditionComponent, MapInitEvent>(OnExpeditionMapInit);
  31. SubscribeLocalEvent<SalvageExpeditionComponent, ComponentShutdown>(OnExpeditionShutdown);
  32. SubscribeLocalEvent<SalvageExpeditionComponent, ComponentGetState>(OnExpeditionGetState);
  33. SubscribeLocalEvent<SalvageStructureComponent, ExaminedEvent>(OnStructureExamine);
  34. _cooldown = _configurationManager.GetCVar(CCVars.SalvageExpeditionCooldown);
  35. Subs.CVar(_configurationManager, CCVars.SalvageExpeditionCooldown, SetCooldownChange);
  36. }
  37. private void OnExpeditionGetState(EntityUid uid, SalvageExpeditionComponent component, ref ComponentGetState args)
  38. {
  39. args.State = new SalvageExpeditionComponentState()
  40. {
  41. Stage = component.Stage
  42. };
  43. }
  44. private void SetCooldownChange(float obj)
  45. {
  46. // Update the active cooldowns if we change it.
  47. var diff = obj - _cooldown;
  48. var query = AllEntityQuery<SalvageExpeditionDataComponent>();
  49. while (query.MoveNext(out var comp))
  50. {
  51. comp.NextOffer += TimeSpan.FromSeconds(diff);
  52. }
  53. _cooldown = obj;
  54. }
  55. private void OnExpeditionMapInit(EntityUid uid, SalvageExpeditionComponent component, MapInitEvent args)
  56. {
  57. component.SelectedSong = _audio.ResolveSound(component.Sound);
  58. }
  59. private void OnExpeditionShutdown(EntityUid uid, SalvageExpeditionComponent component, ComponentShutdown args)
  60. {
  61. component.Stream = _audio.Stop(component.Stream);
  62. foreach (var (job, cancelToken) in _salvageJobs.ToArray())
  63. {
  64. if (job.Station == component.Station)
  65. {
  66. cancelToken.Cancel();
  67. _salvageJobs.Remove((job, cancelToken));
  68. }
  69. }
  70. if (Deleted(component.Station))
  71. return;
  72. // Finish mission
  73. if (TryComp<SalvageExpeditionDataComponent>(component.Station, out var data))
  74. {
  75. FinishExpedition((component.Station, data), uid);
  76. }
  77. }
  78. private void UpdateExpeditions()
  79. {
  80. var currentTime = _timing.CurTime;
  81. _salvageQueue.Process();
  82. foreach (var (job, cancelToken) in _salvageJobs.ToArray())
  83. {
  84. switch (job.Status)
  85. {
  86. case JobStatus.Finished:
  87. _salvageJobs.Remove((job, cancelToken));
  88. break;
  89. }
  90. }
  91. var query = EntityQueryEnumerator<SalvageExpeditionDataComponent>();
  92. while (query.MoveNext(out var uid, out var comp))
  93. {
  94. // Update offers
  95. if (comp.NextOffer > currentTime || comp.Claimed)
  96. continue;
  97. comp.Cooldown = false;
  98. comp.NextOffer += TimeSpan.FromSeconds(_cooldown);
  99. GenerateMissions(comp);
  100. UpdateConsoles((uid, comp));
  101. }
  102. }
  103. private void FinishExpedition(Entity<SalvageExpeditionDataComponent> expedition, EntityUid uid)
  104. {
  105. var component = expedition.Comp;
  106. component.NextOffer = _timing.CurTime + TimeSpan.FromSeconds(_cooldown);
  107. Announce(uid, Loc.GetString("salvage-expedition-mission-completed"));
  108. component.ActiveMission = 0;
  109. component.Cooldown = true;
  110. UpdateConsoles(expedition);
  111. }
  112. private void GenerateMissions(SalvageExpeditionDataComponent component)
  113. {
  114. component.Missions.Clear();
  115. for (var i = 0; i < MissionLimit; i++)
  116. {
  117. var mission = new SalvageMissionParams
  118. {
  119. Index = component.NextIndex,
  120. Seed = _random.Next(),
  121. Difficulty = "Moderate",
  122. };
  123. component.Missions[component.NextIndex++] = mission;
  124. }
  125. }
  126. private SalvageExpeditionConsoleState GetState(SalvageExpeditionDataComponent component)
  127. {
  128. var missions = component.Missions.Values.ToList();
  129. return new SalvageExpeditionConsoleState(component.NextOffer, component.Claimed, component.Cooldown, component.ActiveMission, missions);
  130. }
  131. private void SpawnMission(SalvageMissionParams missionParams, EntityUid station, EntityUid? coordinatesDisk)
  132. {
  133. var cancelToken = new CancellationTokenSource();
  134. var job = new SpawnSalvageMissionJob(
  135. SalvageJobTime,
  136. EntityManager,
  137. _timing,
  138. _logManager,
  139. _mapManager,
  140. _prototypeManager,
  141. _anchorable,
  142. _biome,
  143. _dungeon,
  144. _metaData,
  145. _transform,
  146. _mapSystem,
  147. station,
  148. coordinatesDisk,
  149. missionParams,
  150. cancelToken.Token);
  151. _salvageJobs.Add((job, cancelToken));
  152. _salvageQueue.EnqueueJob(job);
  153. }
  154. private void OnStructureExamine(EntityUid uid, SalvageStructureComponent component, ExaminedEvent args)
  155. {
  156. args.PushMarkup(Loc.GetString("salvage-expedition-structure-examine"));
  157. }
  158. }