1
0

ContainerSpawnPointSystem.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using Content.Server.GameTicking;
  2. using Content.Server.Spawners.Components;
  3. using Content.Server.Station.Systems;
  4. using Content.Shared.Preferences;
  5. using Content.Shared.Roles;
  6. using Robust.Server.Containers;
  7. using Robust.Shared.Containers;
  8. using Robust.Shared.Prototypes;
  9. using Robust.Shared.Random;
  10. namespace Content.Server.Spawners.EntitySystems;
  11. public sealed class ContainerSpawnPointSystem : EntitySystem
  12. {
  13. [Dependency] private readonly ContainerSystem _container = default!;
  14. [Dependency] private readonly GameTicker _gameTicker = default!;
  15. [Dependency] private readonly IPrototypeManager _proto = default!;
  16. [Dependency] private readonly IRobustRandom _random = default!;
  17. [Dependency] private readonly StationSystem _station = default!;
  18. [Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
  19. public override void Initialize()
  20. {
  21. base.Initialize();
  22. SubscribeLocalEvent<PlayerSpawningEvent>(HandlePlayerSpawning, before: new []{ typeof(SpawnPointSystem) });
  23. }
  24. public void HandlePlayerSpawning(PlayerSpawningEvent args)
  25. {
  26. if (args.SpawnResult != null)
  27. return;
  28. // If it's just a spawn pref check if it's for cryo (silly).
  29. if (args.HumanoidCharacterProfile?.SpawnPriority != SpawnPriorityPreference.Cryosleep &&
  30. (!_proto.TryIndex(args.Job, out var jobProto) || jobProto.JobEntity == null))
  31. {
  32. return;
  33. }
  34. var query = EntityQueryEnumerator<ContainerSpawnPointComponent, ContainerManagerComponent, TransformComponent>();
  35. var possibleContainers = new List<Entity<ContainerSpawnPointComponent, ContainerManagerComponent, TransformComponent>>();
  36. while (query.MoveNext(out var uid, out var spawnPoint, out var container, out var xform))
  37. {
  38. if (args.Station != null && _station.GetOwningStation(uid, xform) != args.Station)
  39. continue;
  40. // If it's unset, then we allow it to be used for both roundstart and midround joins
  41. if (spawnPoint.SpawnType == SpawnPointType.Unset)
  42. {
  43. // make sure we also check the job here for various reasons.
  44. if (spawnPoint.Job == null || spawnPoint.Job == args.Job)
  45. possibleContainers.Add((uid, spawnPoint, container, xform));
  46. continue;
  47. }
  48. if (_gameTicker.RunLevel == GameRunLevel.InRound && spawnPoint.SpawnType == SpawnPointType.LateJoin)
  49. {
  50. possibleContainers.Add((uid, spawnPoint, container, xform));
  51. }
  52. if (_gameTicker.RunLevel != GameRunLevel.InRound &&
  53. spawnPoint.SpawnType == SpawnPointType.Job &&
  54. (args.Job == null || spawnPoint.Job == args.Job))
  55. {
  56. possibleContainers.Add((uid, spawnPoint, container, xform));
  57. }
  58. }
  59. if (possibleContainers.Count == 0)
  60. return;
  61. // we just need some default coords so we can spawn the player entity.
  62. var baseCoords = possibleContainers[0].Comp3.Coordinates;
  63. args.SpawnResult = _stationSpawning.SpawnPlayerMob(
  64. baseCoords,
  65. args.Job,
  66. args.HumanoidCharacterProfile,
  67. args.Station);
  68. _random.Shuffle(possibleContainers);
  69. foreach (var (uid, spawnPoint, manager, xform) in possibleContainers)
  70. {
  71. if (!_container.TryGetContainer(uid, spawnPoint.ContainerId, out var container, manager))
  72. continue;
  73. if (!_container.Insert(args.SpawnResult.Value, container, containerXform: xform))
  74. continue;
  75. return;
  76. }
  77. Del(args.SpawnResult);
  78. args.SpawnResult = null;
  79. }
  80. }