| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- using Content.Server.GameTicking;
- using Content.Server.Spawners.Components;
- using Content.Server.Station.Systems;
- using Content.Shared.Preferences;
- using Content.Shared.Roles;
- using Robust.Server.Containers;
- using Robust.Shared.Containers;
- using Robust.Shared.Prototypes;
- using Robust.Shared.Random;
- namespace Content.Server.Spawners.EntitySystems;
- public sealed class ContainerSpawnPointSystem : EntitySystem
- {
- [Dependency] private readonly ContainerSystem _container = default!;
- [Dependency] private readonly GameTicker _gameTicker = default!;
- [Dependency] private readonly IPrototypeManager _proto = default!;
- [Dependency] private readonly IRobustRandom _random = default!;
- [Dependency] private readonly StationSystem _station = default!;
- [Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<PlayerSpawningEvent>(HandlePlayerSpawning, before: new []{ typeof(SpawnPointSystem) });
- }
- public void HandlePlayerSpawning(PlayerSpawningEvent args)
- {
- if (args.SpawnResult != null)
- return;
- // If it's just a spawn pref check if it's for cryo (silly).
- if (args.HumanoidCharacterProfile?.SpawnPriority != SpawnPriorityPreference.Cryosleep &&
- (!_proto.TryIndex(args.Job, out var jobProto) || jobProto.JobEntity == null))
- {
- return;
- }
- var query = EntityQueryEnumerator<ContainerSpawnPointComponent, ContainerManagerComponent, TransformComponent>();
- var possibleContainers = new List<Entity<ContainerSpawnPointComponent, ContainerManagerComponent, TransformComponent>>();
- while (query.MoveNext(out var uid, out var spawnPoint, out var container, out var xform))
- {
- if (args.Station != null && _station.GetOwningStation(uid, xform) != args.Station)
- continue;
- // If it's unset, then we allow it to be used for both roundstart and midround joins
- if (spawnPoint.SpawnType == SpawnPointType.Unset)
- {
- // make sure we also check the job here for various reasons.
- if (spawnPoint.Job == null || spawnPoint.Job == args.Job)
- possibleContainers.Add((uid, spawnPoint, container, xform));
- continue;
- }
- if (_gameTicker.RunLevel == GameRunLevel.InRound && spawnPoint.SpawnType == SpawnPointType.LateJoin)
- {
- possibleContainers.Add((uid, spawnPoint, container, xform));
- }
- if (_gameTicker.RunLevel != GameRunLevel.InRound &&
- spawnPoint.SpawnType == SpawnPointType.Job &&
- (args.Job == null || spawnPoint.Job == args.Job))
- {
- possibleContainers.Add((uid, spawnPoint, container, xform));
- }
- }
- if (possibleContainers.Count == 0)
- return;
- // we just need some default coords so we can spawn the player entity.
- var baseCoords = possibleContainers[0].Comp3.Coordinates;
- args.SpawnResult = _stationSpawning.SpawnPlayerMob(
- baseCoords,
- args.Job,
- args.HumanoidCharacterProfile,
- args.Station);
- _random.Shuffle(possibleContainers);
- foreach (var (uid, spawnPoint, manager, xform) in possibleContainers)
- {
- if (!_container.TryGetContainer(uid, spawnPoint.ContainerId, out var container, manager))
- continue;
- if (!_container.Insert(args.SpawnResult.Value, container, containerXform: xform))
- continue;
- return;
- }
- Del(args.SpawnResult);
- args.SpawnResult = null;
- }
- }
|