diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6365488e05d..264c91a444d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # Last match in file takes precedence. # Ping for all PRs -* @thefuckmybrain # Vanilla-edit +# * @thefuckmybrain diff --git a/.github/workflows/build-test-debug.yml b/.github/workflows/build-test-debug.yml index bc1acbf2bb4..d96763baeca 100644 --- a/.github/workflows/build-test-debug.yml +++ b/.github/workflows/build-test-debug.yml @@ -45,13 +45,23 @@ jobs: run: dotnet build --configuration DebugOpt --no-restore /m - name: Run Content.Tests - run: dotnet test --no-build --configuration DebugOpt Content.Tests/Content.Tests.csproj -- NUnit.ConsoleOut=0 + shell: pwsh + run: dotnet test --no-build --configuration DebugOpt Content.Tests/Content.Tests.csproj -- NUnit.ConsoleOut=0 NUnit.TestOutputXml="logs" NUnit.WorkDirectory="$(pwd)/test_results" - name: Run Content.IntegrationTests shell: pwsh run: | $env:DOTNET_gcServer=1 - dotnet test --no-build --configuration DebugOpt Content.IntegrationTests/Content.IntegrationTests.csproj -- NUnit.ConsoleOut=0 NUnit.MapWarningTo=Failed + dotnet test --no-build --configuration DebugOpt Content.IntegrationTests/Content.IntegrationTests.csproj -- NUnit.ConsoleOut=0 NUnit.MapWarningTo=Failed NUnit.TestOutputXml="logs" NUnit.WorkDirectory="$(pwd)/test_results" + + - name: Archive NUnit3 test results. + if: always() + uses: actions/upload-artifact@v4 + with: + name: nunit3-results-${{ matrix.os }} + path: test_results/* + retention-days: 7 + compression-level: 9 ci-success: name: Build & Test Debug needs: diff --git a/.gitignore b/.gitignore index 7ab04d0c843..dc55b0bdd39 100644 --- a/.gitignore +++ b/.gitignore @@ -316,3 +316,6 @@ Resources/MapImages # Direnv stuff .direnv/ + +# C# Dev Kit cache file +*.lscache diff --git a/Content.Benchmarks/ComponentQueryBenchmark.cs b/Content.Benchmarks/ComponentQueryBenchmark.cs index bfe367790a6..c9aebf7ba36 100644 --- a/Content.Benchmarks/ComponentQueryBenchmark.cs +++ b/Content.Benchmarks/ComponentQueryBenchmark.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.IO; using System.Runtime.CompilerServices; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; @@ -44,7 +45,7 @@ public void Setup() ProgramShared.PathOffset = "../../../../"; PoolManager.Startup(typeof(QueryBenchSystem).Assembly); - _pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); + _pair = PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)).GetAwaiter().GetResult(); _entMan = _pair.Server.ResolveDependency(); _itemQuery = _entMan.GetEntityQuery(); diff --git a/Content.Benchmarks/Content.Benchmarks.csproj b/Content.Benchmarks/Content.Benchmarks.csproj index 8d4dfa31bd6..dd0b760f4ad 100644 --- a/Content.Benchmarks/Content.Benchmarks.csproj +++ b/Content.Benchmarks/Content.Benchmarks.csproj @@ -7,6 +7,7 @@ true false disable + $(DefineConstants);ALLOW_BAD_PRACTICES diff --git a/Content.Benchmarks/DeltaPressureBenchmark.cs b/Content.Benchmarks/DeltaPressureBenchmark.cs index b31b3ed1a24..f4ae62a4652 100644 --- a/Content.Benchmarks/DeltaPressureBenchmark.cs +++ b/Content.Benchmarks/DeltaPressureBenchmark.cs @@ -1,11 +1,11 @@ +using System.IO; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Diagnosers; using Content.IntegrationTests; using Content.IntegrationTests.Pair; -using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; using Content.Shared.CCVar; using Robust.Shared; using Robust.Shared.Analyzers; @@ -32,7 +32,7 @@ public class DeltaPressureBenchmark /// /// Number of entities (windows, really) to spawn with a . /// - [Params(1, 10, 100, 1000, 5000, 10000, 50000, 100000)] + [Params(100, 1000, 5000, 10000)] public int EntityCount; /// @@ -69,7 +69,7 @@ public async Task SetupAsync() { ProgramShared.PathOffset = "../../../../"; PoolManager.Startup(); - _pair = await PoolManager.GetServerClient(); + _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)); var server = _pair.Server; var mapdata = await _pair.CreateTestMap(); diff --git a/Content.Benchmarks/DependencyInjectBenchmark.cs b/Content.Benchmarks/DependencyInjectBenchmark.cs index 06bd45fe3f2..b7c4a9de74f 100644 --- a/Content.Benchmarks/DependencyInjectBenchmark.cs +++ b/Content.Benchmarks/DependencyInjectBenchmark.cs @@ -59,11 +59,11 @@ private sealed class X5 { } private sealed class TestDummy { - [Dependency] private readonly X1 _x1; - [Dependency] private readonly X2 _x2; - [Dependency] private readonly X3 _x3; - [Dependency] private readonly X4 _x4; - [Dependency] private readonly X5 _x5; + [Dependency] private X1 _x1; + [Dependency] private X2 _x2; + [Dependency] private X3 _x3; + [Dependency] private X4 _x4; + [Dependency] private X5 _x5; } } } diff --git a/Content.Benchmarks/DestructibleBenchmark.cs b/Content.Benchmarks/DestructibleBenchmark.cs index aa759c35fc6..58c834c0aef 100644 --- a/Content.Benchmarks/DestructibleBenchmark.cs +++ b/Content.Benchmarks/DestructibleBenchmark.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Content.IntegrationTests; @@ -69,7 +70,7 @@ public async Task SetupAsync() { ProgramShared.PathOffset = "../../../../"; PoolManager.Startup(); - _pair = await PoolManager.GetServerClient(); + _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)); var server = _pair.Server; _entMan = server.ResolveDependency(); diff --git a/Content.Benchmarks/DeviceNetworkingBenchmark.cs b/Content.Benchmarks/DeviceNetworkingBenchmark.cs index bb2a22312ea..fcde4feb646 100644 --- a/Content.Benchmarks/DeviceNetworkingBenchmark.cs +++ b/Content.Benchmarks/DeviceNetworkingBenchmark.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Content.IntegrationTests; @@ -60,7 +61,7 @@ public async Task SetupAsync() { ProgramShared.PathOffset = "../../../../"; PoolManager.Startup(typeof(DeviceNetworkingBenchmark).Assembly); - _pair = await PoolManager.GetServerClient(); + _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)); var server = _pair.Server; await server.WaitPost(() => diff --git a/Content.Benchmarks/GasReactionBenchmark.cs b/Content.Benchmarks/GasReactionBenchmark.cs index 9ed30373d1c..f2988693663 100644 --- a/Content.Benchmarks/GasReactionBenchmark.cs +++ b/Content.Benchmarks/GasReactionBenchmark.cs @@ -1,3 +1,4 @@ +using System.IO; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Content.IntegrationTests; @@ -51,7 +52,7 @@ public async Task SetupAsync() { ProgramShared.PathOffset = "../../../../"; PoolManager.Startup(); - _pair = await PoolManager.GetServerClient(); + _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)); var server = _pair.Server; // Create test map and grid diff --git a/Content.Benchmarks/HeatCapacityBenchmark.cs b/Content.Benchmarks/HeatCapacityBenchmark.cs index cef5bc10c7f..18366306d7a 100644 --- a/Content.Benchmarks/HeatCapacityBenchmark.cs +++ b/Content.Benchmarks/HeatCapacityBenchmark.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.IO; +using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Content.IntegrationTests; using Content.IntegrationTests.Pair; @@ -27,7 +28,7 @@ public async Task SetupAsync() { ProgramShared.PathOffset = "../../../../"; PoolManager.Startup(); - _pair = await PoolManager.GetServerClient(); + _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)); await _pair.Connect(); _cEntMan = _pair.Client.ResolveDependency(); _sEntMan = _pair.Server.ResolveDependency(); diff --git a/Content.Benchmarks/MapLoadBenchmark.cs b/Content.Benchmarks/MapLoadBenchmark.cs index 09bcf258384..02cfc30ebf2 100644 --- a/Content.Benchmarks/MapLoadBenchmark.cs +++ b/Content.Benchmarks/MapLoadBenchmark.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; @@ -29,7 +30,7 @@ public void Setup() ProgramShared.PathOffset = "../../../../"; PoolManager.Startup(); - _pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); + _pair = PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)).GetAwaiter().GetResult(); var server = _pair.Server; Paths = server.ResolveDependency() diff --git a/Content.Benchmarks/PvsBenchmark.cs b/Content.Benchmarks/PvsBenchmark.cs index 51a013539e0..af1ec8d9efc 100644 --- a/Content.Benchmarks/PvsBenchmark.cs +++ b/Content.Benchmarks/PvsBenchmark.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.IO; using System.Linq; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; @@ -50,7 +51,7 @@ public void Setup() #endif PoolManager.Startup(); - _pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); + _pair = PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)).GetAwaiter().GetResult(); _entMan = _pair.Server.ResolveDependency(); _pair.Server.CfgMan.SetCVar(CVars.NetPVS, true); _pair.Server.CfgMan.SetCVar(CVars.ThreadParallelCount, 0); diff --git a/Content.Benchmarks/RaiseEventBenchmark.cs b/Content.Benchmarks/RaiseEventBenchmark.cs index e3d377ccb3e..99e032d0b58 100644 --- a/Content.Benchmarks/RaiseEventBenchmark.cs +++ b/Content.Benchmarks/RaiseEventBenchmark.cs @@ -1,4 +1,5 @@ #nullable enable +using System.IO; using System.Runtime.CompilerServices; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; @@ -21,7 +22,7 @@ public void Setup() { ProgramShared.PathOffset = "../../../../"; PoolManager.Startup(typeof(BenchSystem).Assembly); - _pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); + _pair = PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)).GetAwaiter().GetResult(); var entMan = _pair.Server.EntMan; var fact = _pair.Server.ResolveDependency(); var bus = (EntityEventBus)entMan.EventBus; diff --git a/Content.Benchmarks/SpawnEquipDeleteBenchmark.cs b/Content.Benchmarks/SpawnEquipDeleteBenchmark.cs index 9b878eac40c..b6d5427480c 100644 --- a/Content.Benchmarks/SpawnEquipDeleteBenchmark.cs +++ b/Content.Benchmarks/SpawnEquipDeleteBenchmark.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.IO; +using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Content.IntegrationTests; using Content.IntegrationTests.Pair; @@ -36,7 +37,7 @@ public async Task SetupAsync() { ProgramShared.PathOffset = "../../../../"; PoolManager.Startup(); - _pair = await PoolManager.GetServerClient(); + _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)); var server = _pair.Server; var mapData = await _pair.CreateTestMap(); diff --git a/Content.Client/Access/Commands/ShowAccessReadersCommand.cs b/Content.Client/Access/Commands/ShowAccessReadersCommand.cs index e26cca0fc26..f471975ba36 100644 --- a/Content.Client/Access/Commands/ShowAccessReadersCommand.cs +++ b/Content.Client/Access/Commands/ShowAccessReadersCommand.cs @@ -4,11 +4,11 @@ namespace Content.Client.Access.Commands; -public sealed class ShowAccessReadersCommand : LocalizedEntityCommands +public sealed partial class ShowAccessReadersCommand : LocalizedEntityCommands { - [Dependency] private readonly IOverlayManager _overlay = default!; - [Dependency] private readonly IResourceCache _cache = default!; - [Dependency] private readonly SharedTransformSystem _xform = default!; + [Dependency] private IOverlayManager _overlay = default!; + [Dependency] private IResourceCache _cache = default!; + [Dependency] private SharedTransformSystem _xform = default!; public override string Command => "showaccessreaders"; diff --git a/Content.Client/Access/Systems/JobStatusSystem.cs b/Content.Client/Access/Systems/JobStatusSystem.cs index 8327a6c198d..e651bfdb70d 100644 --- a/Content.Client/Access/Systems/JobStatusSystem.cs +++ b/Content.Client/Access/Systems/JobStatusSystem.cs @@ -6,11 +6,11 @@ namespace Content.Client.Access.Systems; -public sealed class JobStatusSystem : SharedJobStatusSystem +public sealed partial class JobStatusSystem : SharedJobStatusSystem { - [Dependency] private readonly ShowJobIconsSystem _showJobIcons = default!; - [Dependency] private readonly ShowCrewIconsSystem _showCrewIcons = default!; - [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private ShowJobIconsSystem _showJobIcons = default!; + [Dependency] private ShowCrewIconsSystem _showCrewIcons = default!; + [Dependency] private IPrototypeManager _prototype = default!; private static readonly ProtoId CrewBorderIcon = "CrewBorderIcon"; private static readonly ProtoId CrewUncertainBorderIcon = "CrewUncertainBorderIcon"; diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml.cs b/Content.Client/Access/UI/AccessLevelControl.xaml.cs index 12487b2e5ce..76edee84323 100644 --- a/Content.Client/Access/UI/AccessLevelControl.xaml.cs +++ b/Content.Client/Access/UI/AccessLevelControl.xaml.cs @@ -12,7 +12,7 @@ namespace Content.Client.Access.UI; [GenerateTypedNameReferences] public sealed partial class AccessLevelControl : GridContainer { - [Dependency] private readonly ILogManager _logManager = default!; + [Dependency] private ILogManager _logManager = default!; private ISawmill _sawmill = default!; diff --git a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs index d80c600c03e..c93715ad23f 100644 --- a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs +++ b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs @@ -8,9 +8,9 @@ namespace Content.Client.Access.UI { - public sealed class AccessOverriderBoundUserInterface : BoundUserInterface + public sealed partial class AccessOverriderBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; private readonly SharedAccessOverriderSystem _accessOverriderSystem = default!; private AccessOverriderWindow? _window; diff --git a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs index 2b8ebf53b75..6a1255d2d8b 100644 --- a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs +++ b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs @@ -15,8 +15,8 @@ namespace Content.Client.Access.UI [GenerateTypedNameReferences] public sealed partial class AgentIDCardWindow : DefaultWindow { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IEntitySystemManager _entitySystem = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private IEntitySystemManager _entitySystem = default!; private readonly SpriteSystem _spriteSystem; private const int JobIconColumnCount = 10; diff --git a/Content.Client/Access/UI/GroupedAccessLevelChecklist.xaml.cs b/Content.Client/Access/UI/GroupedAccessLevelChecklist.xaml.cs index 2a85530c482..0a25e35cd4f 100644 --- a/Content.Client/Access/UI/GroupedAccessLevelChecklist.xaml.cs +++ b/Content.Client/Access/UI/GroupedAccessLevelChecklist.xaml.cs @@ -17,7 +17,7 @@ public sealed partial class GroupedAccessLevelChecklist : BoxContainer { private static readonly ProtoId GeneralAccessGroup = "General"; - [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private IPrototypeManager _protoManager = default!; private bool _isMonotone; private string? _labelStyleClass; diff --git a/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs b/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs index 801140f5172..3a53b85339a 100644 --- a/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs +++ b/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs @@ -1,34 +1,24 @@ 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 Content.Shared.Roles; -using Robust.Shared.Configuration; using Robust.Shared.Prototypes; using static Content.Shared.Access.Components.IdCardConsoleComponent; namespace Content.Client.Access.UI { - public sealed class IdCardConsoleBoundUserInterface : BoundUserInterface + public sealed partial class IdCardConsoleBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IConfigurationManager _cfgManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = 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(); - - _maxNameLength =_cfgManager.GetCVar(CCVars.MaxNameLength); - _maxIdJobLength = _cfgManager.GetCVar(CCVars.MaxIdJobLength); } protected override void Open() @@ -75,14 +65,8 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); } - public void SubmitData(string newFullName, string newJobTitle, List> newAccessList, ProtoId newJobPrototype) + public void SubmitData(string newFullName, string newJobTitle, List> newAccessList, ProtoId? newJobPrototype) { - if (newFullName.Length > _maxNameLength) - newFullName = newFullName[.._maxNameLength]; - - if (newJobTitle.Length > _maxIdJobLength) - newJobTitle = newJobTitle[.._maxIdJobLength]; - SendMessage(new WriteToTargetIdMessage( newFullName, newJobTitle, diff --git a/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs b/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs index 29f0c287560..161ec91f1a8 100644 --- a/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs +++ b/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs @@ -16,17 +16,13 @@ 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!; + [Dependency] private IConfigurationManager _cfgManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private 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 _jobPrototypeIds = new(); @@ -46,11 +42,8 @@ public IdCardConsoleWindow(IdCardConsoleBoundUserInterface owner, IPrototypeMana _owner = owner; - _maxNameLength = _cfgManager.GetCVar(CCVars.MaxNameLength); - _maxIdJobLength = _cfgManager.GetCVar(CCVars.MaxIdJobLength); - FullNameLineEdit.OnTextEntered += _ => SubmitData(); - FullNameLineEdit.IsValid = s => s.Length <= _maxNameLength; + FullNameLineEdit.IsValid = s => s.Length <= _cfgManager.GetCVar(CCVars.MaxNameLength); FullNameLineEdit.OnTextChanged += _ => { FullNameSaveButton.Disabled = FullNameSaveButton.Text == _lastFullName; @@ -58,7 +51,7 @@ public IdCardConsoleWindow(IdCardConsoleBoundUserInterface owner, IPrototypeMana FullNameSaveButton.OnPressed += _ => SubmitData(); JobTitleLineEdit.OnTextEntered += _ => SubmitData(); - JobTitleLineEdit.IsValid = s => s.Length <= _maxIdJobLength; + JobTitleLineEdit.IsValid = s => s.Length <= _cfgManager.GetCVar(CCVars.MaxIdJobLength); JobTitleLineEdit.OnTextChanged += _ => { JobTitleSaveButton.Disabled = JobTitleLineEdit.Text == _lastJobTitle; @@ -223,7 +216,7 @@ private void SubmitData() JobTitleLineEdit.Text, // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair _accessButtons.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList(), - jobProtoDirty ? _jobPrototypeIds[JobPresetOptionButton.SelectedId] : string.Empty); + jobProtoDirty ? _jobPrototypeIds[JobPresetOptionButton.SelectedId] : null); } } } diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index 49d90dedaf5..90cf4190f2d 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -24,16 +24,16 @@ namespace Content.Client.Actions { [UsedImplicitly] - public sealed class ActionsSystem : SharedActionsSystem + public sealed partial class ActionsSystem : SharedActionsSystem { public delegate void OnActionReplaced(EntityUid actionId); - [Dependency] private readonly SharedChargesSystem _sharedCharges = default!; - [Dependency] private readonly IPlayerManager _playerManager = default!; - [Dependency] private readonly IPrototypeManager _proto = default!; - [Dependency] private readonly IResourceManager _resources = default!; - [Dependency] private readonly MetaDataSystem _metaData = default!; - [Dependency] private readonly ISerializationManager _serialization = default!; + [Dependency] private SharedChargesSystem _sharedCharges = default!; + [Dependency] private IPlayerManager _playerManager = default!; + [Dependency] private IPrototypeManager _proto = default!; + [Dependency] private IResourceManager _resources = default!; + [Dependency] private MetaDataSystem _metaData = default!; + [Dependency] private ISerializationManager _serialization = default!; public event Action? OnActionAdded; public event Action? OnActionRemoved; @@ -262,7 +262,7 @@ public void LoadActionAssignments(string path, bool userData) SetIcon(actionId, new SpriteSpecifier.EntityPrototype(id)); SetEvent(actionId, new StartPlacementActionEvent() { - PlacementOption = "SnapgridCenter", + PlacementOption = proto.PlacementMode, EntityType = id }); _metaData.SetEntityName(actionId, proto.Name); diff --git a/Content.Client/Administration/Managers/ClientAdminManager.cs b/Content.Client/Administration/Managers/ClientAdminManager.cs index 3f072691de6..3abff217f64 100644 --- a/Content.Client/Administration/Managers/ClientAdminManager.cs +++ b/Content.Client/Administration/Managers/ClientAdminManager.cs @@ -10,15 +10,15 @@ namespace Content.Client.Administration.Managers { - public sealed class ClientAdminManager : IClientAdminManager, IClientConGroupImplementation, IPostInjectInit, ISharedAdminManager + public sealed partial class ClientAdminManager : IClientAdminManager, IClientConGroupImplementation, IPostInjectInit, ISharedAdminManager { - [Dependency] private readonly IPlayerManager _player = default!; - [Dependency] private readonly IClientNetManager _netMgr = default!; - [Dependency] private readonly IClientConGroupController _conGroup = default!; - [Dependency] private readonly IClientConsoleHost _host = default!; - [Dependency] private readonly IResourceManager _res = default!; - [Dependency] private readonly ILogManager _logManager = default!; - [Dependency] private readonly IUserInterfaceManager _userInterface = default!; + [Dependency] private IPlayerManager _player = default!; + [Dependency] private IClientNetManager _netMgr = default!; + [Dependency] private IClientConGroupController _conGroup = default!; + [Dependency] private IClientConsoleHost _host = default!; + [Dependency] private IResourceManager _res = default!; + [Dependency] private ILogManager _logManager = default!; + [Dependency] private IUserInterfaceManager _userInterface = default!; private AdminData? _adminData; private readonly HashSet _availableCommands = new(); diff --git a/Content.Client/Administration/Systems/AdminSystem.Overlay.cs b/Content.Client/Administration/Systems/AdminSystem.Overlay.cs index e000bdc0ba0..a07abae90ce 100644 --- a/Content.Client/Administration/Systems/AdminSystem.Overlay.cs +++ b/Content.Client/Administration/Systems/AdminSystem.Overlay.cs @@ -10,15 +10,15 @@ namespace Content.Client.Administration.Systems { public sealed partial class AdminSystem { - [Dependency] private readonly IOverlayManager _overlayManager = default!; - [Dependency] private readonly IResourceCache _resourceCache = default!; - [Dependency] private readonly IClientAdminManager _adminManager = default!; - [Dependency] private readonly IEyeManager _eyeManager = default!; - [Dependency] private readonly EntityLookupSystem _entityLookup = default!; - [Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!; - [Dependency] private readonly IConfigurationManager _configurationManager = default!; - [Dependency] private readonly SharedRoleSystem _roles = default!; - [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private IOverlayManager _overlayManager = default!; + [Dependency] private IResourceCache _resourceCache = default!; + [Dependency] private IClientAdminManager _adminManager = default!; + [Dependency] private IEyeManager _eyeManager = default!; + [Dependency] private EntityLookupSystem _entityLookup = default!; + [Dependency] private IUserInterfaceManager _userInterfaceManager = default!; + [Dependency] private IConfigurationManager _configurationManager = default!; + [Dependency] private SharedRoleSystem _roles = default!; + [Dependency] private IPrototypeManager _proto = default!; private AdminNameOverlay _adminNameOverlay = default!; diff --git a/Content.Client/Administration/Systems/AdminVerbSystem.cs b/Content.Client/Administration/Systems/AdminVerbSystem.cs index 1e15186706c..33141c43cf9 100644 --- a/Content.Client/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Client/Administration/Systems/AdminVerbSystem.cs @@ -10,11 +10,11 @@ namespace Content.Client.Administration.Systems /// /// Client-side admin verb system. These usually open some sort of UIs. /// - sealed class AdminVerbSystem : EntitySystem + sealed partial class AdminVerbSystem : EntitySystem { - [Dependency] private readonly IClientConGroupController _clientConGroupController = default!; - [Dependency] private readonly IClientConsoleHost _clientConsoleHost = default!; - [Dependency] private readonly ISharedAdminManager _admin = default!; + [Dependency] private IClientConGroupController _clientConGroupController = default!; + [Dependency] private IClientConsoleHost _clientConsoleHost = default!; + [Dependency] private ISharedAdminManager _admin = default!; public override void Initialize() { diff --git a/Content.Client/Administration/Systems/BwoinkSystem.cs b/Content.Client/Administration/Systems/BwoinkSystem.cs index 7adf0069b21..70c04f77fb9 100644 --- a/Content.Client/Administration/Systems/BwoinkSystem.cs +++ b/Content.Client/Administration/Systems/BwoinkSystem.cs @@ -7,9 +7,9 @@ namespace Content.Client.Administration.Systems { [UsedImplicitly] - public sealed class BwoinkSystem : SharedBwoinkSystem + public sealed partial class BwoinkSystem : SharedBwoinkSystem { - [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private IGameTiming _timing = default!; public event EventHandler? OnBwoinkTextMessageRecieved; private (TimeSpan Timestamp, bool Typing) _lastTypingUpdateSent; diff --git a/Content.Client/Administration/Systems/KillSignSystem.cs b/Content.Client/Administration/Systems/KillSignSystem.cs index f17c384c1e9..8ed28914681 100644 --- a/Content.Client/Administration/Systems/KillSignSystem.cs +++ b/Content.Client/Administration/Systems/KillSignSystem.cs @@ -5,10 +5,10 @@ namespace Content.Client.Administration.Systems; -public sealed class KillSignSystem : EntitySystem +public sealed partial class KillSignSystem : EntitySystem { - [Dependency] private readonly SpriteSystem _sprite = default!; - [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private SpriteSystem _sprite = default!; + [Dependency] private IPlayerManager _player = default!; public override void Initialize() { diff --git a/Content.Client/Administration/UI/AdminAnnounceWindow.xaml.cs b/Content.Client/Administration/UI/AdminAnnounceWindow.xaml.cs index 5156b7f3c1f..7120550c828 100644 --- a/Content.Client/Administration/UI/AdminAnnounceWindow.xaml.cs +++ b/Content.Client/Administration/UI/AdminAnnounceWindow.xaml.cs @@ -11,7 +11,7 @@ namespace Content.Client.Administration.UI [GenerateTypedNameReferences] public sealed partial class AdminAnnounceWindow : DefaultWindow { - [Dependency] private readonly ILocalizationManager _localization = default!; + [Dependency] private ILocalizationManager _localization = default!; public AdminAnnounceWindow() { diff --git a/Content.Client/Administration/UI/AdminCamera/AdminCameraControl.xaml.cs b/Content.Client/Administration/UI/AdminCamera/AdminCameraControl.xaml.cs index beb8344ce35..147c959b7cd 100644 --- a/Content.Client/Administration/UI/AdminCamera/AdminCameraControl.xaml.cs +++ b/Content.Client/Administration/UI/AdminCamera/AdminCameraControl.xaml.cs @@ -13,8 +13,8 @@ namespace Content.Client.Administration.UI.AdminCamera; [GenerateTypedNameReferences] public sealed partial class AdminCameraControl : Control { - [Dependency] private readonly IEntityManager _entManager = default!; - [Dependency] private readonly IClientGameTiming _timing = default!; + [Dependency] private IEntityManager _entManager = default!; + [Dependency] private IClientGameTiming _timing = default!; public event Action? OnFollow; public event Action? OnPopoutControl; diff --git a/Content.Client/Administration/UI/AdminRemarks/AdminMessagePopupWindow.xaml.cs b/Content.Client/Administration/UI/AdminRemarks/AdminMessagePopupWindow.xaml.cs index 7870dae7b2a..b88bd1728f2 100644 --- a/Content.Client/Administration/UI/AdminRemarks/AdminMessagePopupWindow.xaml.cs +++ b/Content.Client/Administration/UI/AdminRemarks/AdminMessagePopupWindow.xaml.cs @@ -12,7 +12,7 @@ namespace Content.Client.Administration.UI.AdminRemarks; [GenerateTypedNameReferences] public sealed partial class AdminMessagePopupWindow : Control { - [Dependency] private readonly IStylesheetManager _styleMan = default!; + [Dependency] private IStylesheetManager _styleMan = default!; private float _timer = float.MaxValue; diff --git a/Content.Client/Administration/UI/AdminRemarks/AdminRemarksWindow.xaml.cs b/Content.Client/Administration/UI/AdminRemarks/AdminRemarksWindow.xaml.cs index ae77ad68cbb..98333951f54 100644 --- a/Content.Client/Administration/UI/AdminRemarks/AdminRemarksWindow.xaml.cs +++ b/Content.Client/Administration/UI/AdminRemarks/AdminRemarksWindow.xaml.cs @@ -12,7 +12,7 @@ namespace Content.Client.Administration.UI.AdminRemarks; [GenerateTypedNameReferences] public sealed partial class AdminRemarksWindow : FancyWindow { - [Dependency] private readonly IEntitySystemManager _entitySystem = default!; + [Dependency] private IEntitySystemManager _entitySystem = default!; private readonly SpriteSystem _sprites; private readonly Dictionary<(int, NoteType), AdminNotesLine> _inputs = new(); diff --git a/Content.Client/Administration/UI/BanList/BanListEui.cs b/Content.Client/Administration/UI/BanList/BanListEui.cs index 00b27cd173f..ff20e6fa89a 100644 --- a/Content.Client/Administration/UI/BanList/BanListEui.cs +++ b/Content.Client/Administration/UI/BanList/BanListEui.cs @@ -11,9 +11,9 @@ namespace Content.Client.Administration.UI.BanList; [UsedImplicitly] -public sealed class BanListEui : BaseEui +public sealed partial class BanListEui : BaseEui { - [Dependency] private readonly IUserInterfaceManager _ui = default!; + [Dependency] private IUserInterfaceManager _ui = default!; private BanListIdsPopup? _popup; diff --git a/Content.Client/Administration/UI/BanPanel/BanPanel.xaml.cs b/Content.Client/Administration/UI/BanPanel/BanPanel.xaml.cs index cb2839f5d02..130164cf8e6 100644 --- a/Content.Client/Administration/UI/BanPanel/BanPanel.xaml.cs +++ b/Content.Client/Administration/UI/BanPanel/BanPanel.xaml.cs @@ -40,11 +40,11 @@ public sealed partial class BanPanel : DefaultWindow private readonly Dictionary> _roleCheckboxes = new(); private readonly ISawmill _banPanelSawmill; - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly ILogManager _logManager = default!; - [Dependency] private readonly IEntityManager _entMan = default!; - [Dependency] private readonly IPrototypeManager _protoMan = default!; + [Dependency] private IGameTiming _gameTiming = default!; + [Dependency] private IConfigurationManager _cfg = default!; + [Dependency] private ILogManager _logManager = default!; + [Dependency] private IEntityManager _entMan = default!; + [Dependency] private IPrototypeManager _protoMan = default!; private const string ExpandedArrow = "▼"; private const string ContractedArrow = "▶"; diff --git a/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs b/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs index 6ff07f6cbde..369af1d53fe 100644 --- a/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs +++ b/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs @@ -22,10 +22,10 @@ namespace Content.Client.Administration.UI.Bwoink [GenerateTypedNameReferences] public sealed partial class BwoinkControl : Control { - [Dependency] private readonly IClientAdminManager _adminManager = default!; - [Dependency] private readonly IClientConsoleHost _console = default!; - [Dependency] private readonly IUserInterfaceManager _ui = default!; - [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private IClientAdminManager _adminManager = default!; + [Dependency] private IClientConsoleHost _console = default!; + [Dependency] private IUserInterfaceManager _ui = default!; + [Dependency] private IConfigurationManager _cfg = default!; public AdminAHelpUIHandler AHelpHelper = default!; private PlayerInfo? _currentPlayer; diff --git a/Content.Client/Administration/UI/Logs/AdminLogsEui.cs b/Content.Client/Administration/UI/Logs/AdminLogsEui.cs index 28aca23f756..d8323dcd5cc 100644 --- a/Content.Client/Administration/UI/Logs/AdminLogsEui.cs +++ b/Content.Client/Administration/UI/Logs/AdminLogsEui.cs @@ -13,12 +13,12 @@ namespace Content.Client.Administration.UI.Logs; [UsedImplicitly] -public sealed class AdminLogsEui : BaseEui +public sealed partial class AdminLogsEui : BaseEui { - [Dependency] private readonly IClyde _clyde = default!; - [Dependency] private readonly IUserInterfaceManager _uiManager = default!; - [Dependency] private readonly IFileDialogManager _dialogManager = default!; - [Dependency] private readonly ILogManager _log = default!; + [Dependency] private IClyde _clyde = default!; + [Dependency] private IUserInterfaceManager _uiManager = default!; + [Dependency] private IFileDialogManager _dialogManager = default!; + [Dependency] private ILogManager _log = default!; private const char CsvSeparator = ','; private const string CsvQuote = "\""; diff --git a/Content.Client/Administration/UI/ManageSolutions/AddReagentWindow.xaml.cs b/Content.Client/Administration/UI/ManageSolutions/AddReagentWindow.xaml.cs index 1ded5cebb3a..41c3c64166d 100644 --- a/Content.Client/Administration/UI/ManageSolutions/AddReagentWindow.xaml.cs +++ b/Content.Client/Administration/UI/ManageSolutions/AddReagentWindow.xaml.cs @@ -15,8 +15,8 @@ namespace Content.Client.Administration.UI.ManageSolutions [GenerateTypedNameReferences] public sealed partial class AddReagentWindow : DefaultWindow { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IClientConsoleHost _consoleHost = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private IClientConsoleHost _consoleHost = default!; private readonly NetEntity _targetEntity; private string _targetSolution; diff --git a/Content.Client/Administration/UI/ManageSolutions/EditSolutionsWindow.xaml.cs b/Content.Client/Administration/UI/ManageSolutions/EditSolutionsWindow.xaml.cs index 89016fdf41d..0fec1b71e45 100644 --- a/Content.Client/Administration/UI/ManageSolutions/EditSolutionsWindow.xaml.cs +++ b/Content.Client/Administration/UI/ManageSolutions/EditSolutionsWindow.xaml.cs @@ -18,10 +18,10 @@ namespace Content.Client.Administration.UI.ManageSolutions [GenerateTypedNameReferences] public sealed partial class EditSolutionsWindow : DefaultWindow { - [Dependency] private readonly IClientConsoleHost _consoleHost = default!; - [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IClientGameTiming _timing = default!; - [Dependency] private readonly IClientAdminManager _admin = default!; + [Dependency] private IClientConsoleHost _consoleHost = default!; + [Dependency] private IEntityManager _entityManager = default!; + [Dependency] private IClientGameTiming _timing = default!; + [Dependency] private IClientAdminManager _admin = default!; private NetEntity _target = NetEntity.Invalid; private string? _selectedSolution; diff --git a/Content.Client/Administration/UI/Notes/AdminNotesControl.xaml.cs b/Content.Client/Administration/UI/Notes/AdminNotesControl.xaml.cs index 9ad6d2e0ea5..7a889a0b123 100644 --- a/Content.Client/Administration/UI/Notes/AdminNotesControl.xaml.cs +++ b/Content.Client/Administration/UI/Notes/AdminNotesControl.xaml.cs @@ -15,8 +15,8 @@ namespace Content.Client.Administration.UI.Notes; [GenerateTypedNameReferences] public sealed partial class AdminNotesControl : Control { - [Dependency] private readonly IEntitySystemManager _entitySystem = default!; - [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private IEntitySystemManager _entitySystem = default!; + [Dependency] private IConfigurationManager _cfg = default!; public event Action? NoteChanged; public event Action? NewNoteEntered; diff --git a/Content.Client/Administration/UI/Notes/AdminNotesLinePopup.xaml.cs b/Content.Client/Administration/UI/Notes/AdminNotesLinePopup.xaml.cs index e82b85acb6a..4e4027e7d4b 100644 --- a/Content.Client/Administration/UI/Notes/AdminNotesLinePopup.xaml.cs +++ b/Content.Client/Administration/UI/Notes/AdminNotesLinePopup.xaml.cs @@ -14,7 +14,7 @@ public sealed partial class AdminNotesLinePopup : Popup public event Action? OnEditPressed; public event Action? OnDeletePressed; - [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private IGameTiming _gameTiming = default!; public AdminNotesLinePopup(SharedAdminNote note, string playerName, bool showDelete, bool showEdit) { diff --git a/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs b/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs index 0c27d9d646a..5515600d1ef 100644 --- a/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs +++ b/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs @@ -14,8 +14,8 @@ namespace Content.Client.Administration.UI.Notes; [GenerateTypedNameReferences] public sealed partial class NoteEdit : FancyWindow { - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly IClientConsoleHost _console = default!; + [Dependency] private IGameTiming _gameTiming = default!; + [Dependency] private IClientConsoleHost _console = default!; private enum Multipliers { diff --git a/Content.Client/Administration/UI/PermissionsEui.cs b/Content.Client/Administration/UI/PermissionsEui.cs index 96b53babb52..71aea9f45d5 100644 --- a/Content.Client/Administration/UI/PermissionsEui.cs +++ b/Content.Client/Administration/UI/PermissionsEui.cs @@ -20,11 +20,11 @@ namespace Content.Client.Administration.UI { [UsedImplicitly] - public sealed class PermissionsEui : BaseEui + public sealed partial class PermissionsEui : BaseEui { private const int NoRank = -1; - [Dependency] private readonly IClientAdminManager _adminManager = default!; + [Dependency] private IClientAdminManager _adminManager = default!; private readonly Menu _menu; private readonly List _subWindows = new(); diff --git a/Content.Client/Administration/UI/PlayerPanel/PlayerPanelEui.cs b/Content.Client/Administration/UI/PlayerPanel/PlayerPanelEui.cs index 8c8183ef22a..1828d34f2f2 100644 --- a/Content.Client/Administration/UI/PlayerPanel/PlayerPanelEui.cs +++ b/Content.Client/Administration/UI/PlayerPanel/PlayerPanelEui.cs @@ -9,11 +9,11 @@ namespace Content.Client.Administration.UI.PlayerPanel; [UsedImplicitly] -public sealed class PlayerPanelEui : BaseEui +public sealed partial class PlayerPanelEui : BaseEui { - [Dependency] private readonly IClientConsoleHost _console = default!; - [Dependency] private readonly IClientAdminManager _admin = default!; - [Dependency] private readonly IClipboardManager _clipboard = default!; + [Dependency] private IClientConsoleHost _console = default!; + [Dependency] private IClientAdminManager _admin = default!; + [Dependency] private IClipboardManager _clipboard = default!; private PlayerPanel PlayerPanel { get; } diff --git a/Content.Client/Administration/UI/SetOutfit/SetOutfitMenu.xaml.cs b/Content.Client/Administration/UI/SetOutfit/SetOutfitMenu.xaml.cs index 615f1434df2..3268f2aff51 100644 --- a/Content.Client/Administration/UI/SetOutfit/SetOutfitMenu.xaml.cs +++ b/Content.Client/Administration/UI/SetOutfit/SetOutfitMenu.xaml.cs @@ -15,8 +15,8 @@ namespace Content.Client.Administration.UI.SetOutfit [GenerateTypedNameReferences] public sealed partial class SetOutfitMenu : DefaultWindow { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IClientConsoleHost _consoleHost = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private IClientConsoleHost _consoleHost = default!; public NetEntity? TargetEntityId { get; set; } private StartingGearPrototype? _selectedOutfit; diff --git a/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs b/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs index d60094ad897..46ac390181f 100644 --- a/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs +++ b/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs @@ -11,10 +11,10 @@ namespace Content.Client.Administration.UI.SpawnExplosion; [UsedImplicitly] -public sealed class ExplosionDebugOverlay : Overlay +public sealed partial class ExplosionDebugOverlay : Overlay { - [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IEyeManager _eyeManager = default!; + [Dependency] private IEntityManager _entityManager = default!; + [Dependency] private IEyeManager _eyeManager = default!; public Dictionary>? SpaceTiles; public Dictionary>> Tiles = new(); diff --git a/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionEui.cs b/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionEui.cs index 9de177b6c71..df0305105bb 100644 --- a/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionEui.cs +++ b/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionEui.cs @@ -8,10 +8,10 @@ namespace Content.Client.Administration.UI.SpawnExplosion; [UsedImplicitly] -public sealed class SpawnExplosionEui : BaseEui +public sealed partial class SpawnExplosionEui : BaseEui { - [Dependency] private readonly EntityManager _entManager = default!; - [Dependency] private readonly IOverlayManager _overlayManager = default!; + [Dependency] private EntityManager _entManager = default!; + [Dependency] private IOverlayManager _overlayManager = default!; private readonly SpawnExplosionWindow _window; private ExplosionDebugOverlay? _debugOverlay; diff --git a/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionWindow.xaml.cs b/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionWindow.xaml.cs index 287c17e422e..ad9cb331da1 100644 --- a/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionWindow.xaml.cs +++ b/Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionWindow.xaml.cs @@ -18,10 +18,10 @@ namespace Content.Client.Administration.UI.SpawnExplosion; [UsedImplicitly] public sealed partial class SpawnExplosionWindow : DefaultWindow { - [Dependency] private readonly IClientConsoleHost _conHost = default!; - [Dependency] private readonly IPlayerManager _playerManager = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IEntityManager _entMan = default!; + [Dependency] private IClientConsoleHost _conHost = default!; + [Dependency] private IPlayerManager _playerManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private IEntityManager _entMan = default!; private readonly SharedMapSystem _mapSystem; private readonly SharedTransformSystem _transform = default!; diff --git a/Content.Client/Administration/UI/Tabs/AdminbusTab/LoadBlueprintsWindow.xaml.cs b/Content.Client/Administration/UI/Tabs/AdminbusTab/LoadBlueprintsWindow.xaml.cs index 12df72bdcf3..a7985337faa 100644 --- a/Content.Client/Administration/UI/Tabs/AdminbusTab/LoadBlueprintsWindow.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/AdminbusTab/LoadBlueprintsWindow.xaml.cs @@ -14,8 +14,8 @@ 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!; + [Dependency] private IEntityManager _entityManager = default!; + [Dependency] private IPlayerManager _playerManager = default!; public LoadBlueprintsWindow() { diff --git a/Content.Client/Administration/UI/Tabs/AtmosTab/AddAtmosWindow.xaml.cs b/Content.Client/Administration/UI/Tabs/AtmosTab/AddAtmosWindow.xaml.cs index 72a594469d2..2dacc82ec46 100644 --- a/Content.Client/Administration/UI/Tabs/AtmosTab/AddAtmosWindow.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/AtmosTab/AddAtmosWindow.xaml.cs @@ -13,8 +13,8 @@ namespace Content.Client.Administration.UI.Tabs.AtmosTab [UsedImplicitly] public sealed partial class AddAtmosWindow : DefaultWindow { - [Dependency] private readonly IPlayerManager _players = default!; - [Dependency] private readonly IEntityManager _entities = default!; + [Dependency] private IPlayerManager _players = default!; + [Dependency] private IEntityManager _entities = default!; private readonly List> _data = new(); diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs index fa92a3e18fb..4195fe7a759 100644 --- a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs @@ -13,9 +13,9 @@ namespace Content.Client.Administration.UI.Tabs.ObjectsTab; [GenerateTypedNameReferences] public sealed partial class ObjectsTab : Control { - [Dependency] private readonly IClientAdminManager _admin = default!; - [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IClientConsoleHost _console = default!; + [Dependency] private IClientAdminManager _admin = default!; + [Dependency] private IEntityManager _entityManager = default!; + [Dependency] private IClientConsoleHost _console = default!; private readonly Color _altColor = Color.FromHex("#292B38"); private readonly Color _defaultColor = Color.FromHex("#2F2F3B"); diff --git a/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml.cs b/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml.cs index 5de532c8355..3feaa287142 100644 --- a/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/PanicBunkerTab/PanicBunkerTab.xaml.cs @@ -9,7 +9,7 @@ namespace Content.Client.Administration.UI.Tabs.PanicBunkerTab; [GenerateTypedNameReferences] public sealed partial class PanicBunkerTab : Control { - [Dependency] private readonly IConsoleHost _console = default!; + [Dependency] private IConsoleHost _console = default!; private string _minAccountAge; private string _minOverallMinutes; diff --git a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs index 5a75e7223f4..3691ae18524 100644 --- a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs @@ -17,9 +17,9 @@ namespace Content.Client.Administration.UI.Tabs.PlayerTab; [GenerateTypedNameReferences] public sealed partial class PlayerTab : Control { - [Dependency] private readonly IEntityManager _entManager = default!; - [Dependency] private readonly IConfigurationManager _config = default!; - [Dependency] private readonly IPlayerManager _playerMan = default!; + [Dependency] private IEntityManager _entManager = default!; + [Dependency] private IConfigurationManager _config = default!; + [Dependency] private IPlayerManager _playerMan = default!; private const string ArrowUp = "↑"; private const string ArrowDown = "↓"; diff --git a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml.cs b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml.cs index 6a2d939b4bb..68516491d9f 100644 --- a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml.cs @@ -12,8 +12,8 @@ namespace Content.Client.Administration.UI.Tabs.PlayerTab; [GenerateTypedNameReferences] public sealed partial class PlayerTabEntry : PanelContainer { - [Dependency] private readonly IEntityManager _entMan = default!; - [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private IEntityManager _entMan = default!; + [Dependency] private IPrototypeManager _prototype = default!; public PlayerTabEntry( PlayerInfo player, diff --git a/Content.Client/Administration/UI/Tabs/RoundTab.xaml.cs b/Content.Client/Administration/UI/Tabs/RoundTab.xaml.cs index 70f12bb393d..cce809d35a2 100644 --- a/Content.Client/Administration/UI/Tabs/RoundTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/RoundTab.xaml.cs @@ -8,7 +8,7 @@ namespace Content.Client.Administration.UI.Tabs [GenerateTypedNameReferences] public sealed partial class RoundTab : Control { - [Dependency] private readonly IClientConsoleHost _console = default!; + [Dependency] private IClientConsoleHost _console = default!; public RoundTab() { diff --git a/Content.Client/Administration/UI/Tabs/ServerTab.xaml.cs b/Content.Client/Administration/UI/Tabs/ServerTab.xaml.cs index 7a70e42d066..c025a93d585 100644 --- a/Content.Client/Administration/UI/Tabs/ServerTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/ServerTab.xaml.cs @@ -10,8 +10,8 @@ namespace Content.Client.Administration.UI.Tabs [GenerateTypedNameReferences] public sealed partial class ServerTab : Control { - [Dependency] private readonly IConfigurationManager _config = default!; - [Dependency] private readonly IClientConsoleHost _console = default!; + [Dependency] private IConfigurationManager _config = default!; + [Dependency] private IClientConsoleHost _console = default!; public ServerTab() { diff --git a/Content.Client/AlertLevel/AlertLevelDisplaySystem.cs b/Content.Client/AlertLevel/AlertLevelDisplaySystem.cs index 13e2ab32081..845be2e429c 100644 --- a/Content.Client/AlertLevel/AlertLevelDisplaySystem.cs +++ b/Content.Client/AlertLevel/AlertLevelDisplaySystem.cs @@ -6,9 +6,9 @@ namespace Content.Client.AlertLevel; -public sealed class AlertLevelDisplaySystem : EntitySystem +public sealed partial class AlertLevelDisplaySystem : EntitySystem { - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { diff --git a/Content.Client/Alerts/ClientAlertsSystem.cs b/Content.Client/Alerts/ClientAlertsSystem.cs index 43c74adc5db..29cd5da1903 100644 --- a/Content.Client/Alerts/ClientAlertsSystem.cs +++ b/Content.Client/Alerts/ClientAlertsSystem.cs @@ -10,13 +10,13 @@ namespace Content.Client.Alerts; [UsedImplicitly] -public sealed class ClientAlertsSystem : AlertsSystem +public sealed partial class ClientAlertsSystem : AlertsSystem { public AlertOrderPrototype? AlertOrder { get; set; } - [Dependency] private readonly IPlayerManager _playerManager = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IUserInterfaceManager _ui = default!; + [Dependency] private IPlayerManager _playerManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private IUserInterfaceManager _ui = default!; public event EventHandler? ClearAlerts; public event EventHandler>? SyncAlerts; diff --git a/Content.Client/Alerts/GenericCounterAlertSystem.cs b/Content.Client/Alerts/GenericCounterAlertSystem.cs index de9d97d063b..b8d2e2d0d3f 100644 --- a/Content.Client/Alerts/GenericCounterAlertSystem.cs +++ b/Content.Client/Alerts/GenericCounterAlertSystem.cs @@ -8,9 +8,9 @@ namespace Content.Client.Alerts; /// /// This handles /// -public sealed class GenericCounterAlertSystem : EntitySystem +public sealed partial class GenericCounterAlertSystem : EntitySystem { - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SpriteSystem _sprite = default!; /// public override void Initialize() diff --git a/Content.Client/Animations/EntityPickupAnimationSystem.cs b/Content.Client/Animations/EntityPickupAnimationSystem.cs index 58f1740e3c9..7445267ddfe 100644 --- a/Content.Client/Animations/EntityPickupAnimationSystem.cs +++ b/Content.Client/Animations/EntityPickupAnimationSystem.cs @@ -11,12 +11,12 @@ namespace Content.Client.Animations; /// /// System that handles animating an entity that a player has picked up. /// -public sealed class EntityPickupAnimationSystem : EntitySystem +public sealed partial 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!; + [Dependency] private AnimationPlayerSystem _animations = default!; + [Dependency] private MetaDataSystem _metaData = default!; + [Dependency] private SpriteSystem _sprite = default!; + [Dependency] private TransformSystem _transform = default!; public override void Initialize() { diff --git a/Content.Client/Anomaly/AnomalyScannerSystem.cs b/Content.Client/Anomaly/AnomalyScannerSystem.cs index f80e5ead540..f30a2139775 100644 --- a/Content.Client/Anomaly/AnomalyScannerSystem.cs +++ b/Content.Client/Anomaly/AnomalyScannerSystem.cs @@ -8,10 +8,10 @@ namespace Content.Client.Anomaly; /// -public sealed class AnomalyScannerSystem : SharedAnomalyScannerSystem +public sealed partial class AnomalyScannerSystem : SharedAnomalyScannerSystem { - [Dependency] private readonly IClyde _clyde = default!; - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private IClyde _clyde = default!; + [Dependency] private SpriteSystem _sprite = default!; private const float MaxHueDegrees = 360f; private const float GreenHueDegrees = 110f; diff --git a/Content.Client/Anomaly/AnomalySystem.cs b/Content.Client/Anomaly/AnomalySystem.cs index b4bc6efdd2f..bc29ceb6784 100644 --- a/Content.Client/Anomaly/AnomalySystem.cs +++ b/Content.Client/Anomaly/AnomalySystem.cs @@ -9,9 +9,9 @@ namespace Content.Client.Anomaly; public sealed partial class AnomalySystem : SharedAnomalySystem { - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly FloatingVisualizerSystem _floating = default!; - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private IGameTiming _timing = default!; + [Dependency] private FloatingVisualizerSystem _floating = default!; + [Dependency] private SpriteSystem _sprite = default!; /// public override void Initialize() diff --git a/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs b/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs index a9dcfaf2b06..6d48254c190 100644 --- a/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs +++ b/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs @@ -5,9 +5,9 @@ namespace Content.Client.Anomaly.Effects; -public sealed class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem +public sealed partial class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem { - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { diff --git a/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs b/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs index 82d41192dd0..f26219d5322 100644 --- a/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs +++ b/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs @@ -11,7 +11,7 @@ namespace Content.Client.Anomaly.Ui; [GenerateTypedNameReferences] public sealed partial class AnomalyGeneratorWindow : FancyWindow { - [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private IGameTiming _timing = default!; private TimeSpan _cooldownEnd = TimeSpan.Zero; private bool _hasEnoughFuel; diff --git a/Content.Client/Anomaly/Ui/AnomalyScannerMenu.xaml.cs b/Content.Client/Anomaly/Ui/AnomalyScannerMenu.xaml.cs index c012edb89e2..f849ce5d33a 100644 --- a/Content.Client/Anomaly/Ui/AnomalyScannerMenu.xaml.cs +++ b/Content.Client/Anomaly/Ui/AnomalyScannerMenu.xaml.cs @@ -10,7 +10,7 @@ namespace Content.Client.Anomaly.Ui; [GenerateTypedNameReferences] public sealed partial class AnomalyScannerMenu : FancyWindow { - [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private IGameTiming _timing = default!; public FormattedMessage LastMessage = new(); public TimeSpan? NextPulseTime; diff --git a/Content.Client/Atmos/AlignAtmosPipeLayers.cs b/Content.Client/Atmos/AlignAtmosPipeLayers.cs index 51a6ce0c026..c8e69bc17f6 100644 --- a/Content.Client/Atmos/AlignAtmosPipeLayers.cs +++ b/Content.Client/Atmos/AlignAtmosPipeLayers.cs @@ -23,12 +23,12 @@ namespace Content.Client.Atmos; /// /// This placement mode is not on the engine because it is content specific. /// -public sealed class AlignAtmosPipeLayers : SnapgridCenter +public sealed partial class AlignAtmosPipeLayers : SnapgridCenter { - [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IPrototypeManager _protoManager = default!; - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IEyeManager _eyeManager = default!; + [Dependency] private IEntityManager _entityManager = default!; + [Dependency] private IPrototypeManager _protoManager = default!; + [Dependency] private IMapManager _mapManager = default!; + [Dependency] private IEyeManager _eyeManager = default!; private readonly SharedMapSystem _mapSystem; private readonly SharedTransformSystem _transformSystem; diff --git a/Content.Client/Atmos/Components/MapAtmosphereComponent.cs b/Content.Client/Atmos/Components/MapAtmosphereComponent.cs deleted file mode 100644 index abad2491347..00000000000 --- a/Content.Client/Atmos/Components/MapAtmosphereComponent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Content.Shared.Atmos.Components; - -namespace Content.Client.Atmos.Components; - -[RegisterComponent] -public sealed partial class MapAtmosphereComponent : SharedMapAtmosphereComponent -{ - -} diff --git a/Content.Client/Atmos/Components/MaxPressureVisualsComponent.cs b/Content.Client/Atmos/Components/MaxPressureVisualsComponent.cs new file mode 100644 index 00000000000..e71f212786c --- /dev/null +++ b/Content.Client/Atmos/Components/MaxPressureVisualsComponent.cs @@ -0,0 +1,36 @@ +using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; + +namespace Content.Client.Atmos.Components; + +/// +/// This listens to appearance changes from +/// and applies sprite changes to a gas holder currently experiencing loss. +/// +[RegisterComponent] +public sealed partial class MaxPressureVisualsComponent : Component +{ + /// + /// What RsiState we use for our integrity visuals. + /// + [DataField] + public string? IntegrityState = "integrity"; + + /// + /// What RsiState we use for the mask that goes over integrity visuals. + /// + [DataField] + public string? IntegrityMask = "mask"; + + /// + /// How many steps there are + /// + [DataField("steps")] + public int IntegritySteps = 5; +} + +public enum MaxPressureVisualLayers : byte +{ + Base, + BaseUnshaded, +} diff --git a/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml.cs b/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml.cs index f0e4b13356c..e192a66fccb 100644 --- a/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml.cs +++ b/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml.cs @@ -1,6 +1,7 @@ using Content.Client.Stylesheets; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; using Content.Shared.Atmos.Monitor; using Content.Shared.FixedPoint; using Content.Shared.Temperature; @@ -22,6 +23,7 @@ public sealed partial class AtmosAlarmEntryContainer : BoxContainer private readonly IEntityManager _entManager; private readonly IResourceCache _cache; + private readonly SharedAtmosphereSystem _atmosphere; private Dictionary _alarmStrings = new Dictionary() { @@ -37,6 +39,7 @@ public AtmosAlarmEntryContainer(NetEntity uid, EntityCoordinates? coordinates) _entManager = IoCManager.Resolve(); _cache = IoCManager.Resolve(); + _atmosphere = _entManager.System(); NetEntity = uid; Coordinates = coordinates; @@ -149,7 +152,7 @@ public void UpdateEntry(AtmosAlertsComputerEntry entry, bool isFocus, AtmosAlert foreach ((var gas, (var mol, var percent, var alert)) in keyValuePairs) { FixedPoint2 gasPercent = percent * 100f; - var gasAbbreviation = Atmospherics.GasAbbreviations.GetValueOrDefault(gas, Loc.GetString("gas-unknown-abbreviation")); + var gasAbbreviation = Loc.GetString(_atmosphere.GetGas(gas).Abbreviation); var gasLabel = new Label() { diff --git a/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleNavMapControl.cs b/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleNavMapControl.cs index 94bfb4b4f37..1ef23ed5376 100644 --- a/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleNavMapControl.cs +++ b/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleNavMapControl.cs @@ -11,7 +11,7 @@ namespace Content.Client.Atmos.Consoles; public sealed partial class AtmosMonitoringConsoleNavMapControl : NavMapControl { - [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private IEntityManager _entManager = default!; public bool ShowPipeNetwork = true; public int? FocusNetId = null; diff --git a/Content.Client/Atmos/Consoles/AtmosMonitoringEntryContainer.xaml.cs b/Content.Client/Atmos/Consoles/AtmosMonitoringEntryContainer.xaml.cs index 0ce0c9c880a..cf9a89d1a56 100644 --- a/Content.Client/Atmos/Consoles/AtmosMonitoringEntryContainer.xaml.cs +++ b/Content.Client/Atmos/Consoles/AtmosMonitoringEntryContainer.xaml.cs @@ -1,6 +1,7 @@ using Content.Client.Stylesheets; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; using Content.Shared.FixedPoint; using Content.Shared.Temperature; using Robust.Client.AutoGenerated; @@ -19,12 +20,14 @@ public sealed partial class AtmosMonitoringEntryContainer : BoxContainer private readonly IEntityManager _entManager; private readonly IResourceCache _cache; + private readonly SharedAtmosphereSystem _atmosphere; public AtmosMonitoringEntryContainer(AtmosMonitoringConsoleEntry data) { RobustXamlLoader.Load(this); _entManager = IoCManager.Resolve(); _cache = IoCManager.Resolve(); + _atmosphere = _entManager.System(); Data = data; @@ -132,7 +135,7 @@ public void UpdateEntry(AtmosMonitoringConsoleEntry updatedData, bool isFocus) var gasPercent = (FixedPoint2)0f; gasPercent = percent * 100f; - var gasAbbreviation = Atmospherics.GasAbbreviations.GetValueOrDefault(gas, Loc.GetString("gas-unknown-abbreviation")); + var gasAbbreviation = Loc.GetString(_atmosphere.GetGas(gas).Abbreviation); var gasLabel = new Label() { diff --git a/Content.Client/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs b/Content.Client/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs index 32e82922418..07a163a0001 100644 --- a/Content.Client/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs +++ b/Content.Client/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs @@ -8,9 +8,9 @@ namespace Content.Client.Atmos.EntitySystems { [UsedImplicitly] - internal sealed class AtmosDebugOverlaySystem : SharedAtmosDebugOverlaySystem + internal sealed partial class AtmosDebugOverlaySystem : SharedAtmosDebugOverlaySystem { - [Dependency] private readonly IOverlayManager _overlayManager = default!; + [Dependency] private IOverlayManager _overlayManager = default!; public readonly Dictionary TileData = []; diff --git a/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs b/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs index 1a12c3967b5..4ee3d74545f 100644 --- a/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs +++ b/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs @@ -11,8 +11,8 @@ namespace Content.Client.Atmos.EntitySystems; [UsedImplicitly] public sealed partial class AtmosPipeAppearanceSystem : SharedAtmosPipeAppearanceSystem { - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SharedAppearanceSystem _appearance = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { diff --git a/Content.Client/Atmos/EntitySystems/AtmosPipeLayersSystem.cs b/Content.Client/Atmos/EntitySystems/AtmosPipeLayersSystem.cs index f560e0b833b..bdd653ad8f2 100644 --- a/Content.Client/Atmos/EntitySystems/AtmosPipeLayersSystem.cs +++ b/Content.Client/Atmos/EntitySystems/AtmosPipeLayersSystem.cs @@ -14,10 +14,10 @@ namespace Content.Client.Atmos.EntitySystems; /// public sealed partial class AtmosPipeLayersSystem : SharedAtmosPipeLayersSystem { - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly IReflectionManager _reflection = default!; - [Dependency] private readonly IResourceCache _resourceCache = default!; - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SharedAppearanceSystem _appearance = default!; + [Dependency] private IReflectionManager _reflection = default!; + [Dependency] private IResourceCache _resourceCache = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { diff --git a/Content.Client/Atmos/EntitySystems/AtmosphereSystem.Gases.cs b/Content.Client/Atmos/EntitySystems/AtmosphereSystem.Gases.cs index 17b994e64f6..0619e26c4b2 100644 --- a/Content.Client/Atmos/EntitySystems/AtmosphereSystem.Gases.cs +++ b/Content.Client/Atmos/EntitySystems/AtmosphereSystem.Gases.cs @@ -1,5 +1,7 @@ +using System.Numerics.Tensors; using System.Runtime.CompilerServices; using Content.Shared.Atmos; +using Content.Shared.Atmos.Reactions; namespace Content.Client.Atmos.EntitySystems; @@ -13,11 +15,48 @@ code that would escape sandbox. As such these methods are overridden here with a implementation. */ + /// + /// No-op on client as reactions aren't entirely in shared. + /// Don't call it. Smile. + public override ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder) + { + // Reactions don't work on client so don't even try. + throw new NotImplementedException(); + } + + public override bool IsMixtureFuel(GasMixture mixture, float epsilon = Atmospherics.Epsilon) + { + var tmp = new float[Atmospherics.AdjustedNumberOfGases]; + TensorPrimitives.Multiply(mixture.Moles, GasFuelMask, tmp); + return TensorPrimitives.Sum(tmp) > epsilon; + } + + public override bool IsMixtureOxidizer(GasMixture mixture, float epsilon = Atmospherics.Epsilon) + { + var tmp = new float[Atmospherics.AdjustedNumberOfGases]; + TensorPrimitives.Multiply(mixture.Moles, GasOxidizerMask, tmp); + return TensorPrimitives.Sum(tmp) > epsilon; + } + + public override float GetMass(GasMixture mix) + { + return GetMass(mix.Moles); + } + + public override float GetMass(float[] moles) + { + var tmp = new float[moles.Length]; + TensorPrimitives.Multiply(moles, GasMolarMasses, tmp); + + // Conversion of grams to kilograms. + return TensorPrimitives.Sum(tmp) * Atmospherics.gToKg; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override float GetHeatCapacityCalculation(float[] moles, bool space) { // Little hack to make space gas mixtures have heat capacity, therefore allowing them to cool down rooms. - if (space && MathHelper.CloseTo(NumericsHelpers.HorizontalAdd(moles), 0f)) + if (space && MathHelper.CloseTo(TensorPrimitives.Sum(moles), 0f)) { return Atmospherics.SpaceHeatCapacity; } @@ -27,9 +66,9 @@ protected override float GetHeatCapacityCalculation(float[] moles, bool space) // though this isnt the hottest code path so it should be fine // the gc can eat a little as a treat var tmp = new float[moles.Length]; - NumericsHelpers.Multiply(moles, GasSpecificHeats, tmp); + TensorPrimitives.Multiply(moles, GasMolarHeatCapacities, tmp); // Adjust heat capacity by speedup, because this is primarily what // determines how quickly gases heat up/cool. - return MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity); + return MathF.Max(TensorPrimitives.Sum(tmp), Atmospherics.MinimumHeatCapacity); } } diff --git a/Content.Client/Atmos/EntitySystems/FireVisualizerSystem.cs b/Content.Client/Atmos/EntitySystems/FireVisualizerSystem.cs index 431a598678d..ec4500935cc 100644 --- a/Content.Client/Atmos/EntitySystems/FireVisualizerSystem.cs +++ b/Content.Client/Atmos/EntitySystems/FireVisualizerSystem.cs @@ -9,9 +9,9 @@ namespace Content.Client.Atmos.EntitySystems; /// /// This handles the display of fire effects on flammable entities. /// -public sealed class FireVisualizerSystem : VisualizerSystem +public sealed partial class FireVisualizerSystem : VisualizerSystem { - [Dependency] private readonly PointLightSystem _lights = default!; + [Dependency] private PointLightSystem _lights = default!; public override void Initialize() { diff --git a/Content.Client/Atmos/EntitySystems/GasCanisterAppearanceSystem.cs b/Content.Client/Atmos/EntitySystems/GasCanisterAppearanceSystem.cs index f16774ce249..d54f4d20a64 100644 --- a/Content.Client/Atmos/EntitySystems/GasCanisterAppearanceSystem.cs +++ b/Content.Client/Atmos/EntitySystems/GasCanisterAppearanceSystem.cs @@ -8,9 +8,9 @@ namespace Content.Client.Atmos.EntitySystems; /// /// Used to change the appearance of gas canisters. /// -public sealed class GasCanisterAppearanceSystem : VisualizerSystem +public sealed partial class GasCanisterAppearanceSystem : VisualizerSystem { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; protected override void OnAppearanceChange(EntityUid uid, GasCanisterComponent component, ref AppearanceChangeEvent args) { diff --git a/Content.Client/Atmos/EntitySystems/GasTankSystem.cs b/Content.Client/Atmos/EntitySystems/GasTankSystem.cs index 696e7939f60..bae70ea2bdc 100644 --- a/Content.Client/Atmos/EntitySystems/GasTankSystem.cs +++ b/Content.Client/Atmos/EntitySystems/GasTankSystem.cs @@ -11,6 +11,12 @@ public override void Initialize() SubscribeLocalEvent(OnGasTankState); } + protected override void DeviceUpdated(Entity entity, ref AtmosDeviceUpdateEvent args) + { + // Atmos not predicted :( + throw new NotImplementedException(); + } + private void OnGasTankState(Entity ent, ref AfterAutoHandleStateEvent args) { if (UI.TryGetOpenUi(ent.Owner, SharedGasTankUiKey.Key, out var bui)) diff --git a/Content.Client/Atmos/EntitySystems/GasTileFireOverlaySystem.cs b/Content.Client/Atmos/EntitySystems/GasTileFireOverlaySystem.cs new file mode 100644 index 00000000000..f193bcb4117 --- /dev/null +++ b/Content.Client/Atmos/EntitySystems/GasTileFireOverlaySystem.cs @@ -0,0 +1,30 @@ +using Content.Client.Atmos.Overlays; +using JetBrains.Annotations; +using Robust.Client.Graphics; + +namespace Content.Client.Atmos.EntitySystems; + +/// +/// System responsible for rendering atmos fire animations using . +/// +[UsedImplicitly] +public sealed partial class GasTileFireOverlaySystem : EntitySystem +{ + [Dependency] private IOverlayManager _overlayMan = default!; + + private GasTileFireOverlay _fireOverlay = default!; + + public override void Initialize() + { + base.Initialize(); + + _fireOverlay = new GasTileFireOverlay(); + _overlayMan.AddOverlay(_fireOverlay); + } + + public override void Shutdown() + { + base.Shutdown(); + _overlayMan.RemoveOverlay(); + } +} diff --git a/Content.Client/Atmos/EntitySystems/GasTileHeatBlurOverlaySystem.cs b/Content.Client/Atmos/EntitySystems/GasTileHeatBlurOverlaySystem.cs new file mode 100644 index 00000000000..282cd956c7f --- /dev/null +++ b/Content.Client/Atmos/EntitySystems/GasTileHeatBlurOverlaySystem.cs @@ -0,0 +1,30 @@ +using Content.Client.Atmos.Overlays; +using JetBrains.Annotations; +using Robust.Client.Graphics; + +namespace Content.Client.Atmos.EntitySystems; + +/// +/// System responsible for rendering heat distortion using . +/// +[UsedImplicitly] +public sealed partial class GasTileHeatBlurOverlaySystem : EntitySystem +{ + [Dependency] private IOverlayManager _overlayMan = default!; + + private GasTileHeatBlurOverlay _gasTileHeatBlurOverlay = default!; + + public override void Initialize() + { + base.Initialize(); + + _gasTileHeatBlurOverlay = new GasTileHeatBlurOverlay(); + _overlayMan.AddOverlay(_gasTileHeatBlurOverlay); + } + + public override void Shutdown() + { + base.Shutdown(); + _overlayMan.RemoveOverlay(); + } +} diff --git a/Content.Client/Atmos/EntitySystems/GasTileOverlaySystem.cs b/Content.Client/Atmos/EntitySystems/GasTileOverlaySystem.cs index ad264369467..8de649b81c7 100644 --- a/Content.Client/Atmos/EntitySystems/GasTileOverlaySystem.cs +++ b/Content.Client/Atmos/EntitySystems/GasTileOverlaySystem.cs @@ -1,106 +1,85 @@ -using Content.Client.Atmos.Overlays; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; using Content.Shared.Atmos.EntitySystems; using JetBrains.Annotations; -using Robust.Client.GameObjects; -using Robust.Client.Graphics; -using Robust.Client.ResourceManagement; using Robust.Shared.GameStates; -namespace Content.Client.Atmos.EntitySystems +namespace Content.Client.Atmos.EntitySystems; + +[UsedImplicitly] +public sealed class GasTileOverlaySystem : SharedGasTileOverlaySystem { - [UsedImplicitly] - public sealed class GasTileOverlaySystem : SharedGasTileOverlaySystem + public override void Initialize() { - [Dependency] private readonly IResourceCache _resourceCache = default!; - [Dependency] private readonly IOverlayManager _overlayMan = default!; - [Dependency] private readonly SpriteSystem _spriteSys = default!; - [Dependency] private readonly SharedTransformSystem _xformSys = default!; + base.Initialize(); + SubscribeNetworkEvent(HandleGasOverlayUpdate); + SubscribeLocalEvent(OnHandleState); + } - private GasTileOverlay _overlay = default!; + private void OnHandleState(EntityUid gridUid, GasTileOverlayComponent comp, ref ComponentHandleState args) + { + Dictionary modifiedChunks; - public override void Initialize() + switch (args.Current) { - base.Initialize(); - SubscribeNetworkEvent(HandleGasOverlayUpdate); - SubscribeLocalEvent(OnHandleState); + // is this a delta or full state? + case GasTileOverlayDeltaState delta: + { + modifiedChunks = delta.ModifiedChunks; + foreach (var index in comp.Chunks.Keys) + { + if (!delta.AllChunks.Contains(index)) + comp.Chunks.Remove(index); + } + + break; + } + case GasTileOverlayState state: + { + modifiedChunks = state.Chunks; + foreach (var index in comp.Chunks.Keys) + { + if (!state.Chunks.ContainsKey(index)) + comp.Chunks.Remove(index); + } - _overlay = new GasTileOverlay(this, EntityManager, _resourceCache, ProtoMan, _spriteSys, _xformSys); - _overlayMan.AddOverlay(_overlay); + break; + } + default: + return; } - public override void Shutdown() + foreach (var (index, data) in modifiedChunks) { - base.Shutdown(); - _overlayMan.RemoveOverlay(); + comp.Chunks[index] = data; } + } - private void OnHandleState(EntityUid gridUid, GasTileOverlayComponent comp, ref ComponentHandleState args) + private void HandleGasOverlayUpdate(GasOverlayUpdateEvent ev) + { + foreach (var (nent, removedIndicies) in ev.RemovedChunks) { - Dictionary modifiedChunks; + var grid = GetEntity(nent); - switch (args.Current) - { - // is this a delta or full state? - case GasTileOverlayDeltaState delta: - { - modifiedChunks = delta.ModifiedChunks; - foreach (var index in comp.Chunks.Keys) - { - if (!delta.AllChunks.Contains(index)) - comp.Chunks.Remove(index); - } + if (!TryComp(grid, out GasTileOverlayComponent? comp)) + continue; - break; - } - case GasTileOverlayState state: - { - modifiedChunks = state.Chunks; - foreach (var index in comp.Chunks.Keys) - { - if (!state.Chunks.ContainsKey(index)) - comp.Chunks.Remove(index); - } - - break; - } - default: - return; - } - - foreach (var (index, data) in modifiedChunks) + foreach (var index in removedIndicies) { - comp.Chunks[index] = data; + comp.Chunks.Remove(index); } } - private void HandleGasOverlayUpdate(GasOverlayUpdateEvent ev) + foreach (var (nent, gridData) in ev.UpdatedChunks) { - foreach (var (nent, removedIndicies) in ev.RemovedChunks) - { - var grid = GetEntity(nent); + var grid = GetEntity(nent); - if (!TryComp(grid, out GasTileOverlayComponent? comp)) - continue; + if (!TryComp(grid, out GasTileOverlayComponent? comp)) + continue; - foreach (var index in removedIndicies) - { - comp.Chunks.Remove(index); - } - } - - foreach (var (nent, gridData) in ev.UpdatedChunks) + foreach (var chunkData in gridData) { - var grid = GetEntity(nent); - - if (!TryComp(grid, out GasTileOverlayComponent? comp)) - continue; - - foreach (var chunkData in gridData) - { - comp.Chunks[chunkData.Index] = chunkData; - } + comp.Chunks[chunkData.Index] = chunkData; } } } diff --git a/Content.Client/Atmos/EntitySystems/GasTileVisibleGasOverlaySystem.cs b/Content.Client/Atmos/EntitySystems/GasTileVisibleGasOverlaySystem.cs new file mode 100644 index 00000000000..f47e3f7d602 --- /dev/null +++ b/Content.Client/Atmos/EntitySystems/GasTileVisibleGasOverlaySystem.cs @@ -0,0 +1,31 @@ +using Content.Client.Atmos.Overlays; +using JetBrains.Annotations; +using Robust.Client.Graphics; + +namespace Content.Client.Atmos.EntitySystems; + +/// +/// System responsible for rendering visible atmos gasses (like plasma for example) using . +/// +[UsedImplicitly] +public sealed partial class GasTileVisibleGasOverlaySystem : EntitySystem +{ + [Dependency] private IOverlayManager _overlayMan = default!; + + private GasTileVisibleGasOverlay _visibleGasOverlay = default!; + + public override void Initialize() + { + base.Initialize(); + + _visibleGasOverlay = new GasTileVisibleGasOverlay(); + _overlayMan.AddOverlay(_visibleGasOverlay); + } + + public override void Shutdown() + { + base.Shutdown(); + _overlayMan.RemoveOverlay(); + } + +} diff --git a/Content.Client/Atmos/EntitySystems/MaxPressureVisualsSystem.cs b/Content.Client/Atmos/EntitySystems/MaxPressureVisualsSystem.cs new file mode 100644 index 00000000000..28081214dab --- /dev/null +++ b/Content.Client/Atmos/EntitySystems/MaxPressureVisualsSystem.cs @@ -0,0 +1,77 @@ +using Content.Client.Atmos.Components; +using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; +using Content.Shared.Rounding; +using Robust.Client.GameObjects; + +namespace Content.Client.Atmos.EntitySystems; + +/// +/// This system handles sprite changes for a +/// with a when its changes. +/// +public sealed partial class MaxPressureVisualsSystem : EntitySystem +{ + [Dependency] private SpriteSystem _sprite = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnMaxPressureInit); + SubscribeLocalEvent(OnAppearanceChange); + } + + private void OnMaxPressureInit(Entity entity, ref ComponentInit args) + { + if (!TryComp(entity, out var sprite)) + return; + + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(entity.Comp.IntegritySteps); + + if (_sprite.LayerMapTryGet((entity, sprite), MaxPressureVisualLayers.Base, out _, false)) + { + _sprite.LayerSetRsiState((entity, sprite), MaxPressureVisualLayers.Base, $"{entity.Comp.IntegrityMask}"); + _sprite.LayerSetVisible((entity, sprite), MaxPressureVisualLayers.Base, false); + } + + if (_sprite.LayerMapTryGet((entity, sprite), MaxPressureVisualLayers.BaseUnshaded, out _, false)) + { + _sprite.LayerSetRsiState((entity, sprite), MaxPressureVisualLayers.BaseUnshaded, $"{entity.Comp.IntegrityState}-unshaded-0"); + _sprite.LayerSetVisible((entity, sprite), MaxPressureVisualLayers.BaseUnshaded, false); + } + } + + private void OnAppearanceChange(Entity entity, ref AppearanceChangeEvent args) + { + if (args.Sprite is not { } sprite) + return; + + if (!args.AppearanceData.TryGetValue(GasIntegrity.Integrity, out var obj) || obj is not float integrity) + return; + + if (!args.AppearanceData.TryGetValue(GasIntegrity.MaxIntegrity, out obj) || obj is not float maxIntegrity) + return; + + // We don't want visuals at max integrity, so we return if we're at max. + if (integrity >= maxIntegrity) + { + _sprite.LayerSetVisible((entity, sprite), MaxPressureVisualLayers.Base, false); + _sprite.LayerSetVisible((entity, sprite), MaxPressureVisualLayers.BaseUnshaded, false); + return; + } + + _sprite.LayerSetVisible((entity, sprite), MaxPressureVisualLayers.Base, true); + _sprite.LayerSetVisible((entity, sprite), MaxPressureVisualLayers.BaseUnshaded, true); + + // Subtract our integrity + 1 to get an accurate step count. + if (entity.Comp.IntegritySteps > 1) + { + var step = ContentHelpers.RoundToEqualLevels(maxIntegrity - integrity - 1, maxIntegrity, entity.Comp.IntegritySteps); + _sprite.LayerSetRsiState((entity, sprite), MaxPressureVisualLayers.BaseUnshaded, $"{entity.Comp.IntegrityState}-unshaded-{step}"); + } + else + { + _sprite.LayerSetRsiState((entity, sprite), MaxPressureVisualLayers.BaseUnshaded, $"{entity.Comp.IntegrityState}-unshaded-0"); + } + } +} diff --git a/Content.Client/Atmos/Monitor/UI/Widgets/ScrubberControl.xaml.cs b/Content.Client/Atmos/Monitor/UI/Widgets/ScrubberControl.xaml.cs index 70da57df2e4..e197c728552 100644 --- a/Content.Client/Atmos/Monitor/UI/Widgets/ScrubberControl.xaml.cs +++ b/Content.Client/Atmos/Monitor/UI/Widgets/ScrubberControl.xaml.cs @@ -13,8 +13,8 @@ namespace Content.Client.Atmos.Monitor.UI.Widgets; [GenerateTypedNameReferences] public sealed partial class ScrubberControl : BoxContainer { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IEntityManager _entMan = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private IEntityManager _entMan = default!; private GasVentScrubberData _data; private string _address; diff --git a/Content.Client/Atmos/Monitor/UI/Widgets/SensorInfo.xaml.cs b/Content.Client/Atmos/Monitor/UI/Widgets/SensorInfo.xaml.cs index d9945b1accb..ed7a9022e56 100644 --- a/Content.Client/Atmos/Monitor/UI/Widgets/SensorInfo.xaml.cs +++ b/Content.Client/Atmos/Monitor/UI/Widgets/SensorInfo.xaml.cs @@ -14,8 +14,8 @@ namespace Content.Client.Atmos.Monitor.UI.Widgets; [GenerateTypedNameReferences] public sealed partial class SensorInfo : BoxContainer { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IEntityManager _entMan = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private IEntityManager _entMan = default!; public Action? OnThresholdUpdate; public event Action? SensorDataCopied; diff --git a/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs b/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs index ef24f1bee8a..33fec9d985b 100644 --- a/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs +++ b/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs @@ -18,13 +18,13 @@ namespace Content.Client.Atmos.Overlays; -public sealed class AtmosDebugOverlay : Overlay +public sealed partial class AtmosDebugOverlay : Overlay { - [Dependency] private readonly IEntityManager _entManager = default!; - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IInputManager _input = default!; - [Dependency] private readonly IUserInterfaceManager _ui = default!; - [Dependency] private readonly IResourceCache _cache = default!; + [Dependency] private IEntityManager _entManager = default!; + [Dependency] private IMapManager _mapManager = default!; + [Dependency] private IInputManager _input = default!; + [Dependency] private IUserInterfaceManager _ui = default!; + [Dependency] private IResourceCache _cache = default!; private readonly SharedTransformSystem _transform; private readonly AtmosDebugOverlaySystem _system; private readonly SharedMapSystem _map; diff --git a/Content.Client/Atmos/Overlays/GasTileDangerousTemperatureOverlay.cs b/Content.Client/Atmos/Overlays/GasTileDangerousTemperatureOverlay.cs index 69e251d721f..65d1b11e539 100644 --- a/Content.Client/Atmos/Overlays/GasTileDangerousTemperatureOverlay.cs +++ b/Content.Client/Atmos/Overlays/GasTileDangerousTemperatureOverlay.cs @@ -1,4 +1,5 @@ using Content.Client.Atmos.EntitySystems; +using Content.Client.Graphics; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; using Content.Shared.Atmos.EntitySystems; @@ -13,19 +14,20 @@ namespace Content.Client.Atmos.Overlays; /// /// Renders a thermal heatmap overlay for gas tiles, used for equipment like thermal glasses. /// /// -public sealed class GasTileDangerousTemperatureOverlay : Overlay +public sealed partial class GasTileDangerousTemperatureOverlay : Overlay { public override bool RequestScreenTexture { get; set; } = false; - [Dependency] private readonly IEntityManager _entManager = default!; - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IClyde _clyde = default!; + [Dependency] private IEntityManager _entManager = default!; + [Dependency] private IMapManager _mapManager = default!; + [Dependency] private IClyde _clyde = default!; private GasTileOverlaySystem? _gasTileOverlay; private readonly SharedTransformSystem _xformSys; private EntityQuery _overlayQuery; - private IRenderTexture? _temperatureTarget; + private readonly OverlayResourceCache _resources = new(); + private List> _grids = new(); // Cache used to transform ThermalByte into Color for overlay private readonly Color[] _colorCache = new Color[256]; @@ -152,10 +154,11 @@ protected override bool BeforeDraw(in OverlayDrawArgs args) var target = args.Viewport.RenderTarget; - if (_temperatureTarget?.Texture.Size != target.Size) + var res = _resources.GetForViewport(args.Viewport, static _ => new CachedResources()); + if (res.TemperatureTarget is null || res.TemperatureTarget.Texture.Size != target.Size) { - _temperatureTarget?.Dispose(); - _temperatureTarget = _clyde.CreateRenderTarget( + res.TemperatureTarget?.Dispose(); + res.TemperatureTarget = _clyde.CreateRenderTarget( target.Size, new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), name: nameof(GasTileDangerousTemperatureOverlay)); @@ -167,16 +170,13 @@ protected override bool BeforeDraw(in OverlayDrawArgs args) var mapId = args.MapId; var worldToViewportLocal = args.Viewport.GetWorldToLocalMatrix(); - var anyGasDrawn = false; - List> grids = new(); - - drawHandle.RenderInRenderTarget(_temperatureTarget, + drawHandle.RenderInRenderTarget(res.TemperatureTarget, () => { - grids.Clear(); - _mapManager.FindGridsIntersecting(mapId, worldAABB, ref grids); + _grids.Clear(); + _mapManager.FindGridsIntersecting(mapId, worldAABB, ref _grids); - foreach (var grid in grids) + foreach (var grid in _grids) { if (!_overlayQuery.TryGetComponent(grid.Owner, out var comp)) continue; @@ -211,8 +211,6 @@ protected override bool BeforeDraw(in OverlayDrawArgs args) if (gasColor.A <= 0f) continue; - anyGasDrawn = true; - drawHandle.DrawRect( Box2.CenteredAround(tilePosition + gridTileCenterVec, gridTileSizeVec), gasColor @@ -225,29 +223,31 @@ protected override bool BeforeDraw(in OverlayDrawArgs args) drawHandle.SetTransform(Matrix3x2.Identity); - if (!anyGasDrawn) - { - _temperatureTarget?.Dispose(); - _temperatureTarget = null; - return false; - } - return true; } protected override void Draw(in OverlayDrawArgs args) { - if (_temperatureTarget is null) - return; + var res = _resources.GetForViewport(args.Viewport, static _ => new CachedResources()); - args.WorldHandle.DrawTextureRect(_temperatureTarget.Texture, args.WorldBounds); + if (res.TemperatureTarget != null) + args.WorldHandle.DrawTextureRect(res.TemperatureTarget.Texture, args.WorldBounds); args.WorldHandle.SetTransform(Matrix3x2.Identity); } protected override void DisposeBehavior() { - _temperatureTarget?.Dispose(); - _temperatureTarget = null; + _resources.Dispose(); base.DisposeBehavior(); } + + private sealed class CachedResources : IDisposable + { + public IRenderTexture? TemperatureTarget; + + public void Dispose() + { + TemperatureTarget?.Dispose(); + } + } } diff --git a/Content.Client/Atmos/Overlays/GasTileFireOverlay.cs b/Content.Client/Atmos/Overlays/GasTileFireOverlay.cs new file mode 100644 index 00000000000..45cebef98b1 --- /dev/null +++ b/Content.Client/Atmos/Overlays/GasTileFireOverlay.cs @@ -0,0 +1,172 @@ +using Content.Client.Atmos.EntitySystems; +using Content.Shared.Atmos; +using Content.Shared.Atmos.Components; +using Content.Shared.Species; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.ResourceManagement; +using Robust.Shared.Enums; +using Robust.Shared.Graphics.RSI; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; +using System.Numerics; + +namespace Content.Client.Atmos.Overlays; + +/// +/// Overlay responsible for rendering atmos fire animation. +/// +public sealed partial class GasTileFireOverlay : Overlay +{ + [Dependency] private IPrototypeManager _protoMan = default!; + [Dependency] private IResourceCache _resourceCache = default!; + [Dependency] private IEntityManager _entManager = default!; + [Dependency] private IMapManager _mapManager = default!; + + public override OverlaySpace Space => OverlaySpace.WorldSpaceEntities | OverlaySpace.WorldSpaceBelowWorld; + private static readonly ProtoId UnshadedShader = "unshaded"; + + private readonly SharedTransformSystem _xformSys; + private readonly SharedMapSystem _mapSystem = default!; + private readonly ShaderInstance _shader; + + private readonly float[] _timer; + private readonly float[][] _frameDelays; + private readonly int[] _frameCounter; + + // TODO combine textures into a single texture atlas. + private readonly Texture[][] _frames; + + private const int FireStates = 3; + private const string FireRsiPath = "/Textures/Effects/fire.rsi"; + + public const int GasOverlayZIndex = (int)Shared.DrawDepth.DrawDepth.Effects; // Under ghosts, above mostly everything else + + public GasTileFireOverlay() + { + IoCManager.InjectDependencies(this); + _xformSys = _entManager.System(); + _mapSystem = _entManager.System(); + _shader = _protoMan.Index(UnshadedShader).Instance(); + ZIndex = GasOverlayZIndex; + + _timer = new float[FireStates]; + _frameDelays = new float[FireStates][]; + _frameCounter = new int[FireStates]; + _frames = new Texture[FireStates][]; + + var fire = _resourceCache.GetResource(FireRsiPath).RSI; + + for (var i = 0; i < FireStates; i++) + { + if (!fire.TryGetState((i + 1).ToString(), out var state)) + throw new ArgumentOutOfRangeException($"Fire RSI doesn't have state \"{i}\"!"); + + _frames[i] = state.GetFrames(RsiDirection.South); + _frameDelays[i] = state.GetDelays(); + _frameCounter[i] = 0; + } + } + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); + + for (var i = 0; i < FireStates; i++) + { + var delays = _frameDelays[i]; + if (delays.Length == 0) + continue; + + var frameCount = _frameCounter[i]; + _timer[i] += args.DeltaSeconds; + var time = delays[frameCount]; + + if (_timer[i] < time) continue; + _timer[i] -= time; + _frameCounter[i] = (frameCount + 1) % _frames[i].Length; + } + } + + protected override void Draw(in OverlayDrawArgs args) + { + if (args.MapId == MapId.Nullspace) + return; + + var drawHandle = args.WorldHandle; + var xformQuery = _entManager.GetEntityQuery(); + var overlayQuery = _entManager.GetEntityQuery(); + var gridState = (args.WorldBounds, + args.WorldHandle, + _frames, + _frameCounter, + _shader, + overlayQuery, + xformQuery, + _xformSys); + + var mapUid = _mapSystem.GetMapOrInvalid(args.MapId); + + if (args.Space != OverlaySpace.WorldSpaceEntities) + return; + + // TODO: WorldBounds callback. + _mapManager.FindGridsIntersecting(args.MapId, args.WorldAABB, ref gridState, + static (EntityUid uid, MapGridComponent grid, + ref (Box2Rotated WorldBounds, + DrawingHandleWorld drawHandle, + Texture[][] frames, + int[] frameCounter, + ShaderInstance shader, + EntityQuery overlayQuery, + EntityQuery xformQuery, + SharedTransformSystem xformSys) state) => + { + if (!state.overlayQuery.TryGetComponent(uid, out var comp) || + !state.xformQuery.TryGetComponent(uid, out var gridXform)) + { + return true; + } + + var (_, _, worldMatrix, invMatrix) = state.xformSys.GetWorldPositionRotationMatrixWithInv(gridXform); + state.drawHandle.SetTransform(worldMatrix); + var floatBounds = invMatrix.TransformBox(state.WorldBounds).Enlarged(grid.TileSize); + var localBounds = new Box2i( + (int)MathF.Floor(floatBounds.Left), + (int)MathF.Floor(floatBounds.Bottom), + (int)MathF.Ceiling(floatBounds.Right), + (int)MathF.Ceiling(floatBounds.Top)); + + // Currently it would be faster to group drawing by gas rather than by chunk, but if the textures are + // ever moved to a single atlas, that should no longer be the case. So this is just grouping draw calls + // by chunk, even though its currently slower. + + state.drawHandle.UseShader(state.shader); + foreach (var chunk in comp.Chunks.Values) + { + var enumerator = new GasChunkEnumerator(chunk); + + while (enumerator.MoveNext(out var gas)) + { + if (gas.FireState == 0) + continue; + + var index = chunk.Origin + (enumerator.X, enumerator.Y); + if (!localBounds.Contains(index)) + continue; + + var fireState = gas.FireState - 1; + var texture = state.frames[fireState][state.frameCounter[fireState]]; + state.drawHandle.DrawTexture(texture, index); + } + } + + return true; + }); + + drawHandle.UseShader(null); + drawHandle.SetTransform(Matrix3x2.Identity); + } +} diff --git a/Content.Client/Atmos/Overlays/GasTileHeatBlurOverlay.cs b/Content.Client/Atmos/Overlays/GasTileHeatBlurOverlay.cs new file mode 100644 index 00000000000..7815bec6e4a --- /dev/null +++ b/Content.Client/Atmos/Overlays/GasTileHeatBlurOverlay.cs @@ -0,0 +1,263 @@ +using Content.Client.Atmos.EntitySystems; +using Content.Client.Graphics; +using Content.Client.Resources; +using Content.Shared.Atmos; +using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; +using Content.Shared.CCVar; +using Robust.Client.Graphics; +using Robust.Client.ResourceManagement; +using Robust.Shared.Configuration; +using Robust.Shared.Enums; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Prototypes; +using System.Numerics; +using Color = Robust.Shared.Maths.Color; +using Texture = Robust.Client.Graphics.Texture; + +namespace Content.Client.Atmos.Overlays; + +/// +/// Overlay responsible for rendering heat distortion shader. +/// +public sealed partial class GasTileHeatBlurOverlay : Overlay +{ + public override bool RequestScreenTexture { get; set; } = true; + private static readonly ProtoId UnshadedShader = "unshaded"; + private static readonly ProtoId HeatOverlayShader = "HeatBlur"; + + [Dependency] private IEntityManager _entManager = default!; + [Dependency] private IMapManager _mapManager = default!; + [Dependency] private IPrototypeManager _proto = default!; + [Dependency] private IClyde _clyde = default!; + [Dependency] private IConfigurationManager _configManager = default!; + [Dependency] private IResourceCache _resourceCache = default!; + + private readonly SharedTransformSystem _xformSys; + private readonly ShaderInstance _shader; + + private readonly Texture _noiseTexture; + private readonly Texture _heatGradientTexture; + private List> _intersectingGrids = new(); + private readonly OverlayResourceCache _resources = new(); + + // Overlay settings + private const float + ShaderSpilling = 2.5f; // for example 4f - spills shader one tile from hotspot, 2.5f - spills it half tile + + private const float ShaderStrength = 0.04f; // Makes waves stronger + private const float ShaderScale = 1f; // Makes more waves + private const float ShaderSpeed = 0.4f; // Makes waves run faster + + // Overlay settings for reduced motion setting + private const float ShaderStrengthForReducedMotion = 0.01f; + private const float ShaderScaleReducedMotion = 0.5f; + private const float ShaderSpeedReducedMotion = 0.25f; + + private const int MinDistortionTemp = 300; // Distortion starts to show up at this temperature in Kelvins + private const int MaxDistortionTemp = 2000; // Maximum distortion strength at this temperature in Kelvins + + public override OverlaySpace Space => OverlaySpace.WorldSpace; + + public GasTileHeatBlurOverlay() + { + IoCManager.InjectDependencies(this); + _xformSys = _entManager.System(); + + _noiseTexture = _resourceCache.GetTexture("/Textures/Effects/HeatBlur/perlin_noise.png"); + _heatGradientTexture = _resourceCache.GetTexture("/Textures/Effects/HeatBlur/soft_circle.png"); + + _shader = _proto.Index(HeatOverlayShader).InstanceUnique(); + _configManager.OnValueChanged(CCVars.ReducedMotion, SetReducedMotion, invokeImmediately: true); + } + + private void SetReducedMotion(bool reducedMotion) + { + _shader.SetParameter("strength_scale", reducedMotion ? ShaderStrengthForReducedMotion : ShaderStrength); + _shader.SetParameter("spatial_scale", reducedMotion ? ShaderScaleReducedMotion : ShaderScale); + _shader.SetParameter("speed_scale", reducedMotion ? ShaderSpeedReducedMotion : ShaderSpeed); + } + + protected override bool BeforeDraw(in OverlayDrawArgs args) + { + if (args.MapId == MapId.Nullspace) + return false; + + var res = _resources.GetForViewport(args.Viewport, static _ => new CachedResources()); + + var target = args.Viewport.RenderTarget; + + // Probably the resolution of the game window changed, remake the textures. + if (res.HeatTarget?.Texture.Size != target.Size) + { + res.HeatTarget?.Dispose(); + res.HeatTarget = _clyde.CreateRenderTarget( + target.Size, + new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), + name: nameof(GasTileHeatBlurOverlaySystem)); + } + + if (res.HeatBlurTarget?.Texture.Size != target.Size) + { + res.HeatBlurTarget?.Dispose(); + res.HeatBlurTarget = _clyde.CreateRenderTarget( + target.Size, + new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), + name: $"{nameof(GasTileHeatBlurOverlaySystem)}-blur"); + } + + var overlayQuery = _entManager.GetEntityQuery(); + + args.WorldHandle.UseShader(_proto.Index(UnshadedShader).Instance()); + + var mapId = args.MapId; + var worldAABB = args.WorldAABB; + var worldBounds = args.WorldBounds; + var worldHandle = args.WorldHandle; + var worldToViewportLocal = args.Viewport.GetWorldToLocalMatrix(); + + // If there is no distortion after checking all visible tiles, we can bail early + var anyDistortion = false; + + // We're rendering in the context of the heat target texture, which will encode data as to where and how strong + // the heat distortion will be + args.WorldHandle.RenderInRenderTarget(res.HeatTarget, + () => + { + _intersectingGrids.Clear(); + _mapManager.FindGridsIntersecting(mapId, worldAABB, ref _intersectingGrids); + foreach (var grid in _intersectingGrids) + { + if (!overlayQuery.TryGetComponent(grid.Owner, out var comp)) + continue; + + var gridEntToWorld = _xformSys.GetWorldMatrix(grid.Owner); + var gridEntToViewportLocal = gridEntToWorld * worldToViewportLocal; + + if (!Matrix3x2.Invert(gridEntToViewportLocal, out var viewportLocalToGridEnt)) + continue; + + var uvToUi = Matrix3Helpers.CreateScale(res.HeatTarget.Size.X, -res.HeatTarget.Size.Y); + var uvToGridEnt = uvToUi * viewportLocalToGridEnt; + + // Because we want the actual distortion to be calculated based on the grid coordinates*, we need + // to pass a matrix transformation to go from the viewport coordinates to grid coordinates. + // * (why? because otherwise the effect would shimmer like crazy as you moved around, think + // moving a piece of warped glass above a picture instead of placing the warped glass on the + // paper and moving them together) + _shader.SetParameter("grid_ent_from_viewport_local", uvToGridEnt); + + // Draw commands (like DrawRect) will be using grid coordinates from here + worldHandle.SetTransform(gridEntToViewportLocal); + + // We only care about tiles that fit in these bounds + var worldToGridLocal = _xformSys.GetInvWorldMatrix(grid.Owner); + var floatBounds = worldToGridLocal.TransformBox(worldBounds).Enlarged(grid.Comp.TileSize); + + var localBounds = new Box2i( + (int)MathF.Floor(floatBounds.Left), + (int)MathF.Floor(floatBounds.Bottom), + (int)MathF.Ceiling(floatBounds.Right), + (int)MathF.Ceiling(floatBounds.Top)); + + // for each tile and its gas ---> + foreach (var chunk in comp.Chunks.Values) + { + var enumerator = new GasChunkEnumerator(chunk); + + while (enumerator.MoveNext(out var tileGas)) + { + // Check and make sure the tile is within the viewport/screen + var tilePosition = chunk.Origin + (enumerator.X, enumerator.Y); + if (!localBounds.Contains(tilePosition)) + continue; + + // Get the distortion strength from the temperature and bail if it's not hot enough + var strength = GetHeatDistortionStrength(tileGas.ByteGasTemperature); + if (strength <= 0f) + continue; + + anyDistortion = true; + + // Encode the strength in the red channel + // alpha set to 1 as tile is active + worldHandle.DrawTextureRect( + _heatGradientTexture, + Box2.CenteredAround(tilePosition + grid.Comp.TileSizeHalfVector, + grid.Comp.TileSizeVector * ShaderSpilling), + new Color(strength, 0f, 0f)); + } + } + } + }, + // This clears the buffer to all zero first... + new Color(0, 0, 0, 0)); + + // no distortion, no need to render + if (!anyDistortion) + { + args.WorldHandle.UseShader(null); + args.WorldHandle.SetTransform(Matrix3x2.Identity); + return false; + } + + return true; + } + + protected override void Draw(in OverlayDrawArgs args) + { + var res = _resources.GetForViewport(args.Viewport, static _ => new CachedResources()); + + if (ScreenTexture is null || res.HeatTarget is null || res.HeatBlurTarget is null) + return; + + _shader.SetParameter("SCREEN_TEXTURE", ScreenTexture); + _shader.SetParameter("NOISE_TEXTURE", _noiseTexture); + + args.WorldHandle.UseShader(_shader); + args.WorldHandle.DrawTextureRect(res.HeatTarget.Texture, args.WorldBounds); + + args.WorldHandle.UseShader(null); + args.WorldHandle.SetTransform(Matrix3x2.Identity); + } + + protected override void DisposeBehavior() + { + _resources.Dispose(); + + _configManager.UnsubValueChanged(CCVars.ReducedMotion, SetReducedMotion); + base.DisposeBehavior(); + } + + /// + /// Gets the strength of the heat distortion effect based on the temperature of the tile. + /// The strength is a value between 0 and 1, where 0 means no distortion and 1 means maximum distortion. + /// + /// The temperature of the tile. + /// The strength of the heat distortion effect. + /// + private static float GetHeatDistortionStrength(ThermalByte temp) + { + if (!temp.TryGetTemperature(out var kelvinTemp)) + { + return 0f; + } + + var strength = (kelvinTemp - MinDistortionTemp) / (MaxDistortionTemp - MinDistortionTemp); + + return MathHelper.Clamp01(strength); + } + + internal sealed class CachedResources : IDisposable + { + public IRenderTexture? HeatTarget; + public IRenderTexture? HeatBlurTarget; + + public void Dispose() + { + HeatTarget?.Dispose(); + HeatBlurTarget?.Dispose(); + } + } +} diff --git a/Content.Client/Atmos/Overlays/GasTileOverlay.cs b/Content.Client/Atmos/Overlays/GasTileOverlay.cs deleted file mode 100644 index eeb10b54d03..00000000000 --- a/Content.Client/Atmos/Overlays/GasTileOverlay.cs +++ /dev/null @@ -1,302 +0,0 @@ -using System.Numerics; -using Content.Client.Atmos.Components; -using Content.Client.Atmos.EntitySystems; -using Content.Shared.Atmos; -using Content.Shared.Atmos.Components; -using Content.Shared.Atmos.EntitySystems; -using Content.Shared.Atmos.Prototypes; -using Robust.Client.GameObjects; -using Robust.Client.Graphics; -using Robust.Client.ResourceManagement; -using Robust.Shared.Enums; -using Robust.Shared.Graphics.RSI; -using Robust.Shared.Map; -using Robust.Shared.Map.Components; -using Robust.Shared.Prototypes; -using Robust.Shared.Timing; -using Robust.Shared.Utility; - -namespace Content.Client.Atmos.Overlays -{ - public sealed class GasTileOverlay : Overlay - { - private static readonly ProtoId UnshadedShader = "unshaded"; - - private readonly IEntityManager _entManager; - private readonly IMapManager _mapManager; - private readonly SharedAtmosphereSystem _atmosphereSystem; - private readonly SharedMapSystem _mapSystem; - private readonly SharedTransformSystem _xformSys; - - public override OverlaySpace Space => OverlaySpace.WorldSpaceEntities | OverlaySpace.WorldSpaceBelowWorld; - private readonly ShaderInstance _shader; - - // Gas overlays - private readonly float[] _timer; - private readonly float[][] _frameDelays; - private readonly int[] _frameCounter; - - // TODO combine textures into a single texture atlas. - private readonly Texture[][] _frames; - - // Fire overlays - private const int FireStates = 3; - private const string FireRsiPath = "/Textures/Effects/fire.rsi"; - - private readonly float[] _fireTimer = new float[FireStates]; - private readonly float[][] _fireFrameDelays = new float[FireStates][]; - private readonly int[] _fireFrameCounter = new int[FireStates]; - private readonly Texture[][] _fireFrames = new Texture[FireStates][]; - - private int _gasCount; - - public const int GasOverlayZIndex = (int) Shared.DrawDepth.DrawDepth.Effects; // Under ghosts, above mostly everything else - - public GasTileOverlay(GasTileOverlaySystem system, IEntityManager entManager, IResourceCache resourceCache, IPrototypeManager protoMan, SpriteSystem spriteSys, SharedTransformSystem xformSys) - { - _entManager = entManager; - _mapManager = IoCManager.Resolve(); - _atmosphereSystem = entManager.System(); - _mapSystem = entManager.System(); - _xformSys = xformSys; - _shader = protoMan.Index(UnshadedShader).Instance(); - ZIndex = GasOverlayZIndex; - - _gasCount = system.VisibleGasId.Length; - _timer = new float[_gasCount]; - _frameDelays = new float[_gasCount][]; - _frameCounter = new int[_gasCount]; - _frames = new Texture[_gasCount][]; - - for (var i = 0; i < _gasCount; i++) - { - var gasPrototype = _atmosphereSystem.GetGas(system.VisibleGasId[i]); - - SpriteSpecifier overlay; - - if (!string.IsNullOrEmpty(gasPrototype.GasOverlaySprite) && !string.IsNullOrEmpty(gasPrototype.GasOverlayState)) - overlay = new SpriteSpecifier.Rsi(new (gasPrototype.GasOverlaySprite), gasPrototype.GasOverlayState); - else if (!string.IsNullOrEmpty(gasPrototype.GasOverlayTexture)) - overlay = new SpriteSpecifier.Texture(new (gasPrototype.GasOverlayTexture)); - else - continue; - - switch (overlay) - { - case SpriteSpecifier.Rsi animated: - var rsi = resourceCache.GetResource(animated.RsiPath).RSI; - var stateId = animated.RsiState; - - if (!rsi.TryGetState(stateId, out var state)) - continue; - - _frames[i] = state.GetFrames(RsiDirection.South); - _frameDelays[i] = state.GetDelays(); - _frameCounter[i] = 0; - break; - case SpriteSpecifier.Texture texture: - _frames[i] = new[] { spriteSys.Frame0(texture) }; - _frameDelays[i] = Array.Empty(); - break; - } - } - - var fire = resourceCache.GetResource(FireRsiPath).RSI; - - for (var i = 0; i < FireStates; i++) - { - if (!fire.TryGetState((i + 1).ToString(), out var state)) - throw new ArgumentOutOfRangeException($"Fire RSI doesn't have state \"{i}\"!"); - - _fireFrames[i] = state.GetFrames(RsiDirection.South); - _fireFrameDelays[i] = state.GetDelays(); - _fireFrameCounter[i] = 0; - } - } - protected override void FrameUpdate(FrameEventArgs args) - { - base.FrameUpdate(args); - - for (var i = 0; i < _gasCount; i++) - { - var delays = _frameDelays[i]; - if (delays.Length == 0) - continue; - - var frameCount = _frameCounter[i]; - _timer[i] += args.DeltaSeconds; - var time = delays[frameCount]; - - if (_timer[i] < time) - continue; - - _timer[i] -= time; - _frameCounter[i] = (frameCount + 1) % _frames[i].Length; - } - - for (var i = 0; i < FireStates; i++) - { - var delays = _fireFrameDelays[i]; - if (delays.Length == 0) - continue; - - var frameCount = _fireFrameCounter[i]; - _fireTimer[i] += args.DeltaSeconds; - var time = delays[frameCount]; - - if (_fireTimer[i] < time) continue; - _fireTimer[i] -= time; - _fireFrameCounter[i] = (frameCount + 1) % _fireFrames[i].Length; - } - } - - protected override void Draw(in OverlayDrawArgs args) - { - if (args.MapId == MapId.Nullspace) - return; - - var drawHandle = args.WorldHandle; - var xformQuery = _entManager.GetEntityQuery(); - var overlayQuery = _entManager.GetEntityQuery(); - var gridState = (args.WorldBounds, - args.WorldHandle, - _gasCount, - _frames, - _frameCounter, - _fireFrames, - _fireFrameCounter, - _shader, - overlayQuery, - xformQuery, - _xformSys); - - var mapUid = _mapSystem.GetMapOrInvalid(args.MapId); - - if (_entManager.TryGetComponent(mapUid, out var atmos)) - DrawMapOverlay(drawHandle, args, mapUid, atmos); - - if (args.Space != OverlaySpace.WorldSpaceEntities) - return; - - // TODO: WorldBounds callback. - _mapManager.FindGridsIntersecting(args.MapId, args.WorldAABB, ref gridState, - static (EntityUid uid, MapGridComponent grid, - ref (Box2Rotated WorldBounds, - DrawingHandleWorld drawHandle, - int gasCount, - Texture[][] frames, - int[] frameCounter, - Texture[][] fireFrames, - int[] fireFrameCounter, - ShaderInstance shader, - EntityQuery overlayQuery, - EntityQuery xformQuery, - SharedTransformSystem xformSys) state) => - { - if (!state.overlayQuery.TryGetComponent(uid, out var comp) || - !state.xformQuery.TryGetComponent(uid, out var gridXform)) - { - return true; - } - - var (_, _, worldMatrix, invMatrix) = state.xformSys.GetWorldPositionRotationMatrixWithInv(gridXform); - state.drawHandle.SetTransform(worldMatrix); - var floatBounds = invMatrix.TransformBox(state.WorldBounds).Enlarged(grid.TileSize); - var localBounds = new Box2i( - (int) MathF.Floor(floatBounds.Left), - (int) MathF.Floor(floatBounds.Bottom), - (int) MathF.Ceiling(floatBounds.Right), - (int) MathF.Ceiling(floatBounds.Top)); - - // Currently it would be faster to group drawing by gas rather than by chunk, but if the textures are - // ever moved to a single atlas, that should no longer be the case. So this is just grouping draw calls - // by chunk, even though its currently slower. - - state.drawHandle.UseShader(null); - foreach (var chunk in comp.Chunks.Values) - { - var enumerator = new GasChunkEnumerator(chunk); - - while (enumerator.MoveNext(out var gas)) - { - if (gas.Opacity == null!) - continue; - - var tilePosition = chunk.Origin + (enumerator.X, enumerator.Y); - if (!localBounds.Contains(tilePosition)) - continue; - - for (var i = 0; i < state.gasCount; i++) - { - var opacity = gas.Opacity[i]; - if (opacity > 0) - state.drawHandle.DrawTexture(state.frames[i][state.frameCounter[i]], tilePosition, Color.White.WithAlpha(opacity)); - } - } - } - - // And again for fire, with the unshaded shader - state.drawHandle.UseShader(state.shader); - foreach (var chunk in comp.Chunks.Values) - { - var enumerator = new GasChunkEnumerator(chunk); - - while (enumerator.MoveNext(out var gas)) - { - if (gas.FireState == 0) - continue; - - var index = chunk.Origin + (enumerator.X, enumerator.Y); - if (!localBounds.Contains(index)) - continue; - - var fireState = gas.FireState - 1; - var texture = state.fireFrames[fireState][state.fireFrameCounter[fireState]]; - state.drawHandle.DrawTexture(texture, index); - } - } - - return true; - }); - - drawHandle.UseShader(null); - drawHandle.SetTransform(Matrix3x2.Identity); - } - - private void DrawMapOverlay( - DrawingHandleWorld handle, - OverlayDrawArgs args, - EntityUid map, - MapAtmosphereComponent atmos) - { - var mapGrid = _entManager.HasComponent(map); - - // map-grid atmospheres get drawn above grids - if (mapGrid && args.Space != OverlaySpace.WorldSpaceEntities) - return; - - // Normal map atmospheres get drawn below grids - if (!mapGrid && args.Space != OverlaySpace.WorldSpaceBelowWorld) - return; - - var bottomLeft = args.WorldAABB.BottomLeft.Floored(); - var topRight = args.WorldAABB.TopRight.Ceiled(); - - for (var x = bottomLeft.X; x <= topRight.X; x++) - { - for (var y = bottomLeft.Y; y <= topRight.Y; y++) - { - var tilePosition = new Vector2(x, y); - - for (var i = 0; i < atmos.OverlayData.Opacity.Length; i++) - { - var opacity = atmos.OverlayData.Opacity[i]; - - if (opacity > 0) - handle.DrawTexture(_frames[i][_frameCounter[i]], tilePosition, Color.White.WithAlpha(opacity)); - } - } - } - } - } -} diff --git a/Content.Client/Atmos/Overlays/GasTileVisibleGasOverlay.cs b/Content.Client/Atmos/Overlays/GasTileVisibleGasOverlay.cs new file mode 100644 index 00000000000..d5b21aeabe1 --- /dev/null +++ b/Content.Client/Atmos/Overlays/GasTileVisibleGasOverlay.cs @@ -0,0 +1,248 @@ +using Content.Client.Atmos.Components; +using Content.Shared.Atmos; +using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.ResourceManagement; +using Robust.Shared.Enums; +using Robust.Shared.Graphics.RSI; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; +using Robust.Shared.Utility; +using System.Numerics; +using DrawDepth = Content.Shared.DrawDepth.DrawDepth; + +namespace Content.Client.Atmos.Overlays; + +/// +/// Overlay responsible for rendering visible atmos gasses (like plasma for example) usin. +/// +public sealed partial class GasTileVisibleGasOverlay : Overlay +{ + [Dependency] private IEntityManager _entManager = default!; + [Dependency] private IResourceCache _resourceCache = default!; + [Dependency] private IPrototypeManager _protoManager = default!; + [Dependency] private IMapManager _mapManager = default!; + + private static readonly ProtoId UnshadedShader = "unshaded"; + + private readonly SharedAtmosphereSystem _atmosphereSystem; + private readonly SharedMapSystem _mapSystem; + private readonly SharedTransformSystem _xformSys; + private readonly SharedGasTileOverlaySystem _gasTileOverlaySystem; + private readonly SpriteSystem _spriteSystem; + + public override OverlaySpace Space => OverlaySpace.WorldSpaceEntities | OverlaySpace.WorldSpaceBelowWorld; + private readonly ShaderInstance _shader; + + // Gas overlays + private readonly float[] _timer; + private readonly float[][] _frameDelays; + private readonly int[] _frameCounter; + + // TODO combine textures into a single texture atlas. + private readonly Texture[][] _frames; + + private readonly int _gasCount; + + public const int GasOverlayZIndex = (int)DrawDepth.Gasses; // Under ghosts and fire, above mostly everything else + + public GasTileVisibleGasOverlay() + { + IoCManager.InjectDependencies(this); + _atmosphereSystem = _entManager.System(); + _mapSystem = _entManager.System(); + _xformSys = _entManager.System(); + _gasTileOverlaySystem = _entManager.System(); + _spriteSystem = _entManager.System(); + + _shader = _protoManager.Index(UnshadedShader).Instance(); + ZIndex = GasOverlayZIndex; + + _gasCount = _gasTileOverlaySystem.VisibleGasId.Length; + _timer = new float[_gasCount]; + _frameDelays = new float[_gasCount][]; + _frameCounter = new int[_gasCount]; + _frames = new Texture[_gasCount][]; + + for (var i = 0; i < _gasCount; i++) + { + var gasPrototype = _atmosphereSystem.GetGas(_gasTileOverlaySystem.VisibleGasId[i]); + + switch (gasPrototype.GasOverlaySprite) + { + case SpriteSpecifier.Rsi animated: + var rsi = _resourceCache.GetResource(animated.RsiPath).RSI; + var stateId = animated.RsiState; + + if (!rsi.TryGetState(stateId, out var state)) + continue; + + _frames[i] = state.GetFrames(RsiDirection.South); + _frameDelays[i] = state.GetDelays(); + _frameCounter[i] = 0; + break; + case SpriteSpecifier.Texture texture: + _frames[i] = new[] { _spriteSystem.Frame0(texture) }; + _frameDelays[i] = Array.Empty(); + break; + } + } + } + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); + + for (var i = 0; i < _gasCount; i++) + { + var delays = _frameDelays[i]; + if (delays.Length == 0) + continue; + + var frameCount = _frameCounter[i]; + _timer[i] += args.DeltaSeconds; + var time = delays[frameCount]; + + if (_timer[i] < time) + continue; + + _timer[i] -= time; + _frameCounter[i] = (frameCount + 1) % _frames[i].Length; + } + } + + protected override void Draw(in OverlayDrawArgs args) + { + if (args.MapId == MapId.Nullspace) + return; + + var drawHandle = args.WorldHandle; + var xformQuery = _entManager.GetEntityQuery(); + var overlayQuery = _entManager.GetEntityQuery(); + var gridState = (args.WorldBounds, + args.WorldHandle, + _gasCount, + _frames, + _frameCounter, + _shader, + overlayQuery, + xformQuery, + _xformSys); + + var mapUid = _mapSystem.GetMapOrInvalid(args.MapId); + + if (_entManager.TryGetComponent(mapUid, out var atmos)) + DrawMapOverlay(drawHandle, args, mapUid, atmos); + + if (args.Space != OverlaySpace.WorldSpaceEntities) + return; + + // TODO: WorldBounds callback. + _mapManager.FindGridsIntersecting(args.MapId, + args.WorldAABB, + ref gridState, + static (EntityUid uid, + MapGridComponent grid, + ref (Box2Rotated WorldBounds, + DrawingHandleWorld drawHandle, + int gasCount, + Texture[][] frames, + int[] frameCounter, + ShaderInstance shader, + EntityQuery overlayQuery, + EntityQuery xformQuery, + SharedTransformSystem xformSys) state) => + { + if (!state.overlayQuery.TryGetComponent(uid, out var comp) || + !state.xformQuery.TryGetComponent(uid, out var gridXform)) + { + return true; + } + + var (_, _, worldMatrix, invMatrix) = state.xformSys.GetWorldPositionRotationMatrixWithInv(gridXform); + state.drawHandle.SetTransform(worldMatrix); + var floatBounds = invMatrix.TransformBox(state.WorldBounds).Enlarged(grid.TileSize); + var localBounds = new Box2i( + (int)MathF.Floor(floatBounds.Left), + (int)MathF.Floor(floatBounds.Bottom), + (int)MathF.Ceiling(floatBounds.Right), + (int)MathF.Ceiling(floatBounds.Top)); + + // Currently it would be faster to group drawing by gas rather than by chunk, but if the textures are + // ever moved to a single atlas, that should no longer be the case. So this is just grouping draw calls + // by chunk, even though its currently slower. + + state.drawHandle.UseShader(null); + foreach (var chunk in comp.Chunks.Values) + { + var enumerator = new GasChunkEnumerator(chunk); + + while (enumerator.MoveNext(out var gas)) + { + if (gas.Opacity == null!) + continue; + + var tilePosition = chunk.Origin + (enumerator.X, enumerator.Y); + if (!localBounds.Contains(tilePosition)) + continue; + + for (var i = 0; i < state.gasCount; i++) + { + var opacity = gas.Opacity[i]; + if (opacity > 0) + { + state.drawHandle.DrawTexture(state.frames[i][state.frameCounter[i]], + tilePosition, + Color.White.WithAlpha(opacity)); + } + } + } + } + + return true; + }); + + drawHandle.UseShader(null); + drawHandle.SetTransform(Matrix3x2.Identity); + } + + private void DrawMapOverlay( + DrawingHandleWorld handle, + OverlayDrawArgs args, + EntityUid map, + MapAtmosphereComponent atmos) + { + var mapGrid = _entManager.HasComponent(map); + + // map-grid atmospheres get drawn above grids + if (mapGrid && args.Space != OverlaySpace.WorldSpaceEntities) + return; + + // Normal map atmospheres get drawn below grids + if (!mapGrid && args.Space != OverlaySpace.WorldSpaceBelowWorld) + return; + + var bottomLeft = args.WorldAABB.BottomLeft.Floored(); + var topRight = args.WorldAABB.TopRight.Ceiled(); + + for (var x = bottomLeft.X; x <= topRight.X; x++) + { + for (var y = bottomLeft.Y; y <= topRight.Y; y++) + { + var tilePosition = new Vector2(x, y); + + for (var i = 0; i < atmos.OverlayData.Opacity.Length; i++) + { + var opacity = atmos.OverlayData.Opacity[i]; + + if (opacity > 0) + handle.DrawTexture(_frames[i][_frameCounter[i]], tilePosition, Color.White.WithAlpha(opacity)); + } + } + } + } +} diff --git a/Content.Client/Atmos/Piping/Binary/Systems/GasVolumePumpSystem.cs b/Content.Client/Atmos/Piping/Binary/Systems/GasVolumePumpSystem.cs index f615d9a8927..83623a68f12 100644 --- a/Content.Client/Atmos/Piping/Binary/Systems/GasVolumePumpSystem.cs +++ b/Content.Client/Atmos/Piping/Binary/Systems/GasVolumePumpSystem.cs @@ -4,9 +4,9 @@ namespace Content.Client.Atmos.Piping.Binary.Systems; -public sealed class GasVolumePumpSystem : SharedGasVolumePumpSystem +public sealed partial class GasVolumePumpSystem : SharedGasVolumePumpSystem { - [Dependency] private readonly UserInterfaceSystem _ui = default!; + [Dependency] private UserInterfaceSystem _ui = default!; public override void Initialize() { diff --git a/Content.Client/Atmos/Piping/Unary/Systems/GasCanisterSystem.cs b/Content.Client/Atmos/Piping/Unary/Systems/GasCanisterSystem.cs index cae184edbb7..13513e2a957 100644 --- a/Content.Client/Atmos/Piping/Unary/Systems/GasCanisterSystem.cs +++ b/Content.Client/Atmos/Piping/Unary/Systems/GasCanisterSystem.cs @@ -1,4 +1,5 @@ using Content.Client.Atmos.UI; +using Content.Shared.Atmos.Components; using Content.Shared.Atmos.Piping.Binary.Components; using Content.Shared.Atmos.Piping.Unary.Components; using Content.Shared.Atmos.Piping.Unary.Systems; @@ -14,6 +15,12 @@ public override void Initialize() SubscribeLocalEvent(OnGasState); } + protected override void DeviceUpdated(Entity entity, ref AtmosDeviceUpdateEvent args) + { + // Atmos not predicted :( + throw new NotImplementedException(); + } + private void OnGasState(Entity ent, ref AfterAutoHandleStateEvent args) { if (UI.TryGetOpenUi(ent.Owner, GasCanisterUiKey.Key, out var bui)) diff --git a/Content.Client/Atmos/Piping/Unary/Systems/GasThermoMachineSystem.cs b/Content.Client/Atmos/Piping/Unary/Systems/GasThermoMachineSystem.cs index bd75fa00956..647852b8a98 100644 --- a/Content.Client/Atmos/Piping/Unary/Systems/GasThermoMachineSystem.cs +++ b/Content.Client/Atmos/Piping/Unary/Systems/GasThermoMachineSystem.cs @@ -4,9 +4,9 @@ namespace Content.Client.Atmos.Piping.Unary.Systems; -public sealed class GasThermoMachineSystem : SharedGasThermoMachineSystem +public sealed partial class GasThermoMachineSystem : SharedGasThermoMachineSystem { - [Dependency] private readonly SharedUserInterfaceSystem _ui = default!; + [Dependency] private SharedUserInterfaceSystem _ui = default!; public override void Initialize() { diff --git a/Content.Client/Atmos/UI/GasAnalyzerBoundUserInterface.cs b/Content.Client/Atmos/UI/GasAnalyzerBoundUserInterface.cs index 3a5df3f9a88..c8f2091d133 100644 --- a/Content.Client/Atmos/UI/GasAnalyzerBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasAnalyzerBoundUserInterface.cs @@ -1,41 +1,33 @@ -using Robust.Client.GameObjects; using Robust.Client.UserInterface; -using static Content.Shared.Atmos.Components.GasAnalyzerComponent; +using Content.Shared.Atmos.Components; -namespace Content.Client.Atmos.UI +namespace Content.Client.Atmos.UI; + +public sealed class GasAnalyzerBoundUserInterface : BoundUserInterface { - public sealed class GasAnalyzerBoundUserInterface : BoundUserInterface + [ViewVariables] + private GasAnalyzerWindow? _window; + + public GasAnalyzerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + } + + protected override void Open() { - [ViewVariables] - private GasAnalyzerWindow? _window; - - public GasAnalyzerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) - { - } - - protected override void Open() - { - base.Open(); - - _window = this.CreateWindowCenteredLeft(); - _window.OnClose += Close; - } - - protected override void ReceiveMessage(BoundUserInterfaceMessage message) - { - if (_window == null) - return; - if (message is not GasAnalyzerUserMessage cast) - return; - _window.Populate(cast); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - _window?.Dispose(); - } + base.Open(); + + _window = this.CreateWindowCenteredLeft(); + _window.OnClose += Close; + } + + protected override void ReceiveMessage(BoundUserInterfaceMessage message) + { + if (_window == null) + return; + + if (message is not GasAnalyzerUserMessage cast) + return; + + _window.Populate(cast); } } diff --git a/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs b/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs index 63b4e6b0c6f..94a9f237453 100644 --- a/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs +++ b/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs @@ -1,6 +1,8 @@ using System.Numerics; using Content.Client.UserInterface.Controls; using Content.Shared.Atmos; +using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; using Content.Shared.Temperature; using Robust.Client.Graphics; using Robust.Client.UserInterface; @@ -8,7 +10,6 @@ using Robust.Client.UserInterface.CustomControls; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.XAML; -using static Content.Shared.Atmos.Components.GasAnalyzerComponent; using Direction = Robust.Shared.Maths.Direction; namespace Content.Client.Atmos.UI @@ -16,25 +17,17 @@ namespace Content.Client.Atmos.UI [GenerateTypedNameReferences] public sealed partial class GasAnalyzerWindow : DefaultWindow { + private readonly SharedAtmosphereSystem _atmosphere; private NetEntity _currentEntity = NetEntity.Invalid; public GasAnalyzerWindow() { RobustXamlLoader.Load(this); + _atmosphere = IoCManager.Resolve().System(); } public void Populate(GasAnalyzerUserMessage msg) { - if (msg.Error != null) - { - CTopBox.AddChild(new Label - { - Text = Loc.GetString("gas-analyzer-window-error-text", ("errorText", msg.Error)), - FontColorOverride = Color.Red - }); - return; - } - if (msg.NodeGasMixes.Length == 0) { CTopBox.AddChild(new Label @@ -329,31 +322,31 @@ private void GenerateGasDisplay(GasMixEntry gasMix, Control parent) for (var j = 0; j < gasMix.Gases.Length; j++) { - var gas = gasMix.Gases[j]; - var color = Color.FromHex($"#{gas.Color}", Color.White); + var gasEntry = gasMix.Gases[j]; + var gasProto = _atmosphere.GetGas(gasEntry.Gas); // Add to the table tableKey.AddChild(new Label { - Text = Loc.GetString(gas.Name) + Text = Loc.GetString(gasProto.Name) }); tableVal.AddChild(new Label { Text = Loc.GetString("gas-analyzer-window-molarity-text", - ("mol", $"{gas.Amount:0.00}")), + ("mol", $"{gasEntry.Amount:0.00}")), Align = Label.AlignMode.Right, }); tablePercent.AddChild(new Label { Text = Loc.GetString("gas-analyzer-window-percentage-text", - ("percentage", $"{(gas.Amount / totalGasAmount * 100):0.0}")), + ("percentage", $"{(gasEntry.Amount / totalGasAmount * 100):0.0}")), Align = Label.AlignMode.Right }); // Add to the gas bar //TODO: highlight the currently hover one - gasBar.AddEntry(gas.Amount, color, tooltip: Loc.GetString("gas-analyzer-window-molarity-percentage-text", - ("gasName", gas.Name), - ("amount", $"{gas.Amount:0.##}"), - ("percentage", $"{(gas.Amount / totalGasAmount * 100):0.#}"))); + gasBar.AddEntry(gasEntry.Amount, gasProto.Color, tooltip: Loc.GetString("gas-analyzer-window-molarity-percentage-text", + ("gasName", Loc.GetString(gasProto.Name)), + ("amount", $"{gasEntry.Amount:0.##}"), + ("percentage", $"{(gasEntry.Amount / totalGasAmount * 100):0.#}"))); } dataContainer.AddChild(gasBar); diff --git a/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs b/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs index 0456426b1fc..56be898a01d 100644 --- a/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs @@ -74,7 +74,7 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetTankPressure(cast.TankPressure); _window.SetReleasePressureRange(component.MinReleasePressure, component.MaxReleasePressure); _window.SetReleasePressure(component.ReleasePressure); - _window.SetReleaseValve(component.ReleaseValve); + _window.SetReleaseValve(component.ReleaseValveOpen); } protected override void Dispose(bool disposing) diff --git a/Content.Client/Atmos/UI/GasThermomachineWindow.xaml.cs b/Content.Client/Atmos/UI/GasThermomachineWindow.xaml.cs index dd384fa6104..20205cb34d3 100644 --- a/Content.Client/Atmos/UI/GasThermomachineWindow.xaml.cs +++ b/Content.Client/Atmos/UI/GasThermomachineWindow.xaml.cs @@ -10,7 +10,7 @@ namespace Content.Client.Atmos.UI; [GenerateTypedNameReferences] public sealed partial class GasThermomachineWindow : FancyWindow { - [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private IEntityManager _entManager = default!; public FloatSpinBox TemperatureSpinbox; diff --git a/Content.Client/Audio/AmbientOverlayCommand.cs b/Content.Client/Audio/AmbientOverlayCommand.cs index 7bbc6c6cbfe..0730cd4a144 100644 --- a/Content.Client/Audio/AmbientOverlayCommand.cs +++ b/Content.Client/Audio/AmbientOverlayCommand.cs @@ -2,9 +2,9 @@ namespace Content.Client.Audio; -public sealed class AmbientOverlayCommand : LocalizedEntityCommands +public sealed partial class AmbientOverlayCommand : LocalizedEntityCommands { - [Dependency] private readonly AmbientSoundSystem _ambient = default!; + [Dependency] private AmbientSoundSystem _ambient = default!; public override string Command => "showambient"; diff --git a/Content.Client/Audio/AmbientSoundSystem.cs b/Content.Client/Audio/AmbientSoundSystem.cs index 9929751b22d..967eae6ae55 100644 --- a/Content.Client/Audio/AmbientSoundSystem.cs +++ b/Content.Client/Audio/AmbientSoundSystem.cs @@ -20,16 +20,16 @@ namespace Content.Client.Audio; /// /// Samples nearby and plays audio. /// -public sealed class AmbientSoundSystem : SharedAmbientSoundSystem +public sealed partial class AmbientSoundSystem : SharedAmbientSoundSystem { - [Dependency] private readonly AmbientSoundTreeSystem _treeSys = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly SharedTransformSystem _xformSystem = default!; - [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly IOverlayManager _overlayManager = default!; - [Dependency] private readonly IPlayerManager _playerManager = default!; - [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private AmbientSoundTreeSystem _treeSys = default!; + [Dependency] private SharedAudioSystem _audio = default!; + [Dependency] private SharedTransformSystem _xformSystem = default!; + [Dependency] private IConfigurationManager _cfg = default!; + [Dependency] private IGameTiming _gameTiming = default!; + [Dependency] private IOverlayManager _overlayManager = default!; + [Dependency] private IPlayerManager _playerManager = default!; + [Dependency] private IRobustRandom _random = default!; protected override void QueueUpdate(EntityUid uid, AmbientSoundComponent ambience) => _treeSys.QueueTreeUpdate(uid, ambience); @@ -235,8 +235,6 @@ private static bool Callback( /// private void ProcessNearbyAmbience(TransformComponent playerXform) { - var query = GetEntityQuery(); - var metaQuery = GetEntityQuery(); var mapPos = _xformSystem.GetMapCoordinates(playerXform); // Remove out-of-range ambiences @@ -249,9 +247,9 @@ private void ProcessNearbyAmbience(TransformComponent playerXform) if (comp.Enabled && // Don't keep playing sounds that have changed since. sound.Sound == comp.Sound && - query.TryGetComponent(owner, out var xform) && + TryComp(owner, out TransformComponent? xform) && xform.MapID == playerXform.MapID && - !metaQuery.GetComponent(owner).EntityPaused) + !Paused(owner)) { // TODO: This is just trydistance for coordinates. var distance = (xform.ParentUid == playerXform.ParentUid) @@ -294,7 +292,7 @@ private void ProcessNearbyAmbience(TransformComponent playerXform) var comp = sourceEntity.Comp; if (_playingSounds.ContainsKey(sourceEntity) || - metaQuery.GetComponent(uid).EntityPaused) + Paused(uid)) continue; var audioParams = _params diff --git a/Content.Client/Audio/AmbientSoundTreeSystem.cs b/Content.Client/Audio/AmbientSoundTreeSystem.cs index 7a9439c9df1..28443744525 100644 --- a/Content.Client/Audio/AmbientSoundTreeSystem.cs +++ b/Content.Client/Audio/AmbientSoundTreeSystem.cs @@ -23,8 +23,7 @@ protected override Box2 ExtractAabb(in ComponentTreeEntry var pos = XformSystem.GetRelativePosition( entry.Transform, - entry.Component.TreeUid.Value, - GetEntityQuery()); + entry.Component.TreeUid.Value); return ExtractAabb(in entry, pos, default); } diff --git a/Content.Client/Audio/AudioUIController.cs b/Content.Client/Audio/AudioUIController.cs index 16e1edd2523..779f56d619c 100644 --- a/Content.Client/Audio/AudioUIController.cs +++ b/Content.Client/Audio/AudioUIController.cs @@ -7,11 +7,11 @@ namespace Content.Client.Audio; -public sealed class AudioUIController : UIController +public sealed partial class AudioUIController : UIController { - [Dependency] private readonly IAudioManager _audioManager = default!; - [Dependency] private readonly IConfigurationManager _configManager = default!; - [Dependency] private readonly IResourceCache _cache = default!; + [Dependency] private IAudioManager _audioManager = default!; + [Dependency] private IConfigurationManager _configManager = default!; + [Dependency] private IResourceCache _cache = default!; private float _interfaceGain; private IAudioSource? _clickSource; diff --git a/Content.Client/Audio/ClientGlobalSoundSystem.cs b/Content.Client/Audio/ClientGlobalSoundSystem.cs index 882ab1be6d3..b077c1c30fc 100644 --- a/Content.Client/Audio/ClientGlobalSoundSystem.cs +++ b/Content.Client/Audio/ClientGlobalSoundSystem.cs @@ -8,10 +8,10 @@ namespace Content.Client.Audio; -public sealed class ClientGlobalSoundSystem : SharedGlobalSoundSystem +public sealed partial class ClientGlobalSoundSystem : SharedGlobalSoundSystem { - [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private IConfigurationManager _cfg = default!; + [Dependency] private SharedAudioSystem _audio = default!; // Admin music private bool _adminAudioEnabled = true; diff --git a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs index d82f6b07fbb..b54513800e5 100644 --- a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs +++ b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs @@ -20,15 +20,15 @@ namespace Content.Client.Audio; public sealed partial class ContentAudioSystem { - [Dependency] private readonly IConfigurationManager _configManager = default!; - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly ILogManager _logManager = default!; - [Dependency] private readonly IPlayerManager _player = default!; - [Dependency] private readonly IPrototypeManager _proto = default!; - [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly IStateManager _state = default!; - [Dependency] private readonly RulesSystem _rules = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private IConfigurationManager _configManager = default!; + [Dependency] private IGameTiming _timing = default!; + [Dependency] private ILogManager _logManager = default!; + [Dependency] private IPlayerManager _player = default!; + [Dependency] private IPrototypeManager _proto = default!; + [Dependency] private IRobustRandom _random = default!; + [Dependency] private IStateManager _state = default!; + [Dependency] private RulesSystem _rules = default!; + [Dependency] private SharedAudioSystem _audio = default!; private readonly TimeSpan _minAmbienceTime = TimeSpan.FromSeconds(30); private readonly TimeSpan _maxAmbienceTime = TimeSpan.FromSeconds(60); diff --git a/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs b/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs index fda2c0062c7..e6056a9bc8c 100644 --- a/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs +++ b/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs @@ -18,9 +18,9 @@ namespace Content.Client.Audio; // Part of ContentAudioSystem that is responsible for lobby music playing/stopping and round-end sound-effect. public sealed partial class ContentAudioSystem { - [Dependency] private readonly IBaseClient _client = default!; - [Dependency] private readonly ClientGameTicker _gameTicker = default!; - [Dependency] private readonly IResourceCache _resourceCache = default!; + [Dependency] private IBaseClient _client = default!; + [Dependency] private ClientGameTicker _gameTicker = default!; + [Dependency] private IResourceCache _resourceCache = default!; private readonly AudioParams _lobbySoundtrackParams = new(-5f, 1, 0, 0, 0, false, 0f); private readonly AudioParams _roundEndSoundEffectParams = new(-5f, 1, 0, 0, 0, false, 0f); diff --git a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs index 510b9d3def3..acebfc9169d 100644 --- a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs +++ b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs @@ -6,9 +6,9 @@ namespace Content.Client.Audio.Jukebox; -public sealed class JukeboxBoundUserInterface : BoundUserInterface +public sealed partial class JukeboxBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private IPrototypeManager _protoManager = default!; [ViewVariables] private JukeboxMenu? _menu; diff --git a/Content.Client/Audio/Jukebox/JukeboxMenu.xaml.cs b/Content.Client/Audio/Jukebox/JukeboxMenu.xaml.cs index e0904eece86..d0ac6f53ad8 100644 --- a/Content.Client/Audio/Jukebox/JukeboxMenu.xaml.cs +++ b/Content.Client/Audio/Jukebox/JukeboxMenu.xaml.cs @@ -15,7 +15,7 @@ namespace Content.Client.Audio.Jukebox; [GenerateTypedNameReferences] public sealed partial class JukeboxMenu : FancyWindow { - [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private IEntityManager _entManager = default!; private AudioSystem _audioSystem; /// diff --git a/Content.Client/Audio/Jukebox/JukeboxSystem.cs b/Content.Client/Audio/Jukebox/JukeboxSystem.cs index feb4aef3b21..0194c1ccbdf 100644 --- a/Content.Client/Audio/Jukebox/JukeboxSystem.cs +++ b/Content.Client/Audio/Jukebox/JukeboxSystem.cs @@ -6,13 +6,13 @@ namespace Content.Client.Audio.Jukebox; -public sealed class JukeboxSystem : SharedJukeboxSystem +public sealed partial class JukeboxSystem : SharedJukeboxSystem { - [Dependency] private readonly IPrototypeManager _protoManager = default!; - [Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!; - [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; - [Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!; - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private IPrototypeManager _protoManager = default!; + [Dependency] private AnimationPlayerSystem _animationPlayer = default!; + [Dependency] private SharedAppearanceSystem _appearanceSystem = default!; + [Dependency] private SharedUserInterfaceSystem _uiSystem = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { diff --git a/Content.Client/BarSign/BarSignVisualizerSystem.cs b/Content.Client/BarSign/BarSignVisualizerSystem.cs index 3e641fed70e..e17d264cb51 100644 --- a/Content.Client/BarSign/BarSignVisualizerSystem.cs +++ b/Content.Client/BarSign/BarSignVisualizerSystem.cs @@ -5,9 +5,9 @@ namespace Content.Client.BarSign; -public sealed class BarSignVisualizerSystem : VisualizerSystem +public sealed partial class BarSignVisualizerSystem : VisualizerSystem { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; protected override void OnAppearanceChange(EntityUid uid, BarSignComponent component, ref AppearanceChangeEvent args) { diff --git a/Content.Client/BarSign/Ui/BarSignBoundUserInterface.cs b/Content.Client/BarSign/Ui/BarSignBoundUserInterface.cs index 62af75b929d..39409daecb8 100644 --- a/Content.Client/BarSign/Ui/BarSignBoundUserInterface.cs +++ b/Content.Client/BarSign/Ui/BarSignBoundUserInterface.cs @@ -7,9 +7,9 @@ namespace Content.Client.BarSign.Ui; [UsedImplicitly] -public sealed class BarSignBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey) +public sealed partial class BarSignBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey) { - [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private IPrototypeManager _prototype = default!; private BarSignMenu? _menu; diff --git a/Content.Client/Beam/BeamSystem.cs b/Content.Client/Beam/BeamSystem.cs index 66975d53a7f..379bc3af83a 100644 --- a/Content.Client/Beam/BeamSystem.cs +++ b/Content.Client/Beam/BeamSystem.cs @@ -1,13 +1,12 @@ -using Content.Client.Beam.Components; -using Content.Shared.Beam; +using Content.Shared.Beam; using Content.Shared.Beam.Components; using Robust.Client.GameObjects; namespace Content.Client.Beam; -public sealed class BeamSystem : SharedBeamSystem +public sealed partial class BeamSystem : SharedBeamSystem { - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { @@ -23,8 +22,6 @@ private void BeamVisualizerMessage(BeamVisualizerEvent args) if (TryComp(beam, out var sprites)) { - _sprite.SetRotation((beam, sprites), args.UserAngle); - if (args.BodyState != null) { _sprite.LayerSetRsiState((beam, sprites), 0, args.BodyState); diff --git a/Content.Client/Beam/Components/BeamComponent.cs b/Content.Client/Beam/Components/BeamComponent.cs deleted file mode 100644 index 58557b079c0..00000000000 --- a/Content.Client/Beam/Components/BeamComponent.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Content.Shared.Beam.Components; - -namespace Content.Client.Beam.Components; -[RegisterComponent] -public sealed partial class BeamComponent : SharedBeamComponent -{ - -} diff --git a/Content.Client/Body/Systems/InternalsSystem.cs b/Content.Client/Body/Systems/InternalsSystem.cs index 87daac37223..32608a6f5c4 100644 --- a/Content.Client/Body/Systems/InternalsSystem.cs +++ b/Content.Client/Body/Systems/InternalsSystem.cs @@ -4,9 +4,9 @@ namespace Content.Client.Body.Systems; -public sealed class InternalsSystem : SharedInternalsSystem +public sealed partial class InternalsSystem : SharedInternalsSystem { - [Dependency] private readonly SharedUserInterfaceSystem _ui = default!; + [Dependency] private SharedUserInterfaceSystem _ui = default!; public override void Initialize() { diff --git a/Content.Client/Body/VisualBodySystem.cs b/Content.Client/Body/VisualBodySystem.cs index fba936ee58a..c7b5825d143 100644 --- a/Content.Client/Body/VisualBodySystem.cs +++ b/Content.Client/Body/VisualBodySystem.cs @@ -1,4 +1,5 @@ using System.Linq; +using Content.Client.DisplacementMap; using Content.Shared.Body; using Content.Shared.CCVar; using Content.Shared.Humanoid.Markings; @@ -11,12 +12,13 @@ namespace Content.Client.Body; -public sealed class VisualBodySystem : SharedVisualBodySystem +public sealed partial class VisualBodySystem : SharedVisualBodySystem { - [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly IPrototypeManager _prototype = default!; - [Dependency] private readonly MarkingManager _marking = default!; - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private IConfigurationManager _cfg = default!; + [Dependency] private IPrototypeManager _prototype = default!; + [Dependency] private DisplacementMapSystem _displacement = default!; + [Dependency] private MarkingManager _marking = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { @@ -167,8 +169,11 @@ private IEnumerable AllMarkings(Entity en } } - private void ApplyMarkings(Entity ent, EntityUid target) + private void ApplyMarkings(Entity ent, Entity target) { + if (!Resolve(target, ref target.Comp)) + return; + var applied = new List(); foreach (var marking in AllMarkings(ent)) { @@ -178,6 +183,8 @@ private void ApplyMarkings(Entity ent, EntityUid t if (!_sprite.LayerMapTryGet(target, proto.BodyPart, out var index, true)) continue; + ent.Comp.MarkingsDisplacement.TryGetValue(proto.BodyPart, out var displacement); + for (var i = 0; i < proto.Sprites.Count; i++) { var sprite = proto.Sprites[i]; @@ -190,8 +197,8 @@ private void ApplyMarkings(Entity ent, EntityUid t if (!_sprite.LayerMapTryGet(target, layerId, out _, false)) { - var layer = _sprite.AddLayer(target, sprite, index + i + 1); - _sprite.LayerMapSet(target, layerId, layer); + var spriteLayer = _sprite.AddLayer(target, sprite, index + i + 1); + _sprite.LayerMapSet(target, layerId, spriteLayer); _sprite.LayerSetSprite(target, layerId, rsi); } @@ -199,6 +206,9 @@ private void ApplyMarkings(Entity ent, EntityUid t _sprite.LayerSetColor(target, layerId, marking.MarkingColors[i]); else _sprite.LayerSetColor(target, layerId, Color.White); + + if (displacement != null && proto.CanBeDisplaced) + _displacement.TryAddDisplacement(displacement, (target, target.Comp), index + i + 1, layerId, out _); } applied.Add(marking); @@ -206,8 +216,11 @@ private void ApplyMarkings(Entity ent, EntityUid t ent.Comp.AppliedMarkings = applied; } - private void RemoveMarkings(Entity ent, EntityUid target) + private void RemoveMarkings(Entity ent, Entity target) { + if (!Resolve(target, ref target.Comp)) + return; + foreach (var marking in ent.Comp.AppliedMarkings) { if (!_marking.TryGetMarking(marking, out var proto)) @@ -221,6 +234,13 @@ private void RemoveMarkings(Entity ent, EntityUid var layerId = $"{proto.ID}-{rsi.RsiState}"; + // If this marking is one that can be displaced, we need to remove the displacement as well; otherwise + // altering a marking at runtime can lead to the renderer falling over. + // The Vulps must be shaved. + // (https://github.com/space-wizards/space-station-14/issues/40135). + if (proto.CanBeDisplaced) + _displacement.EnsureDisplacementIsNotOnSprite((target, target.Comp), layerId); + if (!_sprite.LayerMapTryGet(target, layerId, out var index, false)) continue; diff --git a/Content.Client/Buckle/BuckleSystem.cs b/Content.Client/Buckle/BuckleSystem.cs index 536c60ed7a2..8e462659a20 100644 --- a/Content.Client/Buckle/BuckleSystem.cs +++ b/Content.Client/Buckle/BuckleSystem.cs @@ -8,12 +8,12 @@ namespace Content.Client.Buckle; -internal sealed class BuckleSystem : SharedBuckleSystem +internal sealed partial 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!; + [Dependency] private RotationVisualizerSystem _rotationVisualizerSystem = default!; + [Dependency] private IEyeManager _eye = default!; + [Dependency] private SharedTransformSystem _xformSystem = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { @@ -49,6 +49,9 @@ private void OnStrapMoveEvent(EntityUid uid, StrapComponent component, ref MoveE // Give some of the sprite rotations their own drawdepth, maybe as an offset within the rsi, or something like this // And we won't ever need to set the draw depth manually + if (!component.ModifyBuckleDrawDepth) + return; + if (args.NewRotation == args.OldRotation) return; @@ -86,6 +89,9 @@ private void OnStrapMoveEvent(EntityUid uid, StrapComponent component, ref MoveE /// private void OnBuckledEvent(Entity ent, ref BuckledEvent args) { + if (!args.Strap.Comp.ModifyBuckleDrawDepth) + return; + if (!TryComp(args.Strap, out var strapSprite)) return; @@ -106,6 +112,9 @@ private void OnBuckledEvent(Entity ent, ref BuckledEvent args) /// private void OnUnbuckledEvent(Entity ent, ref UnbuckledEvent args) { + if (!args.Strap.Comp.ModifyBuckleDrawDepth) + return; + if (!TryComp(ent.Owner, out var buckledSprite)) return; diff --git a/Content.Client/Camera/CameraRecoilSystem.cs b/Content.Client/Camera/CameraRecoilSystem.cs index 3e04cd5bf19..1a50d7ed660 100644 --- a/Content.Client/Camera/CameraRecoilSystem.cs +++ b/Content.Client/Camera/CameraRecoilSystem.cs @@ -5,9 +5,9 @@ namespace Content.Client.Camera; -public sealed class CameraRecoilSystem : SharedCameraRecoilSystem +public sealed partial class CameraRecoilSystem : SharedCameraRecoilSystem { - [Dependency] private readonly IConfigurationManager _configManager = default!; + [Dependency] private IConfigurationManager _configManager = default!; private float _intensity; diff --git a/Content.Client/CardboardBox/CardboardBoxSystem.cs b/Content.Client/CardboardBox/CardboardBoxSystem.cs index ecebe167277..f527caf678d 100644 --- a/Content.Client/CardboardBox/CardboardBoxSystem.cs +++ b/Content.Client/CardboardBox/CardboardBoxSystem.cs @@ -8,21 +8,18 @@ namespace Content.Client.CardboardBox; -public sealed class CardboardBoxSystem : SharedCardboardBoxSystem +public sealed partial 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 _mobStateQuery; + [Dependency] private EntityLookupSystem _entityLookup = default!; + [Dependency] private TransformSystem _transform = default!; + [Dependency] private ExamineSystemShared _examine = default!; + [Dependency] private SpriteSystem _sprite = default!; + [Dependency] private EntityQuery _mobStateQuery = default!; public override void Initialize() { base.Initialize(); - _mobStateQuery = GetEntityQuery(); - SubscribeNetworkEvent(OnBoxEffect); } @@ -33,11 +30,7 @@ private void OnBoxEffect(PlayBoxEffectMessage msg) if (!TryComp(source, out var box)) return; - var xformQuery = GetEntityQuery(); - - if (!xformQuery.TryGetComponent(source, out var xform)) - return; - + var xform = Transform(source); var sourcePos = _transform.GetMapCoordinates(source, xform); //Any mob that can move should be surprised? @@ -72,7 +65,7 @@ private void OnBoxEffect(PlayBoxEffectMessage msg) var ent = Spawn(box.Effect, mapPos); - if (!xformQuery.TryGetComponent(ent, out var entTransform) || !TryComp(ent, out var sprite)) + if (!TryComp(ent, out TransformComponent? entTransform) || !TryComp(ent, out var sprite)) continue; _sprite.SetOffset((ent, sprite), new Vector2(0, 1)); diff --git a/Content.Client/Cargo/BUI/CargoOrderConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoOrderConsoleBoundUserInterface.cs index 9cd614de14c..b509b137676 100644 --- a/Content.Client/Cargo/BUI/CargoOrderConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoOrderConsoleBoundUserInterface.cs @@ -1,5 +1,5 @@ -using Content.Shared.Cargo; using Content.Client.Cargo.UI; +using Content.Shared.Cargo; using Content.Shared.Cargo.BUI; using Content.Shared.Cargo.Components; using Content.Shared.Cargo.Events; @@ -7,15 +7,15 @@ using Content.Shared.IdentityManagement; using Robust.Client.GameObjects; using Robust.Client.Player; -using Robust.Shared.Utility; using Robust.Shared.Prototypes; -using static Robust.Client.UserInterface.Controls.BaseButton; +using Robust.Shared.Utility; namespace Content.Client.Cargo.BUI { - public sealed class CargoOrderConsoleBoundUserInterface : BoundUserInterface + public sealed partial class CargoOrderConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey) { - private readonly SharedCargoSystem _cargoSystem; + [Dependency] private SharedCargoSystem _cargoSystem = default!; + [Dependency] private IdentitySystem _identity = default!; [ViewVariables] private CargoConsoleMenu? _menu; @@ -44,11 +44,6 @@ public sealed class CargoOrderConsoleBoundUserInterface : BoundUserInterface [ViewVariables] private CargoProductPrototype? _product; - public CargoOrderConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) - { - _cargoSystem = EntMan.System(); - } - protected override void Open() { base.Open(); @@ -59,12 +54,9 @@ protected override void Open() var localPlayer = dependencies.Resolve().LocalEntity; var description = new FormattedMessage(); - string orderRequester; - + var orderRequester = Loc.GetString("cargo-console-paper-approver-default"); if (EntMan.EntityExists(localPlayer)) - orderRequester = Identity.Name(localPlayer.Value, EntMan); - else - orderRequester = string.Empty; + orderRequester = _identity.GetIdentityShortInfo(localPlayer.Value, Owner) ?? orderRequester; _orderMenu = new CargoConsoleOrderMenu(); @@ -142,6 +134,11 @@ protected override void UpdateState(BoundUserInterfaceState state) return; _menu.ProductCatalogue = cState.Products; + _menu.ShuttleCapacityLabel.Text = Loc.GetString( + "cargo-console-menu-order-capacity-number", + ("count", OrderCount), + ("capacity", OrderCapacity) + ); _menu?.UpdateStation(station); Populate(cState.Orders); diff --git a/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs deleted file mode 100644 index 02b721b9020..00000000000 --- a/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Content.Client.Cargo.UI; -using Content.Shared.Cargo.BUI; -using JetBrains.Annotations; -using Robust.Client.GameObjects; -using Robust.Client.UserInterface; -using Robust.Shared.Prototypes; - -namespace Content.Client.Cargo.BUI; - -[UsedImplicitly] -public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface -{ - [Dependency] private readonly IPrototypeManager _protoManager = default!; - - [ViewVariables] - private CargoShuttleMenu? _menu; - - public CargoShuttleConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) - { - } - - protected override void Open() - { - base.Open(); - _menu = this.CreateWindow(); - } - - protected override void UpdateState(BoundUserInterfaceState state) - { - base.UpdateState(state); - if (state is not CargoShuttleConsoleBoundUserInterfaceState cargoState) return; - _menu?.SetAccountName(cargoState.AccountName); - _menu?.SetShuttleName(cargoState.ShuttleName); - _menu?.SetOrders(EntMan.System(), _protoManager, cargoState.Orders); - } -} diff --git a/Content.Client/Cargo/Systems/CargoSystem.Telepad.cs b/Content.Client/Cargo/Systems/CargoSystem.Telepad.cs index 85b2dbfb834..8bf47043003 100644 --- a/Content.Client/Cargo/Systems/CargoSystem.Telepad.cs +++ b/Content.Client/Cargo/Systems/CargoSystem.Telepad.cs @@ -9,8 +9,8 @@ namespace Content.Client.Cargo.Systems; public sealed partial class CargoSystem { - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SharedAppearanceSystem _appearance = default!; + [Dependency] private SpriteSystem _sprite = default!; private static readonly Animation CargoTelepadBeamAnimation = new() { diff --git a/Content.Client/Cargo/Systems/CargoSystem.cs b/Content.Client/Cargo/Systems/CargoSystem.cs index 3ffb0636d01..48a3cb87e6c 100644 --- a/Content.Client/Cargo/Systems/CargoSystem.cs +++ b/Content.Client/Cargo/Systems/CargoSystem.cs @@ -5,7 +5,7 @@ namespace Content.Client.Cargo.Systems; public sealed partial class CargoSystem : SharedCargoSystem { - [Dependency] private readonly AnimationPlayerSystem _player = default!; + [Dependency] private AnimationPlayerSystem _player = default!; public override void Initialize() { diff --git a/Content.Client/Cargo/Systems/ClientPriceGunSystem.cs b/Content.Client/Cargo/Systems/ClientPriceGunSystem.cs index 35fb2112c07..bfbe3d904e8 100644 --- a/Content.Client/Cargo/Systems/ClientPriceGunSystem.cs +++ b/Content.Client/Cargo/Systems/ClientPriceGunSystem.cs @@ -7,9 +7,9 @@ namespace Content.Client.Cargo.Systems; /// /// This handles... /// -public sealed class ClientPriceGunSystem : SharedPriceGunSystem +public sealed partial class ClientPriceGunSystem : SharedPriceGunSystem { - [Dependency] private readonly UseDelaySystem _useDelay = default!; + [Dependency] private UseDelaySystem _useDelay = default!; protected override bool GetPriceOrBounty(Entity entity, EntityUid target, EntityUid user) { diff --git a/Content.Client/Cargo/UI/BountyEntry.xaml.cs b/Content.Client/Cargo/UI/BountyEntry.xaml.cs index bac7d84bf78..6a237d3b91b 100644 --- a/Content.Client/Cargo/UI/BountyEntry.xaml.cs +++ b/Content.Client/Cargo/UI/BountyEntry.xaml.cs @@ -13,7 +13,7 @@ namespace Content.Client.Cargo.UI; [GenerateTypedNameReferences] public sealed partial class BountyEntry : BoxContainer { - [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private IPrototypeManager _prototype = default!; public Action? OnLabelButtonPressed; public Action? OnSkipButtonPressed; diff --git a/Content.Client/Cargo/UI/BountyHistoryEntry.xaml.cs b/Content.Client/Cargo/UI/BountyHistoryEntry.xaml.cs index 98658e5f0a5..950b728a5e4 100644 --- a/Content.Client/Cargo/UI/BountyHistoryEntry.xaml.cs +++ b/Content.Client/Cargo/UI/BountyHistoryEntry.xaml.cs @@ -12,7 +12,7 @@ namespace Content.Client.Cargo.UI; [GenerateTypedNameReferences] public sealed partial class BountyHistoryEntry : BoxContainer { - [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private IPrototypeManager _prototype = default!; public BountyHistoryEntry(CargoBountyHistoryData bounty) { diff --git a/Content.Client/Cargo/UI/CargoConsoleMenu.xaml b/Content.Client/Cargo/UI/CargoConsoleMenu.xaml index 3ecfad94aae..018ec3670b7 100644 --- a/Content.Client/Cargo/UI/CargoConsoleMenu.xaml +++ b/Content.Client/Cargo/UI/CargoConsoleMenu.xaml @@ -52,7 +52,8 @@ diff --git a/Content.Client/MainMenu/UI/MainMenuControl.xaml.cs b/Content.Client/MainMenu/UI/MainMenuControl.xaml.cs index 45bd94f7b65..4de55156602 100644 --- a/Content.Client/MainMenu/UI/MainMenuControl.xaml.cs +++ b/Content.Client/MainMenu/UI/MainMenuControl.xaml.cs @@ -1,21 +1,43 @@ -using Robust.Client.AutoGenerated; +using Content.Client.Parallax.Data; +using Robust.Client.AutoGenerated; using Robust.Client.ResourceManagement; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; using Robust.Shared; using Robust.Shared.Configuration; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; namespace Content.Client.MainMenu.UI; [GenerateTypedNameReferences] public sealed partial class MainMenuControl : Control { + [Dependency] private IRobustRandom _random = default!; + public const string StyleIdentifierMainMenu = "mainMenu"; public const string StyleIdentifierMainMenuVBox = "mainMenuVBox"; + private static readonly ProtoId[] Parallaxes = + [ + "Wizard", + "TrainStation", + "PlasmaStation", + "AmberStation", + "FastSpace", + "AspidParallax", + "OriginStation", + "Default", + "Sky", + "KettleStation", + "BagelStation", + "ExoStation", + ]; + public MainMenuControl(IResourceCache resCache, IConfigurationManager configMan) { + IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); LayoutContainer.SetAnchorPreset(this, LayoutContainer.LayoutPreset.Wide); @@ -25,6 +47,10 @@ public MainMenuControl(IResourceCache resCache, IConfigurationManager configMan) LayoutContainer.SetMarginTop(VBox, 30); LayoutContainer.SetGrowHorizontal(VBox, LayoutContainer.GrowDirection.Begin); + // I don't just enumerate them all as there's some hideous parallaxes, and it's easier + // to update an allowlist than to randomly get an ugly one to fix a blocklist. + BackgroundParallax.ParallaxPrototype = _random.Pick(Parallaxes).Id; + var logoTexture = resCache.GetResource("/Textures/Logo/logo.png"); Logo.Texture = logoTexture; diff --git a/Content.Client/MapText/MapTextSystem.cs b/Content.Client/MapText/MapTextSystem.cs index 96ce8f93c29..c94969ad1b1 100644 --- a/Content.Client/MapText/MapTextSystem.cs +++ b/Content.Client/MapText/MapTextSystem.cs @@ -11,14 +11,14 @@ namespace Content.Client.MapText; /// -public sealed class MapTextSystem : SharedMapTextSystem +public sealed partial class MapTextSystem : SharedMapTextSystem { - [Dependency] private readonly IConfigurationManager _configManager = default!; - [Dependency] private readonly IUserInterfaceManager _uiManager = default!; - [Dependency] private readonly SharedTransformSystem _transform = default!; - [Dependency] private readonly IResourceCache _resourceCache = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IOverlayManager _overlayManager = default!; + [Dependency] private IConfigurationManager _configManager = default!; + [Dependency] private IUserInterfaceManager _uiManager = default!; + [Dependency] private SharedTransformSystem _transform = default!; + [Dependency] private IResourceCache _resourceCache = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private IOverlayManager _overlayManager = default!; private MapTextOverlay _overlay = default!; diff --git a/Content.Client/Mapping/MappingManager.cs b/Content.Client/Mapping/MappingManager.cs index 1aac02be714..17cc629c59f 100644 --- a/Content.Client/Mapping/MappingManager.cs +++ b/Content.Client/Mapping/MappingManager.cs @@ -7,10 +7,10 @@ namespace Content.Client.Mapping; -public sealed class MappingManager : IPostInjectInit +public sealed partial class MappingManager : IPostInjectInit { - [Dependency] private readonly IFileDialogManager _file = default!; - [Dependency] private readonly IClientNetManager _net = default!; + [Dependency] private IFileDialogManager _file = default!; + [Dependency] private IClientNetManager _net = default!; private Stream? _saveStream; private MappingMapDataMessage? _mapData; diff --git a/Content.Client/Mapping/MappingOverlay.cs b/Content.Client/Mapping/MappingOverlay.cs index e461440996f..026f50450c9 100644 --- a/Content.Client/Mapping/MappingOverlay.cs +++ b/Content.Client/Mapping/MappingOverlay.cs @@ -9,13 +9,13 @@ namespace Content.Client.Mapping; -public sealed class MappingOverlay : Overlay +public sealed partial class MappingOverlay : Overlay { private static readonly ProtoId UnshadedShader = "unshaded"; - [Dependency] private readonly IEntityManager _entities = default!; - [Dependency] private readonly IPlayerManager _player = default!; - [Dependency] private readonly IPrototypeManager _prototypes = default!; + [Dependency] private IEntityManager _entities = default!; + [Dependency] private IPlayerManager _player = default!; + [Dependency] private IPrototypeManager _prototypes = default!; private readonly SpriteSystem _sprite; diff --git a/Content.Client/Mapping/MappingScreen.xaml.cs b/Content.Client/Mapping/MappingScreen.xaml.cs index 20e2528a440..6ef9ce578bd 100644 --- a/Content.Client/Mapping/MappingScreen.xaml.cs +++ b/Content.Client/Mapping/MappingScreen.xaml.cs @@ -18,7 +18,7 @@ namespace Content.Client.Mapping; [GenerateTypedNameReferences] public sealed partial class MappingScreen : InGameScreen { - [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private IPrototypeManager _prototype = default!; public DecalPlacementSystem DecalSystem = default!; diff --git a/Content.Client/Mapping/MappingState.cs b/Content.Client/Mapping/MappingState.cs index 190ae096769..bddfe27d807 100644 --- a/Content.Client/Mapping/MappingState.cs +++ b/Content.Client/Mapping/MappingState.cs @@ -35,23 +35,23 @@ namespace Content.Client.Mapping; -public sealed class MappingState : GameplayStateBase +public sealed partial class MappingState : GameplayStateBase { #if !FULL_RELEASE - [Dependency] private readonly IClientAdminManager _admin = default!; + [Dependency] private IClientAdminManager _admin = default!; #endif - [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IEntityNetworkManager _entityNetwork = default!; - [Dependency] private readonly IInputManager _input = default!; - [Dependency] private readonly ILogManager _log = default!; - [Dependency] private readonly IMapManager _mapMan = default!; - [Dependency] private readonly MappingManager _mapping = default!; - [Dependency] private readonly IOverlayManager _overlays = default!; - [Dependency] private readonly IPlacementManager _placement = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IResourceCache _resources = default!; - [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private IEntityManager _entityManager = default!; + [Dependency] private IEntityNetworkManager _entityNetwork = default!; + [Dependency] private IInputManager _input = default!; + [Dependency] private ILogManager _log = default!; + [Dependency] private IMapManager _mapMan = default!; + [Dependency] private MappingManager _mapping = default!; + [Dependency] private IOverlayManager _overlays = default!; + [Dependency] private IPlacementManager _placement = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private IResourceCache _resources = default!; + [Dependency] private IGameTiming _timing = default!; private EntityMenuUIController _entityMenuController = default!; diff --git a/Content.Client/Mapping/MappingSystem.cs b/Content.Client/Mapping/MappingSystem.cs index 627977a5268..494f45e6a81 100644 --- a/Content.Client/Mapping/MappingSystem.cs +++ b/Content.Client/Mapping/MappingSystem.cs @@ -11,10 +11,10 @@ namespace Content.Client.Mapping; public sealed partial class MappingSystem : EntitySystem { - [Dependency] private readonly IPlacementManager _placementMan = default!; - [Dependency] private readonly ITileDefinitionManager _tileMan = default!; - [Dependency] private readonly MetaDataSystem _metaData = default!; - [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private IPlacementManager _placementMan = default!; + [Dependency] private ITileDefinitionManager _tileMan = default!; + [Dependency] private MetaDataSystem _metaData = default!; + [Dependency] private SharedActionsSystem _actions = default!; public static readonly EntProtoId SpawnAction = "BaseMappingSpawnAction"; public static readonly EntProtoId EraserAction = "ActionMappingEraser"; diff --git a/Content.Client/Maps/GridDraggingSystem.cs b/Content.Client/Maps/GridDraggingSystem.cs index 5440f1624ff..f78f96c5471 100644 --- a/Content.Client/Maps/GridDraggingSystem.cs +++ b/Content.Client/Maps/GridDraggingSystem.cs @@ -11,14 +11,14 @@ namespace Content.Client.Maps; /// -public sealed class GridDraggingSystem : SharedGridDraggingSystem +public sealed partial class GridDraggingSystem : SharedGridDraggingSystem { - [Dependency] private readonly IEyeManager _eyeManager = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly IInputManager _inputManager = default!; - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly InputSystem _inputSystem = default!; - [Dependency] private readonly SharedTransformSystem _transformSystem = default!; + [Dependency] private IEyeManager _eyeManager = default!; + [Dependency] private IGameTiming _gameTiming = default!; + [Dependency] private IInputManager _inputManager = default!; + [Dependency] private IMapManager _mapManager = default!; + [Dependency] private InputSystem _inputSystem = default!; + [Dependency] private SharedTransformSystem _transformSystem = default!; public bool Enabled { get; set; } diff --git a/Content.Client/Markers/MarkerSystem.cs b/Content.Client/Markers/MarkerSystem.cs index 37888d16c29..325a72159d1 100644 --- a/Content.Client/Markers/MarkerSystem.cs +++ b/Content.Client/Markers/MarkerSystem.cs @@ -3,9 +3,9 @@ namespace Content.Client.Markers; -public sealed class MarkerSystem : EntitySystem +public sealed partial class MarkerSystem : EntitySystem { - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SpriteSystem _sprite = default!; private bool _markersVisible; diff --git a/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs b/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs index af1f9a94414..7129840956f 100644 --- a/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs +++ b/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs @@ -11,7 +11,7 @@ namespace Content.Client.MassMedia.Ui; [GenerateTypedNameReferences] public sealed partial class NewsWriterMenu : FancyWindow { - [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private IGameTiming _gameTiming = default!; private TimeSpan? _nextPublish; diff --git a/Content.Client/Materials/MaterialStorageSystem.cs b/Content.Client/Materials/MaterialStorageSystem.cs index f9078a9032f..2825f457ab7 100644 --- a/Content.Client/Materials/MaterialStorageSystem.cs +++ b/Content.Client/Materials/MaterialStorageSystem.cs @@ -3,11 +3,11 @@ namespace Content.Client.Materials; -public sealed class MaterialStorageSystem : SharedMaterialStorageSystem +public sealed partial class MaterialStorageSystem : SharedMaterialStorageSystem { - [Dependency] private readonly AppearanceSystem _appearance = default!; - [Dependency] private readonly TransformSystem _transform = default!; - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private AppearanceSystem _appearance = default!; + [Dependency] private TransformSystem _transform = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { diff --git a/Content.Client/Materials/UI/MaterialDisplay.xaml.cs b/Content.Client/Materials/UI/MaterialDisplay.xaml.cs index 8a6c18feeaa..d40f896b09a 100644 --- a/Content.Client/Materials/UI/MaterialDisplay.xaml.cs +++ b/Content.Client/Materials/UI/MaterialDisplay.xaml.cs @@ -15,8 +15,8 @@ namespace Content.Client.Materials.UI; [GenerateTypedNameReferences] public sealed partial class MaterialDisplay : PanelContainer { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + [Dependency] private IEntityManager _entityManager = default!; private readonly MaterialStorageSystem _materialStorage; diff --git a/Content.Client/Materials/UI/MaterialStorageControl.xaml.cs b/Content.Client/Materials/UI/MaterialStorageControl.xaml.cs index fd698d890fc..441b6f286eb 100644 --- a/Content.Client/Materials/UI/MaterialStorageControl.xaml.cs +++ b/Content.Client/Materials/UI/MaterialStorageControl.xaml.cs @@ -15,7 +15,7 @@ namespace Content.Client.Materials.UI; [GenerateTypedNameReferences] public sealed partial class MaterialStorageControl : ScrollContainer { - [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private IEntityManager _entityManager = default!; private readonly MaterialStorageSystem _materialStorage; private EntityUid? _owner; diff --git a/Content.Client/Mech/MechSystem.cs b/Content.Client/Mech/MechSystem.cs index 816342ad95f..5320f29aea5 100644 --- a/Content.Client/Mech/MechSystem.cs +++ b/Content.Client/Mech/MechSystem.cs @@ -7,10 +7,10 @@ namespace Content.Client.Mech; /// -public sealed class MechSystem : SharedMechSystem +public sealed partial class MechSystem : SharedMechSystem { - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SharedAppearanceSystem _appearance = default!; + [Dependency] private SpriteSystem _sprite = default!; /// public override void Initialize() diff --git a/Content.Client/Mech/Ui/Equipment/MechGrabberUiFragment.xaml.cs b/Content.Client/Mech/Ui/Equipment/MechGrabberUiFragment.xaml.cs index 94f86e74a02..ad95bf2fbd0 100644 --- a/Content.Client/Mech/Ui/Equipment/MechGrabberUiFragment.xaml.cs +++ b/Content.Client/Mech/Ui/Equipment/MechGrabberUiFragment.xaml.cs @@ -8,7 +8,7 @@ namespace Content.Client.Mech.Ui.Equipment; [GenerateTypedNameReferences] public sealed partial class MechGrabberUiFragment : BoxContainer { - [Dependency] private readonly IEntityManager _entity = default!; + [Dependency] private IEntityManager _entity = default!; public event Action? OnEjectAction; diff --git a/Content.Client/Mech/Ui/MechMenu.xaml.cs b/Content.Client/Mech/Ui/MechMenu.xaml.cs index 7ce863b7cd7..6807451511e 100644 --- a/Content.Client/Mech/Ui/MechMenu.xaml.cs +++ b/Content.Client/Mech/Ui/MechMenu.xaml.cs @@ -10,7 +10,7 @@ namespace Content.Client.Mech.Ui; [GenerateTypedNameReferences] public sealed partial class MechMenu : FancyWindow { - [Dependency] private readonly IEntityManager _ent = default!; + [Dependency] private IEntityManager _ent = default!; private EntityUid _mech; diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs index 3872fa50cc9..ad7c2dad023 100644 --- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs @@ -23,8 +23,8 @@ namespace Content.Client.Medical.CrewMonitoring; [GenerateTypedNameReferences] public sealed partial class CrewMonitoringWindow : FancyWindow { - [Dependency] private readonly IEntityManager _entManager = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private IEntityManager _entManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; private readonly SharedTransformSystem _transformSystem; private readonly SpriteSystem _spriteSystem; diff --git a/Content.Client/Medical/Cryogenics/CryoPodSystem.cs b/Content.Client/Medical/Cryogenics/CryoPodSystem.cs index 63c95a63d8c..d24f59579b3 100644 --- a/Content.Client/Medical/Cryogenics/CryoPodSystem.cs +++ b/Content.Client/Medical/Cryogenics/CryoPodSystem.cs @@ -4,9 +4,9 @@ namespace Content.Client.Medical.Cryogenics; -public sealed class CryoPodSystem : SharedCryoPodSystem +public sealed partial class CryoPodSystem : SharedCryoPodSystem { - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { diff --git a/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs b/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs index f1d0e038f47..76b1c876d34 100644 --- a/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs +++ b/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs @@ -2,8 +2,8 @@ using System.Numerics; using Content.Client.UserInterface.Controls; using Content.Shared.Atmos; +using Content.Shared.Atmos.EntitySystems; using Content.Shared.Chemistry.Reagent; -using Content.Shared.Damage.Components; using Content.Shared.EntityConditions.Conditions; using Content.Shared.FixedPoint; using Content.Shared.Medical.Cryogenics; @@ -17,8 +17,9 @@ namespace Content.Client.Medical.Cryogenics; [GenerateTypedNameReferences] public sealed partial class CryoPodWindow : FancyWindow { - [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private IEntityManager _entityManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; + private readonly SharedAtmosphereSystem _atmosphere = default!; public event Action? OnEjectPatientPressed; public event Action? OnEjectBeakerPressed; @@ -28,6 +29,7 @@ public CryoPodWindow() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); + _atmosphere = _entityManager.System(); EjectPatientButton.OnPressed += _ => OnEjectPatientPressed?.Invoke(); EjectBeakerButton.OnPressed += _ => OnEjectBeakerPressed?.Invoke(); Inject1.OnPressed += _ => OnInjectPressed?.Invoke(1); @@ -70,25 +72,23 @@ public void Populate(CryoPodUserMessage msg) { var totalGasAmount = msg.GasMix.Gases.Sum(gas => gas.Amount); - foreach (var gas in msg.GasMix.Gases) + foreach (var gasEntry in msg.GasMix.Gases) { - var color = Color.FromHex($"#{gas.Color}", Color.White); - var percent = gas.Amount / totalGasAmount * 100; - var localizedName = Loc.GetString(gas.Name); + var gasProto = _atmosphere.GetGas(gasEntry.Gas); + var percent = gasEntry.Amount / totalGasAmount * 100; + var localizedName = Loc.GetString(gasProto.Name); var tooltip = Loc.GetString("gas-analyzer-window-molarity-percentage-text", ("gasName", localizedName), - ("amount", $"{gas.Amount:0.##}"), + ("amount", $"{gasEntry.Amount:0.##}"), ("percentage", $"{percent:0.#}")); - GasMixChart.AddEntry(gas.Amount, color, tooltip: tooltip); + GasMixChart.AddEntry(gasEntry.Amount, gasProto.Color, tooltip: tooltip); } } // Health analyzer var maybePatient = _entityManager.GetEntity(msg.Health.TargetEntity); var hasPatient = msg.Health.TargetEntity.HasValue; - var hasDamage = (hasPatient - && _entityManager.TryGetComponent(maybePatient, out DamageableComponent? damageable) - && damageable.TotalDamage > 0); + var hasDamage = hasPatient && msg.HasDamage; NoDamageText.Visible = (hasPatient && !hasDamage); HealthSection.Visible = hasPatient; diff --git a/Content.Client/Mining/MiningOverlay.cs b/Content.Client/Mining/MiningOverlay.cs index f4140f064fe..bb5302f8255 100644 --- a/Content.Client/Mining/MiningOverlay.cs +++ b/Content.Client/Mining/MiningOverlay.cs @@ -9,11 +9,11 @@ namespace Content.Client.Mining; -public sealed class MiningOverlay : Overlay +public sealed partial class MiningOverlay : Overlay { - [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private IEntityManager _entityManager = default!; + [Dependency] private IGameTiming _timing = default!; + [Dependency] private IPlayerManager _player = default!; private readonly EntityLookupSystem _lookup; private readonly SpriteSystem _sprite; private readonly TransformSystem _xform; diff --git a/Content.Client/Mining/MiningOverlaySystem.cs b/Content.Client/Mining/MiningOverlaySystem.cs index 294cab30ca8..158dd76a59a 100644 --- a/Content.Client/Mining/MiningOverlaySystem.cs +++ b/Content.Client/Mining/MiningOverlaySystem.cs @@ -8,10 +8,10 @@ namespace Content.Client.Mining; /// /// This handles the lifetime of the for a given entity. /// -public sealed class MiningOverlaySystem : EntitySystem +public sealed partial class MiningOverlaySystem : EntitySystem { - [Dependency] private readonly IPlayerManager _player = default!; - [Dependency] private readonly IOverlayManager _overlayMan = default!; + [Dependency] private IPlayerManager _player = default!; + [Dependency] private IOverlayManager _overlayMan = default!; private MiningOverlay _overlay = default!; diff --git a/Content.Client/MouseRotator/MouseRotatorSystem.cs b/Content.Client/MouseRotator/MouseRotatorSystem.cs index 2ee6e43368f..cea4c5b0b82 100644 --- a/Content.Client/MouseRotator/MouseRotatorSystem.cs +++ b/Content.Client/MouseRotator/MouseRotatorSystem.cs @@ -8,13 +8,13 @@ namespace Content.Client.MouseRotator; /// -public sealed class MouseRotatorSystem : SharedMouseRotatorSystem +public sealed partial class MouseRotatorSystem : SharedMouseRotatorSystem { - [Dependency] private readonly IInputManager _input = default!; - [Dependency] private readonly IPlayerManager _player = default!; - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly IEyeManager _eye = default!; - [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private IInputManager _input = default!; + [Dependency] private IPlayerManager _player = default!; + [Dependency] private IGameTiming _timing = default!; + [Dependency] private IEyeManager _eye = default!; + [Dependency] private SharedTransformSystem _transform = default!; public override void Update(float frameTime) { diff --git a/Content.Client/Movement/Systems/ClientSpriteMovementSystem.cs b/Content.Client/Movement/Systems/ClientSpriteMovementSystem.cs index eb60e4fbb6d..ff706ea35e3 100644 --- a/Content.Client/Movement/Systems/ClientSpriteMovementSystem.cs +++ b/Content.Client/Movement/Systems/ClientSpriteMovementSystem.cs @@ -7,18 +7,15 @@ namespace Content.Client.Movement.Systems; /// /// Controls the switching of motion and standing still animation /// -public sealed class ClientSpriteMovementSystem : SharedSpriteMovementSystem +public sealed partial class ClientSpriteMovementSystem : SharedSpriteMovementSystem { - [Dependency] private readonly SpriteSystem _sprite = default!; - - private EntityQuery _spriteQuery; + [Dependency] private SpriteSystem _sprite = default!; + [Dependency] private EntityQuery _spriteQuery = default!; public override void Initialize() { base.Initialize(); - _spriteQuery = GetEntityQuery(); - SubscribeLocalEvent(OnAfterAutoHandleState); } diff --git a/Content.Client/Movement/Systems/ContentEyeSystem.cs b/Content.Client/Movement/Systems/ContentEyeSystem.cs index a332d25f9a1..dc517920fa5 100644 --- a/Content.Client/Movement/Systems/ContentEyeSystem.cs +++ b/Content.Client/Movement/Systems/ContentEyeSystem.cs @@ -5,9 +5,9 @@ namespace Content.Client.Movement.Systems; -public sealed class ContentEyeSystem : SharedContentEyeSystem +public sealed partial class ContentEyeSystem : SharedContentEyeSystem { - [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private IPlayerManager _player = default!; public void RequestZoom(EntityUid uid, Vector2 zoom, bool ignoreLimit, bool scalePvs, ContentEyeComponent? content = null) { diff --git a/Content.Client/Movement/Systems/EyeCursorOffsetSystem.cs b/Content.Client/Movement/Systems/EyeCursorOffsetSystem.cs index 174ae2dd970..f54aaa84038 100644 --- a/Content.Client/Movement/Systems/EyeCursorOffsetSystem.cs +++ b/Content.Client/Movement/Systems/EyeCursorOffsetSystem.cs @@ -10,8 +10,8 @@ namespace Content.Client.Movement.Systems; public sealed partial class EyeCursorOffsetSystem : EntitySystem { - [Dependency] private readonly IEyeManager _eyeManager = default!; - [Dependency] private readonly IInputManager _inputManager = default!; + [Dependency] private IEyeManager _eyeManager = default!; + [Dependency] private IInputManager _inputManager = default!; // This value is here to make sure the user doesn't have to move their mouse // all the way out to the edge of the screen to get the full offset. diff --git a/Content.Client/Movement/Systems/FloorOcclusionSystem.cs b/Content.Client/Movement/Systems/FloorOcclusionSystem.cs index 6520d98ac93..e160a06fb1f 100644 --- a/Content.Client/Movement/Systems/FloorOcclusionSystem.cs +++ b/Content.Client/Movement/Systems/FloorOcclusionSystem.cs @@ -6,20 +6,18 @@ namespace Content.Client.Movement.Systems; -public sealed class FloorOcclusionSystem : SharedFloorOcclusionSystem +public sealed partial class FloorOcclusionSystem : SharedFloorOcclusionSystem { private static readonly ProtoId HorizontalCut = "HorizontalCut"; - [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private IPrototypeManager _proto = default!; - private EntityQuery _spriteQuery; + [Dependency] private EntityQuery _spriteQuery = default!; public override void Initialize() { base.Initialize(); - _spriteQuery = GetEntityQuery(); - SubscribeLocalEvent(OnOcclusionStartup); SubscribeLocalEvent(OnOcclusionShutdown); SubscribeLocalEvent(OnOcclusionAuto); diff --git a/Content.Client/Movement/Systems/JetpackSystem.cs b/Content.Client/Movement/Systems/JetpackSystem.cs index c9e759e129a..ed48b18de88 100644 --- a/Content.Client/Movement/Systems/JetpackSystem.cs +++ b/Content.Client/Movement/Systems/JetpackSystem.cs @@ -10,12 +10,12 @@ namespace Content.Client.Movement.Systems; -public sealed class JetpackSystem : SharedJetpackSystem +public sealed partial class JetpackSystem : SharedJetpackSystem { - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly ClothingSystem _clothing = default!; - [Dependency] private readonly SharedTransformSystem _transform = default!; - [Dependency] private readonly SharedMapSystem _mapSystem = default!; + [Dependency] private IGameTiming _timing = default!; + [Dependency] private ClothingSystem _clothing = default!; + [Dependency] private SharedTransformSystem _transform = default!; + [Dependency] private SharedMapSystem _mapSystem = default!; public override void Initialize() { diff --git a/Content.Client/Movement/Systems/MobCollisionSystem.cs b/Content.Client/Movement/Systems/MobCollisionSystem.cs index b7d464afabd..948f93b6581 100644 --- a/Content.Client/Movement/Systems/MobCollisionSystem.cs +++ b/Content.Client/Movement/Systems/MobCollisionSystem.cs @@ -1,17 +1,15 @@ using System.Numerics; using Content.Shared.CCVar; -using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; using Robust.Client.Player; -using Robust.Shared.Physics.Components; using Robust.Shared.Timing; namespace Content.Client.Movement.Systems; -public sealed class MobCollisionSystem : SharedMobCollisionSystem +public sealed partial class MobCollisionSystem : SharedMobCollisionSystem { - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private IGameTiming _timing = default!; + [Dependency] private IPlayerManager _player = default!; public override void Update(float frameTime) { diff --git a/Content.Client/NPC/NPCSteeringSystem.cs b/Content.Client/NPC/NPCSteeringSystem.cs index 9ca3ec1a7ea..f6272a1f798 100644 --- a/Content.Client/NPC/NPCSteeringSystem.cs +++ b/Content.Client/NPC/NPCSteeringSystem.cs @@ -9,9 +9,9 @@ namespace Content.Client.NPC; -public sealed class NPCSteeringSystem : SharedNPCSteeringSystem +public sealed partial class NPCSteeringSystem : SharedNPCSteeringSystem { - [Dependency] private readonly IOverlayManager _overlay = default!; + [Dependency] private IOverlayManager _overlay = default!; public bool DebugEnabled { diff --git a/Content.Client/NPC/PathfindingSystem.cs b/Content.Client/NPC/PathfindingSystem.cs index dc8fd984331..3cca80198d9 100644 --- a/Content.Client/NPC/PathfindingSystem.cs +++ b/Content.Client/NPC/PathfindingSystem.cs @@ -14,17 +14,17 @@ namespace Content.Client.NPC { - public sealed class PathfindingSystem : SharedPathfindingSystem + public sealed partial class PathfindingSystem : SharedPathfindingSystem { - [Dependency] private readonly IEyeManager _eyeManager = default!; - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly IInputManager _inputManager = default!; - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IOverlayManager _overlayManager = default!; - [Dependency] private readonly IResourceCache _cache = default!; - [Dependency] private readonly NPCSteeringSystem _steering = default!; - [Dependency] private readonly MapSystem _mapSystem = default!; - [Dependency] private readonly SharedTransformSystem _transformSystem = default!; + [Dependency] private IEyeManager _eyeManager = default!; + [Dependency] private IGameTiming _timing = default!; + [Dependency] private IInputManager _inputManager = default!; + [Dependency] private IMapManager _mapManager = default!; + [Dependency] private IOverlayManager _overlayManager = default!; + [Dependency] private IResourceCache _cache = default!; + [Dependency] private NPCSteeringSystem _steering = default!; + [Dependency] private MapSystem _mapSystem = default!; + [Dependency] private SharedTransformSystem _transformSystem = default!; public PathfindingDebugMode Modes { diff --git a/Content.Client/NPC/ShowHTNCommand.cs b/Content.Client/NPC/ShowHTNCommand.cs index c1f00270877..c420be13a6c 100644 --- a/Content.Client/NPC/ShowHTNCommand.cs +++ b/Content.Client/NPC/ShowHTNCommand.cs @@ -3,9 +3,9 @@ namespace Content.Client.NPC; -public sealed class ShowHtnCommand : LocalizedEntityCommands +public sealed partial class ShowHtnCommand : LocalizedEntityCommands { - [Dependency] private readonly HTNSystem _htnSystem = default!; + [Dependency] private HTNSystem _htnSystem = default!; public override string Command => "showhtn"; diff --git a/Content.Client/NPC/Systems/NPCSystem.cs b/Content.Client/NPC/Systems/NPCSystem.cs new file mode 100644 index 00000000000..b20756aea52 --- /dev/null +++ b/Content.Client/NPC/Systems/NPCSystem.cs @@ -0,0 +1,12 @@ +using Content.Client.NPC.HTN; +using Content.Shared.NPC.Systems; + +namespace Content.Client.NPC.Systems; + +public sealed class NPCSystem : SharedNPCSystem +{ + public override bool IsNpc(EntityUid uid) + { + return HasComp(uid); + } +} diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs index d7c010e2e35..729351a756e 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs @@ -15,7 +15,7 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private IPrototypeManager _prototypeManager = default!; private const string PanelBgColor = "#202023"; diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkOverlay.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkOverlay.cs index cd57c3b5fbc..5f415a48c4a 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkOverlay.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkOverlay.cs @@ -7,10 +7,10 @@ namespace Content.Client.NetworkConfigurator; -public sealed class NetworkConfiguratorLinkOverlay : Overlay +public sealed partial class NetworkConfiguratorLinkOverlay : Overlay { - [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private IEntityManager _entityManager = default!; + [Dependency] private IRobustRandom _random = default!; private readonly DeviceListSystem _deviceListSystem; private readonly SharedTransformSystem _transformSystem; diff --git a/Content.Client/NetworkConfigurator/Systems/NetworkConfiguratorSystem.cs b/Content.Client/NetworkConfigurator/Systems/NetworkConfiguratorSystem.cs index 0a55cf0db84..ae39e9ae4af 100644 --- a/Content.Client/NetworkConfigurator/Systems/NetworkConfiguratorSystem.cs +++ b/Content.Client/NetworkConfigurator/Systems/NetworkConfiguratorSystem.cs @@ -16,12 +16,12 @@ namespace Content.Client.NetworkConfigurator.Systems; -public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem +public sealed partial class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem { - [Dependency] private readonly IPlayerManager _playerManager = default!; - [Dependency] private readonly IOverlayManager _overlay = default!; - [Dependency] private readonly ActionsSystem _actions = default!; - [Dependency] private readonly IInputManager _inputManager = default!; + [Dependency] private IPlayerManager _playerManager = default!; + [Dependency] private IOverlayManager _overlay = default!; + [Dependency] private ActionsSystem _actions = default!; + [Dependency] private IInputManager _inputManager = default!; private static readonly EntProtoId Action = "ActionClearNetworkLinkOverlays"; @@ -136,9 +136,9 @@ protected override void FrameUpdate(FrameEventArgs args) } } -public sealed class ClearAllNetworkLinkOverlays : LocalizedEntityCommands +public sealed partial class ClearAllNetworkLinkOverlays : LocalizedEntityCommands { - [Dependency] private readonly NetworkConfiguratorSystem _network = default!; + [Dependency] private NetworkConfiguratorSystem _network = default!; public override string Command => "clearnetworklinkoverlays"; diff --git a/Content.Client/NodeContainer/NodeGroupSystem.cs b/Content.Client/NodeContainer/NodeGroupSystem.cs index 0a3d7ddad02..cbba584a591 100644 --- a/Content.Client/NodeContainer/NodeGroupSystem.cs +++ b/Content.Client/NodeContainer/NodeGroupSystem.cs @@ -12,13 +12,13 @@ namespace Content.Client.NodeContainer { [UsedImplicitly] - public sealed class NodeGroupSystem : EntitySystem + public sealed partial class NodeGroupSystem : EntitySystem { - [Dependency] private readonly IOverlayManager _overlayManager = default!; - [Dependency] private readonly EntityLookupSystem _entityLookup = default!; - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IInputManager _inputManager = default!; - [Dependency] private readonly IResourceCache _resourceCache = default!; + [Dependency] private IOverlayManager _overlayManager = default!; + [Dependency] private EntityLookupSystem _entityLookup = default!; + [Dependency] private IMapManager _mapManager = default!; + [Dependency] private IInputManager _inputManager = default!; + [Dependency] private IResourceCache _resourceCache = default!; public bool VisEnabled { get; private set; } diff --git a/Content.Client/NodeContainer/NodeVisCommand.cs b/Content.Client/NodeContainer/NodeVisCommand.cs index e5f0f8f5fab..8a3160f7577 100644 --- a/Content.Client/NodeContainer/NodeVisCommand.cs +++ b/Content.Client/NodeContainer/NodeVisCommand.cs @@ -4,10 +4,10 @@ namespace Content.Client.NodeContainer { - public sealed class NodeVisCommand : LocalizedEntityCommands + public sealed partial class NodeVisCommand : LocalizedEntityCommands { - [Dependency] private readonly IClientAdminManager _adminManager = default!; - [Dependency] private readonly NodeGroupSystem _nodeSystem = default!; + [Dependency] private IClientAdminManager _adminManager = default!; + [Dependency] private NodeGroupSystem _nodeSystem = default!; public override string Command => "nodevis"; @@ -23,9 +23,9 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) } } - public sealed class NodeVisFilterCommand : LocalizedEntityCommands + public sealed partial class NodeVisFilterCommand : LocalizedEntityCommands { - [Dependency] private readonly NodeGroupSystem _nodeSystem = default!; + [Dependency] private NodeGroupSystem _nodeSystem = default!; public override string Command => "nodevisfilter"; diff --git a/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs b/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs index ad4f1a75d47..af7a11319d6 100644 --- a/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs +++ b/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs @@ -9,9 +9,9 @@ namespace Content.Client.NukeOps; [UsedImplicitly] -public sealed class WarDeclaratorBoundUserInterface : BoundUserInterface +public sealed partial class WarDeclaratorBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private IConfigurationManager _cfg = default!; [ViewVariables] private WarDeclaratorWindow? _window; diff --git a/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs b/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs index 68487e98bd9..b030badc675 100644 --- a/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs +++ b/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs @@ -11,8 +11,8 @@ namespace Content.Client.NukeOps; [GenerateTypedNameReferences] public sealed partial class WarDeclaratorWindow : FancyWindow { - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly ILocalizationManager _localizationManager = default!; + [Dependency] private IGameTiming _gameTiming = default!; + [Dependency] private ILocalizationManager _localizationManager = default!; public event Action? OnActivated; diff --git a/Content.Client/Nutrition/EntitySystems/ClientFoodSequenceSystem.cs b/Content.Client/Nutrition/EntitySystems/ClientFoodSequenceSystem.cs index 46d71917c29..224e596e8bf 100644 --- a/Content.Client/Nutrition/EntitySystems/ClientFoodSequenceSystem.cs +++ b/Content.Client/Nutrition/EntitySystems/ClientFoodSequenceSystem.cs @@ -4,9 +4,9 @@ namespace Content.Client.Nutrition.EntitySystems; -public sealed class ClientFoodSequenceSystem : SharedFoodSequenceSystem +public sealed partial class ClientFoodSequenceSystem : SharedFoodSequenceSystem { - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SpriteSystem _sprite = default!; public override void Initialize() { diff --git a/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs b/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs new file mode 100644 index 00000000000..5dd5192537d --- /dev/null +++ b/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs @@ -0,0 +1,66 @@ +using Content.Shared.Nutrition.Components; +using Content.Shared.Nutrition.EntitySystems; +using Robust.Client.GameObjects; + +namespace Content.Client.Nutrition.EntitySystems; + +public sealed partial class CreamPieSystem : SharedCreamPieSystem +{ + [Dependency] private SpriteSystem _sprite = default!; + [Dependency] private AppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnComponentInit); + SubscribeLocalEvent(OnComponentShutdown); + SubscribeLocalEvent(OnAppearanceChange); + SubscribeLocalEvent(OnAfterAutoHandleState); + } + + private void OnComponentInit(Entity ent, ref ComponentInit args) + { + UpdateAppearance(ent); + } + + private void OnComponentShutdown(Entity ent, ref ComponentShutdown args) + { + _sprite.RemoveLayer(ent.Owner, CreamPiedVisualLayer.Key); + } + + private void OnAppearanceChange(Entity ent, ref AppearanceChangeEvent args) + { + UpdateAppearance((ent.Owner, ent.Comp, args.Sprite, args.Component)); + } + + private void OnAfterAutoHandleState(Entity ent, ref AfterAutoHandleStateEvent args) + { + // Update when the sprite datafield is changed so that changelings can transform properly. + UpdateAppearance(ent); + } + + private void UpdateAppearance(Entity ent) + { + if (!Resolve(ent, ref ent.Comp2, false) || !Resolve(ent, ref ent.Comp3, false)) + return; + + var creamPied = ent.Comp1; + var sprite = ent.Comp2; + var appearance = ent.Comp3; + + // If there is no sprite to use, remove the layer. Otherwise ensure that it exists and set the visuals accordingly. + int index; + if (creamPied.Sprite == null) + { + _sprite.RemoveLayer((ent.Owner, sprite), CreamPiedVisualLayer.Key); + return; + } + + index = _sprite.LayerMapReserve((ent.Owner, sprite), CreamPiedVisualLayer.Key); + + _appearance.TryGetData(ent.Owner, CreamPiedVisuals.Creamed, out var isCreamPied, appearance); + _sprite.LayerSetSprite((ent.Owner, sprite), index, creamPied.Sprite); + _sprite.LayerSetVisible((ent.Owner, sprite), index, isCreamPied); + } +} diff --git a/Content.Client/Nutrition/EntitySystems/CreamPiedSystem.cs b/Content.Client/Nutrition/EntitySystems/CreamPiedSystem.cs deleted file mode 100644 index 24632b71fa2..00000000000 --- a/Content.Client/Nutrition/EntitySystems/CreamPiedSystem.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Content.Shared.Nutrition.EntitySystems; -using JetBrains.Annotations; - -namespace Content.Client.Nutrition.EntitySystems -{ - [UsedImplicitly] - public sealed class CreamPiedSystem : SharedCreamPieSystem - { - } -} diff --git a/Content.Client/Nutrition/EntitySystems/InfantSystem.cs b/Content.Client/Nutrition/EntitySystems/InfantSystem.cs index b003a24f09a..d6fef2ddd80 100644 --- a/Content.Client/Nutrition/EntitySystems/InfantSystem.cs +++ b/Content.Client/Nutrition/EntitySystems/InfantSystem.cs @@ -6,9 +6,9 @@ namespace Content.Client.Nutrition.EntitySystems; /// /// This handles visuals for /// -public sealed class InfantSystem : EntitySystem +public sealed partial class InfantSystem : EntitySystem { - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private SpriteSystem _sprite = default!; /// public override void Initialize() diff --git a/Content.Client/Options/OptionsVisualizerSystem.cs b/Content.Client/Options/OptionsVisualizerSystem.cs index 1876b9bf55d..15af9eb08b4 100644 --- a/Content.Client/Options/OptionsVisualizerSystem.cs +++ b/Content.Client/Options/OptionsVisualizerSystem.cs @@ -8,7 +8,7 @@ namespace Content.Client.Options; /// /// Implements . /// -public sealed class OptionsVisualizerSystem : EntitySystem +public sealed partial class OptionsVisualizerSystem : EntitySystem { private static readonly (OptionVisualizerOptions, CVarDef)[] OptionVars = { @@ -16,9 +16,9 @@ private static readonly (OptionVisualizerOptions, CVarDef)[] OptionVars = (OptionVisualizerOptions.ReducedMotion, CCVars.ReducedMotion), }; - [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly IReflectionManager _reflection = default!; - [Dependency] private readonly SpriteSystem _sprite = default!; + [Dependency] private IConfigurationManager _cfg = default!; + [Dependency] private IReflectionManager _reflection = default!; + [Dependency] private SpriteSystem _sprite = default!; private OptionVisualizerOptions _currentOptions; diff --git a/Content.Client/Options/UI/EscapeMenu.xaml b/Content.Client/Options/UI/EscapeMenu.xaml index f46d65ac736..f47f41b9fde 100644 --- a/Content.Client/Options/UI/EscapeMenu.xaml +++ b/Content.Client/Options/UI/EscapeMenu.xaml @@ -1,22 +1,33 @@  + xmlns:changelog="clr-namespace:Content.Client.Changelog" + xmlns:ui="clr-namespace:Content.Client.Voting.UI" + xmlns:ui1="clr-namespace:Content.Client.Options.UI" + xmlns:system="clr-namespace:System;assembly=System.Runtime" + Title="{Loc 'ui-escape-title'}" + Resizable="False"> - + diff --git a/Content.Client/Options/UI/OptionsMenu.xaml.cs b/Content.Client/Options/UI/OptionsMenu.xaml.cs index 9efd04fd0b8..0952360b16f 100644 --- a/Content.Client/Options/UI/OptionsMenu.xaml.cs +++ b/Content.Client/Options/UI/OptionsMenu.xaml.cs @@ -8,7 +8,7 @@ namespace Content.Client.Options.UI [GenerateTypedNameReferences] public sealed partial class OptionsMenu : DefaultWindow { - [Dependency] private readonly IClientAdminManager _adminManager = default!; + [Dependency] private IClientAdminManager _adminManager = default!; public OptionsMenu() { diff --git a/Content.Client/Options/UI/OptionsTabControlRow.xaml.cs b/Content.Client/Options/UI/OptionsTabControlRow.xaml.cs index 32680dfcc28..26c7b79bfc7 100644 --- a/Content.Client/Options/UI/OptionsTabControlRow.xaml.cs +++ b/Content.Client/Options/UI/OptionsTabControlRow.xaml.cs @@ -48,8 +48,8 @@ namespace Content.Client.Options.UI; [GenerateTypedNameReferences] public sealed partial class OptionsTabControlRow : Control { - [Dependency] private readonly ILocalizationManager _loc = default!; - [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private ILocalizationManager _loc = default!; + [Dependency] private IConfigurationManager _cfg = default!; private ValueList _options; diff --git a/Content.Client/Options/UI/Tabs/AccessibilityTab.xaml b/Content.Client/Options/UI/Tabs/AccessibilityTab.xaml index 72df18390f2..5a389ca4914 100644 --- a/Content.Client/Options/UI/Tabs/AccessibilityTab.xaml +++ b/Content.Client/Options/UI/Tabs/AccessibilityTab.xaml @@ -7,6 +7,7 @@