Skip to content

Commit 0f51c37

Browse files
sleepyyaprilslarticodefastScarKy0
authored
Fix Even More Issues (#1559)
![image](https://github.com/user-attachments/assets/ae89aafd-f4f6-42ad-beac-ed94bbb98f17) Resolves #1529 # Changelog <!-- You can add an author after the `:cl:` to change the name that appears in the changelog (ex: `:cl: Death`) Leaving it blank will default to your GitHub display name This includes all available types for the changelog --> :cl: - fix: Fixed interactions not respecting identity. - fix: Potentially fixed spawning issues. - fix: Fixed borgs, animals and aghosts being able to enter cryosleep. --------- Co-authored-by: slarticodefast <[email protected]> Co-authored-by: ScarKy0 <[email protected]>
1 parent 23c225e commit 0f51c37

File tree

14 files changed

+258
-57
lines changed

14 files changed

+258
-57
lines changed

Content.Server/Shuttles/Systems/ArrivalsSystem.cs

+81-42
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Linq;
22
using System.Numerics;
33
using Content.Server.Administration;
4+
using Content.Server.Chat.Managers;
45
using Content.Server.DeviceNetwork.Components;
56
using Content.Server.DeviceNetwork.Systems;
67
using Content.Server.GameTicking;
@@ -16,12 +17,13 @@
1617
using Content.Server.Station.Systems;
1718
using Content.Shared.Administration;
1819
using Content.Shared.CCVar;
20+
using Content.Shared.Damage.Components;
1921
using Content.Shared.DeviceNetwork;
22+
using Content.Shared.GameTicking;
2023
using Content.Shared.Mobs.Components;
2124
using Content.Shared.Movement.Components;
2225
using Content.Shared.Parallax.Biomes;
2326
using Content.Shared.Roles;
24-
using Content.Shared.Preferences;
2527
using Content.Shared.Salvage;
2628
using Content.Shared.Shuttles.Components;
2729
using Content.Shared.Tiles;
@@ -30,6 +32,7 @@
3032
using Robust.Shared.Configuration;
3133
using Robust.Shared.Console;
3234
using Robust.Shared.Map;
35+
using Robust.Shared.Player;
3336
using Robust.Shared.Prototypes;
3437
using Robust.Shared.Random;
3538
using Robust.Shared.Timing;
@@ -45,17 +48,20 @@ public sealed class ArrivalsSystem : EntitySystem
4548
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
4649
[Dependency] private readonly IConsoleHost _console = default!;
4750
[Dependency] private readonly IGameTiming _timing = default!;
48-
[Dependency] private readonly IMapManager _mapManager = default!;
4951
[Dependency] private readonly IPrototypeManager _protoManager = default!;
5052
[Dependency] private readonly IRobustRandom _random = default!;
53+
[Dependency] private readonly IChatManager _chat = default!;
54+
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
5155
[Dependency] private readonly BiomeSystem _biomes = default!;
5256
[Dependency] private readonly GameTicker _ticker = default!;
5357
[Dependency] private readonly MapLoaderSystem _loader = default!;
58+
[Dependency] private readonly MetaDataSystem _metaData = default!;
5459
[Dependency] private readonly DeviceNetworkSystem _deviceNetworkSystem = default!;
5560
[Dependency] private readonly SharedTransformSystem _transform = default!;
5661
[Dependency] private readonly ShuttleSystem _shuttles = default!;
5762
[Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
5863
[Dependency] private readonly StationSystem _station = default!;
64+
[Dependency] private readonly ActorSystem _actor = default!;
5965

6066
private EntityQuery<PendingClockInComponent> _pendingQuery;
6167
private EntityQuery<ArrivalsBlacklistComponent> _blacklistQuery;
@@ -87,7 +93,7 @@ public override void Initialize()
8793
{
8894
base.Initialize();
8995

90-
SubscribeLocalEvent<PlayerSpawningEvent>(HandlePlayerSpawning, before: new []{ typeof(ContainerSpawnPointSystem), typeof(SpawnPointSystem)});
96+
SubscribeLocalEvent<PlayerSpawningEvent>(HandlePlayerSpawning, before: new []{ typeof(SpawnPointSystem)}, after: new [] { typeof(ContainerSpawnPointSystem)});
9197

9298
SubscribeLocalEvent<StationArrivalsComponent, StationPostInitEvent>(OnStationPostInit);
9399

@@ -98,6 +104,8 @@ public override void Initialize()
98104
SubscribeLocalEvent<ArrivalsShuttleComponent, FTLStartedEvent>(OnArrivalsFTL);
99105
SubscribeLocalEvent<ArrivalsShuttleComponent, FTLCompletedEvent>(OnArrivalsDocked);
100106

107+
SubscribeLocalEvent<PlayerSpawnCompleteEvent>(SendDirections);
108+
101109
_pendingQuery = GetEntityQuery<PendingClockInComponent>();
102110
_blacklistQuery = GetEntityQuery<ArrivalsBlacklistComponent>();
103111
_mobQuery = GetEntityQuery<MobStateComponent>();
@@ -263,6 +271,9 @@ private void OnArrivalsFTL(EntityUid shuttleUid, ArrivalsShuttleComponent compon
263271
// The player has successfully left arrivals and is also not on the shuttle. Remove their warp coupon.
264272
RemCompDeferred<PendingClockInComponent>(pUid);
265273
RemCompDeferred<AutoOrientComponent>(pUid);
274+
275+
if (ArrivalsGodmode)
276+
RemCompDeferred<GodmodeComponent>(pUid);
266277
}
267278
}
268279

@@ -287,16 +298,20 @@ private void OnArrivalsDocked(EntityUid uid, ArrivalsShuttleComponent component,
287298
private void DumpChildren(EntityUid uid, ref FTLStartedEvent args)
288299
{
289300
var toDump = new List<Entity<TransformComponent>>();
290-
DumpChildren(uid, ref args, toDump);
301+
FindDumpChildren(uid, toDump);
291302
foreach (var (ent, xform) in toDump)
292303
{
293304
var rotation = xform.LocalRotation;
294305
_transform.SetCoordinates(ent, new EntityCoordinates(args.FromMapUid!.Value, Vector2.Transform(xform.LocalPosition, args.FTLFrom)));
295306
_transform.SetWorldRotation(ent, args.FromRotation + rotation);
307+
if (_actor.TryGetSession(ent, out var session))
308+
{
309+
_chat.DispatchServerMessage(session!, Loc.GetString("latejoin-arrivals-dumped-from-shuttle"));
310+
}
296311
}
297312
}
298313

299-
private void DumpChildren(EntityUid uid, ref FTLStartedEvent args, List<Entity<TransformComponent>> toDump)
314+
private void FindDumpChildren(EntityUid uid, List<Entity<TransformComponent>> toDump)
300315
{
301316
if (_pendingQuery.HasComponent(uid))
302317
return;
@@ -312,7 +327,7 @@ private void DumpChildren(EntityUid uid, ref FTLStartedEvent args, List<Entity<T
312327
var children = xform.ChildEnumerator;
313328
while (children.MoveNext(out var child))
314329
{
315-
DumpChildren(child, ref args, toDump);
330+
FindDumpChildren(child, toDump);
316331
}
317332
}
318333

@@ -321,8 +336,7 @@ public void HandlePlayerSpawning(PlayerSpawningEvent ev)
321336
if (ev.SpawnResult != null)
322337
return;
323338

324-
if (ev.HumanoidCharacterProfile?.SpawnPriority != SpawnPriorityPreference.Arrivals)
325-
return;
339+
// We use arrivals as the default spawn so don't check for job prio.
326340

327341
// Only works on latejoin even if enabled.
328342
if (!Enabled || _ticker.RunLevel != GameRunLevel.InRound)
@@ -333,39 +347,56 @@ public void HandlePlayerSpawning(PlayerSpawningEvent ev)
333347
&& _protoManager.Index<JobPrototype>(ev.Job.Prototype.Value.Id).AlwaysUseSpawner)
334348
return;
335349

336-
337350
if (!HasComp<StationArrivalsComponent>(ev.Station))
338351
return;
339352

340353
TryGetArrivals(out var arrivals);
341354

342-
if (TryComp<TransformComponent>(arrivals, out var arrivalsXform))
343-
{
344-
var mapId = arrivalsXform.MapID;
355+
if (!TryComp(arrivals, out TransformComponent? arrivalsXform))
356+
return;
345357

346-
var points = EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
347-
var possiblePositions = new List<EntityCoordinates>();
348-
while (points.MoveNext(out var uid, out var spawnPoint, out var xform))
349-
{
350-
if (spawnPoint.SpawnType != SpawnPointType.LateJoin || xform.MapID != mapId)
351-
continue;
358+
var mapId = arrivalsXform.MapID;
352359

353-
possiblePositions.Add(xform.Coordinates);
354-
}
360+
var points = EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
361+
var possiblePositions = new List<EntityCoordinates>();
362+
while (points.MoveNext(out var uid, out var spawnPoint, out var xform))
363+
{
364+
if (spawnPoint.SpawnType != SpawnPointType.LateJoin || xform.MapID != mapId)
365+
continue;
355366

356-
if (possiblePositions.Count > 0)
357-
{
358-
var spawnLoc = _random.Pick(possiblePositions);
359-
ev.SpawnResult = _stationSpawning.SpawnPlayerMob(
360-
spawnLoc,
361-
ev.Job,
362-
ev.HumanoidCharacterProfile,
363-
ev.Station);
364-
365-
EnsureComp<PendingClockInComponent>(ev.SpawnResult.Value);
366-
EnsureComp<AutoOrientComponent>(ev.SpawnResult.Value);
367-
}
367+
possiblePositions.Add(xform.Coordinates);
368368
}
369+
370+
if (possiblePositions.Count <= 0)
371+
return;
372+
373+
var spawnLoc = _random.Pick(possiblePositions);
374+
ev.SpawnResult = _stationSpawning.SpawnPlayerMob(
375+
spawnLoc,
376+
ev.Job,
377+
ev.HumanoidCharacterProfile,
378+
ev.Station);
379+
380+
EnsureComp<PendingClockInComponent>(ev.SpawnResult.Value);
381+
EnsureComp<AutoOrientComponent>(ev.SpawnResult.Value);
382+
383+
// If you're forced to spawn, you're invincible until you leave wherever you were forced to spawn.
384+
if (ArrivalsGodmode)
385+
EnsureComp<GodmodeComponent>(ev.SpawnResult.Value);
386+
}
387+
388+
private void SendDirections(PlayerSpawnCompleteEvent ev)
389+
{
390+
if (!Enabled || !ev.LateJoin || !_pendingQuery.HasComp(ev.Mob))
391+
return;
392+
393+
var arrival = NextShuttleArrival();
394+
395+
var message = arrival is not null
396+
? Loc.GetString("latejoin-arrivals-direction-time", ("time", $"{arrival:mm\\:ss}"))
397+
: Loc.GetString("latejoin-arrivals-direction");
398+
399+
_chat.DispatchServerMessage(ev.Player, message);
369400
}
370401

371402
private bool TryTeleportToMapSpawn(EntityUid player, EntityUid stationId, TransformComponent? transform = null)
@@ -391,6 +422,10 @@ private bool TryTeleportToMapSpawn(EntityUid player, EntityUid stationId, Transf
391422
{
392423
// Move the player to a random late-join spawnpoint.
393424
_transform.SetCoordinates(player, transform, _random.Pick(possiblePositions));
425+
if (_actor.TryGetSession(player, out var session))
426+
{
427+
_chat.DispatchServerMessage(session!, Loc.GetString("latejoin-arrivals-teleport-to-spawn"));
428+
}
394429
return true;
395430
}
396431

@@ -436,7 +471,7 @@ public override void Update(float frameTime)
436471
var curTime = _timing.CurTime;
437472
TryGetArrivals(out var arrivals);
438473

439-
if (TryComp<TransformComponent>(arrivals, out var arrivalsXform))
474+
if (TryComp(arrivals, out TransformComponent? arrivalsXform))
440475
{
441476
while (query.MoveNext(out var uid, out var comp, out var shuttle, out var xform))
442477
{
@@ -449,7 +484,7 @@ public override void Update(float frameTime)
449484
if (xform.MapUid != arrivalsXform.MapUid)
450485
{
451486
if (arrivals.IsValid())
452-
_shuttles.FTLToDock(uid, shuttle, arrivals, _cfgManager.GetCVar(CCVars.ArrivalsStartupTime), _cfgManager.GetCVar(CCVars.ArrivalsHyperspaceTime), "DockArrivals");
487+
_shuttles.FTLToDock(uid, shuttle, arrivals);
453488

454489
comp.NextArrivalsTime = _timing.CurTime + TimeSpan.FromSeconds(tripTime);
455490
}
@@ -459,7 +494,7 @@ public override void Update(float frameTime)
459494
var targetGrid = _station.GetLargestGrid(data);
460495

461496
if (targetGrid != null)
462-
_shuttles.FTLToDock(uid, shuttle, targetGrid.Value, _cfgManager.GetCVar(CCVars.ArrivalsStartupTime), _cfgManager.GetCVar(CCVars.ArrivalsHyperspaceTime), "DockArrivals");
497+
_shuttles.FTLToDock(uid, shuttle, targetGrid.Value);
463498

464499
// The ArrivalsCooldown includes the trip there, so we only need to add the time taken for
465500
// the trip back.
@@ -483,9 +518,8 @@ private void OnRoundStarting(RoundStartingEvent ev)
483518

484519
private void SetupArrivalsStation()
485520
{
486-
var mapId = _mapManager.CreateMap();
487-
var mapUid = _mapManager.GetMapEntityId(mapId);
488-
_mapManager.AddUninitializedMap(mapId);
521+
var mapUid = _mapSystem.CreateMap(out var mapId, false);
522+
_metaData.SetEntityName(mapUid, Loc.GetString("map-name-terminal"));
489523

490524
if (!_loader.TryLoad(mapId, _cfgManager.GetCVar(CCVars.ArrivalsMap), out var uids))
491525
{
@@ -504,9 +538,14 @@ private void SetupArrivalsStation()
504538
{
505539
var template = _random.Pick(_arrivalsBiomeOptions);
506540
_biomes.EnsurePlanet(mapUid, _protoManager.Index(template));
541+
var restricted = new RestrictedRangeComponent
542+
{
543+
Range = 32f
544+
};
545+
AddComp(mapUid, restricted);
507546
}
508547

509-
_mapManager.DoMapInitialize(mapId);
548+
_mapSystem.InitializeMap(mapId);
510549

511550
// Handle roundstart stations.
512551
var query = AllEntityQuery<StationArrivalsComponent>();
@@ -564,10 +603,10 @@ private void SetupShuttle(EntityUid uid, StationArrivalsComponent component)
564603
return;
565604

566605
// Spawn arrivals on a dummy map then dock it to the source.
567-
var dummyMap = _mapManager.CreateMap();
606+
var dummpMapEntity = _mapSystem.CreateMap(out var dummyMapId);
568607

569608
if (TryGetArrivals(out var arrivals) &&
570-
_loader.TryLoad(dummyMap, component.ShuttlePath.ToString(), out var shuttleUids))
609+
_loader.TryLoad(dummyMapId, component.ShuttlePath.ToString(), out var shuttleUids))
571610
{
572611
component.Shuttle = shuttleUids[0];
573612
var shuttleComp = Comp<ShuttleComponent>(component.Shuttle);
@@ -579,7 +618,7 @@ private void SetupShuttle(EntityUid uid, StationArrivalsComponent component)
579618
}
580619

581620
// Don't start the arrivals shuttle immediately docked so power has a time to stabilise?
582-
var timer = AddComp<TimedDespawnComponent>(_mapManager.GetMapEntityId(dummyMap));
621+
var timer = AddComp<TimedDespawnComponent>(dummpMapEntity);
583622
timer.Lifetime = 15f;
584623
}
585624
}

Content.Server/Silicons/StationAi/StationAiSystem.cs

+14-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using Content.Shared.Roles;
77
using Content.Shared.Silicons.StationAi;
88
using Content.Shared.StationAi;
9-
using Robust.Shared.Audio.Systems;
9+
using Robust.Shared.Audio;
1010
using Robust.Shared.Map.Components;
1111
using Robust.Shared.Player;
1212
using static Content.Server.Chat.Systems.ChatSystem;
@@ -87,6 +87,19 @@ public override bool SetWhitelistEnabled(Entity<StationAiWhitelistComponent> ent
8787
return true;
8888
}
8989

90+
public override void AnnounceIntellicardUsage(EntityUid uid, SoundSpecifier? cue = null)
91+
{
92+
if (!TryComp<ActorComponent>(uid, out var actor))
93+
return;
94+
95+
var msg = Loc.GetString("ai-consciousness-download-warning");
96+
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", msg));
97+
_chats.ChatMessageToOne(ChatChannel.Server, msg, wrappedMessage, default, false, actor.PlayerSession.Channel, colorOverride: Color.Red);
98+
99+
if (cue != null && _mind.TryGetMind(uid, out var mindId, out _))
100+
_roles.MindPlaySound(mindId, cue);
101+
}
102+
90103
private void AnnounceSnip(EntityUid entity)
91104
{
92105
var xform = Transform(entity);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Robust.Shared.GameStates;
2+
3+
namespace Content.Shared.Bed.Cryostorage;
4+
5+
/// <summary>
6+
/// Serves as a whitelist that allows an entity with this component to enter cryostorage.
7+
/// It will also require MindContainerComponent.
8+
/// </summary>
9+
[RegisterComponent, NetworkedComponent]
10+
public sealed partial class CanEnterCryostorageComponent : Component { }

Content.Shared/Bed/Cryostorage/SharedCryostorageSystem.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ private void OnInsertAttempt(Entity<CryostorageComponent> ent, ref ContainerIsIn
8989
return;
9090
}
9191

92-
if (!TryComp<MindContainerComponent>(args.EntityUid, out var mindContainer))
92+
if (!HasComp<CanEnterCryostorageComponent>(args.EntityUid) || !TryComp<MindContainerComponent>(args.EntityUid, out var mindContainer))
9393
{
9494
args.Cancel();
9595
return;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using Robust.Shared.Audio;
2+
using Robust.Shared.GameStates;
3+
4+
namespace Content.Shared.Intellicard;
5+
6+
/// <summary>
7+
/// Allows this entity to download the station AI onto an AiHolderComponent.
8+
/// </summary>
9+
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
10+
public sealed partial class IntellicardComponent : Component
11+
{
12+
/// <summary>
13+
/// The duration it takes to download the AI from an AiHolder.
14+
/// </summary>
15+
[DataField, AutoNetworkedField]
16+
public int DownloadTime = 15;
17+
18+
/// <summary>
19+
/// The duration it takes to upload the AI to an AiHolder.
20+
/// </summary>
21+
[DataField, AutoNetworkedField]
22+
public int UploadTime = 3;
23+
24+
/// <summary>
25+
/// The sound that plays for the AI
26+
/// when they are being downloaded
27+
/// </summary>
28+
[DataField, AutoNetworkedField]
29+
public SoundSpecifier? WarningSound = new SoundPathSpecifier("/Audio/Misc/notice2.ogg");
30+
31+
/// <summary>
32+
/// The delay before allowing the warning to play again in seconds.
33+
/// </summary>
34+
[DataField, AutoNetworkedField]
35+
public TimeSpan WarningDelay = TimeSpan.FromSeconds(8);
36+
37+
[ViewVariables]
38+
public TimeSpan NextWarningAllowed = TimeSpan.Zero;
39+
}

0 commit comments

Comments
 (0)