Skip to content
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public sealed partial class IdCardConsoleWindow : DefaultWindow
private string? _lastJobProto;

// The job that will be picked if the ID doesn't have a job on the station.
private static ProtoId<JobPrototype> _defaultJob = "SCPClassD"; // Foundation-14
private static ProtoId<JobPrototype> _defaultJob = "JobSCPClassD"; // Foundation-14

public IdCardConsoleWindow(IdCardConsoleBoundUserInterface owner, IPrototypeManager prototypeManager,
List<ProtoId<AccessLevelPrototype>> accessLevels)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ FormattedMessage GetLoc(string fluentId, params (string,object)[] args)
"wanted-list-job-label",
("job", record.TargetInfo.JobTitle.ToLower())
));
/* SCP-Foundation : Human only
TargetSpecies.SetMessage(GetLoc(
"wanted-list-species-label",
("species", record.TargetInfo.Species.ToLower())
));
*/
TargetGender.SetMessage(GetLoc(
"wanted-list-gender-label",
("gender", record.TargetInfo.Gender)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
<BoxContainer Name="DataContainer" Orientation="Vertical">
<RichTextLabel Name="TargetAge" />
<RichTextLabel Name="TargetJob" />
<!-- SCP-Foundation : Human only
<RichTextLabel Name="TargetSpecies" />
-->
<RichTextLabel Name="TargetGender" />
<PanelContainer StyleClasses="LowDivider" Margin="0 5 0 5"/>
<RichTextLabel Name="InitiatorName" VerticalAlignment="Stretch"/>
Expand Down
1 change: 1 addition & 0 deletions Content.Client/Doors/AirlockSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ private void OnAppearanceChange(EntityUid uid, AirlockComponent comp, ref Appear
|| state == DoorState.Opening
|| state == DoorState.Denying
|| (state == DoorState.Open && comp.OpenUnlitVisible)
|| (state == DoorState.Closed && comp.OpenUnlitVisible) // SCP-Foundation
|| (_appearanceSystem.TryGetData<bool>(uid, DoorVisuals.ClosedLights, out var closedLights, args.Component) && closedLights))
&& !boltedVisible && !emergencyLightsVisible;
}
Expand Down
6 changes: 6 additions & 0 deletions Content.Client/Lobby/UI/HumanoidProfileEditor.Appearance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public sealed partial class HumanoidProfileEditor

public void UpdateSpeciesGuidebookIcon()
{
/* SCP-Foundtion : Human only
SpeciesInfoButton.StyleClasses.Clear();

var species = Profile?.Species;
Expand All @@ -35,6 +36,7 @@ public void UpdateSpeciesGuidebookIcon()

const string style = "SpeciesInfoDefault";
SpeciesInfoButton.StyleIdentifier = style;
*/
}

private void UpdateGenderControls()
Expand Down Expand Up @@ -134,6 +136,7 @@ private void UpdateSkinColor()
}
}

/* SCP-Foundation
private void UpdateSpawnPriorityControls()
{
if (Profile == null)
Expand All @@ -143,12 +146,14 @@ private void UpdateSpawnPriorityControls()

SpawnPriorityButton.SelectId((int)Profile.SpawnPriority);
}
*/

/// <summary>
/// Refreshes the species selector.
/// </summary>
public void RefreshSpecies()
{
/* SCP-Foundation : Human only
SpeciesButton.Clear();
_species.Clear();

Expand All @@ -175,6 +180,7 @@ public void RefreshSpecies()
SetSpecies(HumanoidCharacterProfile.DefaultSpecies);
}
}
*/
}

