Skip to content
This repository was archived by the owner on Apr 21, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ public override void UpdateState(BoundUserInterfaceState state)
if (state is not CrewManifestUiState crewManifestState)
return;

_fragment?.UpdateState(crewManifestState.StationName, crewManifestState.Entries);
_fragment?.UpdateState(crewManifestState.Entries); // coyote: remove name
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ public CrewManifestUiFragment()
VerticalExpand = true;
}

public void UpdateState(string stationName, CrewManifestEntries? entries)
public void UpdateState(CrewManifestEntries? entries) // coyote: remove name
{
CrewManifestListing.DisposeAllChildren();
CrewManifestListing.RemoveAllChildren();

StationNameContainer.Visible = entries != null;
StationName.Text = stationName;
StationName.Text = "Crew Manifest"; // coyote: remove name

if (entries == null)
return;
Expand Down
2 changes: 1 addition & 1 deletion Content.Client/CrewManifest/CrewManifestEui.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ public override void HandleState(EuiStateBase state)
return;
}

_window.Populate(cast.StationName, cast.Entries);
_window.Populate(cast.Entries); // Coyote: Remove name
}
}
4 changes: 2 additions & 2 deletions Content.Client/CrewManifest/CrewManifestUi.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ public CrewManifestUi()
StationName.AddStyleClass("LabelBig");
}

