87 lines
3.5 KiB
C#
87 lines
3.5 KiB
C#
using Content.Server.GameTicking;
|
||
using Content.Server.Shuttles.Systems;
|
||
using Content.Server.Spawners.Components;
|
||
using Content.Server.Station.Systems;
|
||
using Robust.Shared.Map;
|
||
using Robust.Shared.Random;
|
||
|
||
namespace Content.Server.Spawners.EntitySystems;
|
||
|
||
public sealed class SpawnPointSystem : EntitySystem
|
||
{
|
||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||
[Dependency] private readonly IRobustRandom _random = default!;
|
||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||
[Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
|
||
|
||
public override void Initialize()
|
||
{
|
||
SubscribeLocalEvent<PlayerSpawningEvent>(OnPlayerSpawning);
|
||
}
|
||
|
||
private void OnPlayerSpawning(PlayerSpawningEvent args)
|
||
{
|
||
if (args.SpawnResult != null)
|
||
return;
|
||
|
||
// TODO: Cache all this if it ends up important.
|
||
var points = EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
|
||
var possiblePositions = new List<EntityCoordinates>();
|
||
|
||
while (points.MoveNext(out var uid, out var spawnPoint, out var xform))
|
||
{
|
||
if (args.Station != null && _stationSystem.GetOwningStation(uid, xform) != args.Station)
|
||
continue;
|
||
|
||
// Sunrise added start
|
||
// Delta-V: Allow setting a desired SpawnPointType
|
||
|
||
// То, что приходит из ивента главнее заданного в спавнпоинте.
|
||
var spawnPointType = args.DesiredSpawnPointType != SpawnPointType.Unset
|
||
? args.DesiredSpawnPointType
|
||
: spawnPoint.SpawnType;
|
||
|
||
var isMatchingJob = string.IsNullOrEmpty(args.Job)
|
||
|| string.IsNullOrEmpty(spawnPoint.Job)
|
||
|| spawnPoint.Job == args.Job;
|
||
|
||
switch (spawnPointType)
|
||
{
|
||
case SpawnPointType.Job when isMatchingJob && spawnPoint.SpawnType == SpawnPointType.Job:
|
||
case SpawnPointType.LateJoin when spawnPoint.SpawnType == SpawnPointType.LateJoin:
|
||
case SpawnPointType.Observer when spawnPoint.SpawnType == SpawnPointType.Observer:
|
||
possiblePositions.Add(xform.Coordinates);
|
||
break;
|
||
default:
|
||
continue;
|
||
}
|
||
// Sunrise added end
|
||
}
|
||
|
||
if (possiblePositions.Count == 0)
|
||
{
|
||
// Ok we've still not returned, but we need to put them /somewhere/.
|
||
// TODO: Refactor gameticker spawning code so we don't have to do this!
|
||
var points2 = EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
|
||
|
||
if (points2.MoveNext(out _, out var xform))
|
||
{
|
||
Log.Error($"Unable to pick a valid spawn point, picking random spawner as a backup.\nRunLevel: {_gameTicker.RunLevel} Station: {ToPrettyString(args.Station)} Job: {args.Job}");
|
||
possiblePositions.Add(xform.Coordinates);
|
||
}
|
||
else
|
||
{
|
||
Log.Error($"No spawn points were available!\nRunLevel: {_gameTicker.RunLevel} Station: {ToPrettyString(args.Station)} Job: {args.Job}");
|
||
return;
|
||
}
|
||
}
|
||
|
||
var spawnLoc = _random.Pick(possiblePositions);
|
||
|
||
args.SpawnResult = _stationSpawning.SpawnPlayerMob(
|
||
spawnLoc,
|
||
args.Job,
|
||
args.HumanoidCharacterProfile,
|
||
args.Station);
|
||
}
|
||
}
|