private void SetSpecies(string newSpecies)
Expand Down
4 changes: 4 additions & 0 deletions Content.Client/Lobby/UI/HumanoidProfileEditor.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
<BoxContainer Orientation="Vertical">
<BoxContainer Margin="10" Orientation="Vertical" HorizontalExpand="True">
<!-- Species -->
<!-- SCP-Foundation : Human only
<BoxContainer HorizontalExpand="True">
<Label Text="{Loc 'humanoid-profile-editor-species-label'}" />
<Control HorizontalExpand="True"/>
Expand All @@ -62,6 +63,7 @@
ToolTip="{Loc 'humanoid-profile-editor-guidebook-button-tooltip'}"/>
<OptionButton Name="SpeciesButton" HorizontalAlignment="Right" />
</BoxContainer>
-->
<!-- Age -->
<BoxContainer HorizontalExpand="True">
<Label Text="{Loc 'humanoid-profile-editor-age-label'}" />
Expand All @@ -87,11 +89,13 @@
<Button Name="ShowClothes" Pressed="True" ToggleMode="True" Text="{Loc 'humanoid-profile-editor-clothing-show'}" HorizontalAlignment="Right" />
</BoxContainer>
<!-- Spawn Priority -->
<!-- SCP-Foundation
<BoxContainer HorizontalExpand="True">
<Label Text="{Loc 'humanoid-profile-editor-spawn-priority-label'}" />
<Control HorizontalExpand="True"/>
<OptionButton Name="SpawnPriorityButton" HorizontalAlignment="Right" />
</BoxContainer>
-->
</BoxContainer>
<!-- Skin -->
<BoxContainer Margin="10" HorizontalExpand="True" Orientation="Vertical">
Expand Down
12 changes: 8 additions & 4 deletions Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,14 @@ public HumanoidProfileEditor(

RefreshSpecies();

/* SCP-Foundation : Human only
SpeciesButton.OnItemSelected += args =>
{
SpeciesButton.SelectId(args.Id);
SetSpecies(_species[args.Id].ID);
OnSkinColorOnValueChanged();
};
*/

#region Skin

Expand All @@ -216,7 +218,8 @@ public HumanoidProfileEditor(

#endregion

#region SpawnPriority
/* SCP-Foundation
// #region SpawnPriority

foreach (var value in Enum.GetValues<SpawnPriorityPreference>())
{
Expand All @@ -229,7 +232,8 @@ public HumanoidProfileEditor(
SetSpawnPriority((SpawnPriorityPreference)args.Id);
};

#endregion SpawnPriority
// #endregion SpawnPriority
*/

#region Eyes

Expand Down Expand Up @@ -310,7 +314,7 @@ public HumanoidProfileEditor(
ReloadPreview();
};

SpeciesInfoButton.OnPressed += OnSpeciesInfoButtonPressed;
// SpeciesInfoButton.OnPressed += OnSpeciesInfoButtonPressed; SCP-Foundation : Human only

UpdateSpeciesGuidebookIcon();
IsDirty = false;
Expand Down Expand Up @@ -371,7 +375,7 @@ public void SetProfile(HumanoidCharacterProfile? profile, int? slot)
UpdateSexControls();
UpdateGenderControls();
UpdateSkinColor();
UpdateSpawnPriorityControls();
// UpdateSpawnPriorityControls(); // SCP-Foundation
UpdateAgeEdit();
UpdateEyePickers();
UpdateSaveButton();
Expand Down
2 changes: 2 additions & 0 deletions Content.Client/StationRecords/GeneralRecord.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
<Label Name="Age"/>
<Label Name="Title"/>
<Label Name="Job"/>
<!-- SCP-Foundation : Human only
<Label Name="Species"/>
-->
<Label Name="Gender"/>
<Label Name="Fingerprint"/>
<Label Name="Dna"/>
Expand Down
2 changes: 1 addition & 1 deletion Content.Client/StationRecords/GeneralRecord.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public GeneralRecord(GeneralStationRecord record, bool canDelete, uint? id, IPro
Title.Text = Loc.GetString("general-station-record-console-record-title",
("job", Loc.GetString(record.JobTitle)));
var species = Loc.GetString(prototypeManager.Index<SpeciesPrototype>(record.Species).Name);
Species.Text = Loc.GetString("general-station-record-console-record-species", ("species", species));
// Species.Text = Loc.GetString("general-station-record-console-record-species", ("species", species)); SCP-Foundation : Human only
Gender.Text = Loc.GetString("general-station-record-console-record-gender",
("gender", record.Gender.ToString()));
Fingerprint.Text = Loc.GetString("general-station-record-console-record-fingerprint",
Expand Down
119 changes: 78 additions & 41 deletions Content.Client/_SCP/ZLevels/Core/CEClientZLevelsSystem.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
/*
/*
* This file is sublicensed under MIT License
* https://github.com/space-wizards/space-station-14/blob/master/LICENSE.TXT
*/

using System.Numerics;
using Content.Client.Damage.Systems;
using Content.Client._CE.ZLevels.Core.Overlays;
using Content.Shared._CE.ZLevels.Core.Components;
using Content.Shared._CE.ZLevels.Core.EntitySystems;
using Content.Shared.Camera;
using Content.Shared.Damage.Components;
using Content.Shared.StatusEffectNew.Components;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.GameObjects;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;

namespace Content.Client._CE.ZLevels.Core;

Expand All @@ -20,11 +23,7 @@ namespace Content.Client._CE.ZLevels.Core;
public sealed partial class CEClientZLevelsSystem : CESharedZLevelsSystem
{
[Dependency] private IOverlayManager _overlay = default!;
[Dependency] private SpriteSystem _sprite = default!;
[Dependency] private IEyeManager _eye = default!;
[Dependency] private AnimationPlayerSystem _animation = default!;

public static float ZLevelOffset = 0.1f;

public override void Initialize()
{
Expand All @@ -38,7 +37,7 @@ public override void Initialize()
private void OnEyeOffset(Entity<CEZPhysicsComponent> ent, ref GetEyeOffsetEvent args)
{
Angle rotation = _eye.CurrentEye.Rotation * -1;
var localPosition = GetVisualsLocalPosition((ent, ent), Transform(ent));
var localPosition = ent.Comp.LocalPosition;
var offset = rotation.RotateVec(new Vector2(0, localPosition * ZLevelOffset));
args.Offset += offset;
}
Expand All @@ -51,59 +50,97 @@ private void OnStartup(Entity<CEZPhysicsComponent> ent, ref ComponentStartup arg
if (sprite.SnapCardinals)
return;

ent.Comp.NoRotDefault = sprite.NoRotation;
ent.Comp.DrawDepthDefault = sprite.DrawDepth;
ent.Comp.SpriteOffsetDefault = sprite.Offset;
}

public override void Update(float frameTime)
public override void Shutdown()
{
base.Update(frameTime);
base.Shutdown();
_overlay.RemoveOverlay<CEZLevelBlurOverlay>();
}
}

var query = EntityQueryEnumerator<CEZPhysicsComponent, SpriteComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var zPhys, out var sprite, out var xform))
{
var localPosition = GetVisualsLocalPosition((uid, zPhys), xform);
/// <summary>
/// Pre-animation pass for Z-level visuals.
/// Runs its <see cref="FrameUpdate"/> BEFORE <see cref="AnimationPlayerSystem"/> every render frame,
/// resetting <see cref="SpriteComponent.Offset"/> to the entity's clean base (no Z).
/// This prevents Z from accumulating across frames when no animation writes to the offset
/// (e.g. entities that only animate scale, like SlimeIceBig).
/// </summary>
internal sealed partial class CEClientZLevelsPreAnimSystem : EntitySystem
{
[Dependency] private SpriteSystem _sprite = default!;
[Dependency] private EntityQuery<MapGridComponent> _mapGridQuery = default!;
[Dependency] private EntityQuery<CEZPhysicsComponent> _zPhysQuery = default!;

sprite.NoRotation = localPosition != 0 || zPhys.NoRotDefault;
public override void Initialize()
{
base.Initialize();
UpdatesBefore.Add(typeof(AnimationPlayerSystem));
}

_sprite.SetOffset((uid, sprite), zPhys.SpriteOffsetDefault + new Vector2(0, localPosition * ZLevelOffset));
public override void FrameUpdate(float frameTime)
{
// Phase 1 (per render frame): strip any Z left from last frame so the animation player
// always starts from a Z-free base, and Phase 2 can add exactly one Z contribution.
var query = EntityQueryEnumerator<CEZPhysicsComponent, SpriteComponent>();
while (query.MoveNext(out var uid, out var zPhys, out var sprite))
{
var localPosition = zPhys.LocalPosition;
_sprite.SetOffset((uid, sprite), zPhys.SpriteOffsetDefault);
_sprite.SetDrawDepth((uid, sprite), localPosition > 0 ? (int)Shared.DrawDepth.DrawDepth.OverMobs : zPhys.DrawDepthDefault);
}

// Update StartOffset for entities with running fatigue animations
// This allows animations to follow dynamic offset changes (e.g., from Z-levels system)
var query2 = EntityQueryEnumerator<StaminaComponent, SpriteComponent, CEZPhysicsComponent>();
while (query2.MoveNext(out var uid, out var stamina, out var sprite, out var zPhys))
// Set parent-synced status effect offsets to the parent's current Z value each frame — prevents accumulation.
var syncQuery = EntityQueryEnumerator<StatusEffectComponent, SpriteComponent, TransformComponent>();
while (syncQuery.MoveNext(out var uid, out _, out var sprite, out var xform))
{
// Only update if animation is running
if (!_animation.HasRunningAnimation(uid, StaminaSystem.StaminaAnimationKey))
var parent = xform.ParentUid;
if (_mapGridQuery.HasComp(parent))
continue;

// Update the base offset to track changes made by other systems
stamina.StartOffset = zPhys.SpriteOffsetDefault;
if (!_zPhysQuery.TryComp(parent, out var parentZPhys))
continue;
var zOffset = new Vector2(0, parentZPhys.LocalPosition * CESharedZLevelsSystem.ZLevelOffset);
_sprite.SetOffset((uid, sprite), zOffset);
}
}
}

/// <summary>
/// Post-animation pass for Z-level visuals.
/// Runs its <see cref="FrameUpdate"/> AFTER <see cref="AnimationPlayerSystem"/> so that
/// whatever offset the animation player wrote to <see cref="SpriteComponent.Offset"/> this frame
/// (loop animation, one-shot swing, idle bob, etc.) is preserved, and the Z-height contribution
/// is simply added on top. No animation code needs to know about Z levels.
/// </summary>
internal sealed partial class CEClientZLevelsPostAnimSystem : EntitySystem
{
[Dependency] private SpriteSystem _sprite = default!;
[Dependency] private SharedTransformSystem _xform = default!;

public float GetVisualsLocalPosition(Entity<CEZPhysicsComponent?> ent, TransformComponent? xform = null)
public override void Initialize()
{
if (!Resolve(ent, ref ent.Comp, false))
return 0;
if (!Resolve(ent, ref xform, false))
return 0;

var pos = ent.Comp.LocalPosition;

if (xform.ParentUid != xform.MapUid && ZPhyzQuery.TryComp(xform.ParentUid, out var parentZPhys))
pos = parentZPhys.LocalPosition;

return pos;
base.Initialize();
UpdatesAfter.Add(typeof(AnimationPlayerSystem));
}

public override void Shutdown()
public override void FrameUpdate(float frameTime)
{
base.Shutdown();
_overlay.RemoveOverlay<CEZLevelBlurOverlay>();
// Phase 2: add the Z-height contribution on top of the animation-player's output.
// At this point sprite.Offset == animationValue (or SpriteOffsetDefault if no anim ran).
// The offset is counter-rotated by the entity's world angle so it always points world-up,
// preventing it from orbiting the pivot when the entity has angular velocity (e.g. shurikens).
var query = EntityQueryEnumerator<CEZPhysicsComponent, SpriteComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var zPhys, out var sprite, out var xform))
{
var rawZ = new Vector2(0, zPhys.LocalPosition * CESharedZLevelsSystem.ZLevelOffset);
Vector2 zOffset;
if (sprite.NoRotation)
zOffset = rawZ;
else
zOffset = new Angle(-_xform.GetWorldRotation(xform)).RotateVec(rawZ);
_sprite.SetOffset((uid, sprite), sprite.Offset + zOffset);
}
}
}
Loading
Loading