public void Populate(string name, CrewManifestEntries? entries)
public void Populate(CrewManifestEntries? entries) // Coyote: Remove name
{
CrewManifestListing.DisposeAllChildren();
CrewManifestListing.RemoveAllChildren();

StationNameContainer.Visible = entries != null;
StationName.Text = name;
StationName.Text = "Crew Manifest"; // Coyote: Remove name

if (entries == null)
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ private void UpdateUiState(EntityUid uid, EntityUid loaderUid, CrewManifestCartr
if (owningStation is null)
return;

var (stationName, entries) = _crewManifest.GetCrewManifest(owningStation.Value);
var entries = _crewManifest.GetCrewManifest(); // coyote: remove name

var state = new CrewManifestUiState(stationName, entries);
var state = new CrewManifestUiState(entries); // coyote: remove name
_cartridgeLoader.UpdateCartridgeUiState(loaderUid, state);
}

Expand Down
6 changes: 3 additions & 3 deletions Content.Server/CrewManifest/CrewManifestEui.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ public CrewManifestEui(EntityUid station, EntityUid? owner, CrewManifestSystem c
_crewManifest = crewManifestSystem;
}

public override CrewManifestEuiState GetNewState()
public override CrewManifestEuiState GetNewState() // Coyote: Remove name
{
var (name, entries) = _crewManifest.GetCrewManifest(_station);
return new(name, entries);
var entries = _crewManifest.GetCrewManifest();
return new(entries);
}

public override void Closed()
Expand Down
63 changes: 41 additions & 22 deletions Content.Server/CrewManifest/CrewManifestSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System.Linq;
using Content.Server.Access.Components; // Coyote
using Content.Server.Access.Systems; // Coyote
using Content.Server.Administration;
using Content.Server.EUI;
using Content.Server.Medical.SuitSensors; // Coyote
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Server.StationRecords;
Expand All @@ -10,6 +13,7 @@
using Content.Shared.CrewManifest;
using Content.Shared.GameTicking;
using Content.Shared.Roles;
using Content.Shared.SSDIndicator;
using Content.Shared.StationRecords;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
Expand All @@ -26,6 +30,7 @@ public sealed class CrewManifestSystem : EntitySystem
[Dependency] private readonly EuiManager _euiManager = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IdCardSystem _idCardSystem = default!; // Coyote

/// <summary>
/// Cached crew manifest entries. The alternative is to outright
Expand All @@ -41,7 +46,6 @@ public override void Initialize()
SubscribeLocalEvent<AfterGeneralRecordCreatedEvent>(AfterGeneralRecordCreated);
SubscribeLocalEvent<RecordModifiedEvent>(OnRecordModified);
SubscribeLocalEvent<RecordRemovedEvent>(OnRecordRemoved);
/* SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart); */
SubscribeNetworkEvent<RequestCrewManifestMessage>(OnRequestCrewManifest);

SubscribeLocalEvent<CrewManifestViewerComponent, BoundUIClosedEvent>(OnBoundUiClose);
Expand Down Expand Up @@ -78,20 +82,20 @@ private void OnRequestCrewManifest(RequestCrewManifestMessage message, EntitySes
// wrt the amount of players readied up.
private void AfterGeneralRecordCreated(AfterGeneralRecordCreatedEvent ev)
{
BuildCrewManifest(ev.Key.OriginStation);
UpdateEuis(ev.Key.OriginStation);
// BuildCrewManifest(); // coyote: NOP, we build on open
// UpdateEuis(ev.Key.OriginStation);
}

private void OnRecordModified(RecordModifiedEvent ev)
{
BuildCrewManifest(ev.Key.OriginStation);
UpdateEuis(ev.Key.OriginStation);
// BuildCrewManifest(); // coyote: NOP, we build on open
// UpdateEuis(ev.Key.OriginStation);
}

private void OnRecordRemoved(RecordRemovedEvent ev)
{
BuildCrewManifest(ev.Key.OriginStation);
UpdateEuis(ev.Key.OriginStation);
// BuildCrewManifest(); // coyote: NOP, we build on open
// UpdateEuis(ev.Key.OriginStation);
}

private void OnBoundUiClose(EntityUid uid, CrewManifestViewerComponent component, BoundUIClosedEvent ev)
Expand All @@ -113,10 +117,9 @@ private void OnBoundUiClose(EntityUid uid, CrewManifestViewerComponent component
/// </summary>
/// <param name="station">Entity uid of the station.</param>
/// <returns>The name and crew manifest entries (unordered) of the station.</returns>
public (string name, CrewManifestEntries? entries) GetCrewManifest(EntityUid station)
public CrewManifestEntries GetCrewManifest() // coyote: remove args, remove name
{
var valid = _cachedEntries.TryGetValue(station, out var manifest);
return (valid ? MetaData(station).EntityName : string.Empty, valid ? manifest : null);
return BuildCrewManifest(); // coyote
}

private void UpdateEuis(EntityUid station)
Expand Down Expand Up @@ -219,22 +222,37 @@ public void CloseEui(EntityUid station, ICommonSession session, EntityUid? owner
/// <summary>
/// Builds the crew manifest for a station. Stores it in the cache afterwards.
/// </summary>
/// <param name="station"></param>
private void BuildCrewManifest(EntityUid station)
private CrewManifestEntries BuildCrewManifest()
{
var iter = _recordsSystem.GetRecordsOfType<GeneralStationRecord>(station);

var sensors = EntityQueryEnumerator<SuitSensorComponent>(); // Coyote
var entries = new CrewManifestEntries();

var entriesSort = new List<(JobPrototype? job, CrewManifestEntry entry)>();
foreach (var recordObject in iter)

while (sensors.MoveNext(out var uid, out var sensor)) // Coyote start
{
var record = recordObject.Item2;
var entry = new CrewManifestEntry(record.Name, record.JobTitle, record.JobIcon, record.JobPrototype);
if (sensor.User == null || TryComp<SSDIndicatorComponent>(sensor.User, out var indicator) && indicator.IsSSD)
{
continue;
}
var name = Loc.GetString("suit-sensor-component-unknown-name");
var jobTitle = Loc.GetString("suit-sensor-component-unknown-job");

_prototypeManager.TryIndex(record.JobPrototype, out JobPrototype? job);
entriesSort.Add((job, entry));
}
if (!_idCardSystem.TryFindIdCard(sensor.User.Value, out var card))
continue;

if (card.Comp.FullName != null)
name = card.Comp.FullName;

if (card.Comp.LocalizedJobTitle != null)
jobTitle = card.Comp.LocalizedJobTitle;

if (!TryComp<PresetIdCardComponent>(card, out var preset))
continue;

var entry = new CrewManifestEntry(name, jobTitle, card.Comp.JobIcon, preset.JobName!.Value);

entriesSort.Add((null, entry));
} // Coyote end

entriesSort.Sort((a, b) =>
{
Expand All @@ -246,7 +264,8 @@ private void BuildCrewManifest(EntityUid station)
});

entries.Entries = entriesSort.Select(x => x.entry).ToArray();
_cachedEntries[station] = entries;
// _cachedEntries[station] = entries; // coyote: causes problems
return entries; // coyote
}
}

Expand Down
5 changes: 5 additions & 0 deletions Content.Server/GameTicking/GameTicker.Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ public void PlayerJoinGame(ICommonSession session, bool silent = false)
RaiseNetworkEvent(new TickerJoinGameEvent(), session.Channel);
}

public void ReturnPlayerToLobby(ICommonSession session)
{
PlayerJoinLobby(session);
}

private void PlayerJoinLobby(ICommonSession session)
{
_playerGameStatuses[session.UserId] = LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay;
Expand Down
19 changes: 16 additions & 3 deletions Content.Server/Gateway/Systems/GatewaySystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,22 @@ private void UpdateUserInterface(EntityUid uid, GatewayComponent comp, Transform
if (!dest.Enabled || destUid == uid)
continue;

if (!TryComp<MetaDataComponent>(destUid, out var destMeta) || destMeta.EntityLifeStage >= EntityLifeStage.Terminating)
continue;

// Show destination if either no destination comp on the map or it's ours.
TryComp<GatewayGeneratorDestinationComponent>(destXform.MapUid, out var gatewayDestination);
var isDockingArm = HasComp<DockingArmDestinationComponent>(destUid);

Log.Debug($"Gateway {ToPrettyString(uid)} found destination {ToPrettyString(destUid)} - IsDockingArm: {isDockingArm}, HasDockingArmComp: {HasComp<DockingArmDestinationComponent>(destUid)}, DestName: {MetaData(destUid).EntityName}");
Log.Debug($"Gateway {ToPrettyString(uid)} found destination {ToPrettyString(destUid)} - IsDockingArm: {isDockingArm}, HasDockingArmComp: {HasComp<DockingArmDestinationComponent>(destUid)}, DestName: {destMeta.EntityName}");

destinations.Add(new GatewayDestinationData()
{
Entity = GetNetEntity(destUid),
// Fallback to grid's ID if applicable.
Name = dest.Name.IsEmpty && destXform.GridUid != null ? FormattedMessage.FromUnformatted(MetaData(destXform.GridUid.Value).EntityName) : dest.Name ,
Name = dest.Name.IsEmpty && destXform.GridUid != null && TryComp<MetaDataComponent>(destXform.GridUid.Value, out var gridMeta)
? FormattedMessage.FromUnformatted(gridMeta.EntityName)
: dest.Name,
Portal = HasComp<PortalComponent>(destUid),
// If NextUnlock < CurTime it's unlocked, however
// we'll always send the client if it's locked
Expand All @@ -124,10 +129,18 @@ private void UpdateUserInterface(EntityUid uid, GatewayComponent comp, Transform
}

_linkedEntity.GetLink(uid, out var current);
NetEntity? currentNet = null;

if (current is { } currentUid &&
TryComp<MetaDataComponent>(currentUid, out var currentMeta) &&
currentMeta.EntityLifeStage < EntityLifeStage.Terminating)
{
currentNet = GetNetEntity(currentUid, currentMeta);
}

var state = new GatewayBoundUserInterfaceState(
destinations,
GetNetEntity(current),
currentNet,
comp.NextReady,
comp.Cooldown,
nextUnlock,
Expand Down
25 changes: 15 additions & 10 deletions Content.Server/Ghost/GhostCommand.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
using Content.Server.Popups;
using Content.Shared.Administration;
using Content.Shared.GameTicking;
using Content.Shared.Mind;
using Robust.Shared.Console;
using Content.Server.GameTicking;
using Content.Server.Mind;
using Robust.Server.Player;
using Robust.Shared.Console;

namespace Content.Server.Ghost
{
[AnyCommand]
public sealed class GhostCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;

public string Command => "ghost";
public string Description => Loc.GetString("ghost-command-description");
Expand Down Expand Up @@ -43,17 +45,20 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

var minds = _entities.System<SharedMindSystem>();
if (!minds.TryGetMind(player, out var mindId, out var mind))
if (player.AttachedEntity is not { Valid: true } controlled)
{
mindId = minds.CreateMind(player.UserId);
mind = _entities.GetComponent<MindComponent>(mindId);
shell.WriteLine(Loc.GetString("ghost-command-error-lobby"));
return;
}

if (!_entities.System<GhostSystem>().OnGhostAttempt(mindId, true, true, mind: mind))
{
shell.WriteLine(Loc.GetString("ghost-command-denied"));
}
var minds = _entities.System<MindSystem>();
if (minds.TryGetMind(player, out var mindId, out var mind))
minds.WipeMind(mindId, mind);
else
_playerManager.SetAttachedEntity(player, null);

_entities.DeleteEntity(controlled);
gameTicker.ReturnPlayerToLobby(player);
}
}
}
7 changes: 6 additions & 1 deletion Content.Server/Lizards/Systems/LizardLinkerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ public override void Initialize()

private void OnFollowerStartup(Entity<TrailFollowerComponent> ent, ref ComponentStartup args)
{
var xform = Transform(ent.Owner);

// Trail followers are moved directly to recorded leader coordinates, so
// grid traversal only adds recursive reparent checks when the leader crosses grids.
xform.GridTraversal = false;

if (ent.Comp.Leader != default)
return;

// Try to find an entity with TrailLeader in same coordinates to follow
var enumerator = EntityQueryEnumerator<TrailLeaderComponent, TransformComponent>();
while (enumerator.MoveNext(out var leaderUid, out var leaderComp, out var leaderXform))
{
var xform = Transform(ent.Owner);
if (leaderXform.MapID == xform.MapID && leaderXform.Coordinates.TryDistance(EntityManager, xform.Coordinates, out var dist) && dist < 1.0f)
{
ent.Comp.Leader = leaderUid;
Expand Down
7 changes: 6 additions & 1 deletion Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
using Content.Server.Salvage.Expeditions; // Frontier
using Content.Server._NF.Medical.SuitSensors; // Frontier
using Content.Shared.Emp;
using Content.Shared.FloofStation; // Frontier
using Content.Shared.FloofStation;
using Content.Shared.SSDIndicator; // Frontier

namespace Content.Server.Medical.SuitSensors;

Expand Down Expand Up @@ -427,6 +428,10 @@ public void SetAllSensors(EntityUid target, SuitSensorMode mode, SlotFlags slots
if (EntityManager.TryGetComponent(sensor.User.Value, out MobStateComponent? mobState))
isAlive = !_mobStateSystem.IsDead(sensor.User.Value, mobState);

// Coyote: Don't show SSD people on suit sensors.
if (TryComp<SSDIndicatorComponent>(sensor.User.Value, out var ssd) && ssd.IsSSD && isAlive)
return null;

// get mob total damage
var totalDamage = 0;
if (TryComp<DamageableComponent>(sensor.User.Value, out var damageable))
Expand Down
16 changes: 12 additions & 4 deletions Content.Server/Movement/Systems/PullController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,11 @@ private void UpdatePulledRotation(EntityUid puller, EntityUid pulled)
if (!rotatable.RotateWhilePulling)
return;

var pulledXform = _xformQuery.GetComponent(pulled);
var pullerXform = _xformQuery.GetComponent(puller);
if (!_xformQuery.TryGetComponent(pulled, out var pulledXform) ||
!_xformQuery.TryGetComponent(puller, out var pullerXform))
{
return;
}

var pullerData = TransformSystem.GetWorldPositionRotation(pullerXform);
var pulledData = TransformSystem.GetWorldPositionRotation(pulledXform);
Expand Down Expand Up @@ -245,7 +248,12 @@ public override void UpdateBeforeSolve(bool prediction, float frameTime)
if (pullable.Puller is not {Valid: true} puller)
continue;

var pullerXform = _xformQuery.Get(puller);
if (!_xformQuery.TryGetComponent(puller, out var pullerXform))
{
RemCompDeferred<PullMovingComponent>(pullableEnt);
continue;
}

var pullerPosition = TransformSystem.GetMapCoordinates(pullerXform);

var movingTo = TransformSystem.ToMapCoordinates(mover.MovingTo);
Expand Down Expand Up @@ -305,7 +313,7 @@ public override void UpdateBeforeSolve(bool prediction, float frameTime)
// if the puller is weightless or can't move, then we apply the inverse impulse (Newton's third law).
// doing it under gravity produces an unsatisfying wiggling when pulling.
// If player can't move, assume they are on a chair and we need to prevent pull-moving.
if (_gravity.IsWeightless(puller) && pullerXform.Comp.GridUid == null || !_actionBlockerSystem.CanMove(puller))
if ((_gravity.IsWeightless(puller) && pullerXform.GridUid == null) || !_actionBlockerSystem.CanMove(puller))
{
PhysicsSystem.WakeBody(puller);
PhysicsSystem.ApplyLinearImpulse(puller, -impulse);
Expand Down
Loading
Loading