mirror of
https://github.com/wega-team/ss14-wega.git
synced 2026-02-14 19:30:01 +01:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
54
.github/workflows/check-trailing-whitespace.yml
vendored
Normal file
54
.github/workflows/check-trailing-whitespace.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: Trailing Whitespace Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [ opened, reopened, synchronize, ready_for_review ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Trailing Whitespace Check
|
||||
if: github.event.pull_request.draft == false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
- name: Get changed text files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v46.0.5
|
||||
with:
|
||||
files: |
|
||||
**.cs
|
||||
**.yml
|
||||
**.swsl
|
||||
**.json
|
||||
**.py
|
||||
- name: Check for trailing whitespace and EOF newline
|
||||
env:
|
||||
ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||
run: |
|
||||
has_trailing_whitespace=0
|
||||
has_missing_eof_newline=0
|
||||
|
||||
for file in ${ALL_CHANGED_FILES}; do
|
||||
echo "Checking $file"
|
||||
|
||||
# Check for trailing whitespace
|
||||
if grep -qP '[ \t]+$' "$file"; then
|
||||
echo "::error file=$file::Trailing whitespace found"
|
||||
has_trailing_whitespace=1
|
||||
fi
|
||||
|
||||
# Check for missing EOF newline
|
||||
if [ -f "$file" ] && [ -s "$file" ]; then
|
||||
last_char=$(tail -c 1 "$file")
|
||||
if [ "$last_char" != "" ] && [ "$last_char" != $'\n' ]; then
|
||||
echo "::error file=$file::Missing newline at end of file"
|
||||
has_missing_eof_newline=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$has_trailing_whitespace" -eq 1 ] || [ "$has_missing_eof_newline" -eq 1 ]; then
|
||||
echo "Issues found: trailing whitespace or missing EOF newline."
|
||||
echo "We recommend using an IDE to prevent this from happening."
|
||||
exit 1
|
||||
fi
|
||||
@@ -29,7 +29,7 @@ namespace Content.Benchmarks;
|
||||
[CategoriesColumn]
|
||||
public class ComponentQueryBenchmark
|
||||
{
|
||||
public const string Map = "Maps/atlas.yml";
|
||||
public const string Map = "Maps/saltern.yml";
|
||||
|
||||
private TestPair _pair = default!;
|
||||
private IEntityManager _entMan = default!;
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BenchmarkDotNet.Running;
|
||||
using Content.IntegrationTests;
|
||||
using Content.Server.Maps;
|
||||
#if DEBUG
|
||||
using BenchmarkDotNet.Configs;
|
||||
#else
|
||||
using Robust.Benchmarks.Configs;
|
||||
#endif
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Benchmarks
|
||||
{
|
||||
@@ -22,11 +14,15 @@ namespace Content.Benchmarks
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("\nWARNING: YOU ARE RUNNING A DEBUG BUILD, USE A RELEASE BUILD FOR AN ACCURATE BENCHMARK");
|
||||
Console.WriteLine("THE DEBUG BUILD IS ONLY GOOD FOR FIXING A CRASHING BENCHMARK\n");
|
||||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new DebugInProcessConfig());
|
||||
var baseConfig = new DebugInProcessConfig();
|
||||
#else
|
||||
var config = Environment.GetEnvironmentVariable("ROBUST_BENCHMARKS_ENABLE_SQL") != null ? DefaultSQLConfig.Instance : null;
|
||||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config);
|
||||
var baseConfig = Environment.GetEnvironmentVariable("ROBUST_BENCHMARKS_ENABLE_SQL") != null
|
||||
? DefaultSQLConfig.Instance
|
||||
: DefaultConfig.Instance;
|
||||
#endif
|
||||
var config = ManualConfig.Create(baseConfig);
|
||||
config.BuildTimeout = TimeSpan.FromMinutes(5);
|
||||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
126
Content.Benchmarks/RaiseEventBenchmark.cs
Normal file
126
Content.Benchmarks/RaiseEventBenchmark.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
#nullable enable
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Content.IntegrationTests;
|
||||
using Content.IntegrationTests.Pair;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Benchmarks;
|
||||
|
||||
[Virtual]
|
||||
public class RaiseEventBenchmark
|
||||
{
|
||||
private TestPair _pair = default!;
|
||||
private BenchSystem _sys = default!;
|
||||
|
||||
[GlobalSetup]
|
||||
public void Setup()
|
||||
{
|
||||
ProgramShared.PathOffset = "../../../../";
|
||||
PoolManager.Startup(typeof(BenchSystem).Assembly);
|
||||
_pair = PoolManager.GetServerClient().GetAwaiter().GetResult();
|
||||
var entMan = _pair.Server.EntMan;
|
||||
_sys = entMan.System<BenchSystem>();
|
||||
|
||||
_pair.Server.WaitPost(() =>
|
||||
{
|
||||
var uid = entMan.Spawn();
|
||||
_sys.Ent = new(uid, entMan.GetComponent<TransformComponent>(uid));
|
||||
_sys.Ent2 = new(_sys.Ent.Owner, _sys.Ent.Comp);
|
||||
})
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
}
|
||||
|
||||
[GlobalCleanup]
|
||||
public async Task Cleanup()
|
||||
{
|
||||
await _pair.DisposeAsync();
|
||||
PoolManager.Shutdown();
|
||||
}
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public int RaiseEvent()
|
||||
{
|
||||
return _sys.RaiseEvent();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int RaiseCompEvent()
|
||||
{
|
||||
return _sys.RaiseCompEvent();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int RaiseICompEvent()
|
||||
{
|
||||
return _sys.RaiseICompEvent();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int RaiseCSharpEvent()
|
||||
{
|
||||
return _sys.CSharpEvent();
|
||||
}
|
||||
|
||||
public sealed class BenchSystem : EntitySystem
|
||||
{
|
||||
public Entity<TransformComponent> Ent;
|
||||
public Entity<IComponent> Ent2;
|
||||
|
||||
public delegate void EntityEventHandler(EntityUid uid, TransformComponent comp, ref BenchEv ev);
|
||||
|
||||
public event EntityEventHandler? OnCSharpEvent;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<TransformComponent, BenchEv>(OnEvent);
|
||||
OnCSharpEvent += OnEvent;
|
||||
}
|
||||
|
||||
public int RaiseEvent()
|
||||
{
|
||||
var ev = new BenchEv();
|
||||
RaiseLocalEvent(Ent.Owner, ref ev);
|
||||
return ev.N;
|
||||
}
|
||||
|
||||
public int RaiseCompEvent()
|
||||
{
|
||||
var ev = new BenchEv();
|
||||
EntityManager.EventBus.RaiseComponentEvent(Ent.Owner, Ent.Comp, ref ev);
|
||||
return ev.N;
|
||||
}
|
||||
|
||||
public int RaiseICompEvent()
|
||||
{
|
||||
// Raise with an IComponent instead of concrete type
|
||||
var ev = new BenchEv();
|
||||
EntityManager.EventBus.RaiseComponentEvent(Ent2.Owner, Ent2.Comp, ref ev);
|
||||
return ev.N;
|
||||
}
|
||||
|
||||
public int CSharpEvent()
|
||||
{
|
||||
var ev = new BenchEv();
|
||||
OnCSharpEvent?.Invoke(Ent.Owner, Ent.Comp, ref ev);
|
||||
return ev.N;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private void OnEvent(EntityUid uid, TransformComponent component, ref BenchEv args)
|
||||
{
|
||||
args.N += uid.Id;
|
||||
}
|
||||
|
||||
[ByRefEvent]
|
||||
public struct BenchEv
|
||||
{
|
||||
public int N;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
using Content.Shared.Access;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.CrewManifest;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Prototypes;
|
||||
using static Content.Shared.Access.Components.IdCardConsoleComponent;
|
||||
|
||||
@@ -11,13 +13,21 @@ namespace Content.Client.Access.UI
|
||||
public sealed class IdCardConsoleBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
|
||||
private readonly SharedIdCardConsoleSystem _idCardConsoleSystem = default!;
|
||||
|
||||
private IdCardConsoleWindow? _window;
|
||||
|
||||
// CCVar.
|
||||
private int _maxNameLength;
|
||||
private int _maxIdJobLength;
|
||||
|
||||
public IdCardConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
_idCardConsoleSystem = EntMan.System<SharedIdCardConsoleSystem>();
|
||||
|
||||
_maxNameLength =_cfgManager.GetCVar(CCVars.MaxNameLength);
|
||||
_maxIdJobLength = _cfgManager.GetCVar(CCVars.MaxIdJobLength);
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
@@ -66,11 +76,11 @@ namespace Content.Client.Access.UI
|
||||
|
||||
public void SubmitData(string newFullName, string newJobTitle, List<ProtoId<AccessLevelPrototype>> newAccessList, string newJobPrototype)
|
||||
{
|
||||
if (newFullName.Length > MaxFullNameLength)
|
||||
newFullName = newFullName[..MaxFullNameLength];
|
||||
if (newFullName.Length > _maxNameLength)
|
||||
newFullName = newFullName[.._maxNameLength];
|
||||
|
||||
if (newJobTitle.Length > MaxJobTitleLength)
|
||||
newJobTitle = newJobTitle[..MaxJobTitleLength];
|
||||
if (newJobTitle.Length > _maxIdJobLength)
|
||||
newJobTitle = newJobTitle[.._maxIdJobLength];
|
||||
|
||||
SendMessage(new WriteToTargetIdMessage(
|
||||
newFullName,
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.Access;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Prototypes;
|
||||
using static Content.Shared.Access.Components.IdCardConsoleComponent;
|
||||
|
||||
@@ -14,12 +16,17 @@ namespace Content.Client.Access.UI
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class IdCardConsoleWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
private readonly ISawmill _logMill = default!;
|
||||
|
||||
private readonly IdCardConsoleBoundUserInterface _owner;
|
||||
|
||||
// CCVar.
|
||||
private int _maxNameLength;
|
||||
private int _maxIdJobLength;
|
||||
|
||||
private AccessLevelControl _accessButtons = new();
|
||||
private readonly List<string> _jobPrototypeIds = new();
|
||||
|
||||
@@ -39,7 +46,11 @@ namespace Content.Client.Access.UI
|
||||
|
||||
_owner = owner;
|
||||
|
||||
_maxNameLength = _cfgManager.GetCVar(CCVars.MaxNameLength);
|
||||
_maxIdJobLength = _cfgManager.GetCVar(CCVars.MaxIdJobLength);
|
||||
|
||||
FullNameLineEdit.OnTextEntered += _ => SubmitData();
|
||||
FullNameLineEdit.IsValid = s => s.Length <= _maxNameLength;
|
||||
FullNameLineEdit.OnTextChanged += _ =>
|
||||
{
|
||||
FullNameSaveButton.Disabled = FullNameSaveButton.Text == _lastFullName;
|
||||
@@ -47,6 +58,7 @@ namespace Content.Client.Access.UI
|
||||
FullNameSaveButton.OnPressed += _ => SubmitData();
|
||||
|
||||
JobTitleLineEdit.OnTextEntered += _ => SubmitData();
|
||||
JobTitleLineEdit.IsValid = s => s.Length <= _maxIdJobLength;
|
||||
JobTitleLineEdit.OnTextChanged += _ =>
|
||||
{
|
||||
JobTitleSaveButton.Disabled = JobTitleLineEdit.Text == _lastJobTitle;
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace Content.Client.Administration.Systems;
|
||||
|
||||
public sealed class KillSignSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<KillSignComponent, ComponentStartup>(KillSignAdded);
|
||||
@@ -18,10 +20,10 @@ public sealed class KillSignSystem : EntitySystem
|
||||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
if (!sprite.LayerMapTryGet(KillSignKey.Key, out var layer))
|
||||
if (!_sprite.LayerMapTryGet((uid, sprite), KillSignKey.Key, out var layer, false))
|
||||
return;
|
||||
|
||||
sprite.RemoveLayer(layer);
|
||||
_sprite.RemoveLayer((uid, sprite), layer);
|
||||
}
|
||||
|
||||
private void KillSignAdded(EntityUid uid, KillSignComponent component, ComponentStartup args)
|
||||
@@ -29,15 +31,15 @@ public sealed class KillSignSystem : EntitySystem
|
||||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
if (sprite.LayerMapTryGet(KillSignKey.Key, out var _))
|
||||
if (_sprite.LayerMapTryGet((uid, sprite), KillSignKey.Key, out var _, false))
|
||||
return;
|
||||
|
||||
var adj = sprite.Bounds.Height / 2 + ((1.0f/32) * 6.0f);
|
||||
var adj = _sprite.GetLocalBounds((uid, sprite)).Height / 2 + ((1.0f / 32) * 6.0f);
|
||||
|
||||
var layer = sprite.AddLayer(new SpriteSpecifier.Rsi(new ResPath("Objects/Misc/killsign.rsi"), "sign"));
|
||||
sprite.LayerMapSet(KillSignKey.Key, layer);
|
||||
var layer = _sprite.AddLayer((uid, sprite), new SpriteSpecifier.Rsi(new ResPath("Objects/Misc/killsign.rsi"), "sign"));
|
||||
_sprite.LayerMapSet((uid, sprite), KillSignKey.Key, layer);
|
||||
|
||||
sprite.LayerSetOffset(layer, new Vector2(0.0f, adj));
|
||||
_sprite.LayerSetOffset((uid, sprite), layer, new Vector2(0.0f, adj));
|
||||
sprite.LayerSetShader(layer, "unshaded");
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@ namespace Content.Client.Administration.UI.SpawnExplosion;
|
||||
public sealed partial class SpawnExplosionWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IClientConsoleHost _conHost = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
private readonly SharedMapSystem _mapSystem;
|
||||
private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
private readonly SpawnExplosionEui _eui;
|
||||
@@ -38,6 +38,7 @@ public sealed partial class SpawnExplosionWindow : DefaultWindow
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
_mapSystem = _entMan.System<SharedMapSystem>();
|
||||
_transform = _entMan.System<TransformSystem>();
|
||||
_eui = eui;
|
||||
|
||||
@@ -87,7 +88,7 @@ public sealed partial class SpawnExplosionWindow : DefaultWindow
|
||||
{
|
||||
_mapData.Clear();
|
||||
MapOptions.Clear();
|
||||
foreach (var map in _mapManager.GetAllMapIds())
|
||||
foreach (var map in _mapSystem.GetAllMapIds())
|
||||
{
|
||||
_mapData.Add(map);
|
||||
MapOptions.AddItem(map.ToString());
|
||||
|
||||
@@ -14,6 +14,9 @@ namespace Content.Client.Administration.UI.Tabs.AdminbusTab
|
||||
[UsedImplicitly]
|
||||
public sealed partial class LoadBlueprintsWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
public LoadBlueprintsWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
@@ -21,9 +24,9 @@ namespace Content.Client.Administration.UI.Tabs.AdminbusTab
|
||||
|
||||
protected override void EnteredTree()
|
||||
{
|
||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||
var mapSystem = _entityManager.System<SharedMapSystem>();
|
||||
|
||||
foreach (var mapId in mapManager.GetAllMapIds())
|
||||
foreach (var mapId in mapSystem.GetAllMapIds())
|
||||
{
|
||||
MapOptions.AddItem(mapId.ToString(), (int) mapId);
|
||||
}
|
||||
@@ -39,21 +42,19 @@ namespace Content.Client.Administration.UI.Tabs.AdminbusTab
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
var entManager = IoCManager.Resolve<IEntityManager>();
|
||||
var xformSystem = entManager.System<SharedTransformSystem>();
|
||||
var playerManager = IoCManager.Resolve<IPlayerManager>();
|
||||
var player = playerManager.LocalEntity;
|
||||
var xformSystem = _entityManager.System<SharedTransformSystem>();
|
||||
var player = _playerManager.LocalEntity;
|
||||
|
||||
var currentMap = MapId.Nullspace;
|
||||
var position = Vector2.Zero;
|
||||
var rotation = Angle.Zero;
|
||||
|
||||
if (entManager.TryGetComponent<TransformComponent>(player, out var xform))
|
||||
if (_entityManager.TryGetComponent<TransformComponent>(player, out var xform))
|
||||
{
|
||||
currentMap = xform.MapID;
|
||||
position = xformSystem.GetWorldPosition(xform);
|
||||
|
||||
if (entManager.TryGetComponent<TransformComponent>(xform.GridUid, out var gridXform))
|
||||
if (_entityManager.TryGetComponent<TransformComponent>(xform.GridUid, out var gridXform))
|
||||
{
|
||||
rotation = xformSystem.GetWorldRotation(gridXform);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace Content.Client.AlertLevel;
|
||||
|
||||
public sealed class AlertLevelDisplaySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -21,26 +23,26 @@ public sealed class AlertLevelDisplaySystem : EntitySystem
|
||||
{
|
||||
return;
|
||||
}
|
||||
var layer = args.Sprite.LayerMapReserveBlank(AlertLevelDisplay.Layer);
|
||||
var layer = _sprite.LayerMapReserve((uid, args.Sprite), AlertLevelDisplay.Layer);
|
||||
|
||||
if (args.AppearanceData.TryGetValue(AlertLevelDisplay.Powered, out var poweredObject))
|
||||
{
|
||||
args.Sprite.LayerSetVisible(layer, poweredObject is true);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, poweredObject is true);
|
||||
}
|
||||
|
||||
if (!args.AppearanceData.TryGetValue(AlertLevelDisplay.CurrentLevel, out var level))
|
||||
{
|
||||
args.Sprite.LayerSetState(layer, alertLevelDisplay.AlertVisuals.Values.First());
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, alertLevelDisplay.AlertVisuals.Values.First());
|
||||
return;
|
||||
}
|
||||
|
||||
if (alertLevelDisplay.AlertVisuals.TryGetValue((string) level, out var visual))
|
||||
if (alertLevelDisplay.AlertVisuals.TryGetValue((string)level, out var visual))
|
||||
{
|
||||
args.Sprite.LayerSetState(layer, visual);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, visual);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Sprite.LayerSetState(layer, alertLevelDisplay.AlertVisuals.Values.First());
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, alertLevelDisplay.AlertVisuals.Values.First());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ public sealed class EntityPickupAnimationSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _animations = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
|
||||
public override void Initialize()
|
||||
@@ -56,8 +57,8 @@ public sealed class EntityPickupAnimationSystem : EntitySystem
|
||||
}
|
||||
|
||||
var sprite = Comp<SpriteComponent>(animatableClone);
|
||||
sprite.CopyFrom(sprite0);
|
||||
sprite.Visible = true;
|
||||
_sprite.CopySprite((uid, sprite0), (animatableClone, sprite));
|
||||
_sprite.SetVisible((animatableClone, sprite), true);
|
||||
|
||||
var animations = Comp<AnimationPlayerComponent>(animatableClone);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ public sealed class AnomalySystem : SharedAnomalySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly FloatingVisualizerSystem _floating = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
@@ -49,12 +50,12 @@ public sealed class AnomalySystem : SharedAnomalySystem
|
||||
if (HasComp<AnomalySupercriticalComponent>(uid))
|
||||
pulsing = true;
|
||||
|
||||
if (!sprite.LayerMapTryGet(AnomalyVisualLayers.Base, out var layer) ||
|
||||
!sprite.LayerMapTryGet(AnomalyVisualLayers.Animated, out var animatedLayer))
|
||||
if (!_sprite.LayerMapTryGet((uid, sprite), AnomalyVisualLayers.Base, out var layer, false) ||
|
||||
!_sprite.LayerMapTryGet((uid, sprite), AnomalyVisualLayers.Animated, out var animatedLayer, false))
|
||||
return;
|
||||
|
||||
sprite.LayerSetVisible(layer, !pulsing);
|
||||
sprite.LayerSetVisible(animatedLayer, pulsing);
|
||||
_sprite.LayerSetVisible((uid, sprite), layer, !pulsing);
|
||||
_sprite.LayerSetVisible((uid, sprite), animatedLayer, pulsing);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
@@ -63,16 +64,16 @@ public sealed class AnomalySystem : SharedAnomalySystem
|
||||
|
||||
var query = EntityQueryEnumerator<AnomalySupercriticalComponent, SpriteComponent>();
|
||||
|
||||
while (query.MoveNext(out var super, out var sprite))
|
||||
while (query.MoveNext(out var uid, out var super, out var sprite))
|
||||
{
|
||||
var completion = 1f - (float) ((super.EndTime - _timing.CurTime) / super.SupercriticalDuration);
|
||||
var completion = 1f - (float)((super.EndTime - _timing.CurTime) / super.SupercriticalDuration);
|
||||
var scale = completion * (super.MaxScaleAmount - 1f) + 1f;
|
||||
sprite.Scale = new Vector2(scale, scale);
|
||||
_sprite.SetScale((uid, sprite), new Vector2(scale, scale));
|
||||
|
||||
var transparency = (byte) (65 * (1f - completion) + 190);
|
||||
var transparency = (byte)(65 * (1f - completion) + 190);
|
||||
if (transparency < sprite.Color.AByte)
|
||||
{
|
||||
sprite.Color = sprite.Color.WithAlpha(transparency);
|
||||
_sprite.SetColor((uid, sprite), sprite.Color.WithAlpha(transparency));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,7 +83,7 @@ public sealed class AnomalySystem : SharedAnomalySystem
|
||||
if (!TryComp<SpriteComponent>(ent, out var sprite))
|
||||
return;
|
||||
|
||||
sprite.Scale = Vector2.One;
|
||||
sprite.Color = sprite.Color.WithAlpha(1f);
|
||||
_sprite.SetScale((ent.Owner, sprite), Vector2.One);
|
||||
_sprite.SetColor((ent.Owner, sprite), sprite.Color.WithAlpha(1f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace Content.Client.Anomaly.Effects;
|
||||
|
||||
public sealed class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<InnerBodyAnomalyComponent, AfterAutoHandleStateEvent>(OnAfterHandleState);
|
||||
@@ -21,21 +23,20 @@ public sealed class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem
|
||||
if (ent.Comp.FallbackSprite is null)
|
||||
return;
|
||||
|
||||
if (!sprite.LayerMapTryGet(ent.Comp.LayerMap, out var index))
|
||||
index = sprite.LayerMapReserveBlank(ent.Comp.LayerMap);
|
||||
var index = _sprite.LayerMapReserve((ent.Owner, sprite), ent.Comp.LayerMap);
|
||||
|
||||
if (TryComp<BodyComponent>(ent, out var body) &&
|
||||
body.Prototype is not null &&
|
||||
ent.Comp.SpeciesSprites.TryGetValue(body.Prototype.Value, out var speciesSprite))
|
||||
{
|
||||
sprite.LayerSetSprite(index, speciesSprite);
|
||||
_sprite.LayerSetSprite((ent.Owner, sprite), index, speciesSprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetSprite(index, ent.Comp.FallbackSprite);
|
||||
_sprite.LayerSetSprite((ent.Owner, sprite), index, ent.Comp.FallbackSprite);
|
||||
}
|
||||
|
||||
sprite.LayerSetVisible(index, true);
|
||||
_sprite.LayerSetVisible((ent.Owner, sprite), index, true);
|
||||
sprite.LayerSetShader(index, "unshaded");
|
||||
}
|
||||
|
||||
@@ -44,7 +45,7 @@ public sealed class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem
|
||||
if (!TryComp<SpriteComponent>(ent, out var sprite))
|
||||
return;
|
||||
|
||||
var index = sprite.LayerMapGet(ent.Comp.LayerMap);
|
||||
sprite.LayerSetVisible(index, false);
|
||||
var index = _sprite.LayerMapGet((ent.Owner, sprite), ent.Comp.LayerMap);
|
||||
_sprite.LayerSetVisible((ent.Owner, sprite), index, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Content.Client.Atmos.EntitySystems;
|
||||
public sealed class AtmosPipeAppearanceSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -25,21 +26,22 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem
|
||||
if (!TryComp(uid, out SpriteComponent? sprite))
|
||||
return;
|
||||
|
||||
foreach (PipeConnectionLayer layerKey in Enum.GetValues(typeof(PipeConnectionLayer)))
|
||||
foreach (var layerKey in Enum.GetValues<PipeConnectionLayer>())
|
||||
{
|
||||
sprite.LayerMapReserveBlank(layerKey);
|
||||
var layer = sprite.LayerMapGet(layerKey);
|
||||
sprite.LayerSetRSI(layer, component.Sprite.RsiPath);
|
||||
sprite.LayerSetState(layer, component.Sprite.RsiState);
|
||||
sprite.LayerSetDirOffset(layer, ToOffset(layerKey));
|
||||
var layer = _sprite.LayerMapReserve((uid, sprite), layerKey);
|
||||
_sprite.LayerSetRsi((uid, sprite), layer, component.Sprite.RsiPath);
|
||||
_sprite.LayerSetRsiState((uid, sprite), layer, component.Sprite.RsiState);
|
||||
_sprite.LayerSetDirOffset((uid, sprite), layer, ToOffset(layerKey));
|
||||
}
|
||||
}
|
||||
|
||||
private void HideAllPipeConnection(SpriteComponent sprite)
|
||||
private void HideAllPipeConnection(Entity<SpriteComponent> entity)
|
||||
{
|
||||
foreach (PipeConnectionLayer layerKey in Enum.GetValues(typeof(PipeConnectionLayer)))
|
||||
var sprite = entity.Comp;
|
||||
|
||||
foreach (var layerKey in Enum.GetValues<PipeConnectionLayer>())
|
||||
{
|
||||
if (!sprite.LayerMapTryGet(layerKey, out var key))
|
||||
if (!_sprite.LayerMapTryGet(entity.AsNullable(), layerKey, out var key, false))
|
||||
continue;
|
||||
|
||||
var layer = sprite[key];
|
||||
@@ -61,7 +63,7 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem
|
||||
|
||||
if (!_appearance.TryGetData<PipeDirection>(uid, PipeVisuals.VisualState, out var worldConnectedDirections, args.Component))
|
||||
{
|
||||
HideAllPipeConnection(args.Sprite);
|
||||
HideAllPipeConnection((uid, args.Sprite));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -71,13 +73,13 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem
|
||||
// transform connected directions to local-coordinates
|
||||
var connectedDirections = worldConnectedDirections.RotatePipeDirection(-Transform(uid).LocalRotation);
|
||||
|
||||
foreach (PipeConnectionLayer layerKey in Enum.GetValues(typeof(PipeConnectionLayer)))
|
||||
foreach (var layerKey in Enum.GetValues<PipeConnectionLayer>())
|
||||
{
|
||||
if (!args.Sprite.LayerMapTryGet(layerKey, out var key))
|
||||
if (!_sprite.LayerMapTryGet((uid, args.Sprite), layerKey, out var key, false))
|
||||
continue;
|
||||
|
||||
var layer = args.Sprite[key];
|
||||
var dir = (PipeDirection) layerKey;
|
||||
var dir = (PipeDirection)layerKey;
|
||||
var visible = connectedDirections.HasDirection(dir);
|
||||
|
||||
layer.Visible &= visible;
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Client.Atmos.Components;
|
||||
using Content.Shared.Atmos;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Atmos.EntitySystems;
|
||||
|
||||
@@ -31,9 +32,9 @@ public sealed class FireVisualizerSystem : VisualizerSystem<FireVisualsComponent
|
||||
// Need LayerMapTryGet because Init fails if there's no existing sprite / appearancecomp
|
||||
// which means in some setups (most frequently no AppearanceComp) the layer never exists.
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite) &&
|
||||
sprite.LayerMapTryGet(FireVisualLayers.Fire, out var layer))
|
||||
SpriteSystem.LayerMapTryGet((uid, sprite), FireVisualLayers.Fire, out var layer, false))
|
||||
{
|
||||
sprite.RemoveLayer(layer);
|
||||
SpriteSystem.RemoveLayer((uid, sprite), layer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,11 +43,11 @@ public sealed class FireVisualizerSystem : VisualizerSystem<FireVisualsComponent
|
||||
if (!TryComp<SpriteComponent>(uid, out var sprite) || !TryComp(uid, out AppearanceComponent? appearance))
|
||||
return;
|
||||
|
||||
sprite.LayerMapReserveBlank(FireVisualLayers.Fire);
|
||||
sprite.LayerSetVisible(FireVisualLayers.Fire, false);
|
||||
SpriteSystem.LayerMapReserve((uid, sprite), FireVisualLayers.Fire);
|
||||
SpriteSystem.LayerSetVisible((uid, sprite), FireVisualLayers.Fire, false);
|
||||
sprite.LayerSetShader(FireVisualLayers.Fire, "unshaded");
|
||||
if (component.Sprite != null)
|
||||
sprite.LayerSetRSI(FireVisualLayers.Fire, component.Sprite);
|
||||
SpriteSystem.LayerSetRsi((uid, sprite), FireVisualLayers.Fire, new ResPath(component.Sprite));
|
||||
|
||||
UpdateAppearance(uid, component, sprite, appearance);
|
||||
}
|
||||
@@ -59,12 +60,12 @@ public sealed class FireVisualizerSystem : VisualizerSystem<FireVisualsComponent
|
||||
|
||||
private void UpdateAppearance(EntityUid uid, FireVisualsComponent component, SpriteComponent sprite, AppearanceComponent appearance)
|
||||
{
|
||||
if (!sprite.LayerMapTryGet(FireVisualLayers.Fire, out var index))
|
||||
if (!SpriteSystem.LayerMapTryGet((uid, sprite), FireVisualLayers.Fire, out var index, false))
|
||||
return;
|
||||
|
||||
AppearanceSystem.TryGetData<bool>(uid, FireVisuals.OnFire, out var onFire, appearance);
|
||||
AppearanceSystem.TryGetData<float>(uid, FireVisuals.FireStacks, out var fireStacks, appearance);
|
||||
sprite.LayerSetVisible(index, onFire);
|
||||
SpriteSystem.LayerSetVisible((uid, sprite), index, onFire);
|
||||
|
||||
if (!onFire)
|
||||
{
|
||||
@@ -78,9 +79,9 @@ public sealed class FireVisualizerSystem : VisualizerSystem<FireVisualsComponent
|
||||
}
|
||||
|
||||
if (fireStacks > component.FireStackAlternateState && !string.IsNullOrEmpty(component.AlternateState))
|
||||
sprite.LayerSetState(index, component.AlternateState);
|
||||
SpriteSystem.LayerSetRsiState((uid, sprite), index, component.AlternateState);
|
||||
else
|
||||
sprite.LayerSetState(index, component.NormalState);
|
||||
SpriteSystem.LayerSetRsiState((uid, sprite), index, component.NormalState);
|
||||
|
||||
component.LightEntity ??= Spawn(null, new EntityCoordinates(uid, default));
|
||||
var light = EnsureComp<PointLightComponent>(component.LightEntity.Value);
|
||||
|
||||
@@ -9,7 +9,7 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem<AtmosAlarmabl
|
||||
{
|
||||
protected override void OnAppearanceChange(EntityUid uid, AtmosAlarmableVisualsComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null || !args.Sprite.LayerMapTryGet(component.LayerMap, out var layer))
|
||||
if (args.Sprite == null || !SpriteSystem.LayerMapTryGet((uid, args.Sprite), component.LayerMap, out var layer, false))
|
||||
return;
|
||||
|
||||
if (!args.AppearanceData.TryGetValue(PowerDeviceVisuals.Powered, out var poweredObject) ||
|
||||
@@ -22,8 +22,8 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem<AtmosAlarmabl
|
||||
{
|
||||
foreach (var visLayer in component.HideOnDepowered)
|
||||
{
|
||||
if (args.Sprite.LayerMapTryGet(visLayer, out var powerVisibilityLayer))
|
||||
args.Sprite.LayerSetVisible(powerVisibilityLayer, powered);
|
||||
if (SpriteSystem.LayerMapTryGet((uid, args.Sprite), visLayer, out var powerVisibilityLayer, false))
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), powerVisibilityLayer, powered);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem<AtmosAlarmabl
|
||||
{
|
||||
foreach (var (setLayer, powerState) in component.SetOnDepowered)
|
||||
{
|
||||
if (args.Sprite.LayerMapTryGet(setLayer, out var setStateLayer))
|
||||
args.Sprite.LayerSetState(setStateLayer, new RSI.StateId(powerState));
|
||||
if (SpriteSystem.LayerMapTryGet((uid, args.Sprite), setLayer, out var setStateLayer, false))
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), setStateLayer, new RSI.StateId(powerState));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem<AtmosAlarmabl
|
||||
&& powered
|
||||
&& component.AlarmStates.TryGetValue(alarmType, out var state))
|
||||
{
|
||||
args.Sprite.LayerSetState(layer, new RSI.StateId(state));
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), layer, new RSI.StateId(state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,13 @@
|
||||
<!-- Mode buttons -->
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<Label Text="{Loc 'air-alarm-ui-window-mode-label'}" Margin="0 0 2 0" />
|
||||
<OptionButton Name="CModeButton" HorizontalExpand="True" />
|
||||
<Control HorizontalExpand="True">
|
||||
<OptionButton Name="CModeButton" />
|
||||
<ui:StripeBack Name="CModeSelectLocked">
|
||||
<RichTextLabel Text="{Loc 'air-alarm-ui-window-mode-select-locked-label'}"
|
||||
HorizontalAlignment="Center" />
|
||||
</ui:StripeBack>
|
||||
</Control>
|
||||
<CheckBox Name="AutoModeCheckBox" Text="{Loc 'air-alarm-ui-window-auto-mode-label'}" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
@@ -110,6 +110,8 @@ public sealed partial class AirAlarmWindow : FancyWindow
|
||||
{
|
||||
UpdateDeviceData(addr, dev);
|
||||
}
|
||||
_modes.Visible = !state.PanicWireCut;
|
||||
CModeSelectLocked.Visible = state.PanicWireCut;
|
||||
}
|
||||
|
||||
public void UpdateModeSelector(AirAlarmMode mode)
|
||||
|
||||
@@ -71,6 +71,7 @@ public sealed partial class ScrubberControl : BoxContainer
|
||||
_data.PumpDirection = (ScrubberPumpDirection) args.Id;
|
||||
ScrubberDataChanged?.Invoke(_address, _data);
|
||||
};
|
||||
_pumpDirection.Disabled = data.AirAlarmPanicWireCut;
|
||||
|
||||
_copySettings.OnPressed += _ =>
|
||||
{
|
||||
@@ -109,6 +110,7 @@ public sealed partial class ScrubberControl : BoxContainer
|
||||
|
||||
_data.PumpDirection = data.PumpDirection;
|
||||
_pumpDirection.Select((int) _data.PumpDirection);
|
||||
_pumpDirection.Disabled = data.AirAlarmPanicWireCut;
|
||||
|
||||
_data.VolumeRate = data.VolumeRate;
|
||||
_volumeRate.Value = _data.VolumeRate;
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace Content.Client.Atmos.Overlays
|
||||
{
|
||||
private readonly IEntityManager _entManager;
|
||||
private readonly IMapManager _mapManager;
|
||||
private readonly SharedMapSystem _mapSystem;
|
||||
private readonly SharedTransformSystem _xformSys;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpaceEntities | OverlaySpace.WorldSpaceBelowWorld;
|
||||
@@ -51,6 +52,7 @@ namespace Content.Client.Atmos.Overlays
|
||||
{
|
||||
_entManager = entManager;
|
||||
_mapManager = IoCManager.Resolve<IMapManager>();
|
||||
_mapSystem = entManager.System<SharedMapSystem>();
|
||||
_xformSys = xformSys;
|
||||
_shader = protoMan.Index<ShaderPrototype>("unshaded").Instance();
|
||||
ZIndex = GasOverlayZIndex;
|
||||
@@ -163,7 +165,7 @@ namespace Content.Client.Atmos.Overlays
|
||||
xformQuery,
|
||||
_xformSys);
|
||||
|
||||
var mapUid = _mapManager.GetMapEntityId(args.MapId);
|
||||
var mapUid = _mapSystem.GetMapOrInvalid(args.MapId);
|
||||
|
||||
if (_entManager.TryGetComponent<MapAtmosphereComponent>(mapUid, out var atmos))
|
||||
DrawMapOverlay(drawHandle, args, mapUid, atmos);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using Content.Shared.Atmos.Piping.Binary.Systems;
|
||||
|
||||
namespace Content.Client.Atmos.Piping.Binary.Systems;
|
||||
|
||||
public sealed class GasValveSystem : SharedGasValveSystem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Content.Client.Atmos.UI;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Systems;
|
||||
|
||||
namespace Content.Client.Atmos.Piping.Unary.Systems;
|
||||
|
||||
public sealed class GasThermoMachineSystem : SharedGasThermoMachineSystem
|
||||
{
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<GasThermoMachineComponent, AfterAutoHandleStateEvent>(OnGasAfterState);
|
||||
}
|
||||
|
||||
private void OnGasAfterState(Entity<GasThermoMachineComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
DirtyUI(ent.Owner, ent.Comp);
|
||||
}
|
||||
|
||||
protected override void DirtyUI(EntityUid uid, GasThermoMachineComponent? thermoMachine, UserInterfaceComponent? ui = null)
|
||||
{
|
||||
if (_ui.TryGetOpenUi<GasThermomachineBoundUserInterface>(uid, ThermomachineUiKey.Key, out var bui))
|
||||
{
|
||||
bui.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Client.Power.EntitySystems;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Systems;
|
||||
using Content.Shared.Power.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
@@ -36,6 +39,8 @@ namespace Content.Client.Atmos.UI
|
||||
|
||||
_window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed();
|
||||
_window.TemperatureSpinbox.OnValueChanged += _ => OnTemperatureChanged(_window.TemperatureSpinbox.Value);
|
||||
_window.Entity = Owner;
|
||||
Update();
|
||||
}
|
||||
|
||||
private void OnToggleStatusButtonPressed()
|
||||
@@ -43,7 +48,7 @@ namespace Content.Client.Atmos.UI
|
||||
if (_window is null) return;
|
||||
|
||||
_window.SetActive(!_window.Active);
|
||||
SendMessage(new GasThermomachineToggleMessage());
|
||||
SendPredictedMessage(new GasThermomachineToggleMessage());
|
||||
}
|
||||
|
||||
private void OnTemperatureChanged(float value)
|
||||
@@ -60,25 +65,32 @@ namespace Content.Client.Atmos.UI
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage(new GasThermomachineChangeTemperatureMessage(actual));
|
||||
SendPredictedMessage(new GasThermomachineChangeTemperatureMessage(actual));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the UI state based on server-sent info
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
public override void Update()
|
||||
{
|
||||
base.UpdateState(state);
|
||||
if (_window == null || state is not GasThermomachineBoundUserInterfaceState cast)
|
||||
if (_window == null || !EntMan.TryGetComponent(Owner, out GasThermoMachineComponent? thermo))
|
||||
return;
|
||||
|
||||
_minTemp = cast.MinTemperature;
|
||||
_maxTemp = cast.MaxTemperature;
|
||||
_isHeater = cast.IsHeater;
|
||||
var system = EntMan.System<SharedGasThermoMachineSystem>();
|
||||
_minTemp = thermo.MinTemperature;
|
||||
_maxTemp = thermo.MaxTemperature;
|
||||
_isHeater = system.IsHeater(thermo);
|
||||
|
||||
_window.SetTemperature(thermo.TargetTemperature);
|
||||
|
||||
var receiverSys = EntMan.System<PowerReceiverSystem>();
|
||||
SharedApcPowerReceiverComponent? receiver = null;
|
||||
|
||||
receiverSys.ResolveApc(Owner, ref receiver);
|
||||
|
||||
// Also set in frameupdates.
|
||||
if (receiver != null)
|
||||
{
|
||||
_window.SetActive(!receiver.PowerDisabled);
|
||||
}
|
||||
|
||||
_window.SetTemperature(cast.Temperature);
|
||||
_window.SetActive(cast.Enabled);
|
||||
_window.Title = _isHeater switch
|
||||
{
|
||||
false => Loc.GetString("comp-gas-thermomachine-ui-title-freezer"),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
MinSize="300 120" Title="{Loc comp-gas-thermomachine-ui-title-freezer}">
|
||||
<BoxContainer Name="VboxContainer" Orientation="Vertical" Margin="5 5 5 5" SeparationOverride="10">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
@@ -11,4 +12,4 @@
|
||||
<Label Text="{Loc comp-gas-thermomachine-ui-temperature}"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
</controls:FancyWindow>
|
||||
|
||||
@@ -1,19 +1,26 @@
|
||||
using Content.Client.Power.Components;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Atmos.UI;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class GasThermomachineWindow : DefaultWindow
|
||||
public sealed partial class GasThermomachineWindow : FancyWindow
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
|
||||
public bool Active = true;
|
||||
|
||||
public FloatSpinBox TemperatureSpinbox;
|
||||
|
||||
public EntityUid Entity;
|
||||
|
||||
public GasThermomachineWindow()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
SpinboxHBox.AddChild(
|
||||
@@ -27,12 +34,10 @@ public sealed partial class GasThermomachineWindow : DefaultWindow
|
||||
if (active)
|
||||
{
|
||||
ToggleStatusButton.Text = Loc.GetString("comp-gas-thermomachine-ui-status-enabled");
|
||||
ToggleStatusButton.Pressed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ToggleStatusButton.Text = Loc.GetString("comp-gas-thermomachine-ui-status-disabled");
|
||||
ToggleStatusButton.Pressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,4 +45,14 @@ public sealed partial class GasThermomachineWindow : DefaultWindow
|
||||
{
|
||||
TemperatureSpinbox.Value = temperature;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
|
||||
if (_entManager.TryGetComponent(Entity, out ApcPowerReceiverComponent? receiver))
|
||||
{
|
||||
SetActive(!receiver.PowerDisabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,35 +2,35 @@ using Robust.Client.GameObjects;
|
||||
using Content.Shared.Atmos.Visuals;
|
||||
using Content.Client.Power;
|
||||
|
||||
namespace Content.Client.Atmos.Visualizers
|
||||
namespace Content.Client.Atmos.Visualizers;
|
||||
|
||||
/// <summary>
|
||||
/// Controls client-side visuals for portable scrubbers.
|
||||
/// </summary>
|
||||
public sealed class PortableScrubberSystem : VisualizerSystem<PortableScrubberVisualsComponent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls client-side visuals for portable scrubbers.
|
||||
/// </summary>
|
||||
public sealed class PortableScrubberSystem : VisualizerSystem<PortableScrubberVisualsComponent>
|
||||
protected override void OnAppearanceChange(EntityUid uid, PortableScrubberVisualsComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
protected override void OnAppearanceChange(EntityUid uid, PortableScrubberVisualsComponent component, ref AppearanceChangeEvent args)
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
if (AppearanceSystem.TryGetData<bool>(uid, PortableScrubberVisuals.IsFull, out var isFull, args.Component)
|
||||
&& AppearanceSystem.TryGetData<bool>(uid, PortableScrubberVisuals.IsRunning, out var isRunning, args.Component))
|
||||
{
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
var runningState = isRunning ? component.RunningState : component.IdleState;
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), PortableScrubberVisualLayers.IsRunning, runningState);
|
||||
|
||||
if (AppearanceSystem.TryGetData<bool>(uid, PortableScrubberVisuals.IsFull, out var isFull, args.Component)
|
||||
&& AppearanceSystem.TryGetData<bool>(uid, PortableScrubberVisuals.IsRunning, out var isRunning, args.Component))
|
||||
{
|
||||
var runningState = isRunning ? component.RunningState : component.IdleState;
|
||||
args.Sprite.LayerSetState(PortableScrubberVisualLayers.IsRunning, runningState);
|
||||
var fullState = isFull ? component.FullState : component.ReadyState;
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), PowerDeviceVisualLayers.Powered, fullState);
|
||||
}
|
||||
|
||||
var fullState = isFull ? component.FullState : component.ReadyState;
|
||||
args.Sprite.LayerSetState(PowerDeviceVisualLayers.Powered, fullState);
|
||||
}
|
||||
|
||||
if (AppearanceSystem.TryGetData<bool>(uid, PortableScrubberVisuals.IsDraining, out var isDraining, args.Component))
|
||||
{
|
||||
args.Sprite.LayerSetVisible(PortableScrubberVisualLayers.IsDraining, isDraining);
|
||||
}
|
||||
if (AppearanceSystem.TryGetData<bool>(uid, PortableScrubberVisuals.IsDraining, out var isDraining, args.Component))
|
||||
{
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), PortableScrubberVisualLayers.IsDraining, isDraining);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum PortableScrubberVisualLayers : byte
|
||||
{
|
||||
IsRunning,
|
||||
|
||||
@@ -12,6 +12,7 @@ public sealed class JukeboxSystem : SharedJukeboxSystem
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -64,7 +65,7 @@ public sealed class JukeboxSystem : SharedJukeboxSystem
|
||||
visualState = JukeboxVisualState.On;
|
||||
}
|
||||
|
||||
UpdateAppearance(uid, visualState, component, sprite);
|
||||
UpdateAppearance((uid, sprite), visualState, component);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(EntityUid uid, JukeboxComponent component, ref AppearanceChangeEvent args)
|
||||
@@ -78,25 +79,25 @@ public sealed class JukeboxSystem : SharedJukeboxSystem
|
||||
visualState = JukeboxVisualState.On;
|
||||
}
|
||||
|
||||
UpdateAppearance(uid, visualState, component, args.Sprite);
|
||||
UpdateAppearance((uid, args.Sprite), visualState, component);
|
||||
}
|
||||
|
||||
private void UpdateAppearance(EntityUid uid, JukeboxVisualState visualState, JukeboxComponent component, SpriteComponent sprite)
|
||||
private void UpdateAppearance(Entity<SpriteComponent> entity, JukeboxVisualState visualState, JukeboxComponent component)
|
||||
{
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OffState, sprite);
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OffState, entity);
|
||||
|
||||
switch (visualState)
|
||||
{
|
||||
case JukeboxVisualState.On:
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OnState, sprite);
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OnState, entity);
|
||||
break;
|
||||
|
||||
case JukeboxVisualState.Off:
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OffState, sprite);
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OffState, entity);
|
||||
break;
|
||||
|
||||
case JukeboxVisualState.Select:
|
||||
PlayAnimation(uid, JukeboxVisualLayers.Base, component.SelectState, 1.0f, sprite);
|
||||
PlayAnimation(entity.Owner, JukeboxVisualLayers.Base, component.SelectState, 1.0f, entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -109,7 +110,7 @@ public sealed class JukeboxSystem : SharedJukeboxSystem
|
||||
if (!_animationPlayer.HasRunningAnimation(uid, state))
|
||||
{
|
||||
var animation = GetAnimation(layer, state, animationTime);
|
||||
sprite.LayerSetVisible(layer, true);
|
||||
_sprite.LayerSetVisible((uid, sprite), layer, true);
|
||||
_animationPlayer.Play(uid, animation, state);
|
||||
}
|
||||
}
|
||||
@@ -133,13 +134,13 @@ public sealed class JukeboxSystem : SharedJukeboxSystem
|
||||
};
|
||||
}
|
||||
|
||||
private void SetLayerState(JukeboxVisualLayers layer, string? state, SpriteComponent sprite)
|
||||
private void SetLayerState(JukeboxVisualLayers layer, string? state, Entity<SpriteComponent> sprite)
|
||||
{
|
||||
if (string.IsNullOrEmpty(state))
|
||||
return;
|
||||
|
||||
sprite.LayerSetVisible(layer, true);
|
||||
sprite.LayerSetAutoAnimated(layer, true);
|
||||
sprite.LayerSetState(layer, state);
|
||||
_sprite.LayerSetVisible(sprite.AsNullable(), layer, true);
|
||||
_sprite.LayerSetAutoAnimated(sprite.AsNullable(), layer, true);
|
||||
_sprite.LayerSetRsiState(sprite.AsNullable(), layer, state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,12 +41,12 @@ public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
|
||||
&& sign.Current != null
|
||||
&& _prototypeManager.TryIndex(sign.Current, out var proto))
|
||||
{
|
||||
sprite.LayerSetSprite(0, proto.Icon);
|
||||
SpriteSystem.LayerSetSprite((id, sprite), 0, proto.Icon);
|
||||
sprite.LayerSetShader(0, "unshaded");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(0, "empty");
|
||||
SpriteSystem.LayerSetRsiState((id, sprite), 0, "empty");
|
||||
sprite.LayerSetShader(0, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace Content.Client.Beam;
|
||||
|
||||
public sealed class BeamSystem : SharedBeamSystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -21,11 +23,11 @@ public sealed class BeamSystem : SharedBeamSystem
|
||||
|
||||
if (TryComp<SpriteComponent>(beam, out var sprites))
|
||||
{
|
||||
sprites.Rotation = args.UserAngle;
|
||||
_sprite.SetRotation((beam, sprites), args.UserAngle);
|
||||
|
||||
if (args.BodyState != null)
|
||||
{
|
||||
sprites.LayerSetState(0, args.BodyState);
|
||||
_sprite.LayerSetRsiState((beam, sprites), 0, args.BodyState);
|
||||
sprites.LayerSetShader(0, args.Shader);
|
||||
}
|
||||
}
|
||||
|
||||
8
Content.Client/Bed/BedSystem.cs
Normal file
8
Content.Client/Bed/BedSystem.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Content.Shared.Bed;
|
||||
|
||||
namespace Content.Client.Bed;
|
||||
|
||||
public sealed class BedSystem : SharedBedSystem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -10,7 +10,7 @@ public sealed class StasisBedSystem : VisualizerSystem<StasisBedVisualsComponent
|
||||
if (args.Sprite != null
|
||||
&& AppearanceSystem.TryGetData<bool>(uid, StasisBedVisuals.IsOn, out var isOn, args.Component))
|
||||
{
|
||||
args.Sprite.LayerSetVisible(StasisBedVisualLayers.IsOn, isOn);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), StasisBedVisualLayers.IsOn, isOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Client.Botany.Components;
|
||||
using Content.Shared.Botany;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Botany;
|
||||
|
||||
@@ -17,8 +18,8 @@ public sealed class PlantHolderVisualizerSystem : VisualizerSystem<PlantHolderVi
|
||||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
sprite.LayerMapReserveBlank(PlantHolderLayers.Plant);
|
||||
sprite.LayerSetVisible(PlantHolderLayers.Plant, false);
|
||||
SpriteSystem.LayerMapReserve((uid, sprite), PlantHolderLayers.Plant);
|
||||
SpriteSystem.LayerSetVisible((uid, sprite), PlantHolderLayers.Plant, false);
|
||||
}
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, PlantHolderVisualsComponent component, ref AppearanceChangeEvent args)
|
||||
@@ -31,12 +32,12 @@ public sealed class PlantHolderVisualizerSystem : VisualizerSystem<PlantHolderVi
|
||||
{
|
||||
var valid = !string.IsNullOrWhiteSpace(state);
|
||||
|
||||
args.Sprite.LayerSetVisible(PlantHolderLayers.Plant, valid);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), PlantHolderLayers.Plant, valid);
|
||||
|
||||
if (valid)
|
||||
{
|
||||
args.Sprite.LayerSetRSI(PlantHolderLayers.Plant, rsi);
|
||||
args.Sprite.LayerSetState(PlantHolderLayers.Plant, state);
|
||||
SpriteSystem.LayerSetRsi((uid, args.Sprite), PlantHolderLayers.Plant, new ResPath(rsi));
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), PlantHolderLayers.Plant, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ public sealed class PotencyVisualsSystem : VisualizerSystem<PotencyVisualsCompon
|
||||
if (AppearanceSystem.TryGetData<float>(uid, ProduceVisuals.Potency, out var potency, args.Component))
|
||||
{
|
||||
var scale = MathHelper.Lerp(component.MinimumScale, component.MaximumScale, potency / 100);
|
||||
args.Sprite.Scale = new Vector2(scale, scale);
|
||||
SpriteSystem.SetScale((uid, args.Sprite), new Vector2(scale, scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ internal sealed class BuckleSystem : SharedBuckleSystem
|
||||
[Dependency] private readonly RotationVisualizerSystem _rotationVisualizerSystem = default!;
|
||||
[Dependency] private readonly IEyeManager _eye = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _xformSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -69,11 +70,11 @@ internal sealed class BuckleSystem : SharedBuckleSystem
|
||||
{
|
||||
// This will only assign if empty, it won't get overwritten by new depth on multiple calls, which do happen easily
|
||||
buckle.OriginalDrawDepth ??= buckledSprite.DrawDepth;
|
||||
buckledSprite.DrawDepth = strapSprite.DrawDepth - 1;
|
||||
_sprite.SetDrawDepth((buckledEntity, buckledSprite), strapSprite.DrawDepth - 1);
|
||||
}
|
||||
else if (buckle.OriginalDrawDepth.HasValue)
|
||||
{
|
||||
buckledSprite.DrawDepth = buckle.OriginalDrawDepth.Value;
|
||||
_sprite.SetDrawDepth((buckledEntity, buckledSprite), buckle.OriginalDrawDepth.Value);
|
||||
buckle.OriginalDrawDepth = null;
|
||||
}
|
||||
}
|
||||
@@ -97,7 +98,7 @@ internal sealed class BuckleSystem : SharedBuckleSystem
|
||||
return;
|
||||
|
||||
ent.Comp.OriginalDrawDepth ??= buckledSprite.DrawDepth;
|
||||
buckledSprite.DrawDepth = strapSprite.DrawDepth - 1;
|
||||
_sprite.SetDrawDepth((ent.Owner, buckledSprite), strapSprite.DrawDepth - 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -111,7 +112,7 @@ internal sealed class BuckleSystem : SharedBuckleSystem
|
||||
if (!ent.Comp.OriginalDrawDepth.HasValue)
|
||||
return;
|
||||
|
||||
buckledSprite.DrawDepth = ent.Comp.OriginalDrawDepth.Value;
|
||||
_sprite.SetDrawDepth((ent.Owner, buckledSprite), ent.Comp.OriginalDrawDepth.Value);
|
||||
ent.Comp.OriginalDrawDepth = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
|
||||
[Dependency] private readonly EntityLookupSystem _entityLookup = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private EntityQuery<BodyComponent> _bodyQuery;
|
||||
|
||||
@@ -74,7 +75,7 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
|
||||
if (!xformQuery.TryGetComponent(ent, out var entTransform) || !TryComp<SpriteComponent>(ent, out var sprite))
|
||||
continue;
|
||||
|
||||
sprite.Offset = new Vector2(0, 1);
|
||||
_sprite.SetOffset((ent, sprite), new Vector2(0, 1));
|
||||
_transform.SetParent(ent, entTransform, mob);
|
||||
}
|
||||
|
||||
|
||||
@@ -138,6 +138,11 @@ namespace Content.Client.Cargo.BUI
|
||||
|
||||
AccountName = cState.Name;
|
||||
|
||||
if (_menu == null)
|
||||
return;
|
||||
|
||||
_menu.ProductCatalogue = cState.Products;
|
||||
|
||||
_menu?.UpdateStation(station);
|
||||
Populate(cState.Orders);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Content.Client.Cargo.Systems;
|
||||
public sealed partial class CargoSystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private static readonly Animation CargoTelepadBeamAnimation = new()
|
||||
{
|
||||
@@ -80,12 +81,12 @@ public sealed partial class CargoSystem
|
||||
_player.Play((uid, player), CargoTelepadBeamAnimation, TelepadBeamKey);
|
||||
break;
|
||||
case CargoTelepadState.Unpowered:
|
||||
sprite.LayerSetVisible(CargoTelepadLayers.Beam, false);
|
||||
_sprite.LayerSetVisible((uid, sprite), CargoTelepadLayers.Beam, false);
|
||||
_player.Stop(uid, player, TelepadBeamKey);
|
||||
_player.Stop(uid, player, TelepadIdleKey);
|
||||
break;
|
||||
default:
|
||||
sprite.LayerSetVisible(CargoTelepadLayers.Beam, true);
|
||||
_sprite.LayerSetVisible((uid, sprite), CargoTelepadLayers.Beam, true);
|
||||
|
||||
if (_player.HasRunningAnimation(uid, player, TelepadIdleKey) ||
|
||||
_player.HasRunningAnimation(uid, player, TelepadBeamKey))
|
||||
|
||||
@@ -40,6 +40,8 @@ namespace Content.Client.Cargo.UI
|
||||
private readonly List<string> _categoryStrings = new();
|
||||
private string? _category;
|
||||
|
||||
public List<ProtoId<CargoProductPrototype>> ProductCatalogue = new();
|
||||
|
||||
public CargoConsoleMenu(EntityUid owner, IEntityManager entMan, IPrototypeManager protoManager, SpriteSystem spriteSystem)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
@@ -113,14 +115,16 @@ namespace Content.Client.Cargo.UI
|
||||
Categories.SelectId(id);
|
||||
}
|
||||
|
||||
public IEnumerable<CargoProductPrototype> ProductPrototypes
|
||||
private IEnumerable<CargoProductPrototype> ProductPrototypes
|
||||
{
|
||||
get
|
||||
{
|
||||
var allowedGroups = _entityManager.GetComponentOrNull<CargoOrderConsoleComponent>(_owner)?.AllowedGroups;
|
||||
|
||||
foreach (var cargoPrototype in _protoManager.EnumeratePrototypes<CargoProductPrototype>())
|
||||
foreach (var cargoPrototypeId in ProductCatalogue)
|
||||
{
|
||||
var cargoPrototype = _protoManager.Index(cargoPrototypeId);
|
||||
|
||||
if (!allowedGroups?.Contains(cargoPrototype.Group) ?? false)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Content.Client.Chasm;
|
||||
public sealed class ChasmFallingVisualsSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _anim = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private readonly string _chasmFallAnimationKey = "chasm_fall";
|
||||
|
||||
@@ -46,7 +47,7 @@ public sealed class ChasmFallingVisualsSystem : EntitySystem
|
||||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
sprite.Scale = component.OriginalScale;
|
||||
_sprite.SetScale((uid, sprite), component.OriginalScale);
|
||||
|
||||
if (!TryComp<AnimationPlayerComponent>(uid, out var player))
|
||||
return;
|
||||
|
||||
@@ -63,6 +63,9 @@ public sealed class TypingIndicatorSystem : SharedTypingIndicatorSystem
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
if (!_time.IsFirstTimePredicted)
|
||||
return;
|
||||
|
||||
// check if client didn't changed chat text box for a long time
|
||||
if (_isClientTyping)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Content.Shared.Chat.TypingIndicator;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared.Inventory;
|
||||
|
||||
@@ -11,7 +10,6 @@ public sealed class TypingIndicatorVisualizerSystem : VisualizerSystem<TypingInd
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, TypingIndicatorComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null)
|
||||
@@ -35,24 +33,24 @@ public sealed class TypingIndicatorVisualizerSystem : VisualizerSystem<TypingInd
|
||||
return;
|
||||
}
|
||||
|
||||
var layerExists = args.Sprite.LayerMapTryGet(TypingIndicatorLayers.Base, out var layer);
|
||||
var layerExists = SpriteSystem.LayerMapTryGet((uid, args.Sprite), TypingIndicatorLayers.Base, out var layer, false);
|
||||
if (!layerExists)
|
||||
layer = args.Sprite.LayerMapReserveBlank(TypingIndicatorLayers.Base);
|
||||
layer = SpriteSystem.LayerMapReserve((uid, args.Sprite), TypingIndicatorLayers.Base);
|
||||
|
||||
args.Sprite.LayerSetRSI(layer, proto.SpritePath);
|
||||
args.Sprite.LayerSetState(layer, proto.TypingState);
|
||||
SpriteSystem.LayerSetRsi((uid, args.Sprite), layer, proto.SpritePath);
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), layer, proto.TypingState);
|
||||
args.Sprite.LayerSetShader(layer, proto.Shader);
|
||||
args.Sprite.LayerSetOffset(layer, proto.Offset);
|
||||
SpriteSystem.LayerSetOffset((uid, args.Sprite), layer, proto.Offset);
|
||||
|
||||
AppearanceSystem.TryGetData<TypingIndicatorState>(uid, TypingIndicatorVisuals.State, out var state);
|
||||
args.Sprite.LayerSetVisible(layer, state != TypingIndicatorState.None);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), layer, state != TypingIndicatorState.None);
|
||||
switch (state)
|
||||
{
|
||||
case TypingIndicatorState.Idle:
|
||||
args.Sprite.LayerSetState(layer, proto.IdleState);
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), layer, proto.IdleState);
|
||||
break;
|
||||
case TypingIndicatorState.Typing:
|
||||
args.Sprite.LayerSetState(layer, proto.TypingState);
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), layer, proto.TypingState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace Content.Client.Chemistry.EntitySystems;
|
||||
|
||||
public sealed class PillSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -16,9 +18,9 @@ public sealed class PillSystem : EntitySystem
|
||||
if (!TryComp(uid, out SpriteComponent? sprite))
|
||||
return;
|
||||
|
||||
if (!sprite.TryGetLayer(0, out var layer))
|
||||
if (!_sprite.TryGetLayer((uid, sprite), 0, out var layer, false))
|
||||
return;
|
||||
|
||||
layer.SetState($"pill{component.PillType + 1}");
|
||||
_sprite.LayerSetRsiState(layer, $"pill{component.PillType + 1}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
@@ -9,15 +10,15 @@ namespace Content.Client.Chemistry.UI;
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class ReagentCardControl : Control
|
||||
{
|
||||
public string StorageSlotId { get; }
|
||||
public Action<string>? OnPressed;
|
||||
public Action<string>? OnEjectButtonPressed;
|
||||
public ItemStorageLocation StorageLocation { get; }
|
||||
public Action<ItemStorageLocation>? OnPressed;
|
||||
public Action<ItemStorageLocation>? OnEjectButtonPressed;
|
||||
|
||||
public ReagentCardControl(ReagentInventoryItem item)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
StorageSlotId = item.StorageSlotId;
|
||||
StorageLocation = item.StorageLocation;
|
||||
ColorPanel.PanelOverride = new StyleBoxFlat { BackgroundColor = item.ReagentColor };
|
||||
ReagentNameLabel.Text = item.ReagentLabel;
|
||||
FillLabel.Text = Loc.GetString("reagent-dispenser-window-quantity-label-text", ("quantity", item.Quantity));;
|
||||
@@ -26,7 +27,7 @@ public sealed partial class ReagentCardControl : Control
|
||||
if (item.Quantity == 0.0)
|
||||
MainButton.Disabled = true;
|
||||
|
||||
MainButton.OnPressed += args => OnPressed?.Invoke(StorageSlotId);
|
||||
EjectButton.OnPressed += args => OnEjectButtonPressed?.Invoke(StorageSlotId);
|
||||
MainButton.OnPressed += args => OnPressed?.Invoke(StorageLocation);
|
||||
EjectButton.OnPressed += args => OnEjectButtonPressed?.Invoke(StorageLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace Content.Client.Chemistry.UI
|
||||
|
||||
_window.AmountGrid.OnButtonPressed += s => SendMessage(new ReagentDispenserSetDispenseAmountMessage(s));
|
||||
|
||||
_window.OnDispenseReagentButtonPressed += (id) => SendMessage(new ReagentDispenserDispenseReagentMessage(id));
|
||||
_window.OnEjectJugButtonPressed += (id) => SendMessage(new ItemSlotButtonPressedEvent(id));
|
||||
_window.OnDispenseReagentButtonPressed += (location) => SendMessage(new ReagentDispenserDispenseReagentMessage(location));
|
||||
_window.OnEjectJugButtonPressed += (location) => SendMessage(new ReagentDispenserEjectContainerMessage(location));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Client.Stylesheets;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
@@ -18,8 +19,8 @@ namespace Content.Client.Chemistry.UI
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
public event Action<string>? OnDispenseReagentButtonPressed;
|
||||
public event Action<string>? OnEjectJugButtonPressed;
|
||||
public event Action<ItemStorageLocation>? OnDispenseReagentButtonPressed;
|
||||
public event Action<ItemStorageLocation>? OnEjectJugButtonPressed;
|
||||
|
||||
/// <summary>
|
||||
/// Create and initialize the dispenser UI client-side. Creates the basic layout,
|
||||
|
||||
@@ -71,7 +71,7 @@ public sealed class FoamVisualizerSystem : VisualizerSystem<FoamVisualsComponent
|
||||
return;
|
||||
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite))
|
||||
sprite.Visible = false;
|
||||
SpriteSystem.SetVisible((uid, sprite), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ public sealed class SmokeVisualizerSystem : VisualizerSystem<SmokeVisualsCompone
|
||||
{
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
if(!AppearanceSystem.TryGetData<Color>(uid, SmokeVisuals.Color, out var color))
|
||||
if (!AppearanceSystem.TryGetData<Color>(uid, SmokeVisuals.Color, out var color))
|
||||
return;
|
||||
args.Sprite.Color = color;
|
||||
SpriteSystem.SetColor((uid, args.Sprite), color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public sealed class SolutionContainerVisualsSystem : VisualizerSystem<SolutionCo
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
if (!args.Sprite.LayerMapTryGet(component.Layer, out var fillLayer))
|
||||
if (!SpriteSystem.LayerMapTryGet((uid, args.Sprite), component.Layer, out var fillLayer, false))
|
||||
return;
|
||||
|
||||
var maxFillLevels = component.MaxFillLevels;
|
||||
@@ -67,9 +67,9 @@ public sealed class SolutionContainerVisualsSystem : VisualizerSystem<SolutionCo
|
||||
}
|
||||
if (component.Metamorphic)
|
||||
{
|
||||
if (args.Sprite.LayerMapTryGet(component.BaseLayer, out var baseLayer))
|
||||
if (SpriteSystem.LayerMapTryGet((uid, args.Sprite), component.BaseLayer, out var baseLayer, false))
|
||||
{
|
||||
var hasOverlay = args.Sprite.LayerMapTryGet(component.OverlayLayer, out var overlayLayer);
|
||||
var hasOverlay = SpriteSystem.LayerMapTryGet((uid, args.Sprite), component.OverlayLayer, out var overlayLayer, false);
|
||||
|
||||
if (AppearanceSystem.TryGetData<string>(uid, SolutionContainerVisuals.BaseOverride,
|
||||
out var baseOverride,
|
||||
@@ -79,35 +79,35 @@ public sealed class SolutionContainerVisualsSystem : VisualizerSystem<SolutionCo
|
||||
|
||||
if (reagentProto?.MetamorphicSprite is { } sprite)
|
||||
{
|
||||
args.Sprite.LayerSetSprite(baseLayer, sprite);
|
||||
SpriteSystem.LayerSetSprite((uid, args.Sprite), baseLayer, sprite);
|
||||
if (reagentProto.MetamorphicMaxFillLevels > 0)
|
||||
{
|
||||
args.Sprite.LayerSetVisible(fillLayer, true);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), fillLayer, true);
|
||||
maxFillLevels = reagentProto.MetamorphicMaxFillLevels;
|
||||
fillBaseName = reagentProto.MetamorphicFillBaseName;
|
||||
changeColor = reagentProto.MetamorphicChangeColor;
|
||||
fillSprite = sprite;
|
||||
}
|
||||
else
|
||||
args.Sprite.LayerSetVisible(fillLayer, false);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), fillLayer, false);
|
||||
|
||||
if (hasOverlay)
|
||||
args.Sprite.LayerSetVisible(overlayLayer, false);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), overlayLayer, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Sprite.LayerSetVisible(fillLayer, true);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), fillLayer, true);
|
||||
if (hasOverlay)
|
||||
args.Sprite.LayerSetVisible(overlayLayer, true);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), overlayLayer, true);
|
||||
if (component.MetamorphicDefaultSprite != null)
|
||||
args.Sprite.LayerSetSprite(baseLayer, component.MetamorphicDefaultSprite);
|
||||
SpriteSystem.LayerSetSprite((uid, args.Sprite), baseLayer, component.MetamorphicDefaultSprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Sprite.LayerSetVisible(fillLayer, true);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), fillLayer, true);
|
||||
}
|
||||
|
||||
var closestFillSprite = ContentHelpers.RoundToLevels(fraction, 1, maxFillLevels + 1);
|
||||
@@ -119,25 +119,25 @@ public sealed class SolutionContainerVisualsSystem : VisualizerSystem<SolutionCo
|
||||
|
||||
var stateName = fillBaseName + closestFillSprite;
|
||||
if (fillSprite != null)
|
||||
args.Sprite.LayerSetSprite(fillLayer, fillSprite);
|
||||
args.Sprite.LayerSetState(fillLayer, stateName);
|
||||
SpriteSystem.LayerSetSprite((uid, args.Sprite), fillLayer, fillSprite);
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), fillLayer, stateName);
|
||||
|
||||
if (changeColor && AppearanceSystem.TryGetData<Color>(uid, SolutionContainerVisuals.Color, out var color, args.Component))
|
||||
args.Sprite.LayerSetColor(fillLayer, color);
|
||||
SpriteSystem.LayerSetColor((uid, args.Sprite), fillLayer, color);
|
||||
else
|
||||
args.Sprite.LayerSetColor(fillLayer, Color.White);
|
||||
SpriteSystem.LayerSetColor((uid, args.Sprite), fillLayer, Color.White);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (component.EmptySpriteName == null)
|
||||
args.Sprite.LayerSetVisible(fillLayer, false);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), fillLayer, false);
|
||||
else
|
||||
{
|
||||
args.Sprite.LayerSetState(fillLayer, component.EmptySpriteName);
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), fillLayer, component.EmptySpriteName);
|
||||
if (changeColor)
|
||||
args.Sprite.LayerSetColor(fillLayer, component.EmptySpriteColor);
|
||||
SpriteSystem.LayerSetColor((uid, args.Sprite), fillLayer, component.EmptySpriteColor);
|
||||
else
|
||||
args.Sprite.LayerSetColor(fillLayer, Color.White);
|
||||
SpriteSystem.LayerSetColor((uid, args.Sprite), fillLayer, Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public sealed class VaporVisualizerSystem : VisualizerSystem<VaporVisualsCompone
|
||||
{
|
||||
if (AppearanceSystem.TryGetData<Color>(uid, VaporVisuals.Color, out var color, args.Component) && args.Sprite != null)
|
||||
{
|
||||
args.Sprite.Color = color;
|
||||
SpriteSystem.SetColor((uid, args.Sprite), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,10 +77,10 @@ public sealed class ClickableSystem : EntitySystem
|
||||
drawDepth = sprite.DrawDepth;
|
||||
renderOrder = sprite.RenderOrder;
|
||||
var (spritePos, spriteRot) = _transforms.GetWorldPositionRotation(transform);
|
||||
var spriteBB = sprite.CalculateRotatedBoundingBox(spritePos, spriteRot, eye.Rotation);
|
||||
var spriteBB = _sprites.CalculateBounds((entity.Owner, sprite), spritePos, spriteRot, eye.Rotation);
|
||||
bottom = Matrix3Helpers.CreateRotation(eye.Rotation).TransformBox(spriteBB).Bottom;
|
||||
|
||||
Matrix3x2.Invert(sprite.GetLocalMatrix(), out var invSpriteMatrix);
|
||||
Matrix3x2.Invert(sprite.LocalMatrix, out var invSpriteMatrix);
|
||||
|
||||
// This should have been the rotation of the sprite relative to the screen, but this is not the case with no-rot or directional sprites.
|
||||
var relativeRotation = (spriteRot + eye.Rotation).Reduced().FlipPositive();
|
||||
@@ -107,7 +107,7 @@ public sealed class ClickableSystem : EntitySystem
|
||||
if (layer.Texture != null)
|
||||
{
|
||||
// Convert to image coordinates
|
||||
var imagePos = (Vector2i) (localPos * EyeManager.PixelsPerMeter * new Vector2(1, -1) + layer.Texture.Size / 2f);
|
||||
var imagePos = (Vector2i)(localPos * EyeManager.PixelsPerMeter * new Vector2(1, -1) + layer.Texture.Size / 2f);
|
||||
|
||||
if (_clickMapManager.IsOccluding(layer.Texture, imagePos))
|
||||
return true;
|
||||
@@ -125,7 +125,7 @@ public sealed class ClickableSystem : EntitySystem
|
||||
var layerLocal = Vector2.Transform(localPos, inverseMatrix);
|
||||
|
||||
// Convert to image coordinates
|
||||
var layerImagePos = (Vector2i) (layerLocal * EyeManager.PixelsPerMeter * new Vector2(1, -1) + rsiState.Size / 2f);
|
||||
var layerImagePos = (Vector2i)(layerLocal * EyeManager.PixelsPerMeter * new Vector2(1, -1) + rsiState.Size / 2f);
|
||||
|
||||
// Next, to get the right click map we need the "direction" of this layer that is actually being used to draw the sprite on the screen.
|
||||
// This **can** differ from the dir defined before, but can also just be the same.
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace Content.Client.Clock;
|
||||
|
||||
public sealed class ClockSystem : SharedClockSystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
@@ -12,15 +14,15 @@ public sealed class ClockSystem : SharedClockSystem
|
||||
var query = EntityQueryEnumerator<ClockComponent, SpriteComponent>();
|
||||
while (query.MoveNext(out var uid, out var comp, out var sprite))
|
||||
{
|
||||
if (!sprite.LayerMapTryGet(ClockVisualLayers.HourHand, out var hourLayer) ||
|
||||
!sprite.LayerMapTryGet(ClockVisualLayers.MinuteHand, out var minuteLayer))
|
||||
if (!_sprite.LayerMapTryGet((uid, sprite), ClockVisualLayers.HourHand, out var hourLayer, false) ||
|
||||
!_sprite.LayerMapTryGet((uid, sprite), ClockVisualLayers.MinuteHand, out var minuteLayer, false))
|
||||
continue;
|
||||
|
||||
var time = GetClockTime((uid, comp));
|
||||
var hourState = $"{comp.HoursBase}{time.Hours % 12}";
|
||||
var minuteState = $"{comp.MinutesBase}{time.Minutes / 5}";
|
||||
sprite.LayerSetState(hourLayer, hourState);
|
||||
sprite.LayerSetState(minuteLayer, minuteState);
|
||||
_sprite.LayerSetRsiState((uid, sprite), hourLayer, hourState);
|
||||
_sprite.LayerSetRsiState((uid, sprite), minuteLayer, minuteState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
[Dependency] private readonly IResourceCache _cache = default!;
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||
[Dependency] private readonly DisplacementMapSystem _displacement = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -74,10 +75,10 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
UpdateAllSlots(uid, component);
|
||||
|
||||
// No clothing equipped -> make sure the layer is hidden, though this should already be handled by on-unequip.
|
||||
if (args.Sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var layer))
|
||||
if (_sprite.LayerMapTryGet((uid, args.Sprite), HumanoidVisualLayers.StencilMask, out var layer, false))
|
||||
{
|
||||
DebugTools.Assert(!args.Sprite[layer].Visible);
|
||||
args.Sprite.LayerSetVisible(layer, false);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,9 +193,9 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
RenderEquipment(uid, item, clothing.InSlot, component, null, clothing);
|
||||
}
|
||||
|
||||
private void OnDidUnequip(EntityUid uid, SpriteComponent component, DidUnequipEvent args)
|
||||
private void OnDidUnequip(Entity<SpriteComponent> entity, ref DidUnequipEvent args)
|
||||
{
|
||||
if (!TryComp(uid, out InventorySlotsComponent? inventorySlots))
|
||||
if (!TryComp(entity, out InventorySlotsComponent? inventorySlots))
|
||||
return;
|
||||
|
||||
if (!inventorySlots.VisualLayerKeys.TryGetValue(args.Slot, out var revealedLayers))
|
||||
@@ -204,7 +205,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
// may eventually bloat the player with lots of invisible layers.
|
||||
foreach (var layer in revealedLayers)
|
||||
{
|
||||
component.RemoveLayer(layer);
|
||||
_sprite.RemoveLayer(entity.AsNullable(), layer);
|
||||
}
|
||||
revealedLayers.Clear();
|
||||
}
|
||||
@@ -247,7 +248,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
{
|
||||
foreach (var key in revealedLayers)
|
||||
{
|
||||
sprite.RemoveLayer(key);
|
||||
_sprite.RemoveLayer((equipee, sprite), key);
|
||||
}
|
||||
revealedLayers.Clear();
|
||||
}
|
||||
@@ -268,7 +269,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
|
||||
// temporary, until layer draw depths get added. Basically: a layer with the key "slot" is being used as a
|
||||
// bookmark to determine where in the list of layers we should insert the clothing layers.
|
||||
bool slotLayerExists = sprite.LayerMapTryGet(slot, out var index);
|
||||
var slotLayerExists = _sprite.LayerMapTryGet((equipee, sprite), slot, out var index, false);
|
||||
|
||||
// Select displacement maps
|
||||
var displacementData = inventory.Displacements.GetValueOrDefault(slot); //Default unsexed map
|
||||
@@ -302,16 +303,16 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
{
|
||||
index++;
|
||||
// note that every insertion requires reshuffling & remapping all the existing layers.
|
||||
sprite.AddBlankLayer(index);
|
||||
sprite.LayerMapSet(key, index);
|
||||
_sprite.AddBlankLayer((equipee, sprite), index);
|
||||
_sprite.LayerMapSet((equipee, sprite), key, index);
|
||||
|
||||
if (layerData.Color != null)
|
||||
sprite.LayerSetColor(key, layerData.Color.Value);
|
||||
_sprite.LayerSetColor((equipee, sprite), key, layerData.Color.Value);
|
||||
if (layerData.Scale != null)
|
||||
sprite.LayerSetScale(key, layerData.Scale.Value);
|
||||
_sprite.LayerSetScale((equipee, sprite), key, layerData.Scale.Value);
|
||||
}
|
||||
else
|
||||
index = sprite.LayerMapReserveBlank(key);
|
||||
index = _sprite.LayerMapReserve((equipee, sprite), key);
|
||||
|
||||
if (sprite[index] is not Layer layer)
|
||||
continue;
|
||||
@@ -322,11 +323,11 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
&& layer.RSI == null
|
||||
&& TryComp(equipment, out SpriteComponent? clothingSprite))
|
||||
{
|
||||
layer.SetRsi(clothingSprite.BaseRSI);
|
||||
_sprite.LayerSetRsi(layer, clothingSprite.BaseRSI);
|
||||
}
|
||||
|
||||
sprite.LayerSetData(index, layerData);
|
||||
layer.Offset += slotDef.Offset;
|
||||
_sprite.LayerSetData((equipee, sprite), index, layerData);
|
||||
_sprite.LayerSetOffset(layer, layer.Offset + slotDef.Offset);
|
||||
|
||||
if (displacementData is not null)
|
||||
{
|
||||
@@ -334,7 +335,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
if (layerData.State is not null && inventory.SpeciesId is not null && layerData.State.EndsWith(inventory.SpeciesId))
|
||||
continue;
|
||||
|
||||
if (_displacement.TryAddDisplacement(displacementData, sprite, index, key, out var displacementKey))
|
||||
if (_displacement.TryAddDisplacement(displacementData, (equipee, sprite), index, key, out var displacementKey))
|
||||
{
|
||||
revealedLayers.Add(displacementKey);
|
||||
index++;
|
||||
|
||||
@@ -32,7 +32,7 @@ public sealed class FlippableClothingVisualizerSystem : VisualizerSystem<Flippab
|
||||
|
||||
if (clothing.MappedLayer == null ||
|
||||
!AppearanceSystem.TryGetData<bool>(ent, FoldableSystem.FoldedVisuals.State, out var folding) ||
|
||||
!sprite.LayerMapTryGet(folding ? ent.Comp.FoldingLayer : ent.Comp.UnfoldingLayer, out var idx))
|
||||
!SpriteSystem.LayerMapTryGet((ent.Owner, sprite), folding ? ent.Comp.FoldingLayer : ent.Comp.UnfoldingLayer, out var idx, false))
|
||||
return;
|
||||
|
||||
// add each layer to the visuals
|
||||
|
||||
@@ -12,7 +12,6 @@ namespace Content.Client.Clothing.Systems;
|
||||
public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IComponentFactory _factory = default!;
|
||||
|
||||
private static readonly SlotFlags[] IgnoredSlots =
|
||||
{
|
||||
@@ -48,14 +47,14 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
|
||||
{
|
||||
base.UpdateSprite(uid, proto);
|
||||
if (TryComp(uid, out SpriteComponent? sprite)
|
||||
&& proto.TryGetComponent(out SpriteComponent? otherSprite, _factory))
|
||||
&& proto.TryGetComponent(out SpriteComponent? otherSprite, Factory))
|
||||
{
|
||||
sprite.CopyFrom(otherSprite);
|
||||
}
|
||||
|
||||
// Edgecase for PDAs to include visuals when UI is open
|
||||
if (TryComp(uid, out PdaBorderColorComponent? borderColor)
|
||||
&& proto.TryGetComponent(out PdaBorderColorComponent? otherBorderColor, _factory))
|
||||
&& proto.TryGetComponent(out PdaBorderColorComponent? otherBorderColor, Factory))
|
||||
{
|
||||
borderColor.BorderColor = otherBorderColor.BorderColor;
|
||||
borderColor.AccentHColor = otherBorderColor.AccentHColor;
|
||||
@@ -89,7 +88,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
|
||||
// check if this is valid clothing
|
||||
if (!IsValidTarget(proto))
|
||||
continue;
|
||||
if (!proto.TryGetComponent(out ClothingComponent? item, _factory))
|
||||
if (!proto.TryGetComponent(out ClothingComponent? item, Factory))
|
||||
continue;
|
||||
|
||||
// sort item by their slot flags
|
||||
|
||||
@@ -12,7 +12,6 @@ namespace Content.Client.Clothing.UI;
|
||||
[UsedImplicitly]
|
||||
public sealed class ChameleonBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IComponentFactory _factory = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
private readonly ChameleonClothingSystem _chameleon;
|
||||
private readonly TagSystem _tag;
|
||||
@@ -49,7 +48,7 @@ public sealed class ChameleonBoundUserInterface : BoundUserInterface
|
||||
if (string.IsNullOrEmpty(target) || !_proto.TryIndex(target, out EntityPrototype? proto))
|
||||
continue;
|
||||
|
||||
if (!proto.TryGetComponent(out TagComponent? tag, _factory) || !_tag.HasTag(tag, st.RequiredTag))
|
||||
if (!proto.TryGetComponent(out TagComponent? tag, EntMan.ComponentFactory) || !_tag.HasTag(tag, st.RequiredTag))
|
||||
continue;
|
||||
|
||||
newTargets.Add(target);
|
||||
|
||||
@@ -18,23 +18,19 @@ public sealed class HideMechanismsCommand : LocalizedCommands
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var containerSys = _entityManager.System<SharedContainerSystem>();
|
||||
var query = _entityManager.AllEntityQueryEnumerator<OrganComponent>();
|
||||
var spriteSys = _entityManager.System<SpriteSystem>();
|
||||
var query = _entityManager.AllEntityQueryEnumerator<OrganComponent, SpriteComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _))
|
||||
while (query.MoveNext(out var uid, out _, out var sprite))
|
||||
{
|
||||
if (!_entityManager.TryGetComponent(uid, out SpriteComponent? sprite))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sprite.ContainerOccluded = false;
|
||||
spriteSys.SetContainerOccluded((uid, sprite), false);
|
||||
|
||||
var tempParent = uid;
|
||||
while (containerSys.TryGetContainingContainer((tempParent, null, null), out var container))
|
||||
{
|
||||
if (!container.ShowContents)
|
||||
{
|
||||
sprite.ContainerOccluded = true;
|
||||
spriteSys.SetContainerOccluded((uid, sprite), true);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,12 @@ public sealed class ShowMechanismsCommand : LocalizedCommands
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var spriteSys = _entManager.System<SpriteSystem>();
|
||||
var query = _entManager.AllEntityQueryEnumerator<OrganComponent, SpriteComponent>();
|
||||
|
||||
while (query.MoveNext(out _, out var sprite))
|
||||
while (query.MoveNext(out var uid, out _, out var sprite))
|
||||
{
|
||||
sprite.ContainerOccluded = false;
|
||||
spriteSys.SetContainerOccluded((uid, sprite), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace Content.Client.Construction
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examineSystem = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
|
||||
private readonly Dictionary<int, EntityUid> _ghosts = new();
|
||||
@@ -293,14 +294,14 @@ namespace Content.Client.Construction
|
||||
_ghosts.Add(comp.GhostId, ghost.Value);
|
||||
|
||||
var sprite = EntityManager.GetComponent<SpriteComponent>(ghost.Value);
|
||||
sprite.Color = new Color(48, 255, 48, 128);
|
||||
_sprite.SetColor((ghost.Value, sprite), new Color(48, 255, 48, 128));
|
||||
|
||||
if (targetProto.TryGetComponent(out IconComponent? icon, EntityManager.ComponentFactory))
|
||||
{
|
||||
sprite.AddBlankLayer(0);
|
||||
sprite.LayerSetSprite(0, icon.Icon);
|
||||
_sprite.AddBlankLayer((ghost.Value, sprite), 0);
|
||||
_sprite.LayerSetSprite((ghost.Value, sprite), 0, icon.Icon);
|
||||
sprite.LayerSetShader(0, "unshaded");
|
||||
sprite.LayerSetVisible(0, true);
|
||||
_sprite.LayerSetVisible((ghost.Value, sprite), 0, true);
|
||||
}
|
||||
else if (targetProto.Components.TryGetValue("Sprite", out _))
|
||||
{
|
||||
@@ -318,10 +319,10 @@ namespace Content.Client.Construction
|
||||
state.StateId.Name is null)
|
||||
continue;
|
||||
|
||||
sprite.AddBlankLayer(i);
|
||||
sprite.LayerSetSprite(i, new SpriteSpecifier.Rsi(rsi.Path, state.StateId.Name));
|
||||
_sprite.AddBlankLayer((ghost.Value, sprite), i);
|
||||
_sprite.LayerSetSprite((ghost.Value, sprite), i, new SpriteSpecifier.Rsi(rsi.Path, state.StateId.Name));
|
||||
sprite.LayerSetShader(i, "unshaded");
|
||||
sprite.LayerSetVisible(i, true);
|
||||
_sprite.LayerSetVisible((ghost.Value, sprite), i, true);
|
||||
}
|
||||
|
||||
EntityManager.DeleteEntity(dummy);
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Content.Client.Construction;
|
||||
public sealed class FlatpackSystem : SharedFlatpackSystem
|
||||
{
|
||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
@@ -43,6 +44,6 @@ public sealed class FlatpackSystem : SharedFlatpackSystem
|
||||
}
|
||||
|
||||
if (color != null)
|
||||
args.Sprite.LayerSetColor(FlatpackVisualLayers.Overlay, color.Value);
|
||||
_sprite.LayerSetColor((ent.Owner, args.Sprite), FlatpackVisualLayers.Overlay, color.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Client.Lobby;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Client.UserInterface.Systems.MenuBar.Widgets;
|
||||
using Content.Shared.Construction.Prototypes;
|
||||
@@ -28,6 +29,7 @@ namespace Content.Client.Construction.UI
|
||||
[Dependency] private readonly IPlacementManager _placementManager = default!;
|
||||
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IClientPreferencesManager _preferencesManager = default!;
|
||||
private readonly SpriteSystem _spriteSystem;
|
||||
|
||||
private readonly IConstructionMenuView _constructionView;
|
||||
@@ -116,7 +118,7 @@ namespace Content.Client.Construction.UI
|
||||
|
||||
_constructionView.RecipeFavorited += (_, _) => OnViewFavoriteRecipe();
|
||||
|
||||
PopulateCategories();
|
||||
SetFavorites(_preferencesManager.Preferences?.ConstructionFavorites ?? []);
|
||||
OnViewPopulateRecipes(_constructionView, (string.Empty, string.Empty));
|
||||
}
|
||||
|
||||
@@ -493,10 +495,34 @@ namespace Content.Client.Construction.UI
|
||||
_favoritedRecipes.Count > 0 ? (string.Empty, FavoriteCatName) : (string.Empty, string.Empty));
|
||||
}
|
||||
|
||||
var newFavorites = new List<ProtoId<ConstructionPrototype>>(_favoritedRecipes.Count);
|
||||
foreach (var recipe in _favoritedRecipes)
|
||||
newFavorites.Add(recipe.ID);
|
||||
|
||||
_preferencesManager.UpdateConstructionFavorites(newFavorites);
|
||||
PopulateInfo(_selected);
|
||||
PopulateCategories(_selectedCategory);
|
||||
}
|
||||
|
||||
public void SetFavorites(IReadOnlyList<ProtoId<ConstructionPrototype>> favorites)
|
||||
{
|
||||
_favoritedRecipes.Clear();
|
||||
|
||||
foreach (var id in favorites)
|
||||
{
|
||||
if (_prototypeManager.TryIndex(id, out ConstructionPrototype? recipe, logError: false))
|
||||
_favoritedRecipes.Add(recipe);
|
||||
}
|
||||
|
||||
if (_selectedCategory == FavoriteCatName)
|
||||
{
|
||||
OnViewPopulateRecipes(_constructionView,
|
||||
_favoritedRecipes.Count > 0 ? (string.Empty, FavoriteCatName) : (string.Empty, string.Empty));
|
||||
}
|
||||
|
||||
PopulateCategories(_selectedCategory);
|
||||
}
|
||||
|
||||
private void SystemBindingChanged(ConstructionSystem? newSystem)
|
||||
{
|
||||
if (newSystem is null)
|
||||
|
||||
@@ -4,12 +4,14 @@ using Content.Shared.Cuffs.Components;
|
||||
using Content.Shared.Humanoid;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Cuffs;
|
||||
|
||||
public sealed class CuffableSystem : SharedCuffableSystem
|
||||
{
|
||||
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -22,7 +24,7 @@ public sealed class CuffableSystem : SharedCuffableSystem
|
||||
private void OnCuffableShutdown(EntityUid uid, CuffableComponent component, ComponentShutdown args)
|
||||
{
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite))
|
||||
sprite.LayerSetVisible(HumanoidVisualLayers.Handcuffs, false);
|
||||
_sprite.LayerSetVisible((uid, sprite), HumanoidVisualLayers.Handcuffs, false);
|
||||
}
|
||||
|
||||
private void OnCuffableHandleState(EntityUid uid, CuffableComponent component, ref ComponentHandleState args)
|
||||
@@ -39,22 +41,22 @@ public sealed class CuffableSystem : SharedCuffableSystem
|
||||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
var cuffed = cuffState.NumHandsCuffed > 0;
|
||||
sprite.LayerSetVisible(HumanoidVisualLayers.Handcuffs, cuffed);
|
||||
_sprite.LayerSetVisible((uid, sprite), HumanoidVisualLayers.Handcuffs, cuffed);
|
||||
|
||||
// if they are not cuffed, that means that we didn't get a valid color,
|
||||
// iconstate, or RSI. that also means we don't need to update the sprites.
|
||||
if (!cuffed)
|
||||
return;
|
||||
sprite.LayerSetColor(HumanoidVisualLayers.Handcuffs, cuffState.Color!.Value);
|
||||
_sprite.LayerSetColor((uid, sprite), HumanoidVisualLayers.Handcuffs, cuffState.Color!.Value);
|
||||
|
||||
if (!Equals(component.CurrentRSI, cuffState.RSI) && cuffState.RSI != null) // we don't want to keep loading the same RSI
|
||||
{
|
||||
component.CurrentRSI = cuffState.RSI;
|
||||
sprite.LayerSetState(HumanoidVisualLayers.Handcuffs, cuffState.IconState, component.CurrentRSI);
|
||||
_sprite.LayerSetRsi((uid, sprite), _sprite.LayerMapGet((uid, sprite), HumanoidVisualLayers.Handcuffs), new ResPath(component.CurrentRSI), cuffState.IconState);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(HumanoidVisualLayers.Handcuffs, cuffState.IconState);
|
||||
_sprite.LayerSetRsiState((uid, sprite), HumanoidVisualLayers.Handcuffs, cuffState.IconState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
// the layer key just doesn't exist, we skip it.
|
||||
foreach (var key in damageVisComp.TargetLayers)
|
||||
{
|
||||
if (!spriteComponent.LayerMapTryGet(key, out var index))
|
||||
if (!SpriteSystem.LayerMapTryGet((entity, spriteComponent), key, out var index, false))
|
||||
{
|
||||
Log.Warning($"Layer at key {key} was invalid for entity {entity}.");
|
||||
continue;
|
||||
@@ -253,7 +253,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
foreach (var layer in damageVisComp.TargetLayerMapKeys)
|
||||
{
|
||||
var layerCount = spriteComponent.AllLayers.Count();
|
||||
var index = spriteComponent.LayerMapGet(layer);
|
||||
var index = SpriteSystem.LayerMapGet((entity, spriteComponent), layer);
|
||||
// var layerState = spriteComponent.LayerGetState(index).ToString()!;
|
||||
|
||||
if (index + 1 != layerCount)
|
||||
@@ -269,7 +269,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
{
|
||||
foreach (var (group, sprite) in damageVisComp.DamageOverlayGroups)
|
||||
{
|
||||
AddDamageLayerToSprite(spriteComponent,
|
||||
AddDamageLayerToSprite((entity, spriteComponent),
|
||||
sprite,
|
||||
$"{layer}_{group}_{damageVisComp.Thresholds[1]}",
|
||||
$"{layer}{group}",
|
||||
@@ -283,7 +283,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
// was taken.
|
||||
else if (damageVisComp.DamageOverlay != null)
|
||||
{
|
||||
AddDamageLayerToSprite(spriteComponent,
|
||||
AddDamageLayerToSprite((entity, spriteComponent),
|
||||
damageVisComp.DamageOverlay,
|
||||
$"{layer}_{damageVisComp.Thresholds[1]}",
|
||||
$"{layer}trackDamage",
|
||||
@@ -301,7 +301,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
{
|
||||
foreach (var (group, sprite) in damageVisComp.DamageOverlayGroups)
|
||||
{
|
||||
AddDamageLayerToSprite(spriteComponent,
|
||||
AddDamageLayerToSprite((entity, spriteComponent),
|
||||
sprite,
|
||||
$"DamageOverlay_{group}_{damageVisComp.Thresholds[1]}",
|
||||
$"DamageOverlay{group}");
|
||||
@@ -310,7 +310,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
}
|
||||
else if (damageVisComp.DamageOverlay != null)
|
||||
{
|
||||
AddDamageLayerToSprite(spriteComponent,
|
||||
AddDamageLayerToSprite((entity, spriteComponent),
|
||||
damageVisComp.DamageOverlay,
|
||||
$"DamageOverlay_{damageVisComp.Thresholds[1]}",
|
||||
"DamageOverlay");
|
||||
@@ -322,16 +322,19 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
/// <summary>
|
||||
/// Adds a damage tracking layer to a given sprite component.
|
||||
/// </summary>
|
||||
private void AddDamageLayerToSprite(SpriteComponent spriteComponent, DamageVisualizerSprite sprite, string state, string mapKey, int? index = null)
|
||||
private void AddDamageLayerToSprite(Entity<SpriteComponent?> spriteEnt, DamageVisualizerSprite sprite, string state, string mapKey, int? index = null)
|
||||
{
|
||||
var newLayer = spriteComponent.AddLayer(
|
||||
var newLayer = SpriteSystem.AddLayer(
|
||||
spriteEnt,
|
||||
new SpriteSpecifier.Rsi(
|
||||
new (sprite.Sprite), state
|
||||
), index);
|
||||
spriteComponent.LayerMapSet(mapKey, newLayer);
|
||||
new(sprite.Sprite), state
|
||||
),
|
||||
index
|
||||
);
|
||||
SpriteSystem.LayerMapSet(spriteEnt, mapKey, newLayer);
|
||||
if (sprite.Color != null)
|
||||
spriteComponent.LayerSetColor(newLayer, Color.FromHex(sprite.Color));
|
||||
spriteComponent.LayerSetVisible(newLayer, false);
|
||||
SpriteSystem.LayerSetColor(spriteEnt, newLayer, Color.FromHex(sprite.Color));
|
||||
SpriteSystem.LayerSetVisible(spriteEnt, newLayer, false);
|
||||
}
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, DamageVisualsComponent damageVisComp, ref AppearanceChangeEvent args)
|
||||
@@ -362,18 +365,18 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
UpdateDisabledLayers(uid, spriteComponent, component, damageVisComp);
|
||||
|
||||
if (damageVisComp.Overlay && damageVisComp.DamageOverlayGroups != null && damageVisComp.TargetLayers == null)
|
||||
CheckOverlayOrdering(spriteComponent, damageVisComp);
|
||||
CheckOverlayOrdering((uid, spriteComponent), damageVisComp);
|
||||
|
||||
if (AppearanceSystem.TryGetData<bool>(uid, DamageVisualizerKeys.ForceUpdate, out var update, component)
|
||||
&& update)
|
||||
{
|
||||
ForceUpdateLayers(damageComponent, spriteComponent, damageVisComp);
|
||||
ForceUpdateLayers((uid, damageComponent, spriteComponent, damageVisComp));
|
||||
return;
|
||||
}
|
||||
|
||||
if (damageVisComp.TrackAllDamage)
|
||||
{
|
||||
UpdateDamageVisuals(damageComponent, spriteComponent, damageVisComp);
|
||||
UpdateDamageVisuals((uid, damageComponent, spriteComponent, damageVisComp));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -383,7 +386,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
data = new DamageVisualizerGroupData(Comp<DamageableComponent>(uid).DamagePerGroup.Keys.ToList());
|
||||
}
|
||||
|
||||
UpdateDamageVisuals(data.GroupList, damageComponent, spriteComponent, damageVisComp);
|
||||
UpdateDamageVisuals(data.GroupList, (uid, damageComponent, spriteComponent, damageVisComp));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -406,7 +409,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
damageVisComp.DisabledLayers[layer] = disabled;
|
||||
if (damageVisComp.TrackAllDamage)
|
||||
{
|
||||
spriteComponent.LayerSetVisible($"{layer}trackDamage", !disabled);
|
||||
SpriteSystem.LayerSetVisible((uid, spriteComponent), $"{layer}trackDamage", !disabled);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -415,7 +418,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
|
||||
foreach (var damageGroup in damageVisComp.DamageOverlayGroups.Keys)
|
||||
{
|
||||
spriteComponent.LayerSetVisible($"{layer}{damageGroup}", !disabled);
|
||||
SpriteSystem.LayerSetVisible((uid, spriteComponent), $"{layer}{damageGroup}", !disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,16 +430,16 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
/// most layer doesn't match, the sprite
|
||||
/// layers are recreated and placed on top.
|
||||
/// </summary>
|
||||
private void CheckOverlayOrdering(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
|
||||
private void CheckOverlayOrdering(Entity<SpriteComponent> spriteEnt, DamageVisualsComponent damageVisComp)
|
||||
{
|
||||
if (spriteComponent[damageVisComp.TopMostLayerKey] != spriteComponent[spriteComponent.AllLayers.Count() - 1])
|
||||
if (spriteEnt.Comp[damageVisComp.TopMostLayerKey] != spriteEnt.Comp[spriteEnt.Comp.AllLayers.Count() - 1])
|
||||
{
|
||||
if (!damageVisComp.TrackAllDamage && damageVisComp.DamageOverlayGroups != null)
|
||||
{
|
||||
foreach (var (damageGroup, sprite) in damageVisComp.DamageOverlayGroups)
|
||||
{
|
||||
var threshold = damageVisComp.LastThresholdPerGroup[damageGroup];
|
||||
ReorderOverlaySprite(spriteComponent,
|
||||
ReorderOverlaySprite(spriteEnt,
|
||||
damageVisComp,
|
||||
sprite,
|
||||
$"DamageOverlay{damageGroup}",
|
||||
@@ -446,7 +449,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
}
|
||||
else if (damageVisComp.TrackAllDamage && damageVisComp.DamageOverlay != null)
|
||||
{
|
||||
ReorderOverlaySprite(spriteComponent,
|
||||
ReorderOverlaySprite(spriteEnt,
|
||||
damageVisComp,
|
||||
damageVisComp.DamageOverlay,
|
||||
$"DamageOverlay",
|
||||
@@ -456,21 +459,22 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
}
|
||||
}
|
||||
|
||||
private void ReorderOverlaySprite(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, DamageVisualizerSprite sprite, string key, string statePrefix, FixedPoint2 threshold)
|
||||
private void ReorderOverlaySprite(Entity<SpriteComponent> spriteEnt, DamageVisualsComponent damageVisComp, DamageVisualizerSprite sprite, string key, string statePrefix, FixedPoint2 threshold)
|
||||
{
|
||||
spriteComponent.LayerMapTryGet(key, out var spriteLayer);
|
||||
var visibility = spriteComponent[spriteLayer].Visible;
|
||||
spriteComponent.RemoveLayer(spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet(spriteEnt.AsNullable(), key, out var spriteLayer, false);
|
||||
var visibility = spriteEnt.Comp[spriteLayer].Visible;
|
||||
SpriteSystem.RemoveLayer(spriteEnt.AsNullable(), spriteLayer);
|
||||
if (threshold == FixedPoint2.Zero) // these should automatically be invisible
|
||||
threshold = damageVisComp.Thresholds[1];
|
||||
spriteLayer = spriteComponent.AddLayer(
|
||||
spriteLayer = SpriteSystem.AddLayer(
|
||||
spriteEnt.AsNullable(),
|
||||
new SpriteSpecifier.Rsi(
|
||||
new (sprite.Sprite),
|
||||
new(sprite.Sprite),
|
||||
$"{statePrefix}_{threshold}"
|
||||
),
|
||||
spriteLayer);
|
||||
spriteComponent.LayerMapSet(key, spriteLayer);
|
||||
spriteComponent.LayerSetVisible(spriteLayer, visibility);
|
||||
SpriteSystem.LayerMapSet(spriteEnt.AsNullable(), key, spriteLayer);
|
||||
SpriteSystem.LayerSetVisible(spriteEnt.AsNullable(), spriteLayer, visibility);
|
||||
// this is somewhat iffy since it constantly reallocates
|
||||
damageVisComp.TopMostLayerKey = key;
|
||||
}
|
||||
@@ -479,8 +483,12 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
/// Updates damage visuals without tracking
|
||||
/// any damage groups.
|
||||
/// </summary>
|
||||
private void UpdateDamageVisuals(DamageableComponent damageComponent, SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
|
||||
private void UpdateDamageVisuals(Entity<DamageableComponent, SpriteComponent, DamageVisualsComponent> entity)
|
||||
{
|
||||
var damageComponent = entity.Comp1;
|
||||
var spriteComponent = entity.Comp2;
|
||||
var damageVisComp = entity.Comp3;
|
||||
|
||||
if (!CheckThresholdBoundary(damageComponent.TotalDamage, damageVisComp.LastDamageThreshold, damageVisComp, out var threshold))
|
||||
return;
|
||||
|
||||
@@ -490,12 +498,12 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
{
|
||||
foreach (var layerMapKey in damageVisComp.TargetLayerMapKeys)
|
||||
{
|
||||
UpdateTargetLayer(spriteComponent, damageVisComp, layerMapKey, threshold);
|
||||
UpdateTargetLayer((entity, spriteComponent), damageVisComp, layerMapKey, threshold);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateOverlay(spriteComponent, threshold);
|
||||
UpdateOverlay((entity, spriteComponent), threshold);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,8 +512,12 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
/// according to the list of damage groups
|
||||
/// passed into it.
|
||||
/// </summary>
|
||||
private void UpdateDamageVisuals(List<string> delta, DamageableComponent damageComponent, SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
|
||||
private void UpdateDamageVisuals(List<string> delta, Entity<DamageableComponent, SpriteComponent, DamageVisualsComponent> entity)
|
||||
{
|
||||
var damageComponent = entity.Comp1;
|
||||
var spriteComponent = entity.Comp2;
|
||||
var damageVisComp = entity.Comp3;
|
||||
|
||||
foreach (var damageGroup in delta)
|
||||
{
|
||||
if (!damageVisComp.Overlay && damageGroup != damageVisComp.DamageGroup)
|
||||
@@ -525,12 +537,12 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
{
|
||||
foreach (var layerMapKey in damageVisComp.TargetLayerMapKeys)
|
||||
{
|
||||
UpdateTargetLayer(spriteComponent, damageVisComp, layerMapKey, damageGroup, threshold);
|
||||
UpdateTargetLayer((entity, spriteComponent, damageVisComp), layerMapKey, damageGroup, threshold);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateOverlay(spriteComponent, damageVisComp, damageGroup, threshold);
|
||||
UpdateOverlay((entity, spriteComponent, damageVisComp), damageGroup, threshold);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,19 +579,21 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
/// Does different things depending on
|
||||
/// the configuration of the visualizer.
|
||||
/// </summary>
|
||||
private void ForceUpdateLayers(DamageableComponent damageComponent, SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
|
||||
private void ForceUpdateLayers(Entity<DamageableComponent, SpriteComponent, DamageVisualsComponent> entity)
|
||||
{
|
||||
var damageVisComp = entity.Comp3;
|
||||
|
||||
if (damageVisComp.DamageOverlayGroups != null)
|
||||
{
|
||||
UpdateDamageVisuals(damageVisComp.DamageOverlayGroups.Keys.ToList(), damageComponent, spriteComponent, damageVisComp);
|
||||
UpdateDamageVisuals(damageVisComp.DamageOverlayGroups.Keys.ToList(), entity);
|
||||
}
|
||||
else if (damageVisComp.DamageGroup != null)
|
||||
{
|
||||
UpdateDamageVisuals(new List<string>(){ damageVisComp.DamageGroup }, damageComponent, spriteComponent, damageVisComp);
|
||||
UpdateDamageVisuals(new List<string>() { damageVisComp.DamageGroup }, entity);
|
||||
}
|
||||
else if (damageVisComp.DamageOverlay != null)
|
||||
{
|
||||
UpdateDamageVisuals(damageComponent, spriteComponent, damageVisComp);
|
||||
UpdateDamageVisuals(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,16 +602,16 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
/// it assumes you're updating a layer that is tracking all
|
||||
/// damage.
|
||||
/// </summary>
|
||||
private void UpdateTargetLayer(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, object layerMapKey, FixedPoint2 threshold)
|
||||
private void UpdateTargetLayer(Entity<SpriteComponent> spriteEnt, DamageVisualsComponent damageVisComp, object layerMapKey, FixedPoint2 threshold)
|
||||
{
|
||||
if (damageVisComp.Overlay && damageVisComp.DamageOverlayGroups != null)
|
||||
{
|
||||
if (!damageVisComp.DisabledLayers[layerMapKey])
|
||||
{
|
||||
var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
|
||||
spriteComponent.LayerMapTryGet($"{layerMapKey}trackDamage", out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet(spriteEnt.AsNullable(), $"{layerMapKey}trackDamage", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(spriteEnt,
|
||||
spriteLayer,
|
||||
$"{layerState}",
|
||||
threshold);
|
||||
@@ -606,9 +620,9 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
else if (!damageVisComp.Overlay)
|
||||
{
|
||||
var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
|
||||
spriteComponent.LayerMapTryGet(layerMapKey, out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet(spriteEnt.AsNullable(), $"{layerMapKey}", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(spriteEnt,
|
||||
spriteLayer,
|
||||
$"{layerState}",
|
||||
threshold);
|
||||
@@ -618,16 +632,20 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
/// <summary>
|
||||
/// Updates a target layer by damage group.
|
||||
/// </summary>
|
||||
private void UpdateTargetLayer(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, object layerMapKey, string damageGroup, FixedPoint2 threshold)
|
||||
private void UpdateTargetLayer(Entity<SpriteComponent, DamageVisualsComponent> entity, object layerMapKey, string damageGroup, FixedPoint2 threshold)
|
||||
{
|
||||
var spriteComponent = entity.Comp1;
|
||||
var damageVisComp = entity.Comp2;
|
||||
|
||||
if (damageVisComp.Overlay && damageVisComp.DamageOverlayGroups != null)
|
||||
{
|
||||
if (damageVisComp.DamageOverlayGroups.ContainsKey(damageGroup) && !damageVisComp.DisabledLayers[layerMapKey])
|
||||
{
|
||||
var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
|
||||
spriteComponent.LayerMapTryGet($"{layerMapKey}{damageGroup}", out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet((entity, spriteComponent), $"{layerMapKey}{damageGroup}", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(
|
||||
(entity, spriteComponent),
|
||||
spriteLayer,
|
||||
$"{layerState}_{damageGroup}",
|
||||
threshold);
|
||||
@@ -636,9 +654,10 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
else if (!damageVisComp.Overlay)
|
||||
{
|
||||
var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
|
||||
spriteComponent.LayerMapTryGet(layerMapKey, out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet((entity, spriteComponent), $"{layerMapKey}", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(
|
||||
(entity, spriteComponent),
|
||||
spriteLayer,
|
||||
$"{layerState}_{damageGroup}",
|
||||
threshold);
|
||||
@@ -648,11 +667,11 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
/// <summary>
|
||||
/// Updates an overlay that is tracking all damage.
|
||||
/// </summary>
|
||||
private void UpdateOverlay(SpriteComponent spriteComponent, FixedPoint2 threshold)
|
||||
private void UpdateOverlay(Entity<SpriteComponent> spriteEnt, FixedPoint2 threshold)
|
||||
{
|
||||
spriteComponent.LayerMapTryGet($"DamageOverlay", out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet(spriteEnt.AsNullable(), $"DamageOverlay", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(spriteEnt,
|
||||
spriteLayer,
|
||||
$"DamageOverlay",
|
||||
threshold);
|
||||
@@ -661,15 +680,19 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
/// <summary>
|
||||
/// Updates an overlay based on damage group.
|
||||
/// </summary>
|
||||
private void UpdateOverlay(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, string damageGroup, FixedPoint2 threshold)
|
||||
private void UpdateOverlay(Entity<SpriteComponent, DamageVisualsComponent> entity, string damageGroup, FixedPoint2 threshold)
|
||||
{
|
||||
var spriteComponent = entity.Comp1;
|
||||
var damageVisComp = entity.Comp2;
|
||||
|
||||
if (damageVisComp.DamageOverlayGroups != null)
|
||||
{
|
||||
if (damageVisComp.DamageOverlayGroups.ContainsKey(damageGroup))
|
||||
{
|
||||
spriteComponent.LayerMapTryGet($"DamageOverlay{damageGroup}", out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet((entity, spriteComponent), $"DamageOverlay{damageGroup}", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(
|
||||
(entity, spriteComponent),
|
||||
spriteLayer,
|
||||
$"DamageOverlay_{damageGroup}",
|
||||
threshold);
|
||||
@@ -683,19 +706,19 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
||||
/// function calls it), and what threshold
|
||||
/// was passed into it.
|
||||
/// </summary>
|
||||
private void UpdateDamageLayerState(SpriteComponent spriteComponent, int spriteLayer, string statePrefix, FixedPoint2 threshold)
|
||||
private void UpdateDamageLayerState(Entity<SpriteComponent> spriteEnt, int spriteLayer, string statePrefix, FixedPoint2 threshold)
|
||||
{
|
||||
if (threshold == 0)
|
||||
{
|
||||
spriteComponent.LayerSetVisible(spriteLayer, false);
|
||||
SpriteSystem.LayerSetVisible(spriteEnt.AsNullable(), spriteLayer, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!spriteComponent[spriteLayer].Visible)
|
||||
if (!spriteEnt.Comp[spriteLayer].Visible)
|
||||
{
|
||||
spriteComponent.LayerSetVisible(spriteLayer, true);
|
||||
SpriteSystem.LayerSetVisible(spriteEnt.AsNullable(), spriteLayer, true);
|
||||
}
|
||||
spriteComponent.LayerSetState(spriteLayer, $"{statePrefix}_{threshold}");
|
||||
SpriteSystem.LayerSetRsiState(spriteEnt.AsNullable(), spriteLayer, $"{statePrefix}_{threshold}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,34 +21,34 @@ public sealed class DamageStateVisualizerSystem : VisualizerSystem<DamageStateVi
|
||||
}
|
||||
|
||||
// Brain no worky rn so this was just easier.
|
||||
foreach (var key in new []{ DamageStateVisualLayers.Base, DamageStateVisualLayers.BaseUnshaded })
|
||||
foreach (var key in new[] { DamageStateVisualLayers.Base, DamageStateVisualLayers.BaseUnshaded })
|
||||
{
|
||||
if (!sprite.LayerMapTryGet(key, out _)) continue;
|
||||
if (!SpriteSystem.LayerMapTryGet((uid, sprite), key, out _, false)) continue;
|
||||
|
||||
sprite.LayerSetVisible(key, false);
|
||||
SpriteSystem.LayerSetVisible((uid, sprite), key, false);
|
||||
}
|
||||
|
||||
foreach (var (key, state) in layers)
|
||||
{
|
||||
// Inheritance moment.
|
||||
if (!sprite.LayerMapTryGet(key, out _)) continue;
|
||||
if (!SpriteSystem.LayerMapTryGet((uid, sprite), key, out _, false)) continue;
|
||||
|
||||
sprite.LayerSetVisible(key, true);
|
||||
sprite.LayerSetState(key, state);
|
||||
SpriteSystem.LayerSetVisible((uid, sprite), key, true);
|
||||
SpriteSystem.LayerSetRsiState((uid, sprite), key, state);
|
||||
}
|
||||
|
||||
// So they don't draw over mobs anymore
|
||||
if (data == MobState.Dead)
|
||||
{
|
||||
if (sprite.DrawDepth > (int) DrawDepth.DeadMobs)
|
||||
if (sprite.DrawDepth > (int)DrawDepth.DeadMobs)
|
||||
{
|
||||
component.OriginalDrawDepth = sprite.DrawDepth;
|
||||
sprite.DrawDepth = (int) DrawDepth.DeadMobs;
|
||||
SpriteSystem.SetDrawDepth((uid, sprite), (int)DrawDepth.DeadMobs);
|
||||
}
|
||||
}
|
||||
else if (component.OriginalDrawDepth != null)
|
||||
{
|
||||
sprite.DrawDepth = component.OriginalDrawDepth.Value;
|
||||
SpriteSystem.SetDrawDepth((uid, sprite), component.OriginalDrawDepth.Value);
|
||||
component.OriginalDrawDepth = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ public sealed class DeliveryVisualizerSystem : VisualizerSystem<DeliveryComponen
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private static readonly ProtoId<JobIconPrototype> UnknownIcon = "JobIconUnknown";
|
||||
|
||||
@@ -25,11 +24,11 @@ public sealed class DeliveryVisualizerSystem : VisualizerSystem<DeliveryComponen
|
||||
|
||||
if (!_prototype.TryIndex<JobIconPrototype>(job, out var icon))
|
||||
{
|
||||
args.Sprite.LayerSetTexture(DeliveryVisualLayers.JobStamp, _sprite.Frame0(_prototype.Index("JobIconUnknown")));
|
||||
SpriteSystem.LayerSetTexture((uid, args.Sprite), DeliveryVisualLayers.JobStamp, SpriteSystem.Frame0(_prototype.Index("JobIconUnknown")));
|
||||
return;
|
||||
}
|
||||
|
||||
args.Sprite.LayerSetTexture(DeliveryVisualLayers.JobStamp, _sprite.Frame0(icon.Icon));
|
||||
SpriteSystem.LayerSetTexture((uid, args.Sprite), DeliveryVisualLayers.JobStamp, SpriteSystem.Frame0(icon.Icon));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +41,8 @@ public enum DeliveryVisualLayers : byte
|
||||
PriorityTape,
|
||||
Breakage,
|
||||
Trash,
|
||||
Bomb,
|
||||
BombPrimed,
|
||||
}
|
||||
|
||||
public enum DeliverySpawnerVisualLayers : byte
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace Content.Client.Dice;
|
||||
|
||||
public sealed class DiceSystem : SharedDiceSystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -18,11 +20,11 @@ public sealed class DiceSystem : SharedDiceSystem
|
||||
return;
|
||||
|
||||
// TODO maybe just move each die to its own RSI?
|
||||
var state = sprite.LayerGetState(0).Name;
|
||||
var state = _sprite.LayerGetRsiState((entity.Owner, sprite), 0).Name;
|
||||
if (state == null)
|
||||
return;
|
||||
|
||||
var prefix = state.Substring(0, state.IndexOf('_'));
|
||||
sprite.LayerSetState(0, $"{prefix}_{entity.Comp.CurrentValue}");
|
||||
_sprite.LayerSetRsiState((entity.Owner, sprite), 0, $"{prefix}_{entity.Comp.CurrentValue}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,18 +8,19 @@ namespace Content.Client.DisplacementMap;
|
||||
public sealed class DisplacementMapSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ISerializationManager _serialization = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Attempting to apply a displacement map to a specific layer of SpriteComponent
|
||||
/// </summary>
|
||||
/// <param name="data">Information package for applying the displacement map</param>
|
||||
/// <param name="sprite">SpriteComponent</param>
|
||||
/// <param name="sprite">Entity with SpriteComponent</param>
|
||||
/// <param name="index">Index of the layer where the new map layer will be added</param>
|
||||
/// <param name="key">Unique layer key, which will determine which layer to apply displacement map to</param>
|
||||
/// <param name="displacementKey">The key of the new displacement map layer added by this function.</param>
|
||||
/// <returns></returns>
|
||||
public bool TryAddDisplacement(DisplacementData data,
|
||||
SpriteComponent sprite,
|
||||
Entity<SpriteComponent> sprite,
|
||||
int index,
|
||||
object key,
|
||||
out string displacementKey)
|
||||
@@ -30,10 +31,9 @@ public sealed class DisplacementMapSystem : EntitySystem
|
||||
return false;
|
||||
|
||||
if (data.ShaderOverride != null)
|
||||
sprite.LayerSetShader(index, data.ShaderOverride);
|
||||
sprite.Comp.LayerSetShader(index, data.ShaderOverride);
|
||||
|
||||
if (sprite.LayerMapTryGet(displacementKey, out var oldIndex))
|
||||
sprite.RemoveLayer(oldIndex);
|
||||
_sprite.RemoveLayer(sprite.AsNullable(), displacementKey, false);
|
||||
|
||||
//allows you not to write it every time in the YML
|
||||
foreach (var pair in data.SizeMaps)
|
||||
@@ -55,7 +55,7 @@ public sealed class DisplacementMapSystem : EntitySystem
|
||||
// We choose a displacement map from the possible ones, matching the size with the original layer size.
|
||||
// If there is no such a map, we use a standard 32 by 32 one
|
||||
var displacementDataLayer = data.SizeMaps[EyeManager.PixelsPerMeter];
|
||||
var actualRSI = sprite.LayerGetActualRSI(index);
|
||||
var actualRSI = _sprite.LayerGetEffectiveRsi(sprite.AsNullable(), index);
|
||||
if (actualRSI is not null)
|
||||
{
|
||||
if (actualRSI.Size.X != actualRSI.Size.Y)
|
||||
@@ -72,9 +72,20 @@ public sealed class DisplacementMapSystem : EntitySystem
|
||||
var displacementLayer = _serialization.CreateCopy(displacementDataLayer, notNullableOverride: true);
|
||||
displacementLayer.CopyToShaderParameters!.LayerKey = key.ToString() ?? "this is impossible";
|
||||
|
||||
sprite.AddLayer(displacementLayer, index);
|
||||
sprite.LayerMapSet(displacementKey, index);
|
||||
_sprite.AddLayer(sprite.AsNullable(), displacementLayer, index);
|
||||
_sprite.LayerMapSet(sprite.AsNullable(), displacementKey, index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="TryAddDisplacement"/>
|
||||
[Obsolete("Use the Entity<SpriteComponent> overload")]
|
||||
public bool TryAddDisplacement(DisplacementData data,
|
||||
SpriteComponent sprite,
|
||||
int index,
|
||||
object key,
|
||||
out string displacementKey)
|
||||
{
|
||||
return TryAddDisplacement(data, (sprite.Owner, sprite), index, key, out displacementKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private const string AnimationKey = "disposal_unit_animation";
|
||||
|
||||
@@ -67,13 +68,13 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
||||
if (!_appearanceSystem.TryGetData<DisposalUnitComponent.VisualState>(ent, DisposalUnitComponent.Visuals.VisualState, out var state, appearance))
|
||||
return;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.Unanchored, state == DisposalUnitComponent.VisualState.UnAnchored);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.Base, state == DisposalUnitComponent.VisualState.Anchored);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayFlush, state == DisposalUnitComponent.VisualState.OverlayFlushing);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.BaseCharging, state == DisposalUnitComponent.VisualState.OverlayCharging);
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.Unanchored, state == DisposalUnitComponent.VisualState.UnAnchored);
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.Base, state == DisposalUnitComponent.VisualState.Anchored);
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.OverlayFlush, state == DisposalUnitComponent.VisualState.OverlayFlushing);
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.BaseCharging, state == DisposalUnitComponent.VisualState.OverlayCharging);
|
||||
|
||||
var chargingState = sprite.LayerMapTryGet(DisposalUnitVisualLayers.BaseCharging, out var chargingLayer)
|
||||
? sprite.LayerGetState(chargingLayer)
|
||||
var chargingState = _sprite.LayerMapTryGet((ent, sprite), DisposalUnitVisualLayers.BaseCharging, out var chargingLayer, false)
|
||||
? _sprite.LayerGetRsiState((ent, sprite), chargingLayer)
|
||||
: new RSI.StateId(DefaultChargeState);
|
||||
|
||||
// This is a transient state so not too worried about replaying in range.
|
||||
@@ -81,8 +82,8 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
||||
{
|
||||
if (!_animationSystem.HasRunningAnimation(ent, AnimationKey))
|
||||
{
|
||||
var flushState = sprite.LayerMapTryGet(DisposalUnitVisualLayers.OverlayFlush, out var flushLayer)
|
||||
? sprite.LayerGetState(flushLayer)
|
||||
var flushState = _sprite.LayerMapTryGet((ent, sprite), DisposalUnitVisualLayers.OverlayFlush, out var flushLayer, false)
|
||||
? _sprite.LayerGetRsiState((ent, sprite), flushLayer)
|
||||
: new RSI.StateId(DefaultFlushState);
|
||||
|
||||
// Setup the flush animation to play
|
||||
@@ -124,16 +125,16 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
||||
if (!_appearanceSystem.TryGetData<DisposalUnitComponent.HandleState>(ent, DisposalUnitComponent.Visuals.Handle, out var handleState, appearance))
|
||||
handleState = DisposalUnitComponent.HandleState.Normal;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayEngaged, handleState != DisposalUnitComponent.HandleState.Normal);
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.OverlayEngaged, handleState != DisposalUnitComponent.HandleState.Normal);
|
||||
|
||||
if (!_appearanceSystem.TryGetData<DisposalUnitComponent.LightStates>(ent, DisposalUnitComponent.Visuals.Light, out var lightState, appearance))
|
||||
lightState = DisposalUnitComponent.LightStates.Off;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayCharging,
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.OverlayCharging,
|
||||
(lightState & DisposalUnitComponent.LightStates.Charging) != 0);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayReady,
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.OverlayReady,
|
||||
(lightState & DisposalUnitComponent.LightStates.Ready) != 0);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayFull,
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.OverlayFull,
|
||||
(lightState & DisposalUnitComponent.LightStates.Full) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ public sealed class DoAfterOverlay : Overlay
|
||||
private readonly MetaDataSystem _meta;
|
||||
private readonly ProgressColorSystem _progressColor;
|
||||
private readonly SharedContainerSystem _container;
|
||||
private readonly SpriteSystem _sprite;
|
||||
|
||||
private readonly Texture _barTexture;
|
||||
private readonly ShaderInstance _unshadedShader;
|
||||
@@ -45,6 +46,7 @@ public sealed class DoAfterOverlay : Overlay
|
||||
_meta = _entManager.EntitySysManager.GetEntitySystem<MetaDataSystem>();
|
||||
_container = _entManager.EntitySysManager.GetEntitySystem<SharedContainerSystem>();
|
||||
_progressColor = _entManager.System<ProgressColorSystem>();
|
||||
_sprite = _entManager.System<SpriteSystem>();
|
||||
var sprite = new SpriteSpecifier.Rsi(new("/Textures/Interface/Misc/progress_bar.rsi"), "icon");
|
||||
_barTexture = _entManager.EntitySysManager.GetEntitySystem<SpriteSystem>().Frame0(sprite);
|
||||
|
||||
@@ -118,7 +120,7 @@ public sealed class DoAfterOverlay : Overlay
|
||||
|
||||
// Use the sprite itself if we know its bounds. This means short or tall sprites don't get overlapped
|
||||
// by the bar.
|
||||
float yOffset = sprite.Bounds.Height / 2f + 0.05f;
|
||||
var yOffset = _sprite.GetLocalBounds((uid, sprite)).Height / 2f + 0.05f;
|
||||
|
||||
// Position above the entity (we've already applied the matrix transform to the entity itself)
|
||||
// Offset by the texture size for every do_after we have.
|
||||
@@ -135,7 +137,7 @@ public sealed class DoAfterOverlay : Overlay
|
||||
if (doAfter.CancelledTime != null)
|
||||
{
|
||||
var elapsed = doAfter.CancelledTime.Value - doAfter.StartTime;
|
||||
elapsedRatio = (float) Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
||||
elapsedRatio = (float)Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
||||
var cancelElapsed = (time - doAfter.CancelledTime.Value).TotalSeconds;
|
||||
var flash = Math.Floor(cancelElapsed / FlashTime) % 2 == 0;
|
||||
color = GetProgressColor(0, flash ? alpha : 0);
|
||||
@@ -143,7 +145,7 @@ public sealed class DoAfterOverlay : Overlay
|
||||
else
|
||||
{
|
||||
var elapsed = time - doAfter.StartTime;
|
||||
elapsedRatio = (float) Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
||||
elapsedRatio = (float)Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
||||
color = GetProgressColor(elapsedRatio, alpha);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Content.Client.Doors;
|
||||
public sealed class AirlockSystem : SharedAirlockSystem
|
||||
{
|
||||
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -21,7 +22,7 @@ public sealed class AirlockSystem : SharedAirlockSystem
|
||||
private void OnComponentStartup(EntityUid uid, AirlockComponent comp, ComponentStartup args)
|
||||
{
|
||||
// Has to be on component startup because we don't know what order components initialize in and running this before DoorComponent inits _will_ crash.
|
||||
if(!TryComp<DoorComponent>(uid, out var door))
|
||||
if (!TryComp<DoorComponent>(uid, out var door))
|
||||
return;
|
||||
|
||||
if (comp.OpenUnlitVisible) // Otherwise there are flashes of the fallback sprite between clicking on the door and the door closing animation starting.
|
||||
@@ -31,17 +32,17 @@ public sealed class AirlockSystem : SharedAirlockSystem
|
||||
}
|
||||
|
||||
((Animation)door.OpeningAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick()
|
||||
{
|
||||
LayerKey = DoorVisualLayers.BaseUnlit,
|
||||
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningSpriteState, 0f) },
|
||||
}
|
||||
{
|
||||
LayerKey = DoorVisualLayers.BaseUnlit,
|
||||
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningSpriteState, 0f) },
|
||||
}
|
||||
);
|
||||
|
||||
((Animation)door.ClosingAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick()
|
||||
{
|
||||
LayerKey = DoorVisualLayers.BaseUnlit,
|
||||
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingSpriteState, 0f) },
|
||||
}
|
||||
{
|
||||
LayerKey = DoorVisualLayers.BaseUnlit,
|
||||
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingSpriteState, 0f) },
|
||||
}
|
||||
);
|
||||
|
||||
door.DenyingAnimation = new Animation()
|
||||
@@ -57,19 +58,19 @@ public sealed class AirlockSystem : SharedAirlockSystem
|
||||
}
|
||||
};
|
||||
|
||||
if(!comp.AnimatePanel)
|
||||
if (!comp.AnimatePanel)
|
||||
return;
|
||||
|
||||
((Animation)door.OpeningAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick()
|
||||
{
|
||||
LayerKey = WiresVisualLayers.MaintenancePanel,
|
||||
KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningPanelSpriteState, 0f)},
|
||||
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningPanelSpriteState, 0f) },
|
||||
});
|
||||
|
||||
((Animation)door.ClosingAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick
|
||||
{
|
||||
LayerKey = WiresVisualLayers.MaintenancePanel,
|
||||
KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingPanelSpriteState, 0f)},
|
||||
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingPanelSpriteState, 0f) },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,11 +102,12 @@ public sealed class AirlockSystem : SharedAirlockSystem
|
||||
&& !boltedVisible && !emergencyLightsVisible;
|
||||
}
|
||||
|
||||
args.Sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, unlitVisible);
|
||||
args.Sprite.LayerSetVisible(DoorVisualLayers.BaseBolted, boltedVisible);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), DoorVisualLayers.BaseUnlit, unlitVisible);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), DoorVisualLayers.BaseBolted, boltedVisible);
|
||||
if (comp.EmergencyAccessLayer)
|
||||
{
|
||||
args.Sprite.LayerSetVisible(
|
||||
_sprite.LayerSetVisible(
|
||||
(uid, args.Sprite),
|
||||
DoorVisualLayers.BaseEmergencyAccess,
|
||||
emergencyLightsVisible
|
||||
&& state != DoorState.Open
|
||||
@@ -118,12 +120,12 @@ public sealed class AirlockSystem : SharedAirlockSystem
|
||||
switch (state)
|
||||
{
|
||||
case DoorState.Open:
|
||||
args.Sprite.LayerSetState(DoorVisualLayers.BaseUnlit, comp.ClosingSpriteState);
|
||||
args.Sprite.LayerSetAnimationTime(DoorVisualLayers.BaseUnlit, 0);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), DoorVisualLayers.BaseUnlit, comp.ClosingSpriteState);
|
||||
_sprite.LayerSetAnimationTime((uid, args.Sprite), DoorVisualLayers.BaseUnlit, 0);
|
||||
break;
|
||||
case DoorState.Closed:
|
||||
args.Sprite.LayerSetState(DoorVisualLayers.BaseUnlit, comp.OpeningSpriteState);
|
||||
args.Sprite.LayerSetAnimationTime(DoorVisualLayers.BaseUnlit, 0);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), DoorVisualLayers.BaseUnlit, comp.OpeningSpriteState);
|
||||
_sprite.LayerSetAnimationTime((uid, args.Sprite), DoorVisualLayers.BaseUnlit, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ public sealed class DoorSystem : SharedDoorSystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationSystem = default!;
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -85,7 +86,7 @@ public sealed class DoorSystem : SharedDoorSystem
|
||||
state = DoorState.Closed;
|
||||
|
||||
if (AppearanceSystem.TryGetData<string>(entity, DoorVisuals.BaseRSI, out var baseRsi, args.Component))
|
||||
UpdateSpriteLayers(args.Sprite, baseRsi);
|
||||
UpdateSpriteLayers((entity.Owner, args.Sprite), baseRsi);
|
||||
|
||||
if (_animationSystem.HasRunningAnimation(entity, DoorComponent.AnimationKey))
|
||||
_animationSystem.Stop(entity.Owner, DoorComponent.AnimationKey);
|
||||
@@ -95,21 +96,21 @@ public sealed class DoorSystem : SharedDoorSystem
|
||||
|
||||
private void UpdateAppearanceForDoorState(Entity<DoorComponent> entity, SpriteComponent sprite, DoorState state)
|
||||
{
|
||||
sprite.DrawDepth = state is DoorState.Open ? entity.Comp.OpenDrawDepth : entity.Comp.ClosedDrawDepth;
|
||||
_sprite.SetDrawDepth((entity.Owner, sprite), state is DoorState.Open ? entity.Comp.OpenDrawDepth : entity.Comp.ClosedDrawDepth);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case DoorState.Open:
|
||||
foreach (var (layer, layerState) in entity.Comp.OpenSpriteStates)
|
||||
{
|
||||
sprite.LayerSetState(layer, layerState);
|
||||
_sprite.LayerSetRsiState((entity.Owner, sprite), layer, layerState);
|
||||
}
|
||||
|
||||
return;
|
||||
case DoorState.Closed:
|
||||
foreach (var (layer, layerState) in entity.Comp.ClosedSpriteStates)
|
||||
{
|
||||
sprite.LayerSetState(layer, layerState);
|
||||
_sprite.LayerSetRsiState((entity.Owner, sprite), layer, layerState);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -138,7 +139,7 @@ public sealed class DoorSystem : SharedDoorSystem
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSpriteLayers(SpriteComponent sprite, string baseRsi)
|
||||
private void UpdateSpriteLayers(Entity<SpriteComponent> sprite, string baseRsi)
|
||||
{
|
||||
if (!_resourceCache.TryGetResource<RSIResource>(SpriteSpecifierSerializer.TextureRoot / baseRsi, out var res))
|
||||
{
|
||||
@@ -146,6 +147,6 @@ public sealed class DoorSystem : SharedDoorSystem
|
||||
return;
|
||||
}
|
||||
|
||||
sprite.BaseRSI = res.RSI;
|
||||
_sprite.SetBaseRsi(sprite.AsNullable(), res.RSI);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Content.Client.Doors;
|
||||
public sealed class FirelockSystem : SharedFirelockSystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -18,7 +19,7 @@ public sealed class FirelockSystem : SharedFirelockSystem
|
||||
protected override void OnComponentStartup(Entity<FirelockComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
base.OnComponentStartup(ent, ref args);
|
||||
if(!TryComp<DoorComponent>(ent.Owner, out var door))
|
||||
if (!TryComp<DoorComponent>(ent.Owner, out var door))
|
||||
return;
|
||||
|
||||
door.ClosedSpriteStates.Add((DoorVisualLayers.BaseUnlit, ent.Comp.WarningLightSpriteState));
|
||||
@@ -57,7 +58,7 @@ public sealed class FirelockSystem : SharedFirelockSystem
|
||||
|| state == DoorState.Denying
|
||||
|| (_appearanceSystem.TryGetData<bool>(uid, DoorVisuals.ClosedLights, out var closedLights, args.Component) && closedLights);
|
||||
|
||||
args.Sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, unlitVisible && !boltedVisible);
|
||||
args.Sprite.LayerSetVisible(DoorVisualLayers.BaseBolted, boltedVisible);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), DoorVisualLayers.BaseUnlit, unlitVisible && !boltedVisible);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), DoorVisualLayers.BaseBolted, boltedVisible);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,9 @@ namespace Content.Client.Doors;
|
||||
public sealed class TurnstileSystem : SharedTurnstileSystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private static EntProtoId _examineArrow = "TurnstileArrow";
|
||||
private static readonly EntProtoId ExamineArrow = "TurnstileArrow";
|
||||
|
||||
private const string AnimationKey = "Turnstile";
|
||||
|
||||
@@ -33,12 +34,12 @@ public sealed class TurnstileSystem : SharedTurnstileSystem
|
||||
|
||||
if (!TryComp<SpriteComponent>(ent, out var sprite))
|
||||
return;
|
||||
sprite.LayerSetState(TurnstileVisualLayers.Base, new RSI.StateId(ent.Comp.DefaultState));
|
||||
_sprite.LayerSetRsiState((ent.Owner, sprite), TurnstileVisualLayers.Base, new RSI.StateId(ent.Comp.DefaultState));
|
||||
}
|
||||
|
||||
private void OnExamined(Entity<TurnstileComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
Spawn(_examineArrow, new EntityCoordinates(ent, 0, 0));
|
||||
Spawn(ExamineArrow, new EntityCoordinates(ent, 0, 0));
|
||||
}
|
||||
|
||||
protected override void PlayAnimation(EntityUid uid, string stateId)
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Content.Client.Dragon;
|
||||
public sealed class DragonSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedPointLightSystem _lights = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -31,7 +32,7 @@ public sealed class DragonSystem : EntitySystem
|
||||
switch (state.State)
|
||||
{
|
||||
case DragonRiftState.Charging:
|
||||
sprite?.LayerSetColor(0, Color.FromHex("#569fff"));
|
||||
_sprite.LayerSetColor((uid, sprite), 0, Color.FromHex("#569fff"));
|
||||
|
||||
if (light != null)
|
||||
{
|
||||
@@ -39,7 +40,7 @@ public sealed class DragonSystem : EntitySystem
|
||||
}
|
||||
break;
|
||||
case DragonRiftState.AlmostFinished:
|
||||
sprite?.LayerSetColor(0, Color.FromHex("#cf4cff"));
|
||||
_sprite.LayerSetColor((uid, sprite), 0, Color.FromHex("#cf4cff"));
|
||||
|
||||
if (light != null)
|
||||
{
|
||||
@@ -47,7 +48,7 @@ public sealed class DragonSystem : EntitySystem
|
||||
}
|
||||
break;
|
||||
case DragonRiftState.Finished:
|
||||
sprite?.LayerSetColor(0, Color.FromHex("#edbc36"));
|
||||
_sprite.LayerSetColor((uid, sprite), 0, Color.FromHex("#edbc36"));
|
||||
|
||||
if (light != null)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Shared.Drugs;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Client.Drugs;
|
||||
|
||||
@@ -12,6 +13,7 @@ public sealed class DrugOverlaySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlayMan = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
private RainbowOverlay _overlay = default!;
|
||||
|
||||
@@ -45,7 +47,10 @@ public sealed class DrugOverlaySystem : EntitySystem
|
||||
private void OnInit(EntityUid uid, SeeingRainbowsComponent component, ComponentInit args)
|
||||
{
|
||||
if (_player.LocalEntity == uid)
|
||||
{
|
||||
_overlay.Phase = _random.NextFloat(MathF.Tau); // random starting phase for movement effect
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnShutdown(EntityUid uid, SeeingRainbowsComponent component, ComponentShutdown args)
|
||||
|
||||
@@ -24,16 +24,27 @@ public sealed class RainbowOverlay : Overlay
|
||||
|
||||
public float Intoxication = 0.0f;
|
||||
public float TimeTicker = 0.0f;
|
||||
public float Phase = 0.0f;
|
||||
|
||||
private const float VisualThreshold = 10.0f;
|
||||
private const float PowerDivisor = 250.0f;
|
||||
private float _timeScale = 0.0f;
|
||||
private float _warpScale = 0.0f;
|
||||
|
||||
private float EffectScale => Math.Clamp((Intoxication - VisualThreshold) / PowerDivisor, 0.0f, 1.0f);
|
||||
|
||||
public RainbowOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_rainbowShader = _prototypeManager.Index<ShaderPrototype>("Rainbow").InstanceUnique();
|
||||
_config.OnValueChanged(CCVars.ReducedMotion, OnReducedMotionChanged, invokeImmediately: true);
|
||||
}
|
||||
|
||||
private void OnReducedMotionChanged(bool reducedMotion)
|
||||
{
|
||||
_timeScale = reducedMotion ? 0.0f : 1.0f;
|
||||
_warpScale = reducedMotion ? 0.0f : 1.0f;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
@@ -51,7 +62,7 @@ public sealed class RainbowOverlay : Overlay
|
||||
if (!statusSys.TryGetTime(playerEntity.Value, DrugOverlaySystem.RainbowKey, out var time, status))
|
||||
return;
|
||||
|
||||
var timeLeft = (float) (time.Value.Item2 - time.Value.Item1).TotalSeconds;
|
||||
var timeLeft = (float)(time.Value.Item2 - time.Value.Item1).TotalSeconds;
|
||||
|
||||
TimeTicker += args.DeltaSeconds;
|
||||
|
||||
@@ -61,7 +72,7 @@ public sealed class RainbowOverlay : Overlay
|
||||
}
|
||||
else
|
||||
{
|
||||
Intoxication -= Intoxication/(timeLeft - TimeTicker) * args.DeltaSeconds;
|
||||
Intoxication -= Intoxication / (timeLeft - TimeTicker) * args.DeltaSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,16 +89,15 @@ public sealed class RainbowOverlay : Overlay
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
// TODO disable only the motion part or ike's idea (single static frame of the overlay)
|
||||
if (_config.GetCVar(CCVars.ReducedMotion))
|
||||
return;
|
||||
|
||||
if (ScreenTexture == null)
|
||||
return;
|
||||
|
||||
var handle = args.WorldHandle;
|
||||
_rainbowShader.SetParameter("SCREEN_TEXTURE", ScreenTexture);
|
||||
_rainbowShader.SetParameter("effectScale", EffectScale);
|
||||
_rainbowShader.SetParameter("colorScale", EffectScale);
|
||||
_rainbowShader.SetParameter("timeScale", _timeScale);
|
||||
_rainbowShader.SetParameter("warpScale", _warpScale * EffectScale);
|
||||
_rainbowShader.SetParameter("phase", Phase);
|
||||
handle.UseShader(_rainbowShader);
|
||||
handle.DrawRect(args.WorldBounds, Color.White);
|
||||
handle.UseShader(null);
|
||||
|
||||
@@ -13,6 +13,7 @@ public sealed class ColorFlashEffectSystem : SharedColorFlashEffectSystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly AnimationPlayerSystem _animation = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <summary>
|
||||
/// It's a little on the long side but given we use multiple colours denoting what happened it makes it easier to register.
|
||||
@@ -44,7 +45,7 @@ public sealed class ColorFlashEffectSystem : SharedColorFlashEffectSystem
|
||||
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite))
|
||||
{
|
||||
sprite.Color = component.Color;
|
||||
_sprite.SetColor((uid, sprite), component.Color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,15 +53,12 @@ public sealed class ElectrocutionHUDVisualizerSystem : VisualizerSystem<Electroc
|
||||
private void ShowHUD()
|
||||
{
|
||||
var electrifiedQuery = AllEntityQuery<ElectrocutionHUDVisualsComponent, AppearanceComponent, SpriteComponent>();
|
||||
while (electrifiedQuery.MoveNext(out var uid, out var _, out var appearanceComp, out var spriteComp))
|
||||
while (electrifiedQuery.MoveNext(out var uid, out _, out var appearanceComp, out var spriteComp))
|
||||
{
|
||||
if (!AppearanceSystem.TryGetData<bool>(uid, ElectrifiedVisuals.IsElectrified, out var electrified, appearanceComp))
|
||||
continue;
|
||||
|
||||
if (electrified)
|
||||
spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, true);
|
||||
else
|
||||
spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, false);
|
||||
SpriteSystem.LayerSetVisible((uid, spriteComp), ElectrifiedLayers.HUD, electrified);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,10 +67,9 @@ public sealed class ElectrocutionHUDVisualizerSystem : VisualizerSystem<Electroc
|
||||
private void RemoveHUD()
|
||||
{
|
||||
var electrifiedQuery = AllEntityQuery<ElectrocutionHUDVisualsComponent, AppearanceComponent, SpriteComponent>();
|
||||
while (electrifiedQuery.MoveNext(out var uid, out var _, out var appearanceComp, out var spriteComp))
|
||||
while (electrifiedQuery.MoveNext(out var uid, out _, out _, out var spriteComp))
|
||||
{
|
||||
|
||||
spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, false);
|
||||
SpriteSystem.LayerSetVisible((uid, spriteComp), ElectrifiedLayers.HUD, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,9 +83,6 @@ public sealed class ElectrocutionHUDVisualizerSystem : VisualizerSystem<Electroc
|
||||
return;
|
||||
|
||||
var player = _playerMan.LocalEntity;
|
||||
if (electrified && HasComp<ShowElectrocutionHUDComponent>(player))
|
||||
args.Sprite.LayerSetVisible(ElectrifiedLayers.HUD, true);
|
||||
else
|
||||
args.Sprite.LayerSetVisible(ElectrifiedLayers.HUD, false);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), ElectrifiedLayers.HUD, electrified && HasComp<ShowElectrocutionHUDComponent>(player));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
using Content.Shared.Ensnaring;
|
||||
using Content.Shared.Ensnaring.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Ensnaring;
|
||||
|
||||
public sealed class EnsnareableSystem : SharedEnsnareableSystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -19,25 +21,25 @@ public sealed class EnsnareableSystem : SharedEnsnareableSystem
|
||||
{
|
||||
base.OnEnsnareInit(ent, ref args);
|
||||
|
||||
if(!TryComp<SpriteComponent>(ent.Owner, out var sprite))
|
||||
if (!TryComp<SpriteComponent>(ent.Owner, out var sprite))
|
||||
return;
|
||||
|
||||
// TODO remove this, this should just be in yaml.
|
||||
sprite.LayerMapReserveBlank(EnsnaredVisualLayers.Ensnared);
|
||||
_sprite.LayerMapReserve((ent.Owner, sprite), EnsnaredVisualLayers.Ensnared);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(EntityUid uid, EnsnareableComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null || !args.Sprite.LayerMapTryGet(EnsnaredVisualLayers.Ensnared, out var layer))
|
||||
if (args.Sprite == null || !_sprite.LayerMapTryGet((uid, args.Sprite), EnsnaredVisualLayers.Ensnared, out var layer, false))
|
||||
return;
|
||||
|
||||
if (_appearance.TryGetData<bool>(uid, EnsnareableVisuals.IsEnsnared, out var isEnsnared, args.Component))
|
||||
{
|
||||
if (component.Sprite != null)
|
||||
{
|
||||
args.Sprite.LayerSetRSI(layer, component.Sprite);
|
||||
args.Sprite.LayerSetState(layer, component.State);
|
||||
args.Sprite.LayerSetVisible(layer, isEnsnared);
|
||||
_sprite.LayerSetRsi((uid, args.Sprite), layer, new ResPath(component.Sprite));
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, component.State);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, isEnsnared);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@ public sealed class ClusterGrenadeVisualizerSystem : VisualizerSystem<ClusterGre
|
||||
return;
|
||||
|
||||
if (AppearanceSystem.TryGetData<int>(uid, ClusterGrenadeVisuals.GrenadesCounter, out var grenadesCounter, args.Component))
|
||||
args.Sprite.LayerSetState(0, $"{comp.State}-{grenadesCounter}");
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), 0, $"{comp.State}-{grenadesCounter}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Explosion;
|
||||
@@ -19,7 +18,7 @@ public sealed class ExplosionOverlaySystem : EntitySystem
|
||||
[Dependency] private readonly IResourceCache _resCache = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlayMan = default!;
|
||||
[Dependency] private readonly SharedPointLightSystem _lights = default!;
|
||||
[Dependency] private readonly IMapManager _mapMan = default!;
|
||||
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
|
||||
public override void Initialize()
|
||||
@@ -69,7 +68,7 @@ public sealed class ExplosionOverlaySystem : EntitySystem
|
||||
}
|
||||
|
||||
// Map may have been deleted.
|
||||
if (_mapMan.MapExists(component.Epicenter.MapId))
|
||||
if (_mapSystem.MapExists(component.Epicenter.MapId))
|
||||
{
|
||||
// spawn in a client-side light source at the epicenter
|
||||
var lightEntity = Spawn("ExplosionLight", component.Epicenter);
|
||||
|
||||
@@ -9,6 +9,7 @@ public sealed partial class TriggerSystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _player = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/*
|
||||
* Currently all of the appearance stuff is hardcoded for portable flashers
|
||||
@@ -79,7 +80,7 @@ public sealed partial class TriggerSystem
|
||||
if (!_appearance.TryGetData<ProximityTriggerVisuals>(uid, ProximityTriggerVisualState.State, out var state, appearance))
|
||||
return;
|
||||
|
||||
if (!spriteComponent.LayerMapTryGet(ProximityTriggerVisualLayers.Base, out var layer))
|
||||
if (!_sprite.LayerMapTryGet((uid, spriteComponent), ProximityTriggerVisualLayers.Base, out var layer, false))
|
||||
// Don't do anything if the sprite doesn't have the layer.
|
||||
return;
|
||||
|
||||
@@ -89,7 +90,7 @@ public sealed partial class TriggerSystem
|
||||
// Don't interrupt the flash animation
|
||||
if (_player.HasRunningAnimation(uid, player, AnimKey)) return;
|
||||
_player.Stop(uid, player, AnimKey);
|
||||
spriteComponent.LayerSetState(layer, "on");
|
||||
_sprite.LayerSetRsiState((uid, spriteComponent), layer, "on");
|
||||
break;
|
||||
case ProximityTriggerVisuals.Active:
|
||||
if (_player.HasRunningAnimation(uid, player, AnimKey)) return;
|
||||
@@ -98,7 +99,7 @@ public sealed partial class TriggerSystem
|
||||
case ProximityTriggerVisuals.Off:
|
||||
default:
|
||||
_player.Stop(uid, player, AnimKey);
|
||||
spriteComponent.LayerSetState(layer, "off");
|
||||
_sprite.LayerSetRsiState((uid, spriteComponent), layer, "off");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,116 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
Title="{Loc 'fax-machine-ui-window'}"
|
||||
MinWidth="250">
|
||||
<BoxContainer Orientation="Vertical" VerticalExpand="True">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Label Text="{Loc 'fax-machine-ui-paper'}" />
|
||||
<Control MinWidth="4" />
|
||||
<Label Name="PaperStatusLabel" />
|
||||
</BoxContainer>
|
||||
<Control HorizontalExpand="True" MinHeight="20" />
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Label Text="{Loc 'fax-machine-ui-from'}" />
|
||||
<Control MinWidth="4" />
|
||||
<Label Name="FromLabel" />
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Label Text="{Loc 'fax-machine-ui-to'}" />
|
||||
<Control MinWidth="4" />
|
||||
<OptionButton Name="PeerSelector" HorizontalExpand="True" />
|
||||
</BoxContainer>
|
||||
<Control HorizontalExpand="True" MinHeight="20" />
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Button Name="FileButton"
|
||||
Text="{Loc 'fax-machine-ui-file-button'}"
|
||||
HorizontalExpand="False"/>
|
||||
<Button Name="PaperButton"
|
||||
Text="{Loc 'fax-machine-ui-paper-button-normal'}"
|
||||
HorizontalExpand="False"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Button Name="CopyButton"
|
||||
Text="{Loc 'fax-machine-ui-copy-button'}"
|
||||
HorizontalExpand="False"
|
||||
Disabled="True" />
|
||||
<Button Name="SendButton"
|
||||
Text="{Loc 'fax-machine-ui-send-button'}"
|
||||
HorizontalExpand="True"
|
||||
Disabled="True" />
|
||||
<Button Name="RefreshButton"
|
||||
Text="{Loc 'fax-machine-ui-refresh-button'}" />
|
||||
</BoxContainer>
|
||||
<DefaultWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
Title="{Loc 'fax-machine-ui-window'}"
|
||||
MinSize="380 220">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
SeparationOverride="2"
|
||||
VerticalExpand="True">
|
||||
|
||||
<PanelContainer StyleClasses="PanelBackgroundBaseDark" HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
Margin="0 0 0 2">
|
||||
|
||||
<!-- From Line -->
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
|
||||
<!-- From Value Name -->
|
||||
<Label Text="{Loc 'fax-machine-ui-from'}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom"/>
|
||||
|
||||
<Control HorizontalExpand="True"
|
||||
MinWidth="8"
|
||||
HorizontalAlignment="Center"/>
|
||||
|
||||
<!-- From Value -->
|
||||
<Label Name="FromLabel"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Align="Right"/>
|
||||
</BoxContainer>
|
||||
|
||||
<!-- To Line -->
|
||||
<BoxContainer
|
||||
Orientation="Horizontal">
|
||||
|
||||
<!-- To Label -->
|
||||
<Label Text="{Loc 'fax-machine-ui-to'}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom"/>
|
||||
|
||||
<Control HorizontalExpand="True"
|
||||
MinWidth="8"
|
||||
HorizontalAlignment="Center"/>
|
||||
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<!-- To Value -->
|
||||
<OptionButton Name="PeerSelector"
|
||||
StyleClasses="OpenRight" />
|
||||
|
||||
<!-- Refresh Fax Recipients -->
|
||||
<Button StyleClasses="OpenLeft"
|
||||
Name="RefreshButton"
|
||||
ToolTip="{Loc 'fax-machine-ui-refresh-button'}">
|
||||
<TextureButton
|
||||
MouseFilter="Ignore"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Scale="0.9 0.9"
|
||||
StyleClasses="Refresh" />
|
||||
</Button>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<PanelContainer StyleClasses="LowDivider" Margin="0 4 0 4"/>
|
||||
|
||||
<!-- Send & Copy -->
|
||||
<BoxContainer Orientation="Vertical">
|
||||
|
||||
<!-- Paper Status -->
|
||||
<Label Name="PaperStatusLabel"
|
||||
HorizontalAlignment="Center" />
|
||||
|
||||
<BoxContainer>
|
||||
<Button Name="CopyButton"
|
||||
Text="{Loc 'fax-machine-ui-copy-button'}"
|
||||
StyleClasses="OpenRight"
|
||||
HorizontalExpand="True"
|
||||
Disabled="True" />
|
||||
<Button Name="SendButton"
|
||||
Text="{Loc 'fax-machine-ui-send-button'}"
|
||||
StyleClasses="OpenLeft"
|
||||
HorizontalExpand="True"
|
||||
Disabled="True" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
</PanelContainer>
|
||||
|
||||
<PanelContainer StyleClasses="PanelBackgroundBaseDark"
|
||||
HorizontalExpand="True" Margin="0 10 0 0"
|
||||
VerticalExpand="True" VerticalAlignment="Bottom">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
VerticalExpand="True">
|
||||
|
||||
<!-- Other actions -->
|
||||
<BoxContainer Margin="0 4 0 4">
|
||||
|
||||
<Button Name="PaperButton"
|
||||
Text="{Loc 'fax-machine-ui-paper-button-normal'}"
|
||||
StyleClasses="OpenRight"
|
||||
HorizontalExpand="True"/>
|
||||
|
||||
<Button Name="FileButton"
|
||||
Text="{Loc 'fax-machine-ui-file-button'}"
|
||||
StyleClasses="OpenLeft"
|
||||
HorizontalExpand="True"/>
|
||||
|
||||
</BoxContainer>
|
||||
|
||||
<!-- It would be cool to add a display of the inserted file here. -->
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Content.Client.Fluids;
|
||||
public sealed class PuddleSystem : SharedPuddleSystem
|
||||
{
|
||||
[Dependency] private readonly IconSmoothSystem _smooth = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -27,7 +28,7 @@ public sealed class PuddleSystem : SharedPuddleSystem
|
||||
|
||||
if (args.AppearanceData.TryGetValue(PuddleVisuals.CurrentVolume, out var volumeObj))
|
||||
{
|
||||
volume = (float) volumeObj;
|
||||
volume = (float)volumeObj;
|
||||
}
|
||||
|
||||
// Update smoothing and sprite based on volume.
|
||||
@@ -35,19 +36,19 @@ public sealed class PuddleSystem : SharedPuddleSystem
|
||||
{
|
||||
if (volume < LowThreshold)
|
||||
{
|
||||
args.Sprite.LayerSetState(0, $"{smooth.StateBase}a");
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), 0, $"{smooth.StateBase}a");
|
||||
_smooth.SetEnabled(uid, false, smooth);
|
||||
}
|
||||
else if (volume < MediumThreshold)
|
||||
{
|
||||
args.Sprite.LayerSetState(0, $"{smooth.StateBase}b");
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), 0, $"{smooth.StateBase}b");
|
||||
_smooth.SetEnabled(uid, false, smooth);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!smooth.Enabled)
|
||||
{
|
||||
args.Sprite.LayerSetState(0, $"{smooth.StateBase}0");
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), 0, $"{smooth.StateBase}0");
|
||||
_smooth.SetEnabled(uid, true, smooth);
|
||||
_smooth.DirtyNeighbours(uid);
|
||||
}
|
||||
@@ -58,12 +59,12 @@ public sealed class PuddleSystem : SharedPuddleSystem
|
||||
|
||||
if (args.AppearanceData.TryGetValue(PuddleVisuals.SolutionColor, out var colorObj))
|
||||
{
|
||||
var color = (Color) colorObj;
|
||||
args.Sprite.Color = color * baseColor;
|
||||
var color = (Color)colorObj;
|
||||
_sprite.SetColor((uid, args.Sprite), color * baseColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Sprite.Color *= baseColor;
|
||||
_sprite.SetColor((uid, args.Sprite), args.Sprite.Color * baseColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Content.Client.Ghost
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
[Dependency] private readonly PointLightSystem _pointLightSystem = default!;
|
||||
[Dependency] private readonly ContentEyeSystem _contentEye = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public int AvailableGhostRoleCount { get; private set; }
|
||||
|
||||
@@ -35,7 +36,7 @@ namespace Content.Client.Ghost
|
||||
var query = AllEntityQuery<GhostComponent, SpriteComponent>();
|
||||
while (query.MoveNext(out var uid, out _, out var sprite))
|
||||
{
|
||||
sprite.Visible = value || uid == _playerManager.LocalEntity;
|
||||
_sprite.SetVisible((uid, sprite), value || uid == _playerManager.LocalEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,7 +73,7 @@ namespace Content.Client.Ghost
|
||||
private void OnStartup(EntityUid uid, GhostComponent component, ComponentStartup args)
|
||||
{
|
||||
if (TryComp(uid, out SpriteComponent? sprite))
|
||||
sprite.Visible = GhostVisibility || uid == _playerManager.LocalEntity;
|
||||
_sprite.SetVisible((uid, sprite), GhostVisibility || uid == _playerManager.LocalEntity);
|
||||
}
|
||||
|
||||
private void OnToggleLighting(EntityUid uid, EyeComponent component, ToggleLightingActionEvent args)
|
||||
@@ -150,7 +151,7 @@ namespace Content.Client.Ghost
|
||||
private void OnGhostState(EntityUid uid, GhostComponent component, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite))
|
||||
sprite.LayerSetColor(0, component.Color);
|
||||
_sprite.LayerSetColor((uid, sprite), 0, component.Color);
|
||||
|
||||
if (uid != _playerManager.LocalEntity)
|
||||
return;
|
||||
|
||||
@@ -25,6 +25,7 @@ public sealed class GhostToggleSelfVisibility : IConsoleCommand
|
||||
if (!entityManager.TryGetComponent(attachedEntity, out SpriteComponent? spriteComponent))
|
||||
return;
|
||||
|
||||
spriteComponent.Visible = !spriteComponent.Visible;
|
||||
var spriteSys = entityManager.System<SpriteSystem>();
|
||||
spriteSys.SetVisible((attachedEntity.Value, spriteComponent), !spriteComponent.Visible);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace Content.Client.Gravity;
|
||||
public sealed partial class GravitySystem : SharedGravitySystem
|
||||
{
|
||||
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -26,34 +28,34 @@ public sealed partial class GravitySystem : SharedGravitySystem
|
||||
{
|
||||
if (comp.SpriteMap.TryGetValue(state, out var spriteState))
|
||||
{
|
||||
var layer = args.Sprite.LayerMapGet(GravityGeneratorVisualLayers.Base);
|
||||
args.Sprite.LayerSetState(layer, spriteState);
|
||||
var layer = _sprite.LayerMapGet((uid, args.Sprite), GravityGeneratorVisualLayers.Base);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, spriteState);
|
||||
}
|
||||
}
|
||||
|
||||
if (_appearanceSystem.TryGetData<float>(uid, PowerChargeVisuals.Charge, out var charge, args.Component))
|
||||
{
|
||||
var layer = args.Sprite.LayerMapGet(GravityGeneratorVisualLayers.Core);
|
||||
var layer = _sprite.LayerMapGet((uid, args.Sprite), GravityGeneratorVisualLayers.Core);
|
||||
switch (charge)
|
||||
{
|
||||
case < 0.2f:
|
||||
args.Sprite.LayerSetVisible(layer, false);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, false);
|
||||
break;
|
||||
case >= 0.2f and < 0.4f:
|
||||
args.Sprite.LayerSetVisible(layer, true);
|
||||
args.Sprite.LayerSetState(layer, comp.CoreStartupState);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, true);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, comp.CoreStartupState);
|
||||
break;
|
||||
case >= 0.4f and < 0.6f:
|
||||
args.Sprite.LayerSetVisible(layer, true);
|
||||
args.Sprite.LayerSetState(layer, comp.CoreIdleState);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, true);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, comp.CoreIdleState);
|
||||
break;
|
||||
case >= 0.6f and < 0.8f:
|
||||
args.Sprite.LayerSetVisible(layer, true);
|
||||
args.Sprite.LayerSetState(layer, comp.CoreActivatingState);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, true);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, comp.CoreActivatingState);
|
||||
break;
|
||||
default:
|
||||
args.Sprite.LayerSetVisible(layer, true);
|
||||
args.Sprite.LayerSetState(layer, comp.CoreActivatedState);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, true);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, comp.CoreActivatedState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,15 @@ namespace Content.Client.Guidebook.Controls;
|
||||
/// Control for embedding a microwave recipe into a guidebook.
|
||||
/// </summary>
|
||||
[UsedImplicitly, GenerateTypedNameReferences]
|
||||
public sealed partial class GuideMicrowaveEmbed : PanelContainer, IDocumentTag, ISearchableControl
|
||||
public sealed partial class GuideMicrowaveEmbed : PanelContainer, IDocumentTag, ISearchableControl, IPrototypeRepresentationControl
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
public IPrototype? RepresentedPrototype { get; private set; }
|
||||
|
||||
public GuideMicrowaveEmbed()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
@@ -80,6 +82,8 @@ public sealed partial class GuideMicrowaveEmbed : PanelContainer, IDocumentTag,
|
||||
{
|
||||
var entity = _prototype.Index<EntityPrototype>(recipe.Result);
|
||||
|
||||
RepresentedPrototype = entity;
|
||||
|
||||
IconContainer.AddChild(new GuideEntityEmbed(recipe.Result, false, false));
|
||||
ResultName.SetMarkup(entity.Name);
|
||||
ResultDescription.SetMarkup(entity.Description);
|
||||
@@ -99,8 +103,9 @@ public sealed partial class GuideMicrowaveEmbed : PanelContainer, IDocumentTag,
|
||||
solidNameMsg.AddMarkupOrThrow(Loc.GetString("guidebook-microwave-solid-name-display", ("ingredient", ingredient.Name)));
|
||||
solidNameMsg.Pop();
|
||||
|
||||
var solidNameLabel = new RichTextLabel();
|
||||
var solidNameLabel = new GuidebookRichPrototypeLink();
|
||||
solidNameLabel.SetMessage(solidNameMsg);
|
||||
solidNameLabel.LinkedPrototype = ingredient;
|
||||
|
||||
IngredientsGrid.AddChild(solidNameLabel);
|
||||
|
||||
@@ -129,9 +134,10 @@ public sealed partial class GuideMicrowaveEmbed : PanelContainer, IDocumentTag,
|
||||
liquidColorMsg.AddMarkupOrThrow(Loc.GetString("guidebook-microwave-reagent-color-display", ("color", reagent.SubstanceColor)));
|
||||
liquidColorMsg.Pop();
|
||||
|
||||
var liquidColorLabel = new RichTextLabel();
|
||||
var liquidColorLabel = new GuidebookRichPrototypeLink();
|
||||
liquidColorLabel.SetMessage(liquidColorMsg);
|
||||
liquidColorLabel.HorizontalAlignment = Control.HAlignment.Center;
|
||||
liquidColorLabel.LinkedPrototype = reagent;
|
||||
|
||||
IngredientsGrid.AddChild(liquidColorLabel);
|
||||
|
||||
|
||||
@@ -22,13 +22,15 @@ namespace Content.Client.Guidebook.Controls;
|
||||
/// Control for embedding a reagent into a guidebook.
|
||||
/// </summary>
|
||||
[UsedImplicitly, GenerateTypedNameReferences]
|
||||
public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISearchableControl
|
||||
public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISearchableControl, IPrototypeRepresentationControl
|
||||
{
|
||||
[Dependency] private readonly IEntitySystemManager _systemManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
|
||||
private readonly ChemistryGuideDataSystem _chemistryGuideData;
|
||||
|
||||
public IPrototype? RepresentedPrototype { get; private set; }
|
||||
|
||||
public GuideReagentEmbed()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
@@ -80,6 +82,8 @@ public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISea
|
||||
|
||||
private void GenerateControl(ReagentPrototype reagent)
|
||||
{
|
||||
RepresentedPrototype = reagent;
|
||||
|
||||
NameBackground.PanelOverride = new StyleBoxFlat
|
||||
{
|
||||
BackgroundColor = reagent.SubstanceColor
|
||||
|
||||
@@ -4,13 +4,11 @@
|
||||
HorizontalExpand="True"
|
||||
Margin="0 0 0 5">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<BoxContainer Name="ReactantsContainer" Orientation="Vertical" HorizontalExpand="True"
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True"
|
||||
VerticalAlignment="Center">
|
||||
<RichTextLabel Name="ReactantsLabel"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Access="Public"
|
||||
Visible="False" />
|
||||
<BoxContainer Name="ReactantsContainer" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Vertical">
|
||||
<!-- Reactants will be added as children here -->
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextureRect TexturePath="/Textures/Interface/Misc/beakerlarge.png"
|
||||
@@ -23,11 +21,9 @@
|
||||
Margin="2 0 0 0" />
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalAlignment="Center">
|
||||
<RichTextLabel Name="ProductsLabel"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Access="Public"
|
||||
Visible="False" />
|
||||
<BoxContainer Name="ProductsContainer" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Vertical">
|
||||
<!-- Products will be added as children here -->
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
<PanelContainer StyleClasses="LowDivider" Margin="0 5 0 5" />
|
||||
|
||||
@@ -34,16 +34,16 @@ public sealed partial class GuideReagentReaction : BoxContainer, ISearchableCont
|
||||
|
||||
public GuideReagentReaction(ReactionPrototype prototype, IPrototypeManager protoMan, IEntitySystemManager sysMan) : this(protoMan)
|
||||
{
|
||||
var reactantsLabel = ReactantsLabel;
|
||||
SetReagents(prototype.Reactants, ref reactantsLabel, protoMan);
|
||||
var productLabel = ProductsLabel;
|
||||
Container container = ReactantsContainer;
|
||||
SetReagents(prototype.Reactants, ref container, protoMan);
|
||||
Container productContainer = ProductsContainer;
|
||||
var products = new Dictionary<string, FixedPoint2>(prototype.Products);
|
||||
foreach (var (reagent, reactantProto) in prototype.Reactants)
|
||||
{
|
||||
if (reactantProto.Catalyst)
|
||||
products.Add(reagent, reactantProto.Amount);
|
||||
}
|
||||
SetReagents(products, ref productLabel, protoMan);
|
||||
SetReagents(products, ref productContainer, protoMan, false);
|
||||
|
||||
var mixingCategories = new List<MixingCategoryPrototype>();
|
||||
if (prototype.MixingCategories != null)
|
||||
@@ -85,8 +85,8 @@ public sealed partial class GuideReagentReaction : BoxContainer, ISearchableCont
|
||||
entContainer.AddChild(nameLabel);
|
||||
ReactantsContainer.AddChild(entContainer);
|
||||
|
||||
var productLabel = ProductsLabel;
|
||||
SetReagents(solution.Contents, ref productLabel, protoMan);
|
||||
Container productContainer = ProductsContainer;
|
||||
SetReagents(solution.Contents, ref productContainer, protoMan, false);
|
||||
SetMixingCategory(categories, null, sysMan);
|
||||
}
|
||||
|
||||
@@ -95,75 +95,80 @@ public sealed partial class GuideReagentReaction : BoxContainer, ISearchableCont
|
||||
IPrototypeManager protoMan,
|
||||
IEntitySystemManager sysMan) : this(protoMan)
|
||||
{
|
||||
ReactantsLabel.Visible = true;
|
||||
ReactantsLabel.SetMarkup(Loc.GetString("guidebook-reagent-sources-gas-wrapper",
|
||||
var label = new RichTextLabel();
|
||||
label.SetMarkup(Loc.GetString("guidebook-reagent-sources-gas-wrapper",
|
||||
("name", Loc.GetString(prototype.Name).ToLower())));
|
||||
|
||||
ReactantsContainer.Visible = true;
|
||||
ReactantsContainer.AddChild(label);
|
||||
|
||||
if (prototype.Reagent != null)
|
||||
{
|
||||
var quantity = new Dictionary<string, FixedPoint2>
|
||||
{
|
||||
{ prototype.Reagent, FixedPoint2.New(0.21f) }
|
||||
};
|
||||
var productLabel = ProductsLabel;
|
||||
SetReagents(quantity, ref productLabel, protoMan);
|
||||
Container productContainer = ProductsContainer;
|
||||
SetReagents(quantity, ref productContainer, protoMan, false);
|
||||
}
|
||||
SetMixingCategory(categories, null, sysMan);
|
||||
}
|
||||
|
||||
private void SetReagents(List<ReagentQuantity> reagents, ref RichTextLabel label, IPrototypeManager protoMan)
|
||||
private void SetReagents(List<ReagentQuantity> reagents, ref Container container, IPrototypeManager protoMan, bool addLinks = true)
|
||||
{
|
||||
var amounts = new Dictionary<string, FixedPoint2>();
|
||||
foreach (var (reagent, quantity) in reagents)
|
||||
{
|
||||
amounts.Add(reagent.Prototype, quantity);
|
||||
}
|
||||
SetReagents(amounts, ref label, protoMan);
|
||||
SetReagents(amounts, ref container, protoMan, addLinks);
|
||||
}
|
||||
|
||||
private void SetReagents(
|
||||
Dictionary<string, ReactantPrototype> reactants,
|
||||
ref RichTextLabel label,
|
||||
IPrototypeManager protoMan)
|
||||
ref Container container,
|
||||
IPrototypeManager protoMan,
|
||||
bool addLinks = true)
|
||||
{
|
||||
var amounts = new Dictionary<string, FixedPoint2>();
|
||||
foreach (var (reagent, reactantPrototype) in reactants)
|
||||
{
|
||||
amounts.Add(reagent, reactantPrototype.Amount);
|
||||
}
|
||||
SetReagents(amounts, ref label, protoMan);
|
||||
SetReagents(amounts, ref container, protoMan, addLinks);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
private void SetReagents(
|
||||
Dictionary<ProtoId<MixingCategoryPrototype>, ReactantPrototype> reactants,
|
||||
ref RichTextLabel label,
|
||||
IPrototypeManager protoMan)
|
||||
ref Container container,
|
||||
IPrototypeManager protoMan,
|
||||
bool addLinks = true)
|
||||
{
|
||||
var amounts = new Dictionary<string, FixedPoint2>();
|
||||
foreach (var (reagent, reactantPrototype) in reactants)
|
||||
{
|
||||
amounts.Add(reagent, reactantPrototype.Amount);
|
||||
}
|
||||
SetReagents(amounts, ref label, protoMan);
|
||||
SetReagents(amounts, ref container, protoMan, addLinks);
|
||||
}
|
||||
|
||||
private void SetReagents(Dictionary<string, FixedPoint2> reagents, ref RichTextLabel label, IPrototypeManager protoMan)
|
||||
private void SetReagents(Dictionary<string, FixedPoint2> reagents, ref Container container, IPrototypeManager protoMan, bool addLinks = true)
|
||||
{
|
||||
var msg = new FormattedMessage();
|
||||
var reagentCount = reagents.Count;
|
||||
var i = 0;
|
||||
foreach (var (product, amount) in reagents.OrderByDescending(p => p.Value))
|
||||
{
|
||||
var productProto = protoMan.Index<ReagentPrototype>(product);
|
||||
var msg = new FormattedMessage();
|
||||
msg.AddMarkupOrThrow(Loc.GetString("guidebook-reagent-recipes-reagent-display",
|
||||
("reagent", protoMan.Index<ReagentPrototype>(product).LocalizedName), ("ratio", amount)));
|
||||
i++;
|
||||
if (i < reagentCount)
|
||||
msg.PushNewline();
|
||||
("reagent", productProto.LocalizedName), ("ratio", amount)));
|
||||
|
||||
var label = new GuidebookRichPrototypeLink();
|
||||
if (addLinks)
|
||||
label.LinkedPrototype = productProto;
|
||||
label.SetMessage(msg);
|
||||
container.AddChild(label);
|
||||
}
|
||||
msg.Pop();
|
||||
label.SetMessage(msg);
|
||||
label.Visible = true;
|
||||
container.Visible = true;
|
||||
}
|
||||
|
||||
private void SetMixingCategory(IReadOnlyList<ProtoId<MixingCategoryPrototype>> mixingCategories, ReactionPrototype? prototype, IEntitySystemManager sysMan)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
using Content.Client.Guidebook.RichText;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Client.UserInterface.ControlExtensions;
|
||||
|
||||
namespace Content.Client.Guidebook.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// A RichTextLabel which is a link to a specified IPrototype.
|
||||
/// The link is activated by the owner if the prototype is represented
|
||||
/// somewhere in the same document.
|
||||
/// </summary>
|
||||
public sealed class GuidebookRichPrototypeLink : Control, IPrototypeLinkControl
|
||||
{
|
||||
private bool _linkActive = false;
|
||||
private FormattedMessage? _message;
|
||||
private readonly RichTextLabel _richTextLabel;
|
||||
|
||||
public void EnablePrototypeLink()
|
||||
{
|
||||
if (_message == null)
|
||||
return;
|
||||
|
||||
_linkActive = true;
|
||||
|
||||
DefaultCursorShape = CursorShape.Hand;
|
||||
|
||||
_richTextLabel.SetMessage(_message, null, TextLinkTag.LinkColor);
|
||||
}
|
||||
|
||||
public GuidebookRichPrototypeLink() : base()
|
||||
{
|
||||
MouseFilter = MouseFilterMode.Pass;
|
||||
OnKeyBindDown += HandleClick;
|
||||
_richTextLabel = new RichTextLabel();
|
||||
AddChild(_richTextLabel);
|
||||
}
|
||||
|
||||
public void SetMessage(FormattedMessage message)
|
||||
{
|
||||
_message = message;
|
||||
_richTextLabel.SetMessage(_message);
|
||||
}
|
||||
|
||||
public IPrototype? LinkedPrototype { get; set; }
|
||||
|
||||
private void HandleClick(GUIBoundKeyEventArgs args)
|
||||
{
|
||||
if (!_linkActive)
|
||||
return;
|
||||
|
||||
if (args.Function != EngineKeyFunctions.UIClick)
|
||||
return;
|
||||
|
||||
if (this.TryGetParentHandler<IAnchorClickHandler>(out var handler))
|
||||
{
|
||||
handler.HandleAnchor(this);
|
||||
args.Handle();
|
||||
}
|
||||
else
|
||||
Logger.Warning("Warning! No valid IAnchorClickHandler found.");
|
||||
}
|
||||
}
|
||||
|
||||
public interface IAnchorClickHandler
|
||||
{
|
||||
public void HandleAnchor(IPrototypeLinkControl prototypeLinkControl);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Content.Client.Guidebook.RichText;
|
||||
using Content.Client.UserInterface.ControlExtensions;
|
||||
@@ -6,6 +7,7 @@ using Content.Client.UserInterface.Controls.FancyTree;
|
||||
using Content.Client.UserInterface.Systems.Info;
|
||||
using Content.Shared.Guidebook;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.ContentPack;
|
||||
@@ -14,7 +16,7 @@ using Robust.Shared.Prototypes;
|
||||
namespace Content.Client.Guidebook.Controls;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class GuidebookWindow : FancyWindow, ILinkClickHandler
|
||||
public sealed partial class GuidebookWindow : FancyWindow, ILinkClickHandler, IAnchorClickHandler
|
||||
{
|
||||
[Dependency] private readonly DocumentParsingManager _parsingMan = default!;
|
||||
[Dependency] private readonly IResourceManager _resourceManager = default!;
|
||||
@@ -53,6 +55,38 @@ public sealed partial class GuidebookWindow : FancyWindow, ILinkClickHandler
|
||||
ShowGuide(entry);
|
||||
}
|
||||
|
||||
public void HandleAnchor(IPrototypeLinkControl prototypeLinkControl)
|
||||
{
|
||||
var prototype = prototypeLinkControl.LinkedPrototype;
|
||||
if (prototype == null)
|
||||
return;
|
||||
|
||||
var (linkableControls, _) = GetLinkableControlsAndLinks(EntryContainer);
|
||||
foreach (var linkableControl in linkableControls)
|
||||
{
|
||||
if (linkableControl.RepresentedPrototype != prototype)
|
||||
continue;
|
||||
|
||||
if (linkableControl is not Control control)
|
||||
return;
|
||||
|
||||
// Check if the target item is currently filtered out
|
||||
if (!control.Visible)
|
||||
control.Visible = true;
|
||||
|
||||
UserInterfaceManager.DeferAction(() =>
|
||||
{
|
||||
if (control.GetControlScrollPosition() is not {} position)
|
||||
return;
|
||||
|
||||
Scroll.HScrollTarget = position.X;
|
||||
Scroll.VScrollTarget = position.Y;
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectionChanged(TreeItem? item)
|
||||
{
|
||||
if (item != null && item.Metadata is GuideEntry entry)
|
||||
@@ -94,6 +128,23 @@ public sealed partial class GuidebookWindow : FancyWindow, ILinkClickHandler
|
||||
}
|
||||
|
||||
LastEntry = entry.Id;
|
||||
|
||||
var (linkableControls, linkControls) = GetLinkableControlsAndLinks(EntryContainer);
|
||||
|
||||
HashSet<IPrototype> availablePrototypeLinks = new();
|
||||
foreach (var linkableControl in linkableControls)
|
||||
{
|
||||
var prototype = linkableControl.RepresentedPrototype;
|
||||
if (prototype != null)
|
||||
availablePrototypeLinks.Add(prototype);
|
||||
}
|
||||
|
||||
foreach (var linkControl in linkControls)
|
||||
{
|
||||
var prototype = linkControl.LinkedPrototype;
|
||||
if (prototype != null && availablePrototypeLinks.Contains(prototype))
|
||||
linkControl.EnablePrototypeLink();
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateGuides(
|
||||
@@ -209,4 +260,30 @@ public sealed partial class GuidebookWindow : FancyWindow, ILinkClickHandler
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static (List<IPrototypeRepresentationControl>, List<IPrototypeLinkControl>) GetLinkableControlsAndLinks(Control parent)
|
||||
{
|
||||
List<IPrototypeRepresentationControl> linkableList = new();
|
||||
List<IPrototypeLinkControl> linkList = new();
|
||||
|
||||
foreach (var child in parent.Children)
|
||||
{
|
||||
var hasChildren = child.ChildCount > 0;
|
||||
|
||||
if (child is IPrototypeLinkControl linkChild)
|
||||
linkList.Add(linkChild);
|
||||
else if (child is IPrototypeRepresentationControl linkableChild)
|
||||
linkableList.Add(linkableChild);
|
||||
|
||||
if (!hasChildren)
|
||||
continue;
|
||||
|
||||
var (childLinkableList, childLinkList) = GetLinkableControlsAndLinks(child);
|
||||
|
||||
linkableList.AddRange(childLinkableList);
|
||||
linkList.AddRange(childLinkList);
|
||||
}
|
||||
|
||||
return (linkableList, linkList);
|
||||
}
|
||||
}
|
||||
|
||||
28
Content.Client/Guidebook/Controls/IPrototypeLinkControl.cs
Normal file
28
Content.Client/Guidebook/Controls/IPrototypeLinkControl.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Guidebook.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for controls which represent a Prototype
|
||||
/// These can be linked to from a IPrototypeLinkControl
|
||||
/// </summary>
|
||||
public interface IPrototypeRepresentationControl
|
||||
{
|
||||
// The prototype that this control represents
|
||||
public IPrototype? RepresentedPrototype { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for controls which can be clicked to navigate
|
||||
/// to a specified prototype representation on the same page.
|
||||
/// </summary>
|
||||
public interface IPrototypeLinkControl
|
||||
{
|
||||
// This control is a link to the specified prototype
|
||||
public IPrototype? LinkedPrototype { get; }
|
||||
|
||||
// Initially the link will not be enabled,
|
||||
// the owner can enable the link once there is a valid target
|
||||
// for the Prototype link.
|
||||
public void EnablePrototypeLink();
|
||||
}
|
||||
@@ -5,12 +5,15 @@ using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.RichText;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Client.UserInterface.ControlExtensions;
|
||||
|
||||
namespace Content.Client.Guidebook.RichText;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class TextLinkTag : IMarkupTag
|
||||
{
|
||||
public static Color LinkColor => Color.CornflowerBlue;
|
||||
|
||||
public string Name => "textlink";
|
||||
|
||||
public Control? Control;
|
||||
@@ -30,7 +33,7 @@ public sealed class TextLinkTag : IMarkupTag
|
||||
label.Text = text;
|
||||
|
||||
label.MouseFilter = Control.MouseFilterMode.Stop;
|
||||
label.FontColorOverride = Color.CornflowerBlue;
|
||||
label.FontColorOverride = LinkColor;
|
||||
label.DefaultCursorShape = Control.CursorShape.Hand;
|
||||
|
||||
label.OnMouseEntered += _ => label.FontColorOverride = Color.LightSkyBlue;
|
||||
@@ -50,17 +53,10 @@ public sealed class TextLinkTag : IMarkupTag
|
||||
if (Control == null)
|
||||
return;
|
||||
|
||||
var current = Control;
|
||||
while (current != null)
|
||||
{
|
||||
current = current.Parent;
|
||||
|
||||
if (current is not ILinkClickHandler handler)
|
||||
continue;
|
||||
if (Control.TryGetParentHandler<ILinkClickHandler>(out var handler))
|
||||
handler.HandleClick(link);
|
||||
return;
|
||||
}
|
||||
Logger.Warning($"Warning! No valid ILinkClickHandler found.");
|
||||
else
|
||||
Logger.Warning("Warning! No valid ILinkClickHandler found.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Hands.Systems
|
||||
{
|
||||
@@ -28,6 +29,7 @@ namespace Content.Client.Hands.Systems
|
||||
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
[Dependency] private readonly StrippableSystem _stripSys = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly ExamineSystem _examine = default!;
|
||||
[Dependency] private readonly DisplacementMapSystem _displacement = default!;
|
||||
|
||||
@@ -297,7 +299,7 @@ namespace Content.Client.Hands.Systems
|
||||
{
|
||||
foreach (var key in revealedLayers)
|
||||
{
|
||||
sprite.RemoveLayer(key);
|
||||
_sprite.RemoveLayer((uid, sprite), key);
|
||||
}
|
||||
|
||||
revealedLayers.Clear();
|
||||
@@ -333,7 +335,7 @@ namespace Content.Client.Hands.Systems
|
||||
continue;
|
||||
}
|
||||
|
||||
var index = sprite.LayerMapReserveBlank(key);
|
||||
var index = _sprite.LayerMapReserve((uid, sprite), key);
|
||||
|
||||
// In case no RSI is given, use the item's base RSI as a default. This cuts down on a lot of unnecessary yaml entries.
|
||||
if (layerData.RsiPath == null
|
||||
@@ -341,12 +343,12 @@ namespace Content.Client.Hands.Systems
|
||||
&& sprite[index].Rsi == null)
|
||||
{
|
||||
if (TryComp<ItemComponent>(held, out var itemComponent) && itemComponent.RsiPath != null)
|
||||
sprite.LayerSetRSI(index, itemComponent.RsiPath);
|
||||
_sprite.LayerSetRsi((uid, sprite), index, new ResPath(itemComponent.RsiPath));
|
||||
else if (TryComp(held, out SpriteComponent? clothingSprite))
|
||||
sprite.LayerSetRSI(index, clothingSprite.BaseRSI);
|
||||
_sprite.LayerSetRsi((uid, sprite), index, clothingSprite.BaseRSI);
|
||||
}
|
||||
|
||||
sprite.LayerSetData(index, layerData);
|
||||
_sprite.LayerSetData((uid, sprite), index, layerData);
|
||||
|
||||
// Add displacement maps
|
||||
var displacement = hand.Location switch
|
||||
@@ -356,7 +358,7 @@ namespace Content.Client.Hands.Systems
|
||||
_ => handComp.HandDisplacement
|
||||
};
|
||||
|
||||
if (displacement is not null && _displacement.TryAddDisplacement(displacement, sprite, index, key, out var displacementKey))
|
||||
if (displacement is not null && _displacement.TryAddDisplacement(displacement, (uid, sprite), index, key, out var displacementKey))
|
||||
revealedLayers.Add(displacementKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ public sealed class HolidaySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IResourceCache _rescache = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
@@ -29,6 +30,6 @@ public sealed class HolidaySystem : EntitySystem
|
||||
|
||||
var path = SpriteSpecifierSerializer.TextureRoot / rsistring;
|
||||
if (_rescache.TryGetResource(path, out RSIResource? rsi))
|
||||
args.Sprite.BaseRSI = rsi.RSI;
|
||||
_sprite.SetBaseRsi((ent.Owner, args.Sprite), rsi.RSI);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public sealed class HolopadSystem : SharedHolopadSystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -58,8 +59,8 @@ public sealed class HolopadSystem : SharedHolopadSystem
|
||||
return;
|
||||
|
||||
// Remove all sprite layers
|
||||
for (int i = hologramSprite.AllLayers.Count() - 1; i >= 0; i--)
|
||||
hologramSprite.RemoveLayer(i);
|
||||
for (var i = hologramSprite.AllLayers.Count() - 1; i >= 0; i--)
|
||||
_sprite.RemoveLayer((hologram, hologramSprite), i);
|
||||
|
||||
if (TryComp<SpriteComponent>(target, out var targetSprite))
|
||||
{
|
||||
@@ -67,17 +68,16 @@ public sealed class HolopadSystem : SharedHolopadSystem
|
||||
if (TryComp<HolographicAvatarComponent>(target, out var targetAvatar) &&
|
||||
targetAvatar.LayerData != null)
|
||||
{
|
||||
for (int i = 0; i < targetAvatar.LayerData.Length; i++)
|
||||
for (var i = 0; i < targetAvatar.LayerData.Length; i++)
|
||||
{
|
||||
var layer = targetAvatar.LayerData[i];
|
||||
hologramSprite.AddLayer(targetAvatar.LayerData[i], i);
|
||||
_sprite.AddLayer((hologram, hologramSprite), targetAvatar.LayerData[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise copy the target's current physical appearance
|
||||
else
|
||||
{
|
||||
hologramSprite.CopyFrom(targetSprite);
|
||||
_sprite.CopySprite((target.Value, targetSprite), (hologram, hologramSprite));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,25 +87,27 @@ public sealed class HolopadSystem : SharedHolopadSystem
|
||||
if (string.IsNullOrEmpty(holopadhologram.RsiPath) || string.IsNullOrEmpty(holopadhologram.RsiState))
|
||||
return;
|
||||
|
||||
var layer = new PrototypeLayerData();
|
||||
layer.RsiPath = holopadhologram.RsiPath;
|
||||
layer.State = holopadhologram.RsiState;
|
||||
var layer = new PrototypeLayerData
|
||||
{
|
||||
RsiPath = holopadhologram.RsiPath,
|
||||
State = holopadhologram.RsiState
|
||||
};
|
||||
|
||||
hologramSprite.AddLayer(layer);
|
||||
_sprite.AddLayer((hologram, hologramSprite), layer, null);
|
||||
}
|
||||
|
||||
// Override specific values
|
||||
hologramSprite.Color = Color.White;
|
||||
hologramSprite.Offset = holopadhologram.Offset;
|
||||
hologramSprite.DrawDepth = (int)DrawDepth.Mobs;
|
||||
_sprite.SetColor((hologram, hologramSprite), Color.White);
|
||||
_sprite.SetOffset((hologram, hologramSprite), holopadhologram.Offset);
|
||||
_sprite.SetDrawDepth((hologram, hologramSprite), (int)DrawDepth.Mobs);
|
||||
hologramSprite.NoRotation = true;
|
||||
hologramSprite.DirectionOverride = Direction.South;
|
||||
hologramSprite.EnableDirectionOverride = true;
|
||||
|
||||
// Remove shading from all layers (except displacement maps)
|
||||
for (int i = 0; i < hologramSprite.AllLayers.Count(); i++)
|
||||
for (var i = 0; i < hologramSprite.AllLayers.Count(); i++)
|
||||
{
|
||||
if (hologramSprite.TryGetLayer(i, out var layer) && layer.ShaderPrototype != "DisplacedStencilDraw")
|
||||
if (_sprite.TryGetLayer((hologram, hologramSprite), i, out var layer, false) && layer.ShaderPrototype != "DisplacedStencilDraw")
|
||||
hologramSprite.LayerSetShader(i, "unshaded");
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
[Dependency] private readonly MarkingManager _markingManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
[Dependency] private readonly DisplacementMapSystem _displacement = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -30,31 +31,37 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
|
||||
private void OnHandleState(EntityUid uid, HumanoidAppearanceComponent component, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
UpdateSprite(component, Comp<SpriteComponent>(uid));
|
||||
UpdateSprite((uid, component, Comp<SpriteComponent>(uid)));
|
||||
}
|
||||
|
||||
private void OnCvarChanged(bool value)
|
||||
{
|
||||
var humanoidQuery = EntityManager.AllEntityQueryEnumerator<HumanoidAppearanceComponent, SpriteComponent>();
|
||||
while (humanoidQuery.MoveNext(out var _, out var humanoidComp, out var spriteComp))
|
||||
while (humanoidQuery.MoveNext(out var uid, out var humanoidComp, out var spriteComp))
|
||||
{
|
||||
UpdateSprite(humanoidComp, spriteComp);
|
||||
UpdateSprite((uid, humanoidComp, spriteComp));
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSprite(HumanoidAppearanceComponent component, SpriteComponent sprite)
|
||||
private void UpdateSprite(Entity<HumanoidAppearanceComponent, SpriteComponent> entity)
|
||||
{
|
||||
UpdateLayers(component, sprite);
|
||||
ApplyMarkingSet(component, sprite);
|
||||
UpdateLayers(entity);
|
||||
ApplyMarkingSet(entity);
|
||||
|
||||
sprite[sprite.LayerMapReserveBlank(HumanoidVisualLayers.Eyes)].Color = component.EyeColor;
|
||||
var humanoidAppearance = entity.Comp1;
|
||||
var sprite = entity.Comp2;
|
||||
|
||||
sprite[_sprite.LayerMapReserve((entity.Owner, sprite), HumanoidVisualLayers.Eyes)].Color = humanoidAppearance.EyeColor;
|
||||
}
|
||||
|
||||
private static bool IsHidden(HumanoidAppearanceComponent humanoid, HumanoidVisualLayers layer)
|
||||
=> humanoid.HiddenLayers.ContainsKey(layer) || humanoid.PermanentlyHidden.Contains(layer);
|
||||
|
||||
private void UpdateLayers(HumanoidAppearanceComponent component, SpriteComponent sprite)
|
||||
private void UpdateLayers(Entity<HumanoidAppearanceComponent, SpriteComponent> entity)
|
||||
{
|
||||
var component = entity.Comp1;
|
||||
var sprite = entity.Comp2;
|
||||
|
||||
var oldLayers = new HashSet<HumanoidVisualLayers>(component.BaseLayers.Keys);
|
||||
component.BaseLayers.Clear();
|
||||
|
||||
@@ -65,34 +72,36 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
{
|
||||
oldLayers.Remove(key);
|
||||
if (!component.CustomBaseLayers.ContainsKey(key))
|
||||
SetLayerData(component, sprite, key, id, sexMorph: true);
|
||||
SetLayerData(entity, key, id, sexMorph: true);
|
||||
}
|
||||
|
||||
// add custom layers
|
||||
foreach (var (key, info) in component.CustomBaseLayers)
|
||||
{
|
||||
oldLayers.Remove(key);
|
||||
SetLayerData(component, sprite, key, info.Id, sexMorph: false, color: info.Color);
|
||||
SetLayerData(entity, key, info.Id, sexMorph: false, color: info.Color);
|
||||
}
|
||||
|
||||
// hide old layers
|
||||
// TODO maybe just remove them altogether?
|
||||
foreach (var key in oldLayers)
|
||||
{
|
||||
if (sprite.LayerMapTryGet(key, out var index))
|
||||
if (_sprite.LayerMapTryGet((entity.Owner, sprite), key, out var index, false))
|
||||
sprite[index].Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLayerData(
|
||||
HumanoidAppearanceComponent component,
|
||||
SpriteComponent sprite,
|
||||
Entity<HumanoidAppearanceComponent, SpriteComponent> entity,
|
||||
HumanoidVisualLayers key,
|
||||
string? protoId,
|
||||
bool sexMorph = false,
|
||||
Color? color = null)
|
||||
{
|
||||
var layerIndex = sprite.LayerMapReserveBlank(key);
|
||||
var component = entity.Comp1;
|
||||
var sprite = entity.Comp2;
|
||||
|
||||
var layerIndex = _sprite.LayerMapReserve((entity.Owner, sprite), key);
|
||||
var layer = sprite[layerIndex];
|
||||
layer.Visible = !IsHidden(component, key);
|
||||
|
||||
@@ -112,7 +121,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
layer.Color = component.SkinColor.WithAlpha(proto.LayerAlpha);
|
||||
|
||||
if (proto.BaseSprite != null)
|
||||
sprite.LayerSetSprite(layerIndex, proto.BaseSprite);
|
||||
_sprite.LayerSetSprite((entity.Owner, sprite), layerIndex, proto.BaseSprite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -215,14 +224,17 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
humanoid.SkinColor = profile.Appearance.SkinColor;
|
||||
humanoid.EyeColor = profile.Appearance.EyeColor;
|
||||
|
||||
UpdateSprite(humanoid, Comp<SpriteComponent>(uid));
|
||||
UpdateSprite((uid, humanoid, Comp<SpriteComponent>(uid)));
|
||||
}
|
||||
|
||||
private void ApplyMarkingSet(HumanoidAppearanceComponent humanoid, SpriteComponent sprite)
|
||||
private void ApplyMarkingSet(Entity<HumanoidAppearanceComponent, SpriteComponent> entity)
|
||||
{
|
||||
var humanoid = entity.Comp1;
|
||||
var sprite = entity.Comp2;
|
||||
|
||||
// I am lazy and I CBF resolving the previous mess, so I'm just going to nuke the markings.
|
||||
// Really, markings should probably be a separate component altogether.
|
||||
ClearAllMarkings(humanoid, sprite);
|
||||
ClearAllMarkings(entity);
|
||||
|
||||
var censorNudity = _configurationManager.GetCVar(CCVars.AccessibilityClientCensorNudity) ||
|
||||
_configurationManager.GetCVar(CCVars.AccessibilityServerCensorNudity);
|
||||
@@ -236,7 +248,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
{
|
||||
if (_markingManager.TryGetMarking(marking, out var markingPrototype))
|
||||
{
|
||||
ApplyMarking(markingPrototype, marking.MarkingColors, marking.Visible, humanoid, sprite);
|
||||
ApplyMarking(markingPrototype, marking.MarkingColors, marking.Visible, entity);
|
||||
if (markingPrototype.BodyPart == HumanoidVisualLayers.UndergarmentTop)
|
||||
applyUndergarmentTop = false;
|
||||
else if (markingPrototype.BodyPart == HumanoidVisualLayers.UndergarmentBottom)
|
||||
@@ -247,16 +259,19 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
|
||||
humanoid.ClientOldMarkings = new MarkingSet(humanoid.MarkingSet);
|
||||
|
||||
AddUndergarments(humanoid, sprite, applyUndergarmentTop, applyUndergarmentBottom);
|
||||
AddUndergarments(entity, applyUndergarmentTop, applyUndergarmentBottom);
|
||||
}
|
||||
|
||||
private void ClearAllMarkings(HumanoidAppearanceComponent humanoid, SpriteComponent sprite)
|
||||
private void ClearAllMarkings(Entity<HumanoidAppearanceComponent, SpriteComponent> entity)
|
||||
{
|
||||
var humanoid = entity.Comp1;
|
||||
var sprite = entity.Comp2;
|
||||
|
||||
foreach (var markingList in humanoid.ClientOldMarkings.Markings.Values)
|
||||
{
|
||||
foreach (var marking in markingList)
|
||||
{
|
||||
RemoveMarking(marking, sprite);
|
||||
RemoveMarking(marking, (entity, sprite));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,12 +281,12 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
{
|
||||
foreach (var marking in markingList)
|
||||
{
|
||||
RemoveMarking(marking, sprite);
|
||||
RemoveMarking(marking, (entity, sprite));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveMarking(Marking marking, SpriteComponent spriteComp)
|
||||
private void RemoveMarking(Marking marking, Entity<SpriteComponent> spriteEnt)
|
||||
{
|
||||
if (!_markingManager.TryGetMarking(marking, out var prototype))
|
||||
{
|
||||
@@ -286,26 +301,28 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
}
|
||||
|
||||
var layerId = $"{marking.MarkingId}-{rsi.RsiState}";
|
||||
if (!spriteComp.LayerMapTryGet(layerId, out var index))
|
||||
if (!_sprite.LayerMapTryGet(spriteEnt.AsNullable(), layerId, out var index, false))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
spriteComp.LayerMapRemove(layerId);
|
||||
spriteComp.RemoveLayer(index);
|
||||
_sprite.LayerMapRemove(spriteEnt.AsNullable(), layerId);
|
||||
_sprite.RemoveLayer(spriteEnt.AsNullable(), index);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddUndergarments(HumanoidAppearanceComponent humanoid, SpriteComponent sprite, bool undergarmentTop, bool undergarmentBottom)
|
||||
private void AddUndergarments(Entity<HumanoidAppearanceComponent, SpriteComponent> entity, bool undergarmentTop, bool undergarmentBottom)
|
||||
{
|
||||
var humanoid = entity.Comp1;
|
||||
|
||||
if (undergarmentTop && humanoid.UndergarmentTop != null)
|
||||
{
|
||||
var marking = new Marking(humanoid.UndergarmentTop, new List<Color> { new Color() });
|
||||
if (_markingManager.TryGetMarking(marking, out var prototype))
|
||||
{
|
||||
// Markings are added to ClientOldMarkings because otherwise it causes issues when toggling the feature on/off.
|
||||
humanoid.ClientOldMarkings.Markings.Add(MarkingCategories.UndergarmentTop, new List<Marking>{ marking });
|
||||
ApplyMarking(prototype, null, true, humanoid, sprite);
|
||||
humanoid.ClientOldMarkings.Markings.Add(MarkingCategories.UndergarmentTop, new List<Marking> { marking });
|
||||
ApplyMarking(prototype, null, true, entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,8 +331,8 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
var marking = new Marking(humanoid.UndergarmentBottom, new List<Color> { new Color() });
|
||||
if (_markingManager.TryGetMarking(marking, out var prototype))
|
||||
{
|
||||
humanoid.ClientOldMarkings.Markings.Add(MarkingCategories.UndergarmentBottom, new List<Marking>{ marking });
|
||||
ApplyMarking(prototype, null, true, humanoid, sprite);
|
||||
humanoid.ClientOldMarkings.Markings.Add(MarkingCategories.UndergarmentBottom, new List<Marking> { marking });
|
||||
ApplyMarking(prototype, null, true, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -323,10 +340,12 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
private void ApplyMarking(MarkingPrototype markingPrototype,
|
||||
IReadOnlyList<Color>? colors,
|
||||
bool visible,
|
||||
HumanoidAppearanceComponent humanoid,
|
||||
SpriteComponent sprite)
|
||||
Entity<HumanoidAppearanceComponent, SpriteComponent> entity)
|
||||
{
|
||||
if (!sprite.LayerMapTryGet(markingPrototype.BodyPart, out int targetLayer))
|
||||
var humanoid = entity.Comp1;
|
||||
var sprite = entity.Comp2;
|
||||
|
||||
if (!_sprite.LayerMapTryGet((entity.Owner, sprite), markingPrototype.BodyPart, out var targetLayer, false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -346,14 +365,14 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
|
||||
var layerId = $"{markingPrototype.ID}-{rsi.RsiState}";
|
||||
|
||||
if (!sprite.LayerMapTryGet(layerId, out _))
|
||||
if (!_sprite.LayerMapTryGet((entity.Owner, sprite), layerId, out _, false))
|
||||
{
|
||||
var layer = sprite.AddLayer(markingSprite, targetLayer + j + 1);
|
||||
sprite.LayerMapSet(layerId, layer);
|
||||
sprite.LayerSetSprite(layerId, rsi);
|
||||
var layer = _sprite.AddLayer((entity.Owner, sprite), markingSprite, targetLayer + j + 1);
|
||||
_sprite.LayerMapSet((entity.Owner, sprite), layerId, layer);
|
||||
_sprite.LayerSetSprite((entity.Owner, sprite), layerId, rsi);
|
||||
}
|
||||
|
||||
sprite.LayerSetVisible(layerId, visible);
|
||||
_sprite.LayerSetVisible((entity.Owner, sprite), layerId, visible);
|
||||
|
||||
if (!visible || setting == null) // this is kinda implied
|
||||
{
|
||||
@@ -365,16 +384,16 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
// So if that happens just default to white?
|
||||
if (colors != null && j < colors.Count)
|
||||
{
|
||||
sprite.LayerSetColor(layerId, colors[j]);
|
||||
_sprite.LayerSetColor((entity.Owner, sprite), layerId, colors[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetColor(layerId, Color.White);
|
||||
_sprite.LayerSetColor((entity.Owner, sprite), layerId, Color.White);
|
||||
}
|
||||
|
||||
if (humanoid.MarkingsDisplacement.TryGetValue(markingPrototype.BodyPart, out var displacementData) && markingPrototype.CanBeDisplaced)
|
||||
{
|
||||
_displacement.TryAddDisplacement(displacementData, sprite, targetLayer + j + 1, layerId, out _);
|
||||
_displacement.TryAddDisplacement(displacementData, (entity.Owner, sprite), targetLayer + j + 1, layerId, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -394,7 +413,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
if (!spriteInfo.MatchSkin)
|
||||
continue;
|
||||
|
||||
var index = sprite.LayerMapReserveBlank(layer);
|
||||
var index = _sprite.LayerMapReserve((uid, sprite), layer);
|
||||
sprite[index].Color = skinColor.WithAlpha(spriteInfo.LayerAlpha);
|
||||
}
|
||||
}
|
||||
@@ -409,11 +428,11 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
base.SetLayerVisibility(ent, layer, visible, slot, ref dirty);
|
||||
|
||||
var sprite = Comp<SpriteComponent>(ent);
|
||||
if (!sprite.LayerMapTryGet(layer, out var index))
|
||||
if (!_sprite.LayerMapTryGet((ent.Owner, sprite), layer, out var index, false))
|
||||
{
|
||||
if (!visible)
|
||||
return;
|
||||
index = sprite.LayerMapReserveBlank(layer);
|
||||
index = _sprite.LayerMapReserve((ent.Owner, sprite), layer);
|
||||
}
|
||||
|
||||
var spriteLayer = sprite[index];
|
||||
@@ -430,7 +449,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
||||
foreach (var marking in markingList)
|
||||
{
|
||||
if (_markingManager.TryGetMarking(marking, out var markingPrototype) && markingPrototype.BodyPart == layer)
|
||||
ApplyMarking(markingPrototype, marking.MarkingColors, marking.Visible, ent, sprite);
|
||||
ApplyMarking(markingPrototype, marking.MarkingColors, marking.Visible, (ent, ent.Comp, sprite));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,15 @@ public sealed partial class IconSmoothSystem
|
||||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
sprite.LayerSetOffset(EdgeLayer.South, new Vector2(0, -1f));
|
||||
sprite.LayerSetOffset(EdgeLayer.East, new Vector2(1f, 0f));
|
||||
sprite.LayerSetOffset(EdgeLayer.North, new Vector2(0, 1f));
|
||||
sprite.LayerSetOffset(EdgeLayer.West, new Vector2(-1f, 0f));
|
||||
_sprite.LayerSetOffset((uid, sprite), EdgeLayer.South, new Vector2(0, -1f));
|
||||
_sprite.LayerSetOffset((uid, sprite), EdgeLayer.East, new Vector2(1, 0f));
|
||||
_sprite.LayerSetOffset((uid, sprite), EdgeLayer.North, new Vector2(0, 1f));
|
||||
_sprite.LayerSetOffset((uid, sprite), EdgeLayer.West, new Vector2(-1, 0f));
|
||||
|
||||
sprite.LayerSetVisible(EdgeLayer.South, false);
|
||||
sprite.LayerSetVisible(EdgeLayer.East, false);
|
||||
sprite.LayerSetVisible(EdgeLayer.North, false);
|
||||
sprite.LayerSetVisible(EdgeLayer.West, false);
|
||||
_sprite.LayerSetVisible((uid, sprite), EdgeLayer.South, false);
|
||||
_sprite.LayerSetVisible((uid, sprite), EdgeLayer.East, false);
|
||||
_sprite.LayerSetVisible((uid, sprite), EdgeLayer.North, false);
|
||||
_sprite.LayerSetVisible((uid, sprite), EdgeLayer.West, false);
|
||||
}
|
||||
|
||||
private void OnEdgeShutdown(EntityUid uid, SmoothEdgeComponent component, ComponentShutdown args)
|
||||
@@ -35,10 +35,10 @@ public sealed partial class IconSmoothSystem
|
||||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
sprite.LayerMapRemove(EdgeLayer.South);
|
||||
sprite.LayerMapRemove(EdgeLayer.East);
|
||||
sprite.LayerMapRemove(EdgeLayer.North);
|
||||
sprite.LayerMapRemove(EdgeLayer.West);
|
||||
_sprite.LayerMapRemove((uid, sprite), EdgeLayer.South);
|
||||
_sprite.LayerMapRemove((uid, sprite), EdgeLayer.East);
|
||||
_sprite.LayerMapRemove((uid, sprite), EdgeLayer.North);
|
||||
_sprite.LayerMapRemove((uid, sprite), EdgeLayer.West);
|
||||
}
|
||||
|
||||
private void CalculateEdge(EntityUid uid, DirectionFlag directions, SpriteComponent? sprite = null, SmoothEdgeComponent? component = null)
|
||||
@@ -48,16 +48,16 @@ public sealed partial class IconSmoothSystem
|
||||
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
var dir = (DirectionFlag) Math.Pow(2, i);
|
||||
var dir = (DirectionFlag)Math.Pow(2, i);
|
||||
var edge = GetEdge(dir);
|
||||
|
||||
if ((dir & directions) != 0x0)
|
||||
{
|
||||
sprite.LayerSetVisible(edge, false);
|
||||
_sprite.LayerSetVisible((uid, sprite), edge, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
sprite.LayerSetVisible(edge, true);
|
||||
_sprite.LayerSetVisible((uid, sprite), edge, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Content.Client.IconSmoothing
|
||||
public sealed partial class IconSmoothSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private readonly Queue<EntityUid> _dirtyEntities = new();
|
||||
private readonly Queue<EntityUid> _anchorChangedEntities = new();
|
||||
@@ -57,7 +58,7 @@ namespace Content.Client.IconSmoothing
|
||||
if (component.Mode != IconSmoothingMode.Corners || !TryComp(uid, out SpriteComponent? sprite))
|
||||
return;
|
||||
|
||||
SetCornerLayers(sprite, component);
|
||||
SetCornerLayers((uid, sprite), component);
|
||||
|
||||
if (component.Shader != null)
|
||||
{
|
||||
@@ -74,25 +75,25 @@ namespace Content.Client.IconSmoothing
|
||||
return;
|
||||
|
||||
component.StateBase = newState;
|
||||
SetCornerLayers(sprite, component);
|
||||
SetCornerLayers((uid, sprite), component);
|
||||
}
|
||||
|
||||
private void SetCornerLayers(SpriteComponent sprite, IconSmoothComponent component)
|
||||
private void SetCornerLayers(Entity<SpriteComponent?> sprite, IconSmoothComponent component)
|
||||
{
|
||||
sprite.LayerMapRemove(CornerLayers.SE);
|
||||
sprite.LayerMapRemove(CornerLayers.NE);
|
||||
sprite.LayerMapRemove(CornerLayers.NW);
|
||||
sprite.LayerMapRemove(CornerLayers.SW);
|
||||
_sprite.LayerMapRemove(sprite, CornerLayers.SE);
|
||||
_sprite.LayerMapRemove(sprite, CornerLayers.NE);
|
||||
_sprite.LayerMapRemove(sprite, CornerLayers.NW);
|
||||
_sprite.LayerMapRemove(sprite, CornerLayers.SW);
|
||||
|
||||
var state0 = $"{component.StateBase}0";
|
||||
sprite.LayerMapSet(CornerLayers.SE, sprite.AddLayerState(state0));
|
||||
sprite.LayerSetDirOffset(CornerLayers.SE, DirectionOffset.None);
|
||||
sprite.LayerMapSet(CornerLayers.NE, sprite.AddLayerState(state0));
|
||||
sprite.LayerSetDirOffset(CornerLayers.NE, DirectionOffset.CounterClockwise);
|
||||
sprite.LayerMapSet(CornerLayers.NW, sprite.AddLayerState(state0));
|
||||
sprite.LayerSetDirOffset(CornerLayers.NW, DirectionOffset.Flip);
|
||||
sprite.LayerMapSet(CornerLayers.SW, sprite.AddLayerState(state0));
|
||||
sprite.LayerSetDirOffset(CornerLayers.SW, DirectionOffset.Clockwise);
|
||||
_sprite.LayerMapSet(sprite, CornerLayers.SE, _sprite.AddRsiLayer(sprite, state0));
|
||||
_sprite.LayerSetDirOffset(sprite, CornerLayers.SE, DirectionOffset.None);
|
||||
_sprite.LayerMapSet(sprite, CornerLayers.NE, _sprite.AddRsiLayer(sprite, state0));
|
||||
_sprite.LayerSetDirOffset(sprite, CornerLayers.NE, DirectionOffset.CounterClockwise);
|
||||
_sprite.LayerMapSet(sprite, CornerLayers.NW, _sprite.AddRsiLayer(sprite, state0));
|
||||
_sprite.LayerSetDirOffset(sprite, CornerLayers.NW, DirectionOffset.Flip);
|
||||
_sprite.LayerMapSet(sprite, CornerLayers.SW, _sprite.AddRsiLayer(sprite, state0));
|
||||
_sprite.LayerSetDirOffset(sprite, CornerLayers.SW, DirectionOffset.Clockwise);
|
||||
}
|
||||
|
||||
private void OnShutdown(EntityUid uid, IconSmoothComponent component, ComponentShutdown args)
|
||||
@@ -298,7 +299,7 @@ namespace Content.Client.IconSmoothing
|
||||
{
|
||||
if (gridEntity == null)
|
||||
{
|
||||
sprite.Comp.LayerSetState(0, $"{smooth.StateBase}0");
|
||||
_sprite.LayerSetRsiState(sprite.AsNullable(), 0, $"{smooth.StateBase}0");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -324,11 +325,11 @@ namespace Content.Client.IconSmoothing
|
||||
|
||||
if (matching)
|
||||
{
|
||||
sprite.Comp.LayerSetState(0, $"{smooth.StateBase}1");
|
||||
_sprite.LayerSetRsiState(sprite.AsNullable(), 0, $"{smooth.StateBase}1");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.Comp.LayerSetState(0, $"{smooth.StateBase}0");
|
||||
_sprite.LayerSetRsiState(sprite.AsNullable(), 0, $"{smooth.StateBase}0");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,7 +339,7 @@ namespace Content.Client.IconSmoothing
|
||||
|
||||
if (gridEntity == null)
|
||||
{
|
||||
sprite.Comp.LayerSetState(0, $"{smooth.StateBase}{(int)dirs}");
|
||||
_sprite.LayerSetRsiState(sprite.AsNullable(), 0, $"{smooth.StateBase}{(int)dirs}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -355,7 +356,7 @@ namespace Content.Client.IconSmoothing
|
||||
if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.West)), smoothQuery))
|
||||
dirs |= CardinalConnectDirs.West;
|
||||
|
||||
sprite.Comp.LayerSetState(0, $"{smooth.StateBase}{(int)dirs}");
|
||||
_sprite.LayerSetRsiState(sprite.AsNullable(), 0, $"{smooth.StateBase}{(int)dirs}");
|
||||
|
||||
var directions = DirectionFlag.None;
|
||||
|
||||
@@ -399,10 +400,10 @@ namespace Content.Client.IconSmoothing
|
||||
// At the very least each event currently only queues a sprite for updating.
|
||||
// Oh god sprite component is a mess.
|
||||
var sprite = spriteEnt.Comp;
|
||||
sprite.LayerSetState(CornerLayers.NE, $"{smooth.StateBase}{(int)cornerNE}");
|
||||
sprite.LayerSetState(CornerLayers.SE, $"{smooth.StateBase}{(int)cornerSE}");
|
||||
sprite.LayerSetState(CornerLayers.SW, $"{smooth.StateBase}{(int)cornerSW}");
|
||||
sprite.LayerSetState(CornerLayers.NW, $"{smooth.StateBase}{(int)cornerNW}");
|
||||
_sprite.LayerSetRsiState(spriteEnt.AsNullable(), CornerLayers.NE, $"{smooth.StateBase}{(int)cornerNE}");
|
||||
_sprite.LayerSetRsiState(spriteEnt.AsNullable(), CornerLayers.SE, $"{smooth.StateBase}{(int)cornerSE}");
|
||||
_sprite.LayerSetRsiState(spriteEnt.AsNullable(), CornerLayers.SW, $"{smooth.StateBase}{(int)cornerSW}");
|
||||
_sprite.LayerSetRsiState(spriteEnt.AsNullable(), CornerLayers.NW, $"{smooth.StateBase}{(int)cornerNW}");
|
||||
|
||||
var directions = DirectionFlag.None;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user