1
0

SpawnPointSystem.cs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using Content.Server.GameTicking;
  2. using Content.Server.Spawners.Components;
  3. using Content.Server.Station.Systems;
  4. using Robust.Shared.Map;
  5. using Robust.Shared.Random;
  6. using Robust.Shared.Prototypes;
  7. namespace Content.Server.Spawners.EntitySystems;
  8. public sealed class SpawnPointSystem : EntitySystem
  9. {
  10. [Dependency] private readonly GameTicker _gameTicker = default!;
  11. [Dependency] private readonly IRobustRandom _random = default!;
  12. [Dependency] private readonly StationSystem _stationSystem = default!;
  13. [Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
  14. [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
  15. public override void Initialize()
  16. {
  17. SubscribeLocalEvent<PlayerSpawningEvent>(OnPlayerSpawning);
  18. }
  19. private void OnPlayerSpawning(PlayerSpawningEvent args)
  20. {
  21. if (args.SpawnResult != null)
  22. return;
  23. // TODO: Cache all this if it ends up important.
  24. var points = EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
  25. var possiblePositions = new List<EntityCoordinates>();
  26. while (points.MoveNext(out var uid, out var spawnPoint, out var xform))
  27. {
  28. if (args.Station != null && _stationSystem.GetOwningStation(uid, xform) != args.Station)
  29. continue;
  30. // Try to get the actual JobPrototype data from the ID (args.Job)
  31. if (args.Job != null && _prototypeManager.TryIndex(args.Job.Value, out var jobPrototype))
  32. {
  33. if (jobPrototype != null && jobPrototype.Faction == spawnPoint.Faction)
  34. {
  35. possiblePositions.Add(xform.Coordinates);
  36. }
  37. }
  38. if (_gameTicker.RunLevel == GameRunLevel.InRound && spawnPoint.SpawnType == SpawnPointType.LateJoin)
  39. {
  40. possiblePositions.Add(xform.Coordinates);
  41. }
  42. if (_gameTicker.RunLevel != GameRunLevel.InRound &&
  43. spawnPoint.SpawnType == SpawnPointType.Job &&
  44. (args.Job == null || spawnPoint.Job == args.Job))
  45. {
  46. possiblePositions.Add(xform.Coordinates);
  47. }
  48. }
  49. if (possiblePositions.Count == 0)
  50. {
  51. // Ok we've still not returned, but we need to put them /somewhere/.
  52. // TODO: Refactor gameticker spawning code so we don't have to do this!
  53. var points2 = EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
  54. if (points2.MoveNext(out var spawnPoint, out var xform))
  55. {
  56. possiblePositions.Add(xform.Coordinates);
  57. }
  58. else
  59. {
  60. Log.Error("No spawn points were available!");
  61. return;
  62. }
  63. }
  64. var spawnLoc = _random.Pick(possiblePositions);
  65. args.SpawnResult = _stationSpawning.SpawnPlayerMob(
  66. spawnLoc,
  67. args.Job,
  68. args.HumanoidCharacterProfile,
  69. args.Station);
  70. }
  71. }