merge remote wizden/stable

This commit is contained in:
Dmitry
2026-04-18 19:47:29 +07:00
620 changed files with 7724 additions and 7208 deletions
@@ -1,5 +1,6 @@
#nullable enable #nullable enable
using System; using System;
using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
@@ -44,7 +45,7 @@ public class ComponentQueryBenchmark
ProgramShared.PathOffset = "../../../../"; ProgramShared.PathOffset = "../../../../";
PoolManager.Startup(typeof(QueryBenchSystem).Assembly); 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<IEntityManager>(); _entMan = _pair.Server.ResolveDependency<IEntityManager>();
_itemQuery = _entMan.GetEntityQuery<ItemComponent>(); _itemQuery = _entMan.GetEntityQuery<ItemComponent>();
+2 -1
View File
@@ -1,3 +1,4 @@
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using Content.IntegrationTests; using Content.IntegrationTests;
@@ -68,7 +69,7 @@ public class DeltaPressureBenchmark
{ {
ProgramShared.PathOffset = "../../../../"; ProgramShared.PathOffset = "../../../../";
PoolManager.Startup(); PoolManager.Startup();
_pair = await PoolManager.GetServerClient(); _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null));
var server = _pair.Server; var server = _pair.Server;
var mapdata = await _pair.CreateTestMap(); var mapdata = await _pair.CreateTestMap();
+2 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using Content.IntegrationTests; using Content.IntegrationTests;
@@ -69,7 +70,7 @@ public class DestructibleBenchmark
{ {
ProgramShared.PathOffset = "../../../../"; ProgramShared.PathOffset = "../../../../";
PoolManager.Startup(); PoolManager.Startup();
_pair = await PoolManager.GetServerClient(); _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null));
var server = _pair.Server; var server = _pair.Server;
_entMan = server.ResolveDependency<IEntityManager>(); _entMan = server.ResolveDependency<IEntityManager>();
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using Content.IntegrationTests; using Content.IntegrationTests;
@@ -60,7 +61,7 @@ public class DeviceNetworkingBenchmark
{ {
ProgramShared.PathOffset = "../../../../"; ProgramShared.PathOffset = "../../../../";
PoolManager.Startup(typeof(DeviceNetworkingBenchmark).Assembly); PoolManager.Startup(typeof(DeviceNetworkingBenchmark).Assembly);
_pair = await PoolManager.GetServerClient(); _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null));
var server = _pair.Server; var server = _pair.Server;
await server.WaitPost(() => await server.WaitPost(() =>
+2 -1
View File
@@ -1,3 +1,4 @@
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using Content.IntegrationTests; using Content.IntegrationTests;
@@ -51,7 +52,7 @@ public class GasReactionBenchmark
{ {
ProgramShared.PathOffset = "../../../../"; ProgramShared.PathOffset = "../../../../";
PoolManager.Startup(); PoolManager.Startup();
_pair = await PoolManager.GetServerClient(); _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null));
var server = _pair.Server; var server = _pair.Server;
// Create test map and grid // Create test map and grid
+3 -2
View File
@@ -1,4 +1,5 @@
using System.Threading.Tasks; using System.IO;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using Content.IntegrationTests; using Content.IntegrationTests;
using Content.IntegrationTests.Pair; using Content.IntegrationTests.Pair;
@@ -27,7 +28,7 @@ public class HeatCapacityBenchmark
{ {
ProgramShared.PathOffset = "../../../../"; ProgramShared.PathOffset = "../../../../";
PoolManager.Startup(); PoolManager.Startup();
_pair = await PoolManager.GetServerClient(); _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null));
await _pair.Connect(); await _pair.Connect();
_cEntMan = _pair.Client.ResolveDependency<IEntityManager>(); _cEntMan = _pair.Client.ResolveDependency<IEntityManager>();
_sEntMan = _pair.Server.ResolveDependency<IEntityManager>(); _sEntMan = _pair.Server.ResolveDependency<IEntityManager>();
+2 -1
View File
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
@@ -29,7 +30,7 @@ public class MapLoadBenchmark
ProgramShared.PathOffset = "../../../../"; ProgramShared.PathOffset = "../../../../";
PoolManager.Startup(); PoolManager.Startup();
_pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); _pair = PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)).GetAwaiter().GetResult();
var server = _pair.Server; var server = _pair.Server;
Paths = server.ResolveDependency<IPrototypeManager>() Paths = server.ResolveDependency<IPrototypeManager>()
+2 -1
View File
@@ -1,5 +1,6 @@
#nullable enable #nullable enable
using System; using System;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
@@ -50,7 +51,7 @@ public class PvsBenchmark
#endif #endif
PoolManager.Startup(); PoolManager.Startup();
_pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); _pair = PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null)).GetAwaiter().GetResult();
_entMan = _pair.Server.ResolveDependency<IEntityManager>(); _entMan = _pair.Server.ResolveDependency<IEntityManager>();
_pair.Server.CfgMan.SetCVar(CVars.NetPVS, true); _pair.Server.CfgMan.SetCVar(CVars.NetPVS, true);
_pair.Server.CfgMan.SetCVar(CVars.ThreadParallelCount, 0); _pair.Server.CfgMan.SetCVar(CVars.ThreadParallelCount, 0);
+2 -1
View File
@@ -1,4 +1,5 @@
#nullable enable #nullable enable
using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
@@ -21,7 +22,7 @@ public class RaiseEventBenchmark
{ {
ProgramShared.PathOffset = "../../../../"; ProgramShared.PathOffset = "../../../../";
PoolManager.Startup(typeof(BenchSystem).Assembly); 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 entMan = _pair.Server.EntMan;
var fact = _pair.Server.ResolveDependency<IComponentFactory>(); var fact = _pair.Server.ResolveDependency<IComponentFactory>();
var bus = (EntityEventBus)entMan.EventBus; var bus = (EntityEventBus)entMan.EventBus;
@@ -1,4 +1,5 @@
using System.Threading.Tasks; using System.IO;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using Content.IntegrationTests; using Content.IntegrationTests;
using Content.IntegrationTests.Pair; using Content.IntegrationTests.Pair;
@@ -36,7 +37,7 @@ public class SpawnEquipDeleteBenchmark
{ {
ProgramShared.PathOffset = "../../../../"; ProgramShared.PathOffset = "../../../../";
PoolManager.Startup(); PoolManager.Startup();
_pair = await PoolManager.GetServerClient(); _pair = await PoolManager.GetServerClient(testContext: new ExternalTestContext("Benchmark", StreamWriter.Null));
var server = _pair.Server; var server = _pair.Server;
var mapData = await _pair.CreateTestMap(); var mapData = await _pair.CreateTestMap();
@@ -65,7 +65,7 @@ namespace Content.Client.Access.UI
_window?.UpdateState(castState); _window?.UpdateState(castState);
} }
public void SubmitData(string newFullName, string newJobTitle, List<ProtoId<AccessLevelPrototype>> newAccessList, ProtoId<JobPrototype> newJobPrototype) public void SubmitData(string newFullName, string newJobTitle, List<ProtoId<AccessLevelPrototype>> newAccessList, ProtoId<JobPrototype>? newJobPrototype)
{ {
SendMessage(new WriteToTargetIdMessage( SendMessage(new WriteToTargetIdMessage(
newFullName, newFullName,
@@ -216,7 +216,7 @@ namespace Content.Client.Access.UI
JobTitleLineEdit.Text, JobTitleLineEdit.Text,
// Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair // 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(), _accessButtons.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList(),
jobProtoDirty ? _jobPrototypeIds[JobPresetOptionButton.SelectedId] : string.Empty); jobProtoDirty ? _jobPrototypeIds[JobPresetOptionButton.SelectedId] : null);
} }
} }
} }
@@ -1,6 +1,7 @@
using Content.Client.Stylesheets; using Content.Client.Stylesheets;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Atmos.Components; using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.EntitySystems;
using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Monitor;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
using Content.Shared.Temperature; using Content.Shared.Temperature;
@@ -22,6 +23,7 @@ public sealed partial class AtmosAlarmEntryContainer : BoxContainer
private readonly IEntityManager _entManager; private readonly IEntityManager _entManager;
private readonly IResourceCache _cache; private readonly IResourceCache _cache;
private readonly SharedAtmosphereSystem _atmosphere;
private Dictionary<AtmosAlarmType, string> _alarmStrings = new Dictionary<AtmosAlarmType, string>() private Dictionary<AtmosAlarmType, string> _alarmStrings = new Dictionary<AtmosAlarmType, string>()
{ {
@@ -37,6 +39,7 @@ public sealed partial class AtmosAlarmEntryContainer : BoxContainer
_entManager = IoCManager.Resolve<IEntityManager>(); _entManager = IoCManager.Resolve<IEntityManager>();
_cache = IoCManager.Resolve<IResourceCache>(); _cache = IoCManager.Resolve<IResourceCache>();
_atmosphere = _entManager.System<SharedAtmosphereSystem>();
NetEntity = uid; NetEntity = uid;
Coordinates = coordinates; Coordinates = coordinates;
@@ -149,7 +152,7 @@ public sealed partial class AtmosAlarmEntryContainer : BoxContainer
foreach ((var gas, (var mol, var percent, var alert)) in keyValuePairs) foreach ((var gas, (var mol, var percent, var alert)) in keyValuePairs)
{ {
FixedPoint2 gasPercent = percent * 100f; 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() var gasLabel = new Label()
{ {
@@ -1,6 +1,7 @@
using Content.Client.Stylesheets; using Content.Client.Stylesheets;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Atmos.Components; using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.EntitySystems;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
using Content.Shared.Temperature; using Content.Shared.Temperature;
using Robust.Client.AutoGenerated; using Robust.Client.AutoGenerated;
@@ -19,12 +20,14 @@ public sealed partial class AtmosMonitoringEntryContainer : BoxContainer
private readonly IEntityManager _entManager; private readonly IEntityManager _entManager;
private readonly IResourceCache _cache; private readonly IResourceCache _cache;
private readonly SharedAtmosphereSystem _atmosphere;
public AtmosMonitoringEntryContainer(AtmosMonitoringConsoleEntry data) public AtmosMonitoringEntryContainer(AtmosMonitoringConsoleEntry data)
{ {
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
_entManager = IoCManager.Resolve<IEntityManager>(); _entManager = IoCManager.Resolve<IEntityManager>();
_cache = IoCManager.Resolve<IResourceCache>(); _cache = IoCManager.Resolve<IResourceCache>();
_atmosphere = _entManager.System<SharedAtmosphereSystem>();
Data = data; Data = data;
@@ -132,7 +135,7 @@ public sealed partial class AtmosMonitoringEntryContainer : BoxContainer
var gasPercent = (FixedPoint2)0f; var gasPercent = (FixedPoint2)0f;
gasPercent = percent * 100f; 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() var gasLabel = new Label()
{ {
@@ -51,7 +51,7 @@ public sealed partial class AtmosphereSystem
// though this isnt the hottest code path so it should be fine // though this isnt the hottest code path so it should be fine
// the gc can eat a little as a treat // the gc can eat a little as a treat
var tmp = new float[moles.Length]; var tmp = new float[moles.Length];
NumericsHelpers.Multiply(moles, GasSpecificHeats, tmp); NumericsHelpers.Multiply(moles, GasMolarHeatCapacities, tmp);
// Adjust heat capacity by speedup, because this is primarily what // Adjust heat capacity by speedup, because this is primarily what
// determines how quickly gases heat up/cool. // determines how quickly gases heat up/cool.
return MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity); return MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity);
@@ -0,0 +1,30 @@
using Content.Client.Atmos.Overlays;
using JetBrains.Annotations;
using Robust.Client.Graphics;
namespace Content.Client.Atmos.EntitySystems;
/// <summary>
/// System responsible for rendering heat distortion using <see cref="GasTileHeatBlurOverlay"/>.
/// </summary>
[UsedImplicitly]
public sealed class GasTileHeatBlurOverlaySystem : EntitySystem
{
[Dependency] private readonly 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<GasTileHeatBlurOverlay>();
}
}
@@ -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;
/// <summary>
/// Overlay responsible for rendering heat distortion shader.
/// </summary>
public sealed class GasTileHeatBlurOverlay : Overlay
{
public override bool RequestScreenTexture { get; set; } = true;
private static readonly ProtoId<ShaderPrototype> UnshadedShader = "unshaded";
private static readonly ProtoId<ShaderPrototype> HeatOverlayShader = "HeatBlur";
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IClyde _clyde = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;
private readonly SharedTransformSystem _xformSys;
private readonly ShaderInstance _shader;
private readonly Texture _noiseTexture;
private readonly Texture _heatGradientTexture;
private List<Entity<MapGridComponent>> _intersectingGrids = new();
private readonly OverlayResourceCache<CachedResources> _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<SharedTransformSystem>();
_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<GasTileOverlayComponent>();
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();
}
/// <summary>
/// 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.
/// </summary>
/// <param name="temp">The temperature of the tile.</param>
/// <returns>The strength of the heat distortion effect.</returns>
/// <seealso cref="ThermalByte"/>
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();
}
}
}
@@ -72,17 +72,7 @@ public sealed class GasTileVisibleGasOverlay : Overlay
{ {
var gasPrototype = _atmosphereSystem.GetGas(_gasTileOverlaySystem.VisibleGasId[i]); var gasPrototype = _atmosphereSystem.GetGas(_gasTileOverlaySystem.VisibleGasId[i]);
SpriteSpecifier overlay; switch (gasPrototype.GasOverlaySprite)
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: case SpriteSpecifier.Rsi animated:
var rsi = _resourceCache.GetResource<RSIResource>(animated.RsiPath).RSI; var rsi = _resourceCache.GetResource<RSIResource>(animated.RsiPath).RSI;
@@ -1,41 +1,33 @@
using Robust.Client.GameObjects;
using Robust.Client.UserInterface; 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)
{ {
[ViewVariables] }
private GasAnalyzerWindow? _window;
public GasAnalyzerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) protected override void Open()
{ {
} base.Open();
protected override void Open() _window = this.CreateWindowCenteredLeft<GasAnalyzerWindow>();
{ _window.OnClose += Close;
base.Open(); }
_window = this.CreateWindowCenteredLeft<GasAnalyzerWindow>(); protected override void ReceiveMessage(BoundUserInterfaceMessage message)
_window.OnClose += Close; {
} if (_window == null)
return;
protected override void ReceiveMessage(BoundUserInterfaceMessage message) if (message is not GasAnalyzerUserMessage cast)
{ return;
if (_window == null)
return;
if (message is not GasAnalyzerUserMessage cast)
return;
_window.Populate(cast);
}
protected override void Dispose(bool disposing) _window.Populate(cast);
{
base.Dispose(disposing);
if (disposing)
_window?.Dispose();
}
} }
} }
@@ -1,6 +1,8 @@
using System.Numerics; using System.Numerics;
using Content.Client.UserInterface.Controls; using Content.Client.UserInterface.Controls;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.EntitySystems;
using Content.Shared.Temperature; using Content.Shared.Temperature;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
@@ -8,7 +10,6 @@ using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.CustomControls;
using Robust.Client.AutoGenerated; using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML; using Robust.Client.UserInterface.XAML;
using static Content.Shared.Atmos.Components.GasAnalyzerComponent;
using Direction = Robust.Shared.Maths.Direction; using Direction = Robust.Shared.Maths.Direction;
namespace Content.Client.Atmos.UI namespace Content.Client.Atmos.UI
@@ -16,25 +17,17 @@ namespace Content.Client.Atmos.UI
[GenerateTypedNameReferences] [GenerateTypedNameReferences]
public sealed partial class GasAnalyzerWindow : DefaultWindow public sealed partial class GasAnalyzerWindow : DefaultWindow
{ {
private readonly SharedAtmosphereSystem _atmosphere;
private NetEntity _currentEntity = NetEntity.Invalid; private NetEntity _currentEntity = NetEntity.Invalid;
public GasAnalyzerWindow() public GasAnalyzerWindow()
{ {
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
_atmosphere = IoCManager.Resolve<IEntityManager>().System<SharedAtmosphereSystem>();
} }
public void Populate(GasAnalyzerUserMessage msg) 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) if (msg.NodeGasMixes.Length == 0)
{ {
CTopBox.AddChild(new Label CTopBox.AddChild(new Label
@@ -329,31 +322,31 @@ namespace Content.Client.Atmos.UI
for (var j = 0; j < gasMix.Gases.Length; j++) for (var j = 0; j < gasMix.Gases.Length; j++)
{ {
var gas = gasMix.Gases[j]; var gasEntry = gasMix.Gases[j];
var color = Color.FromHex($"#{gas.Color}", Color.White); var gasProto = _atmosphere.GetGas(gasEntry.Gas);
// Add to the table // Add to the table
tableKey.AddChild(new Label tableKey.AddChild(new Label
{ {
Text = Loc.GetString(gas.Name) Text = Loc.GetString(gasProto.Name)
}); });
tableVal.AddChild(new Label tableVal.AddChild(new Label
{ {
Text = Loc.GetString("gas-analyzer-window-molarity-text", Text = Loc.GetString("gas-analyzer-window-molarity-text",
("mol", $"{gas.Amount:0.00}")), ("mol", $"{gasEntry.Amount:0.00}")),
Align = Label.AlignMode.Right, Align = Label.AlignMode.Right,
}); });
tablePercent.AddChild(new Label tablePercent.AddChild(new Label
{ {
Text = Loc.GetString("gas-analyzer-window-percentage-text", 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 Align = Label.AlignMode.Right
}); });
// Add to the gas bar //TODO: highlight the currently hover one // 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", gasBar.AddEntry(gasEntry.Amount, gasProto.Color, tooltip: Loc.GetString("gas-analyzer-window-molarity-percentage-text",
("gasName", gas.Name), ("gasName", Loc.GetString(gasProto.Name)),
("amount", $"{gas.Amount:0.##}"), ("amount", $"{gasEntry.Amount:0.##}"),
("percentage", $"{(gas.Amount / totalGasAmount * 100):0.#}"))); ("percentage", $"{(gasEntry.Amount / totalGasAmount * 100):0.#}")));
} }
dataContainer.AddChild(gasBar); dataContainer.AddChild(gasBar);
+3 -5
View File
@@ -235,8 +235,6 @@ public sealed class AmbientSoundSystem : SharedAmbientSoundSystem
/// </summary> /// </summary>
private void ProcessNearbyAmbience(TransformComponent playerXform) private void ProcessNearbyAmbience(TransformComponent playerXform)
{ {
var query = GetEntityQuery<TransformComponent>();
var metaQuery = GetEntityQuery<MetaDataComponent>();
var mapPos = _xformSystem.GetMapCoordinates(playerXform); var mapPos = _xformSystem.GetMapCoordinates(playerXform);
// Remove out-of-range ambiences // Remove out-of-range ambiences
@@ -249,9 +247,9 @@ public sealed class AmbientSoundSystem : SharedAmbientSoundSystem
if (comp.Enabled && if (comp.Enabled &&
// Don't keep playing sounds that have changed since. // Don't keep playing sounds that have changed since.
sound.Sound == comp.Sound && sound.Sound == comp.Sound &&
query.TryGetComponent(owner, out var xform) && TryComp(owner, out TransformComponent? xform) &&
xform.MapID == playerXform.MapID && xform.MapID == playerXform.MapID &&
!metaQuery.GetComponent(owner).EntityPaused) !Paused(owner))
{ {
// TODO: This is just trydistance for coordinates. // TODO: This is just trydistance for coordinates.
var distance = (xform.ParentUid == playerXform.ParentUid) var distance = (xform.ParentUid == playerXform.ParentUid)
@@ -294,7 +292,7 @@ public sealed class AmbientSoundSystem : SharedAmbientSoundSystem
var comp = sourceEntity.Comp; var comp = sourceEntity.Comp;
if (_playingSounds.ContainsKey(sourceEntity) || if (_playingSounds.ContainsKey(sourceEntity) ||
metaQuery.GetComponent(uid).EntityPaused) Paused(uid))
continue; continue;
var audioParams = _params var audioParams = _params
@@ -23,8 +23,7 @@ public sealed class AmbientSoundTreeSystem : ComponentTreeSystem<AmbientSoundTre
var pos = XformSystem.GetRelativePosition( var pos = XformSystem.GetRelativePosition(
entry.Transform, entry.Transform,
entry.Component.TreeUid.Value, entry.Component.TreeUid.Value);
GetEntityQuery<TransformComponent>());
return ExtractAabb(in entry, pos, default); return ExtractAabb(in entry, pos, default);
} }
@@ -14,15 +14,12 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
[Dependency] private readonly TransformSystem _transform = default!; [Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly ExamineSystemShared _examine = default!; [Dependency] private readonly ExamineSystemShared _examine = default!;
[Dependency] private readonly SpriteSystem _sprite = default!; [Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly EntityQuery<MobStateComponent> _mobStateQuery = default!;
private EntityQuery<MobStateComponent> _mobStateQuery;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
_mobStateQuery = GetEntityQuery<MobStateComponent>();
SubscribeNetworkEvent<PlayBoxEffectMessage>(OnBoxEffect); SubscribeNetworkEvent<PlayBoxEffectMessage>(OnBoxEffect);
} }
@@ -33,11 +30,7 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
if (!TryComp<CardboardBoxComponent>(source, out var box)) if (!TryComp<CardboardBoxComponent>(source, out var box))
return; return;
var xformQuery = GetEntityQuery<TransformComponent>(); var xform = Transform(source);
if (!xformQuery.TryGetComponent(source, out var xform))
return;
var sourcePos = _transform.GetMapCoordinates(source, xform); var sourcePos = _transform.GetMapCoordinates(source, xform);
//Any mob that can move should be surprised? //Any mob that can move should be surprised?
@@ -72,7 +65,7 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
var ent = Spawn(box.Effect, mapPos); var ent = Spawn(box.Effect, mapPos);
if (!xformQuery.TryGetComponent(ent, out var entTransform) || !TryComp<SpriteComponent>(ent, out var sprite)) if (!TryComp(ent, out TransformComponent? entTransform) || !TryComp<SpriteComponent>(ent, out var sprite))
continue; continue;
_sprite.SetOffset((ent, sprite), new Vector2(0, 1)); _sprite.SetOffset((ent, sprite), new Vector2(0, 1));
@@ -4,6 +4,7 @@ using Content.Shared.Changeling.Components;
using Content.Shared.Changeling.Systems; using Content.Shared.Changeling.Systems;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Shared.Utility;
namespace Content.Client.Changeling.UI; namespace Content.Client.Changeling.UI;
@@ -12,7 +13,9 @@ public sealed partial class ChangelingTransformBoundUserInterface(EntityUid owne
{ {
private SimpleRadialMenu? _menu; private SimpleRadialMenu? _menu;
private static readonly Color SelectedOptionBackground = Palettes.Green.Element.WithAlpha(128); private static readonly Color SelectedOptionBackground = Palettes.Green.Element.WithAlpha(128);
private static readonly Color DisabledOptionBackground = Palettes.Slate.Element.WithAlpha(128);
private static readonly Color SelectedOptionHoverBackground = Palettes.Green.HoveredElement.WithAlpha(128); private static readonly Color SelectedOptionHoverBackground = Palettes.Green.HoveredElement.WithAlpha(128);
private static readonly Color DisabledOptionHoverBackground = Palettes.Slate.HoveredElement.WithAlpha(128);
protected override void Open() protected override void Open()
{ {
@@ -23,7 +26,6 @@ public sealed partial class ChangelingTransformBoundUserInterface(EntityUid owne
_menu.OpenOverMouseScreenPosition(); _menu.OpenOverMouseScreenPosition();
} }
public override void Update() public override void Update()
{ {
if (_menu == null) if (_menu == null)
@@ -32,7 +34,7 @@ public sealed partial class ChangelingTransformBoundUserInterface(EntityUid owne
if (!EntMan.TryGetComponent<ChangelingIdentityComponent>(Owner, out var lingIdentity)) if (!EntMan.TryGetComponent<ChangelingIdentityComponent>(Owner, out var lingIdentity))
return; return;
var models = ConvertToButtons(lingIdentity.ConsumedIdentities, lingIdentity?.CurrentIdentity); var models = ConvertToButtons(lingIdentity.ConsumedIdentities.Keys, lingIdentity?.CurrentIdentity);
_menu.SetButtons(models); _menu.SetButtons(models);
} }
@@ -43,21 +45,41 @@ public sealed partial class ChangelingTransformBoundUserInterface(EntityUid owne
) )
{ {
var buttons = new List<RadialMenuOptionBase>(); var buttons = new List<RadialMenuOptionBase>();
var dropButtons = new List<RadialMenuOptionBase>();
foreach (var identity in identities) foreach (var identity in identities)
{ {
if (!EntMan.TryGetComponent<MetaDataComponent>(identity, out var metadata)) // Options for selecting identities.
continue;
var option = new RadialMenuActionOption<NetEntity>(SendIdentitySelect, EntMan.GetNetEntity(identity)) var option = new RadialMenuActionOption<NetEntity>(SendIdentitySelect, EntMan.GetNetEntity(identity))
{ {
IconSpecifier = RadialMenuIconSpecifier.With(identity), IconSpecifier = RadialMenuIconSpecifier.With(identity),
ToolTip = metadata.EntityName, ToolTip = Loc.GetString("changeling-transform-bui-select-entity", ("entity", identity)),
BackgroundColor = (currentIdentity == identity) ? SelectedOptionBackground : null, BackgroundColor = (currentIdentity == identity) ? SelectedOptionBackground : null, // mark as selected
HoverBackgroundColor = (currentIdentity == identity) ? SelectedOptionHoverBackground : null HoverBackgroundColor = (currentIdentity == identity) ? SelectedOptionHoverBackground : null
}; };
buttons.Add(option); buttons.Add(option);
// Options for dropping identities.
var dropOption = new RadialMenuActionOption<NetEntity>(SendIdentityDrop, EntMan.GetNetEntity(identity))
{
IconSpecifier = RadialMenuIconSpecifier.With(identity),
ToolTip = (currentIdentity == identity)
? Loc.GetString("changeling-transform-bui-drop-identity-cannot-drop")
: Loc.GetString("changeling-transform-bui-drop-identity-entity", ("entity", identity)),
BackgroundColor = (currentIdentity == identity) ? DisabledOptionBackground : null, // cannot drop your current identity
HoverBackgroundColor = (currentIdentity == identity) ? DisabledOptionHoverBackground : null
};
dropButtons.Add(dropOption);
} }
// Menu category for dropping identities.
var dropMenuButton = new RadialMenuNestedLayerOption(dropButtons)
{
IconSpecifier = RadialMenuIconSpecifier.With(new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/delete.svg.192dpi.png"))),
ToolTip = Loc.GetString("changeling-transform-bui-drop-identity-menu")
};
buttons.Add(dropMenuButton);
return buttons; return buttons;
} }
@@ -65,4 +87,9 @@ public sealed partial class ChangelingTransformBoundUserInterface(EntityUid owne
{ {
SendPredictedMessage(new ChangelingTransformIdentitySelectMessage(identityId)); SendPredictedMessage(new ChangelingTransformIdentitySelectMessage(identityId));
} }
private void SendIdentityDrop(NetEntity identityId)
{
SendPredictedMessage(new ChangelingTransformIdentityDropMessage(identityId));
}
} }
+3 -11
View File
@@ -16,17 +16,9 @@ public sealed class ClickableSystem : EntitySystem
[Dependency] private readonly SharedTransformSystem _transforms = default!; [Dependency] private readonly SharedTransformSystem _transforms = default!;
[Dependency] private readonly SpriteSystem _sprites = default!; [Dependency] private readonly SpriteSystem _sprites = default!;
private EntityQuery<ClickableComponent> _clickableQuery; [Dependency] private readonly EntityQuery<ClickableComponent> _clickableQuery = default!;
private EntityQuery<TransformComponent> _xformQuery; [Dependency] private readonly EntityQuery<TransformComponent> _xformQuery = default!;
private EntityQuery<FadingSpriteComponent> _fadingSpriteQuery; [Dependency] private readonly EntityQuery<FadingSpriteComponent> _fadingSpriteQuery = default!;
public override void Initialize()
{
base.Initialize();
_clickableQuery = GetEntityQuery<ClickableComponent>();
_xformQuery = GetEntityQuery<TransformComponent>();
_fadingSpriteQuery = GetEntityQuery<FadingSpriteComponent>();
}
/// <summary> /// <summary>
/// Used to check whether a click worked. Will first check if the click falls inside of some explicit bounding /// Used to check whether a click worked. Will first check if the click falls inside of some explicit bounding
@@ -2,14 +2,18 @@ using System.Diagnostics.CodeAnalysis;
using Content.Shared.DisplacementMap; using Content.Shared.DisplacementMap;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager; using Robust.Shared.Serialization.Manager;
namespace Content.Client.DisplacementMap; namespace Content.Client.DisplacementMap;
public sealed class DisplacementMapSystem : EntitySystem public sealed class DisplacementMapSystem : EntitySystem
{ {
[Dependency] private readonly ISerializationManager _serialization = default!; [Dependency] private readonly ISerializationManager _serialization = null!;
[Dependency] private readonly SpriteSystem _sprite = default!; [Dependency] private readonly SpriteSystem _sprite = null!;
//needs to be replaced later: see comment on line 48
private static readonly ProtoId<ShaderPrototype> UnshadedID = "unshaded";
private static string? BuildDisplacementLayerKey(object key) private static string? BuildDisplacementLayerKey(object key)
{ {
@@ -40,7 +44,16 @@ public sealed class DisplacementMapSystem : EntitySystem
EnsureDisplacementIsNotOnSprite(sprite, key); EnsureDisplacementIsNotOnSprite(sprite, key);
if (data.ShaderOverride is not null) if (data.ShaderOverride is not null)
sprite.Comp.LayerSetShader(index, data.ShaderOverride); {
//TODO : this is a kinda janky workaround for the fact that the current rendering pipeline does not have
//proper support for multiple shaders on a given layer (or an ubershader to handle stacking all of the effects well)
//should be replaced by an engine-level solution, but this is an adequate temporary solution.
//what's that phrase about temporary solutions?
sprite.Comp.LayerSetShader(index,
(sprite.Comp[index] is SpriteComponent.Layer layer && layer.ShaderPrototype == UnshadedID)
? data.ShaderOverrideUnshaded
: data.ShaderOverride);
}
//allows you not to write it every time in the YML //allows you not to write it every time in the YML
foreach (var pair in data.SizeMaps) foreach (var pair in data.SizeMaps)
+1 -3
View File
@@ -50,9 +50,7 @@ public sealed class DoAfterSystem : SharedDoAfterSystem
var time = GameTiming.CurTime; var time = GameTiming.CurTime;
var comp = Comp<DoAfterComponent>(playerEntity.Value); var comp = Comp<DoAfterComponent>(playerEntity.Value);
var xformQuery = GetEntityQuery<TransformComponent>(); Update(playerEntity.Value, active, comp, time);
var handsQuery = GetEntityQuery<HandsComponent>();
Update(playerEntity.Value, active, comp, time, xformQuery, handsQuery);
} }
/// <summary> /// <summary>
+27 -10
View File
@@ -1,8 +1,8 @@
using Content.Shared.CCVar;
using Content.Shared.Drunk; using Content.Shared.Drunk;
using Content.Shared.StatusEffect;
using Content.Shared.StatusEffectNew;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.Player; using Robust.Client.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Enums; using Robust.Shared.Enums;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@@ -11,19 +11,23 @@ namespace Content.Client.Drunk;
public sealed class DrunkOverlay : Overlay public sealed class DrunkOverlay : Overlay
{ {
private static readonly ProtoId<ShaderPrototype> Shader = "Drunk"; private static readonly ProtoId<ShaderPrototype> DrunkShader = "Drunk";
[Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
[Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
private readonly Shared.StatusEffectNew.StatusEffectsSystem _statusEffectsSystem;
public override OverlaySpace Space => OverlaySpace.WorldSpace; public override OverlaySpace Space => OverlaySpace.WorldSpace;
public override bool RequestScreenTexture => true; public override bool RequestScreenTexture => true;
private readonly ShaderInstance _drunkShader; private readonly ShaderInstance _drunkShader;
public float CurrentBoozePower = 0.0f; public float CurrentBoozePower = 0.0f;
// Starting phase for the rotation effect.
// Needed so it doesn't always look the same for 0 motion.
public float Phase = 0f;
private const float VisualThreshold = 10.0f; private const float VisualThreshold = 10.0f;
private const float PowerDivisor = 250.0f; private const float PowerDivisor = 250.0f;
@@ -37,12 +41,22 @@ public sealed class DrunkOverlay : Overlay
private const float BoozePowerScale = 8f; private const float BoozePowerScale = 8f;
private float _visualScale = 0; private float _visualScale = 0f;
private float _timeScale = 1f;
private float _distortionScale = 1f;
public DrunkOverlay() public DrunkOverlay()
{ {
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
_drunkShader = _prototypeManager.Index(Shader).InstanceUnique(); _statusEffectsSystem = _entityManager.System<Shared.StatusEffectNew.StatusEffectsSystem>();
_drunkShader = _prototypeManager.Index(DrunkShader).InstanceUnique();
_configManager.OnValueChanged(CCVars.ReducedMotion, OnReducedMotionChanged, invokeImmediately: true);
}
private void OnReducedMotionChanged(bool reducedMotion)
{
_timeScale = reducedMotion ? 0.0f : 1.0f;
_distortionScale = reducedMotion ? 4.0f : 1.0f; // Make the offset stronger to compensate the lack of motion.
} }
protected override void FrameUpdate(FrameEventArgs args) protected override void FrameUpdate(FrameEventArgs args)
@@ -53,15 +67,14 @@ public sealed class DrunkOverlay : Overlay
if (playerEntity == null) if (playerEntity == null)
return; return;
var statusSys = _sysMan.GetEntitySystem<Shared.StatusEffectNew.StatusEffectsSystem>(); if (!_statusEffectsSystem.TryGetMaxTime<DrunkStatusEffectComponent>(playerEntity.Value, out var status))
if (!statusSys.TryGetMaxTime<DrunkStatusEffectComponent>(playerEntity.Value, out var status))
return; return;
var time = status.Item2; var time = status.Item2;
var power = time == null ? MaxBoozePower : (float) Math.Min((time - _timing.CurTime).Value.TotalSeconds, MaxBoozePower); var power = time == null ? MaxBoozePower : (float)Math.Min((time - _timing.CurTime).Value.TotalSeconds, MaxBoozePower);
CurrentBoozePower += BoozePowerScale * (power - CurrentBoozePower) * args.DeltaSeconds / (power+1); CurrentBoozePower += BoozePowerScale * (power - CurrentBoozePower) * args.DeltaSeconds / (power + 1);
} }
protected override bool BeforeDraw(in OverlayDrawArgs args) protected override bool BeforeDraw(in OverlayDrawArgs args)
@@ -82,8 +95,12 @@ public sealed class DrunkOverlay : Overlay
return; return;
var handle = args.WorldHandle; var handle = args.WorldHandle;
_drunkShader.SetParameter("SCREEN_TEXTURE", ScreenTexture); _drunkShader.SetParameter("SCREEN_TEXTURE", ScreenTexture);
_drunkShader.SetParameter("boozePower", _visualScale); _drunkShader.SetParameter("boozePower", _visualScale);
_drunkShader.SetParameter("timeScale", _timeScale);
_drunkShader.SetParameter("distortionScale", _distortionScale);
_drunkShader.SetParameter("phase", Phase);
handle.UseShader(_drunkShader); handle.UseShader(_drunkShader);
handle.DrawRect(args.WorldBounds, Color.White); handle.DrawRect(args.WorldBounds, Color.White);
handle.UseShader(null); handle.UseShader(null);
+6
View File
@@ -3,6 +3,7 @@ using Content.Shared.StatusEffectNew;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.Player; using Robust.Client.Player;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Random;
namespace Content.Client.Drunk; namespace Content.Client.Drunk;
@@ -10,6 +11,7 @@ public sealed class DrunkSystem : SharedDrunkSystem
{ {
[Dependency] private readonly IPlayerManager _player = default!; [Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IOverlayManager _overlayMan = default!; [Dependency] private readonly IOverlayManager _overlayMan = default!;
[Dependency] private readonly IRobustRandom _random = default!;
private DrunkOverlay _overlay = default!; private DrunkOverlay _overlay = default!;
@@ -29,7 +31,10 @@ public sealed class DrunkSystem : SharedDrunkSystem
private void OnStatusApplied(Entity<DrunkStatusEffectComponent> entity, ref StatusEffectAppliedEvent args) private void OnStatusApplied(Entity<DrunkStatusEffectComponent> entity, ref StatusEffectAppliedEvent args)
{ {
if (!_overlayMan.HasOverlay<DrunkOverlay>()) if (!_overlayMan.HasOverlay<DrunkOverlay>())
{
_overlay.Phase = _random.NextFloat(MathF.Tau); // random starting phase for movement effect
_overlayMan.AddOverlay(_overlay); _overlayMan.AddOverlay(_overlay);
}
} }
private void OnStatusRemoved(Entity<DrunkStatusEffectComponent> entity, ref StatusEffectRemovedEvent args) private void OnStatusRemoved(Entity<DrunkStatusEffectComponent> entity, ref StatusEffectRemovedEvent args)
@@ -47,6 +52,7 @@ public sealed class DrunkSystem : SharedDrunkSystem
private void OnPlayerAttached(Entity<DrunkStatusEffectComponent> entity, ref StatusEffectRelayedEvent<LocalPlayerAttachedEvent> args) private void OnPlayerAttached(Entity<DrunkStatusEffectComponent> entity, ref StatusEffectRelayedEvent<LocalPlayerAttachedEvent> args)
{ {
_overlayMan.AddOverlay(_overlay); _overlayMan.AddOverlay(_overlay);
} }
private void OnPlayerDetached(Entity<DrunkStatusEffectComponent> entity, ref StatusEffectRelayedEvent<LocalPlayerDetachedEvent> args) private void OnPlayerDetached(Entity<DrunkStatusEffectComponent> entity, ref StatusEffectRelayedEvent<LocalPlayerDetachedEvent> args)
-1
View File
@@ -123,7 +123,6 @@ namespace Content.Client.Entry
_prototypeManager.RegisterIgnore("noiseChannel"); _prototypeManager.RegisterIgnore("noiseChannel");
_prototypeManager.RegisterIgnore("playerConnectionWhitelist"); _prototypeManager.RegisterIgnore("playerConnectionWhitelist");
_prototypeManager.RegisterIgnore("spaceBiome"); _prototypeManager.RegisterIgnore("spaceBiome");
_prototypeManager.RegisterIgnore("worldgenConfig");
_prototypeManager.RegisterIgnore("gameRule"); _prototypeManager.RegisterIgnore("gameRule");
_prototypeManager.RegisterIgnore("worldSpell"); _prototypeManager.RegisterIgnore("worldSpell");
_prototypeManager.RegisterIgnore("entitySpell"); _prototypeManager.RegisterIgnore("entitySpell");
@@ -31,7 +31,7 @@ public sealed class ClientFeedbackManager : SharedFeedbackManager
/// <inheritdoc /> /// <inheritdoc />
public override void Display(List<ProtoId<FeedbackPopupPrototype>>? prototypes) public override void Display(List<ProtoId<FeedbackPopupPrototype>>? prototypes)
{ {
if (prototypes == null || !NetManager.IsClient) if (prototypes == null)
return; return;
var count = _displayedPopups.Count; var count = _displayedPopups.Count;
@@ -42,9 +42,6 @@ public sealed class ClientFeedbackManager : SharedFeedbackManager
/// <inheritdoc /> /// <inheritdoc />
public override void Remove(List<ProtoId<FeedbackPopupPrototype>>? prototypes) public override void Remove(List<ProtoId<FeedbackPopupPrototype>>? prototypes)
{ {
if (!NetManager.IsClient)
return;
if (prototypes == null) if (prototypes == null)
{ {
_displayedPopups.Clear(); _displayedPopups.Clear();
@@ -18,6 +18,8 @@ namespace Content.Client.IconSmoothing
{ {
[Dependency] private readonly SharedMapSystem _mapSystem = default!; [Dependency] private readonly SharedMapSystem _mapSystem = default!;
[Dependency] private readonly SpriteSystem _sprite = default!; [Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly EntityQuery<IconSmoothComponent> _iconSmoothQuery = default!;
[Dependency] private readonly EntityQuery<SpriteComponent> _spriteQuery = default!;
private readonly Queue<EntityUid> _dirtyEntities = new(); private readonly Queue<EntityUid> _dirtyEntities = new();
private readonly Queue<EntityUid> _anchorChangedEntities = new(); private readonly Queue<EntityUid> _anchorChangedEntities = new();
@@ -106,13 +108,10 @@ namespace Content.Client.IconSmoothing
{ {
base.FrameUpdate(frameTime); base.FrameUpdate(frameTime);
var xformQuery = GetEntityQuery<TransformComponent>();
var smoothQuery = GetEntityQuery<IconSmoothComponent>();
// first process anchor state changes. // first process anchor state changes.
while (_anchorChangedEntities.TryDequeue(out var uid)) while (_anchorChangedEntities.TryDequeue(out var uid))
{ {
if (!xformQuery.TryGetComponent(uid, out var xform)) if (!TryComp(uid, out TransformComponent? xform))
continue; continue;
if (xform.MapID == MapId.Nullspace) if (xform.MapID == MapId.Nullspace)
@@ -123,7 +122,7 @@ namespace Content.Client.IconSmoothing
continue; continue;
} }
DirtyNeighbours(uid, comp: null, xform, smoothQuery); DirtyNeighbours(uid, comp: null, xform);
} }
// Next, update actual sprites. // Next, update actual sprites.
@@ -132,19 +131,16 @@ namespace Content.Client.IconSmoothing
_generation += 1; _generation += 1;
var spriteQuery = GetEntityQuery<SpriteComponent>();
// Performance: This could be spread over multiple updates, or made parallel. // Performance: This could be spread over multiple updates, or made parallel.
while (_dirtyEntities.TryDequeue(out var uid)) while (_dirtyEntities.TryDequeue(out var uid))
{ {
CalculateNewSprite(uid, spriteQuery, smoothQuery, xformQuery); CalculateNewSprite(uid);
} }
} }
public void DirtyNeighbours(EntityUid uid, IconSmoothComponent? comp = null, TransformComponent? transform = null, EntityQuery<IconSmoothComponent>? smoothQuery = null) public void DirtyNeighbours(EntityUid uid, IconSmoothComponent? comp = null, TransformComponent? transform = null)
{ {
smoothQuery ??= GetEntityQuery<IconSmoothComponent>(); if (!_iconSmoothQuery.Resolve(uid, ref comp) || !comp.Running)
if (!smoothQuery.Value.Resolve(uid, ref comp) || !comp.Running)
return; return;
_dirtyEntities.Enqueue(uid); _dirtyEntities.Enqueue(uid);
@@ -206,11 +202,7 @@ namespace Content.Client.IconSmoothing
_anchorChangedEntities.Enqueue(uid); _anchorChangedEntities.Enqueue(uid);
} }
private void CalculateNewSprite(EntityUid uid, private void CalculateNewSprite(EntityUid uid, IconSmoothComponent? smooth = null)
EntityQuery<SpriteComponent> spriteQuery,
EntityQuery<IconSmoothComponent> smoothQuery,
EntityQuery<TransformComponent> xformQuery,
IconSmoothComponent? smooth = null)
{ {
TransformComponent? xform; TransformComponent? xform;
Entity<MapGridComponent>? gridEntity = null; Entity<MapGridComponent>? gridEntity = null;
@@ -218,7 +210,7 @@ namespace Content.Client.IconSmoothing
// The generation check prevents updating an entity multiple times per tick. // The generation check prevents updating an entity multiple times per tick.
// As it stands now, it's totally possible for something to get queued twice. // As it stands now, it's totally possible for something to get queued twice.
// Generation on the component is set after an update so we can cull updates that happened this generation. // Generation on the component is set after an update so we can cull updates that happened this generation.
if (!smoothQuery.Resolve(uid, ref smooth, false) if (!_iconSmoothQuery.Resolve(uid, ref smooth, false)
|| smooth.Mode == IconSmoothingMode.NoSprite || smooth.Mode == IconSmoothingMode.NoSprite
|| smooth.UpdateGeneration == _generation || smooth.UpdateGeneration == _generation
|| !smooth.Enabled || !smooth.Enabled
@@ -226,7 +218,7 @@ namespace Content.Client.IconSmoothing
{ {
if (smooth is { Enabled: true } && if (smooth is { Enabled: true } &&
TryComp<SmoothEdgeComponent>(uid, out var edge) && TryComp<SmoothEdgeComponent>(uid, out var edge) &&
xformQuery.TryGetComponent(uid, out xform)) TryComp(uid, out xform))
{ {
var directions = DirectionFlag.None; var directions = DirectionFlag.None;
@@ -237,13 +229,13 @@ namespace Content.Client.IconSmoothing
gridEntity = (gridUid, grid); gridEntity = (gridUid, grid);
if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.North)), smoothQuery)) if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.North))))
directions |= DirectionFlag.North; directions |= DirectionFlag.North;
if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.South)), smoothQuery)) if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.South))))
directions |= DirectionFlag.South; directions |= DirectionFlag.South;
if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.East)), smoothQuery)) if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.East))))
directions |= DirectionFlag.East; directions |= DirectionFlag.East;
if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.West)), smoothQuery)) if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.West))))
directions |= DirectionFlag.West; directions |= DirectionFlag.West;
} }
@@ -253,10 +245,10 @@ namespace Content.Client.IconSmoothing
return; return;
} }
xform = xformQuery.GetComponent(uid); xform = Transform(uid);
smooth.UpdateGeneration = _generation; smooth.UpdateGeneration = _generation;
if (!spriteQuery.TryGetComponent(uid, out var sprite)) if (!_spriteQuery.TryGetComponent(uid, out var sprite))
{ {
Log.Error($"Encountered a icon-smoothing entity without a sprite: {ToPrettyString(uid)}"); Log.Error($"Encountered a icon-smoothing entity without a sprite: {ToPrettyString(uid)}");
RemCompDeferred(uid, smooth); RemCompDeferred(uid, smooth);
@@ -281,13 +273,13 @@ namespace Content.Client.IconSmoothing
switch (smooth.Mode) switch (smooth.Mode)
{ {
case IconSmoothingMode.Corners: case IconSmoothingMode.Corners:
CalculateNewSpriteCorners(gridEntity, smooth, spriteEnt, xform, smoothQuery); CalculateNewSpriteCorners(gridEntity, smooth, spriteEnt, xform);
break; break;
case IconSmoothingMode.CardinalFlags: case IconSmoothingMode.CardinalFlags:
CalculateNewSpriteCardinal(gridEntity, smooth, spriteEnt, xform, smoothQuery); CalculateNewSpriteCardinal(gridEntity, smooth, spriteEnt, xform);
break; break;
case IconSmoothingMode.Diagonal: case IconSmoothingMode.Diagonal:
CalculateNewSpriteDiagonal(gridEntity, smooth, spriteEnt, xform, smoothQuery); CalculateNewSpriteDiagonal(gridEntity, smooth, spriteEnt, xform);
break; break;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
@@ -295,7 +287,7 @@ namespace Content.Client.IconSmoothing
} }
private void CalculateNewSpriteDiagonal(Entity<MapGridComponent>? gridEntity, IconSmoothComponent smooth, private void CalculateNewSpriteDiagonal(Entity<MapGridComponent>? gridEntity, IconSmoothComponent smooth,
Entity<SpriteComponent> sprite, TransformComponent xform, EntityQuery<IconSmoothComponent> smoothQuery) Entity<SpriteComponent> sprite, TransformComponent xform)
{ {
if (gridEntity == null) if (gridEntity == null)
{ {
@@ -320,7 +312,7 @@ namespace Content.Client.IconSmoothing
for (var i = 0; i < neighbors.Length; i++) for (var i = 0; i < neighbors.Length; i++)
{ {
var neighbor = (Vector2i)rotation.RotateVec(neighbors[i]); var neighbor = (Vector2i)rotation.RotateVec(neighbors[i]);
matching = matching && MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos + neighbor), smoothQuery); matching = matching && MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos + neighbor));
} }
if (matching) if (matching)
@@ -333,7 +325,7 @@ namespace Content.Client.IconSmoothing
} }
} }
private void CalculateNewSpriteCardinal(Entity<MapGridComponent>? gridEntity, IconSmoothComponent smooth, Entity<SpriteComponent> sprite, TransformComponent xform, EntityQuery<IconSmoothComponent> smoothQuery) private void CalculateNewSpriteCardinal(Entity<MapGridComponent>? gridEntity, IconSmoothComponent smooth, Entity<SpriteComponent> sprite, TransformComponent xform)
{ {
var dirs = CardinalConnectDirs.None; var dirs = CardinalConnectDirs.None;
@@ -347,13 +339,13 @@ namespace Content.Client.IconSmoothing
var grid = gridEntity.Value.Comp; var grid = gridEntity.Value.Comp;
var pos = _mapSystem.TileIndicesFor(gridUid, grid, xform.Coordinates); var pos = _mapSystem.TileIndicesFor(gridUid, grid, xform.Coordinates);
if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.North)), smoothQuery)) if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.North))))
dirs |= CardinalConnectDirs.North; dirs |= CardinalConnectDirs.North;
if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.South)), smoothQuery)) if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.South))))
dirs |= CardinalConnectDirs.South; dirs |= CardinalConnectDirs.South;
if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.East)), smoothQuery)) if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.East))))
dirs |= CardinalConnectDirs.East; dirs |= CardinalConnectDirs.East;
if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.West)), smoothQuery)) if (MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.West))))
dirs |= CardinalConnectDirs.West; dirs |= CardinalConnectDirs.West;
_sprite.LayerSetRsiState(sprite.AsNullable(), 0, $"{smooth.StateBase}{(int)dirs}"); _sprite.LayerSetRsiState(sprite.AsNullable(), 0, $"{smooth.StateBase}{(int)dirs}");
@@ -372,11 +364,11 @@ namespace Content.Client.IconSmoothing
CalculateEdge(sprite, directions, sprite); CalculateEdge(sprite, directions, sprite);
} }
private bool MatchingEntity(IconSmoothComponent smooth, AnchoredEntitiesEnumerator candidates, EntityQuery<IconSmoothComponent> smoothQuery) private bool MatchingEntity(IconSmoothComponent smooth, AnchoredEntitiesEnumerator candidates)
{ {
while (candidates.MoveNext(out var entity)) while (candidates.MoveNext(out var entity))
{ {
if (smoothQuery.TryGetComponent(entity, out var other) && if (_iconSmoothQuery.TryGetComponent(entity, out var other) &&
other.SmoothKey != null && other.SmoothKey != null &&
(other.SmoothKey == smooth.SmoothKey || smooth.AdditionalKeys.Contains(other.SmoothKey)) && (other.SmoothKey == smooth.SmoothKey || smooth.AdditionalKeys.Contains(other.SmoothKey)) &&
other.Enabled) other.Enabled)
@@ -388,11 +380,11 @@ namespace Content.Client.IconSmoothing
return false; return false;
} }
private void CalculateNewSpriteCorners(Entity<MapGridComponent>? gridEntity, IconSmoothComponent smooth, Entity<SpriteComponent> spriteEnt, TransformComponent xform, EntityQuery<IconSmoothComponent> smoothQuery) private void CalculateNewSpriteCorners(Entity<MapGridComponent>? gridEntity, IconSmoothComponent smooth, Entity<SpriteComponent> spriteEnt, TransformComponent xform)
{ {
var (cornerNE, cornerNW, cornerSW, cornerSE) = gridEntity == null var (cornerNE, cornerNW, cornerSW, cornerSE) = gridEntity == null
? (CornerFill.None, CornerFill.None, CornerFill.None, CornerFill.None) ? (CornerFill.None, CornerFill.None, CornerFill.None, CornerFill.None)
: CalculateCornerFill(gridEntity.Value, smooth, xform, smoothQuery); : CalculateCornerFill(gridEntity.Value, smooth, xform);
// TODO figure out a better way to set multiple sprite layers. // TODO figure out a better way to set multiple sprite layers.
// This will currently re-calculate the sprite bounding box 4 times. // This will currently re-calculate the sprite bounding box 4 times.
@@ -422,20 +414,20 @@ namespace Content.Client.IconSmoothing
CalculateEdge(spriteEnt, directions, sprite); CalculateEdge(spriteEnt, directions, sprite);
} }
private (CornerFill ne, CornerFill nw, CornerFill sw, CornerFill se) CalculateCornerFill(Entity<MapGridComponent> gridEntity, IconSmoothComponent smooth, TransformComponent xform, EntityQuery<IconSmoothComponent> smoothQuery) private (CornerFill ne, CornerFill nw, CornerFill sw, CornerFill se) CalculateCornerFill(Entity<MapGridComponent> gridEntity, IconSmoothComponent smooth, TransformComponent xform)
{ {
var gridUid = gridEntity.Owner; var gridUid = gridEntity.Owner;
var grid = gridEntity.Comp; var grid = gridEntity.Comp;
var pos = _mapSystem.TileIndicesFor(gridUid, grid, xform.Coordinates); var pos = _mapSystem.TileIndicesFor(gridUid, grid, xform.Coordinates);
var n = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.North)), smoothQuery); var n = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.North)));
var ne = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.NorthEast)), smoothQuery); var ne = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.NorthEast)));
var e = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.East)), smoothQuery); var e = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.East)));
var se = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.SouthEast)), smoothQuery); var se = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.SouthEast)));
var s = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.South)), smoothQuery); var s = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.South)));
var sw = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.SouthWest)), smoothQuery); var sw = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.SouthWest)));
var w = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.West)), smoothQuery); var w = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.West)));
var nw = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.NorthWest)), smoothQuery); var nw = MatchingEntity(smooth, _mapSystem.GetAnchoredEntitiesEnumerator(gridUid, grid, pos.Offset(Direction.NorthWest)));
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
var cornerNE = CornerFill.None; var cornerNE = CornerFill.None;
+2 -3
View File
@@ -48,6 +48,7 @@ public sealed class DragDropSystem : SharedDragDropSystem
[Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly SpriteSystem _sprite = default!; [Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly EntityQuery<SpriteComponent> _spriteQuery = default!;
// how often to recheck possible targets (prevents calling expensive // how often to recheck possible targets (prevents calling expensive
// check logic each update) // check logic each update)
@@ -433,11 +434,9 @@ public sealed class DragDropSystem : SharedDragDropSystem
var bounds = new Box2(mousePos.Position - expansion, mousePos.Position + expansion); var bounds = new Box2(mousePos.Position - expansion, mousePos.Position + expansion);
var pvsEntities = _lookup.GetEntitiesIntersecting(mousePos.MapId, bounds); var pvsEntities = _lookup.GetEntitiesIntersecting(mousePos.MapId, bounds);
var spriteQuery = GetEntityQuery<SpriteComponent>();
foreach (var entity in pvsEntities) foreach (var entity in pvsEntities)
{ {
if (!spriteQuery.TryGetComponent(entity, out var inRangeSprite) || if (!_spriteQuery.TryGetComponent(entity, out var inRangeSprite) ||
!inRangeSprite.Visible || !inRangeSprite.Visible ||
entity == _draggedEntity) entity == _draggedEntity)
{ {
+3 -2
View File
@@ -1,8 +1,9 @@
<DefaultWindow <controls:FancyWindow
xmlns="https://spacestation14.io" xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client" xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:system="clr-namespace:System;assembly=System.Runtime" xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:ui="clr-namespace:Content.Client.Materials.UI" xmlns:ui="clr-namespace:Content.Client.Materials.UI"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'lathe-menu-title'}" Title="{Loc 'lathe-menu-title'}"
MinSize="550 450" MinSize="550 450"
SetSize="750 500"> SetSize="750 500">
@@ -156,4 +157,4 @@
</BoxContainer> </BoxContainer>
</DefaultWindow> </controls:FancyWindow>
+3 -2
View File
@@ -1,6 +1,7 @@
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Content.Client.Materials; using Content.Client.Materials;
using Content.Client.UserInterface.Controls;
using Content.Shared.Lathe; using Content.Shared.Lathe;
using Content.Shared.Lathe.Prototypes; using Content.Shared.Lathe.Prototypes;
using Content.Shared.Research.Prototypes; using Content.Shared.Research.Prototypes;
@@ -8,7 +9,6 @@ using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML; using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -16,7 +16,7 @@ using Robust.Shared.Utility;
namespace Content.Client.Lathe.UI; namespace Content.Client.Lathe.UI;
[GenerateTypedNameReferences] [GenerateTypedNameReferences]
public sealed partial class LatheMenu : DefaultWindow public sealed partial class LatheMenu : FancyWindow
{ {
[Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
@@ -75,6 +75,7 @@ public sealed partial class LatheMenu : DefaultWindow
public void SetEntity(EntityUid uid) public void SetEntity(EntityUid uid)
{ {
Entity = uid; Entity = uid;
this.SetInfoFromEntity(_entityManager, Entity);
if (_entityManager.TryGetComponent<LatheComponent>(Entity, out var latheComponent)) if (_entityManager.TryGetComponent<LatheComponent>(Entity, out var latheComponent))
{ {
@@ -2,9 +2,8 @@ using System.Linq;
using System.Numerics; using System.Numerics;
using Content.Client.UserInterface.Controls; using Content.Client.UserInterface.Controls;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Atmos.EntitySystems;
using Content.Shared.Chemistry.Reagent; using Content.Shared.Chemistry.Reagent;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.EntityConditions.Conditions; using Content.Shared.EntityConditions.Conditions;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
using Content.Shared.Medical.Cryogenics; using Content.Shared.Medical.Cryogenics;
@@ -20,6 +19,7 @@ public sealed partial class CryoPodWindow : FancyWindow
{ {
[Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private readonly SharedAtmosphereSystem _atmosphere = default!;
public event Action? OnEjectPatientPressed; public event Action? OnEjectPatientPressed;
public event Action? OnEjectBeakerPressed; public event Action? OnEjectBeakerPressed;
@@ -29,6 +29,7 @@ public sealed partial class CryoPodWindow : FancyWindow
{ {
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
_atmosphere = _entityManager.System<SharedAtmosphereSystem>();
EjectPatientButton.OnPressed += _ => OnEjectPatientPressed?.Invoke(); EjectPatientButton.OnPressed += _ => OnEjectPatientPressed?.Invoke();
EjectBeakerButton.OnPressed += _ => OnEjectBeakerPressed?.Invoke(); EjectBeakerButton.OnPressed += _ => OnEjectBeakerPressed?.Invoke();
Inject1.OnPressed += _ => OnInjectPressed?.Invoke(1); Inject1.OnPressed += _ => OnInjectPressed?.Invoke(1);
@@ -71,16 +72,16 @@ public sealed partial class CryoPodWindow : FancyWindow
{ {
var totalGasAmount = msg.GasMix.Gases.Sum(gas => gas.Amount); 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 gasProto = _atmosphere.GetGas(gasEntry.Gas);
var percent = gas.Amount / totalGasAmount * 100; var percent = gasEntry.Amount / totalGasAmount * 100;
var localizedName = Loc.GetString(gas.Name); var localizedName = Loc.GetString(gasProto.Name);
var tooltip = Loc.GetString("gas-analyzer-window-molarity-percentage-text", var tooltip = Loc.GetString("gas-analyzer-window-molarity-percentage-text",
("gasName", localizedName), ("gasName", localizedName),
("amount", $"{gas.Amount:0.##}"), ("amount", $"{gasEntry.Amount:0.##}"),
("percentage", $"{percent:0.#}")); ("percentage", $"{percent:0.#}"));
GasMixChart.AddEntry(gas.Amount, color, tooltip: tooltip); GasMixChart.AddEntry(gasEntry.Amount, gasProto.Color, tooltip: tooltip);
} }
} }
@@ -10,15 +10,12 @@ namespace Content.Client.Movement.Systems;
public sealed class ClientSpriteMovementSystem : SharedSpriteMovementSystem public sealed class ClientSpriteMovementSystem : SharedSpriteMovementSystem
{ {
[Dependency] private readonly SpriteSystem _sprite = default!; [Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly EntityQuery<SpriteComponent> _spriteQuery = default!;
private EntityQuery<SpriteComponent> _spriteQuery;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
_spriteQuery = GetEntityQuery<SpriteComponent>();
SubscribeLocalEvent<SpriteMovementComponent, AfterAutoHandleStateEvent>(OnAfterAutoHandleState); SubscribeLocalEvent<SpriteMovementComponent, AfterAutoHandleStateEvent>(OnAfterAutoHandleState);
} }
@@ -12,14 +12,12 @@ public sealed class FloorOcclusionSystem : SharedFloorOcclusionSystem
[Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly IPrototypeManager _proto = default!;
private EntityQuery<SpriteComponent> _spriteQuery; [Dependency] private readonly EntityQuery<SpriteComponent> _spriteQuery = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
_spriteQuery = GetEntityQuery<SpriteComponent>();
SubscribeLocalEvent<FloorOcclusionComponent, ComponentStartup>(OnOcclusionStartup); SubscribeLocalEvent<FloorOcclusionComponent, ComponentStartup>(OnOcclusionStartup);
SubscribeLocalEvent<FloorOcclusionComponent, ComponentShutdown>(OnOcclusionShutdown); SubscribeLocalEvent<FloorOcclusionComponent, ComponentShutdown>(OnOcclusionShutdown);
SubscribeLocalEvent<FloorOcclusionComponent, AfterAutoHandleStateEvent>(OnOcclusionAuto); SubscribeLocalEvent<FloorOcclusionComponent, AfterAutoHandleStateEvent>(OnOcclusionAuto);
@@ -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 class CreamPieSystem : SharedCreamPieSystem
{
[Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CreamPiedComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<CreamPiedComponent, ComponentShutdown>(OnComponentShutdown);
SubscribeLocalEvent<CreamPiedComponent, AppearanceChangeEvent>(OnAppearanceChange);
SubscribeLocalEvent<CreamPiedComponent, AfterAutoHandleStateEvent>(OnAfterAutoHandleState);
}
private void OnComponentInit(Entity<CreamPiedComponent> ent, ref ComponentInit args)
{
UpdateAppearance(ent);
}
private void OnComponentShutdown(Entity<CreamPiedComponent> ent, ref ComponentShutdown args)
{
_sprite.RemoveLayer(ent.Owner, CreamPiedVisualLayer.Key);
}
private void OnAppearanceChange(Entity<CreamPiedComponent> ent, ref AppearanceChangeEvent args)
{
UpdateAppearance((ent.Owner, ent.Comp, args.Sprite, args.Component));
}
private void OnAfterAutoHandleState(Entity<CreamPiedComponent> ent, ref AfterAutoHandleStateEvent args)
{
// Update when the sprite datafield is changed so that changelings can transform properly.
UpdateAppearance(ent);
}
private void UpdateAppearance(Entity<CreamPiedComponent, SpriteComponent?, AppearanceComponent?> 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<bool>(ent.Owner, CreamPiedVisuals.Creamed, out var isCreamPied, appearance);
_sprite.LayerSetSprite((ent.Owner, sprite), index, creamPied.Sprite);
_sprite.LayerSetVisible((ent.Owner, sprite), index, isCreamPied);
}
}
@@ -1,10 +0,0 @@
using Content.Shared.Nutrition.EntitySystems;
using JetBrains.Annotations;
namespace Content.Client.Nutrition.EntitySystems
{
[UsedImplicitly]
public sealed class CreamPiedSystem : SharedCreamPieSystem
{
}
}
@@ -27,6 +27,7 @@ public sealed class TargetOutlineSystem : EntitySystem
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly EntityQuery<SpriteComponent> _spriteQuery = default!;
private bool _enabled = false; private bool _enabled = false;
@@ -130,11 +131,10 @@ public sealed class TargetOutlineSystem : EntitySystem
var mousePos = _eyeManager.PixelToMap(_inputManager.MouseScreenPosition).Position; var mousePos = _eyeManager.PixelToMap(_inputManager.MouseScreenPosition).Position;
var bounds = new Box2(mousePos - LookupVector, mousePos + LookupVector); var bounds = new Box2(mousePos - LookupVector, mousePos + LookupVector);
var pvsEntities = _lookup.GetEntitiesIntersecting(_eyeManager.CurrentEye.Position.MapId, bounds, LookupFlags.Approximate | LookupFlags.Static); var pvsEntities = _lookup.GetEntitiesIntersecting(_eyeManager.CurrentEye.Position.MapId, bounds, LookupFlags.Approximate | LookupFlags.Static);
var spriteQuery = GetEntityQuery<SpriteComponent>();
foreach (var entity in pvsEntities) foreach (var entity in pvsEntities)
{ {
if (!spriteQuery.TryGetComponent(entity, out var sprite) || !sprite.Visible) if (!_spriteQuery.TryGetComponent(entity, out var sprite) || !sprite.Visible)
continue; continue;
// Check the predicate // Check the predicate
@@ -4,7 +4,6 @@ using Content.Shared.Chemistry.Components;
using Content.Shared.Polymorph.Components; using Content.Shared.Polymorph.Components;
using Content.Shared.Polymorph.Systems; using Content.Shared.Polymorph.Systems;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Shared.Player;
namespace Content.Client.Polymorph.Systems; namespace Content.Client.Polymorph.Systems;
@@ -13,16 +12,13 @@ public sealed class ChameleonProjectorSystem : SharedChameleonProjectorSystem
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SpriteSystem _sprite = default!; [Dependency] private readonly SpriteSystem _sprite = default!;
private EntityQuery<AppearanceComponent> _appearanceQuery; [Dependency] private readonly EntityQuery<AppearanceComponent> _appearanceQuery = default!;
private EntityQuery<SpriteComponent> _spriteQuery; [Dependency] private readonly EntityQuery<SpriteComponent> _spriteQuery = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
_appearanceQuery = GetEntityQuery<AppearanceComponent>();
_spriteQuery = GetEntityQuery<SpriteComponent>();
SubscribeLocalEvent<ChameleonDisguiseComponent, AfterAutoHandleStateEvent>(OnHandleState); SubscribeLocalEvent<ChameleonDisguiseComponent, AfterAutoHandleStateEvent>(OnHandleState);
SubscribeLocalEvent<ChameleonDisguisedComponent, ComponentStartup>(OnStartup); SubscribeLocalEvent<ChameleonDisguisedComponent, ComponentStartup>(OnStartup);
@@ -5,7 +5,7 @@ using Robust.Client.Graphics;
namespace Content.Client.Radiation.Systems; namespace Content.Client.Radiation.Systems;
public sealed class RadiationSystem : EntitySystem public sealed class RadiationSystem : SharedRadiationSystem
{ {
[Dependency] private readonly IOverlayManager _overlayMan = default!; [Dependency] private readonly IOverlayManager _overlayMan = default!;
@@ -74,8 +74,7 @@ public sealed partial class ReplaySpectatorSystem
if ((Direction & DirectionFlag.East) != 0) if ((Direction & DirectionFlag.East) != 0)
effectiveDir &= ~DirectionFlag.West; effectiveDir &= ~DirectionFlag.West;
var query = GetEntityQuery<TransformComponent>(); var xform = Transform(player);
var xform = query.GetComponent(player);
var pos = _transform.GetWorldPosition(xform); var pos = _transform.GetWorldPosition(xform);
if (!xform.ParentUid.IsValid()) if (!xform.ParentUid.IsValid())
@@ -13,16 +13,11 @@ public sealed partial class BorgSystem
// Don't put this on the component because we only need to track the time for a single entity // Don't put this on the component because we only need to track the time for a single entity
// and we don't want to TryComp it every single tick. // and we don't want to TryComp it every single tick.
private TimeSpan _nextAlertUpdate = TimeSpan.Zero; private TimeSpan _nextAlertUpdate = TimeSpan.Zero;
private EntityQuery<BorgChassisComponent> _chassisQuery;
private EntityQuery<PowerCellSlotComponent> _slotQuery;
public void InitializeBattery() public void InitializeBattery()
{ {
SubscribeLocalEvent<BorgChassisComponent, LocalPlayerAttachedEvent>(OnPlayerAttached); SubscribeLocalEvent<BorgChassisComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<BorgChassisComponent, LocalPlayerDetachedEvent>(OnPlayerDetached); SubscribeLocalEvent<BorgChassisComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
_chassisQuery = GetEntityQuery<BorgChassisComponent>();
_slotQuery = GetEntityQuery<PowerCellSlotComponent>();
} }
private void OnPlayerAttached(Entity<BorgChassisComponent> ent, ref LocalPlayerAttachedEvent args) private void OnPlayerAttached(Entity<BorgChassisComponent> ent, ref LocalPlayerAttachedEvent args)
@@ -2,6 +2,7 @@
using Content.Shared.Mobs; using Content.Shared.Mobs;
using Content.Shared.Power.EntitySystems; using Content.Shared.Power.EntitySystems;
using Content.Shared.PowerCell; using Content.Shared.PowerCell;
using Content.Shared.PowerCell.Components;
using Content.Shared.Silicons.Borgs; using Content.Shared.Silicons.Borgs;
using Content.Shared.Silicons.Borgs.Components; using Content.Shared.Silicons.Borgs.Components;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
@@ -22,6 +23,8 @@ public sealed partial class BorgSystem : SharedBorgSystem
[Dependency] private readonly AlertsSystem _alerts = default!; [Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPlayerManager _player = default!; [Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly EntityQuery<BorgChassisComponent> _chassisQuery = default!;
[Dependency] private readonly EntityQuery<PowerCellSlotComponent> _slotQuery = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -1,9 +1,11 @@
using System.Numerics;
using Content.Shared.CCVar;
using Content.Shared.Singularity.Components; using Content.Shared.Singularity.Components;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Configuration;
using Robust.Shared.Enums; using Robust.Shared.Enums;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using System.Numerics;
namespace Content.Client.Singularity namespace Content.Client.Singularity
{ {
@@ -13,6 +15,7 @@ namespace Content.Client.Singularity
[Dependency] private readonly IEntityManager _entMan = default!; [Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
private SharedTransformSystem? _xformSystem = null; private SharedTransformSystem? _xformSystem = null;
/// <summary> /// <summary>
@@ -28,6 +31,8 @@ namespace Content.Client.Singularity
private readonly ShaderInstance _shader; private readonly ShaderInstance _shader;
private bool _reducedMotion;
public SingularityOverlay() public SingularityOverlay()
{ {
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
@@ -35,6 +40,8 @@ namespace Content.Client.Singularity
_shader.SetParameter("maxDistance", MaxDistance * EyeManager.PixelsPerMeter); _shader.SetParameter("maxDistance", MaxDistance * EyeManager.PixelsPerMeter);
_entMan.EventBus.SubscribeEvent<PixelToMapEvent>(EventSource.Local, this, OnProjectFromScreenToMap); _entMan.EventBus.SubscribeEvent<PixelToMapEvent>(EventSource.Local, this, OnProjectFromScreenToMap);
ZIndex = 101; // Should be drawn after the placement overlay so admins placing items near the singularity can tell where they're going. ZIndex = 101; // Should be drawn after the placement overlay so admins placing items near the singularity can tell where they're going.
_configManager.OnValueChanged(CCVars.ReducedMotion, (b) => { _reducedMotion = b; }, invokeImmediately: true);
} }
private readonly Vector2[] _positions = new Vector2[MaxCount]; private readonly Vector2[] _positions = new Vector2[MaxCount];
@@ -44,6 +51,8 @@ namespace Content.Client.Singularity
protected override bool BeforeDraw(in OverlayDrawArgs args) protected override bool BeforeDraw(in OverlayDrawArgs args)
{ {
if (_reducedMotion)
return false;
if (args.Viewport.Eye == null) if (args.Viewport.Eye == null)
return false; return false;
if (_xformSystem is null && !_entMan.TrySystem(out _xformSystem)) if (_xformSystem is null && !_entMan.TrySystem(out _xformSystem))
@@ -102,6 +111,8 @@ namespace Content.Client.Singularity
/// </summary> /// </summary>
private void OnProjectFromScreenToMap(ref PixelToMapEvent args) private void OnProjectFromScreenToMap(ref PixelToMapEvent args)
{ // Mostly copypasta from the singularity shader. { // Mostly copypasta from the singularity shader.
if (_reducedMotion)
return;
if (args.Viewport.Eye == null) if (args.Viewport.Eye == null)
return; return;
var maxDistance = MaxDistance * EyeManager.PixelsPerMeter; var maxDistance = MaxDistance * EyeManager.PixelsPerMeter;
+4 -10
View File
@@ -27,16 +27,15 @@ public sealed class SpriteFadeSystem : EntitySystem
[Dependency] private readonly IInputManager _inputManager = default!; [Dependency] private readonly IInputManager _inputManager = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SpriteSystem _sprite = default!; [Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly EntityQuery<SpriteComponent> _spriteQuery = default!;
[Dependency] private readonly EntityQuery<SpriteFadeComponent> _fadeQuery = default!;
[Dependency] private readonly EntityQuery<FadingSpriteComponent> _fadingQuery = default!;
[Dependency] private readonly EntityQuery<FixturesComponent> _fixturesQuery = default!;
private List<(MapCoordinates Point, bool ExcludeBoundingBox)> _points = new(); private List<(MapCoordinates Point, bool ExcludeBoundingBox)> _points = new();
private readonly HashSet<FadingSpriteComponent> _comps = new(); private readonly HashSet<FadingSpriteComponent> _comps = new();
private EntityQuery<SpriteComponent> _spriteQuery;
private EntityQuery<SpriteFadeComponent> _fadeQuery;
private EntityQuery<FadingSpriteComponent> _fadingQuery;
private EntityQuery<FixturesComponent> _fixturesQuery;
private const float TargetAlpha = 0.4f; private const float TargetAlpha = 0.4f;
private const float ChangeRate = 1f; private const float ChangeRate = 1f;
@@ -44,11 +43,6 @@ public sealed class SpriteFadeSystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
_spriteQuery = GetEntityQuery<SpriteComponent>();
_fadeQuery = GetEntityQuery<SpriteFadeComponent>();
_fadingQuery = GetEntityQuery<FadingSpriteComponent>();
_fixturesQuery = GetEntityQuery<FixturesComponent>();
SubscribeLocalEvent<FadingSpriteComponent, ComponentShutdown>(OnFadingShutdown); SubscribeLocalEvent<FadingSpriteComponent, ComponentShutdown>(OnFadingShutdown);
} }
@@ -5,14 +5,12 @@ namespace Content.Client.Sticky.Visualizers;
public sealed class StickyVisualizerSystem : VisualizerSystem<StickyVisualizerComponent> public sealed class StickyVisualizerSystem : VisualizerSystem<StickyVisualizerComponent>
{ {
private EntityQuery<SpriteComponent> _spriteQuery; [Dependency] private readonly EntityQuery<SpriteComponent> _spriteQuery = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
_spriteQuery = GetEntityQuery<SpriteComponent>();
SubscribeLocalEvent<StickyVisualizerComponent, ComponentInit>(OnInit); SubscribeLocalEvent<StickyVisualizerComponent, ComponentInit>(OnInit);
} }
+5
View File
@@ -0,0 +1,5 @@
using Content.Shared.Store;
namespace Content.Client.Store;
public sealed class StoreSystem : SharedStoreSystem;
@@ -1,7 +1,6 @@
using System.Linq;
using Content.Shared.Store; using Content.Shared.Store;
using JetBrains.Annotations; using JetBrains.Annotations;
using System.Linq;
using Content.Shared.Store.Components;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -11,6 +10,7 @@ namespace Content.Client.Store.Ui;
public sealed class StoreBoundUserInterface : BoundUserInterface public sealed class StoreBoundUserInterface : BoundUserInterface
{ {
private IPrototypeManager _prototypeManager = default!; private IPrototypeManager _prototypeManager = default!;
private readonly StoreSystem _storeSystem = default!;
[ViewVariables] [ViewVariables]
private StoreMenu? _menu; private StoreMenu? _menu;
@@ -23,6 +23,7 @@ public sealed class StoreBoundUserInterface : BoundUserInterface
public StoreBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) public StoreBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{ {
_storeSystem = EntMan.System<StoreSystem>();
} }
protected override void Open() protected override void Open()
@@ -30,12 +31,12 @@ public sealed class StoreBoundUserInterface : BoundUserInterface
base.Open(); base.Open();
_menu = this.CreateWindow<StoreMenu>(); _menu = this.CreateWindow<StoreMenu>();
if (EntMan.TryGetComponent<StoreComponent>(Owner, out var store)) if (_storeSystem.TryGetStore(Owner, out var store))
_menu.Title = Loc.GetString(store.Name); _menu.Title = Loc.GetString(store.Value.Comp.Name);
_menu.OnListingButtonPressed += (_, listing) => _menu.OnListingButtonPressed += (_, listing) =>
{ {
SendMessage(new StoreBuyListingMessage(listing.ID)); SendMessage(new StoreBuyListingMessage(listing.ID, EntMan.GetNetEntity(Owner)));
}; };
_menu.OnCategoryButtonPressed += (_, category) => _menu.OnCategoryButtonPressed += (_, category) =>
@@ -2,7 +2,7 @@
namespace Content.Client.Stylesheets.Stylesheets; namespace Content.Client.Stylesheets.Stylesheets;
public sealed partial class NanotrasenStylesheet public partial class NanotrasenStylesheet
{ {
public override ColorPalette PrimaryPalette => Palettes.Navy; public override ColorPalette PrimaryPalette => Palettes.Navy;
public override ColorPalette SecondaryPalette => Palettes.Slate; public override ColorPalette SecondaryPalette => Palettes.Slate;
+7 -8
View File
@@ -20,6 +20,8 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem
[Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SpriteSystem _sprite = default!; [Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly TrayScanRevealSystem _trayScanReveal = default!; [Dependency] private readonly TrayScanRevealSystem _trayScanReveal = default!;
[Dependency] private readonly EntityQuery<TrayScannerComponent> _trayScannerQuery = default!;
[Dependency] private readonly EntityQuery<SubFloorHideComponent> _subFloorHideQuery = default!;
private const string TRayAnimationKey = "trays"; private const string TRayAnimationKey = "trays";
private const double AnimationLength = 0.3; private const double AnimationLength = 0.3;
@@ -35,16 +37,14 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem
// TODO: Multiple viewports or w/e // TODO: Multiple viewports or w/e
var player = _player.LocalEntity; var player = _player.LocalEntity;
var xformQuery = GetEntityQuery<TransformComponent>();
if (!xformQuery.TryGetComponent(player, out var playerXform)) if (!TryComp(player, out TransformComponent? playerXform))
return; return;
var playerPos = _transform.GetWorldPosition(playerXform, xformQuery); var playerPos = _transform.GetWorldPosition(playerXform);
var playerMap = playerXform.MapID; var playerMap = playerXform.MapID;
var range = 0f; var range = 0f;
HashSet<Entity<SubFloorHideComponent>> inRange; HashSet<Entity<SubFloorHideComponent>> inRange;
var scannerQuery = GetEntityQuery<TrayScannerComponent>();
// TODO: Should probably sub to player attached changes / inventory changes but inventory's // TODO: Should probably sub to player attached changes / inventory changes but inventory's
// API is extremely skrungly. If this ever shows up on dottrace ping me and laugh. // API is extremely skrungly. If this ever shows up on dottrace ping me and laugh.
@@ -57,7 +57,7 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem
{ {
foreach (var ent in slot.ContainedEntities) foreach (var ent in slot.ContainedEntities)
{ {
if (!scannerQuery.TryGetComponent(ent, out var sneakScanner) || !sneakScanner.Enabled) if (!_trayScannerQuery.TryGetComponent(ent, out var sneakScanner) || !sneakScanner.Enabled)
continue; continue;
canSee = true; canSee = true;
@@ -71,7 +71,7 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem
if (!_hands.TryGetHeldItem(player.Value, hand, out var heldEntity)) if (!_hands.TryGetHeldItem(player.Value, hand, out var heldEntity))
continue; continue;
if (!scannerQuery.TryGetComponent(heldEntity, out var heldScanner) || !heldScanner.Enabled) if (!_trayScannerQuery.TryGetComponent(heldEntity, out var heldScanner) || !heldScanner.Enabled)
continue; continue;
range = MathF.Max(heldScanner.Range, range); range = MathF.Max(heldScanner.Range, range);
@@ -93,13 +93,12 @@ public sealed class TrayScannerSystem : SharedTrayScannerSystem
} }
var revealedQuery = AllEntityQuery<TrayRevealedComponent, SpriteComponent>(); var revealedQuery = AllEntityQuery<TrayRevealedComponent, SpriteComponent>();
var subfloorQuery = GetEntityQuery<SubFloorHideComponent>();
while (revealedQuery.MoveNext(out var uid, out _, out var sprite)) while (revealedQuery.MoveNext(out var uid, out _, out var sprite))
{ {
// Revealing // Revealing
// Add buffer range to avoid flickers. // Add buffer range to avoid flickers.
if (subfloorQuery.TryGetComponent(uid, out var subfloor) && if (_subFloorHideQuery.TryGetComponent(uid, out var subfloor) &&
inRange.Contains((uid, subfloor))) inRange.Contains((uid, subfloor)))
{ {
// Due to the fact client is predicting this server states will reset it constantly // Due to the fact client is predicting this server states will reset it constantly
@@ -33,15 +33,7 @@ public sealed class BuiPreTickUpdateSystem : EntitySystem
[Dependency] private readonly IPlayerManager _playerManager = null!; [Dependency] private readonly IPlayerManager _playerManager = null!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = null!; [Dependency] private readonly UserInterfaceSystem _uiSystem = null!;
[Dependency] private readonly IGameTiming _gameTiming = null!; [Dependency] private readonly IGameTiming _gameTiming = null!;
[Dependency] private readonly EntityQuery<UserInterfaceUserComponent> _userQuery = default!;
private EntityQuery<UserInterfaceUserComponent> _userQuery;
public override void Initialize()
{
base.Initialize();
_userQuery = GetEntityQuery<UserInterfaceUserComponent>();
}
public void RunUpdates() public void RunUpdates()
{ {
@@ -228,7 +228,6 @@ public class RadialMenu : BaseWindow
/// Base class for radial menu buttons. Excludes all actions except clicks and alt-clicks /// Base class for radial menu buttons. Excludes all actions except clicks and alt-clicks
/// from interactions. /// from interactions.
/// </summary> /// </summary>
[Virtual]
public abstract class RadialMenuButtonBase : BaseButton public abstract class RadialMenuButtonBase : BaseButton
{ {
/// <inheritdoc /> /// <inheritdoc />
@@ -9,7 +9,6 @@ using Robust.Shared.Prototypes;
namespace Content.Client.UserInterface.Controls namespace Content.Client.UserInterface.Controls
{ {
[Virtual]
public abstract class SlotControl : Control, IEntityControl public abstract class SlotControl : Control, IEntityControl
{ {
public static int DefaultButtonSize = 64; public static int DefaultButtonSize = 64;
@@ -11,7 +11,6 @@ public interface IItemslotUIContainer
public bool TryAddButton(SlotControl control); public bool TryAddButton(SlotControl control);
} }
[Virtual]
public abstract class ItemSlotUIContainer<T> : GridContainer, IItemslotUIContainer where T : SlotControl public abstract class ItemSlotUIContainer<T> : GridContainer, IItemslotUIContainer where T : SlotControl
{ {
private readonly Dictionary<string, T> _buttons = new(); private readonly Dictionary<string, T> _buttons = new();
+2 -2
View File
@@ -34,6 +34,7 @@ namespace Content.Client.Verbs
[Dependency] private readonly SharedContainerSystem _containers = default!; [Dependency] private readonly SharedContainerSystem _containers = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly EntityQuery<SpriteComponent> _spriteQuery = default!;
private float _lookupSize; private float _lookupSize;
@@ -159,10 +160,9 @@ namespace Content.Client.Verbs
if (container == null && (visibility & MenuVisibility.InContainer) == 0) if (container == null && (visibility & MenuVisibility.InContainer) == 0)
return entities.Count != 0; return entities.Count != 0;
var spriteQuery = GetEntityQuery<SpriteComponent>();
for (var i = entities.Count - 1; i >= 0; i--) for (var i = entities.Count - 1; i >= 0; i--)
{ {
if (!spriteQuery.TryGetComponent(entities[i], out var spriteComponent) || !spriteComponent.Visible) if (!_spriteQuery.TryGetComponent(entities[i], out var spriteComponent) || !spriteComponent.Visible)
entities.RemoveSwap(i); entities.RemoveSwap(i);
} }
@@ -32,7 +32,7 @@ public sealed partial class MeleeWeaponSystem
if (localPos == Vector2.Zero || animation == null) if (localPos == Vector2.Zero || animation == null)
return; return;
if (!_xformQuery.TryGetComponent(user, out var userXform) || userXform.MapID == MapId.Nullspace) if (!TryComp(user, out TransformComponent? userXform) || userXform.MapID == MapId.Nullspace)
return; return;
var animationUid = Spawn(animation, userXform.Coordinates); var animationUid = Spawn(animation, userXform.Coordinates);
@@ -64,7 +64,7 @@ public sealed partial class MeleeWeaponSystem
} }
_sprite.SetRotation((animationUid, sprite), localPos.ToWorldAngle()); _sprite.SetRotation((animationUid, sprite), localPos.ToWorldAngle());
var xform = _xformQuery.GetComponent(animationUid); var xform = Transform(animationUid);
TrackUserComponent track; TrackUserComponent track;
switch (arcComponent.Animation) switch (arcComponent.Animation)
@@ -35,14 +35,12 @@ public sealed partial class MeleeWeaponSystem : SharedMeleeWeaponSystem
[Dependency] private readonly SpriteSystem _sprite = default!; [Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IConfigurationManager _cfg = default!;
private EntityQuery<TransformComponent> _xformQuery;
private const string MeleeLungeKey = "melee-lunge"; private const string MeleeLungeKey = "melee-lunge";
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
_xformQuery = GetEntityQuery<TransformComponent>();
SubscribeNetworkEvent<MeleeLungeEvent>(OnMeleeLunge); SubscribeNetworkEvent<MeleeLungeEvent>(OnMeleeLunge);
UpdatesOutsidePrediction = true; UpdatesOutsidePrediction = true;
} }
@@ -177,7 +175,7 @@ public sealed partial class MeleeWeaponSystem : SharedMeleeWeaponSystem
private void ClientHeavyAttack(EntityUid user, EntityCoordinates coordinates, EntityUid meleeUid, MeleeWeaponComponent component) private void ClientHeavyAttack(EntityUid user, EntityCoordinates coordinates, EntityUid meleeUid, MeleeWeaponComponent component)
{ {
// Only run on first prediction to avoid the potential raycast entities changing. // Only run on first prediction to avoid the potential raycast entities changing.
if (!_xformQuery.TryGetComponent(user, out var userXform) || if (!TryComp(user, out TransformComponent? userXform) ||
!Timing.IsFirstTimePredicted) !Timing.IsFirstTimePredicted)
{ {
return; return;
+3 -7
View File
@@ -20,19 +20,15 @@ public sealed class WeatherSystem : SharedWeatherSystem
[Dependency] private readonly MapSystem _mapSystem = default!; [Dependency] private readonly MapSystem _mapSystem = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedTransformSystem _transform = default!;
private EntityQuery<AudioComponent> _audioQuery; [Dependency] private readonly EntityQuery<AudioComponent> _audioQuery = default!;
private EntityQuery<MapGridComponent> _gridQuery; [Dependency] private readonly EntityQuery<MapGridComponent> _gridQuery = default!;
private EntityQuery<RoofComponent> _roofQuery; [Dependency] private readonly EntityQuery<RoofComponent> _roofQuery = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<WeatherStatusEffectComponent, ComponentShutdown>(OnComponentShutdown); SubscribeLocalEvent<WeatherStatusEffectComponent, ComponentShutdown>(OnComponentShutdown);
_audioQuery = GetEntityQuery<AudioComponent>();
_gridQuery = GetEntityQuery<MapGridComponent>();
_roofQuery = GetEntityQuery<RoofComponent>();
} }
private void OnComponentShutdown(Entity<WeatherStatusEffectComponent> ent, ref ComponentShutdown args) private void OnComponentShutdown(Entity<WeatherStatusEffectComponent> ent, ref ComponentShutdown args)
@@ -28,7 +28,7 @@ public sealed class TrackingIssueAttribute : PropertyAttribute
"github.com" "github.com"
]; ];
private static readonly Regex GithubStyleIssueMatch = new(@"^\/[a-z\-\$\#]*\/[a-z\-\$\#]*\/(issues|pulls)\/\d*$", private static readonly Regex GithubStyleIssueMatch = new(@"^\/[a-z\d\-\$\#]*\/[a-z\d\-\$\#]*\/(issues|pulls)\/\d*$",
RegexOptions.Compiled | RegexOptions.NonBacktracking | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.NonBacktracking | RegexOptions.IgnoreCase);
public TrackingIssueAttribute([StringSyntax(StringSyntaxAttribute.Uri)] string url) : base(url) public TrackingIssueAttribute([StringSyntax(StringSyntaxAttribute.Uri)] string url) : base(url)
@@ -25,7 +25,6 @@ public static partial class PoolManager
(CCVars.ArrivalsShuttles.Name, "false"), (CCVars.ArrivalsShuttles.Name, "false"),
(CCVars.EmergencyShuttleEnabled.Name, "false"), (CCVars.EmergencyShuttleEnabled.Name, "false"),
(CCVars.ProcgenPreload.Name, "false"), (CCVars.ProcgenPreload.Name, "false"),
(CCVars.WorldgenEnabled.Name, "false"),
(CCVars.GatewayGeneratorEnabled.Name, "false"), (CCVars.GatewayGeneratorEnabled.Name, "false"),
(CCVars.GameDummyTicker.Name, "true"), (CCVars.GameDummyTicker.Name, "true"),
(CCVars.GameLobbyEnabled.Name, "false"), (CCVars.GameLobbyEnabled.Name, "false"),
@@ -1,16 +1,17 @@
#nullable enable
using System.Collections.Generic; using System.Collections.Generic;
using Content.IntegrationTests.Fixtures;
using Content.IntegrationTests.Fixtures.Attributes;
using Content.Shared.Access; using Content.Shared.Access;
using Content.Shared.Access.Components; using Content.Shared.Access.Components;
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests.Access namespace Content.IntegrationTests.Tests.Access
{ {
[TestFixture]
[TestOf(typeof(AccessReaderComponent))] [TestOf(typeof(AccessReaderComponent))]
public sealed class AccessReaderTest public sealed class AccessReaderTest : GameTest
{ {
[TestPrototypes] [TestPrototypes]
private const string Prototypes = @" private const string Prototypes = @"
@@ -21,91 +22,85 @@ namespace Content.IntegrationTests.Tests.Access
- type: AccessReader - type: AccessReader
"; ";
[SidedDependency(Side.Server)] private readonly AccessReaderSystem _system = null!;
[Test] [Test]
[RunOnSide(Side.Server)]
public async Task TestTags() public async Task TestTags()
{ {
await using var pair = await PoolManager.GetServerClient(); var ent = SSpawn("TestAccessReader");
var server = pair.Server; var reader = new Entity<AccessReaderComponent>(ent, SComp<AccessReaderComponent>(ent));
var entityManager = server.ResolveDependency<IEntityManager>();
await server.WaitAssertion(() => // test empty
Assert.Multiple(() =>
{ {
var system = entityManager.System<AccessReaderSystem>(); Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Foo" }, reader), Is.True);
var ent = entityManager.SpawnEntity("TestAccessReader", MapCoordinates.Nullspace); Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Bar" }, reader), Is.True);
var reader = new Entity<AccessReaderComponent>(ent, entityManager.GetComponent<AccessReaderComponent>(ent)); Assert.That(_system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.True);
// test empty
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Foo" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Bar" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.True);
});
// test deny
system.AddDenyTag(reader, "A");
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Foo" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "Foo" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.True);
});
system.ClearDenyTags(reader);
// test one list
system.TryAddAccess(reader, "A");
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
system.TryClearAccesses(reader);
// test one list - two items
system.TryAddAccess(reader, new HashSet<ProtoId<AccessLevelPrototype>> { "A", "B" });
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
system.TryClearAccesses(reader);
// test two list
var accesses = new List<HashSet<ProtoId<AccessLevelPrototype>>>() {
new HashSet<ProtoId<AccessLevelPrototype>> () { "A" },
new HashSet<ProtoId<AccessLevelPrototype>> () { "B", "C" }
};
system.TryAddAccesses(reader, accesses);
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "C", "B" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "C", "B", "A" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
system.TryClearAccesses(reader);
// test deny list
system.TryAddAccess(reader, new HashSet<ProtoId<AccessLevelPrototype>> { "A" });
system.AddDenyTag(reader, "B");
Assert.Multiple(() =>
{
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.False);
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
system.TryClearAccesses(reader);
system.ClearDenyTags(reader);
}); });
await pair.CleanReturnAsync();
// test deny
_system.AddDenyTag(reader, "A");
Assert.Multiple(() =>
{
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Foo" }, reader), Is.True);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.False);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "Foo" }, reader), Is.False);
Assert.That(_system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.True);
});
_system.ClearDenyTags(reader);
// test one list
_system.TryAddAccess(reader, "A");
Assert.Multiple(() =>
{
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
Assert.That(_system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
_system.TryClearAccesses(reader);
// test one list - two items
_system.TryAddAccess(reader, new HashSet<ProtoId<AccessLevelPrototype>> { "A", "B" });
Assert.Multiple(() =>
{
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.False);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
Assert.That(_system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
_system.TryClearAccesses(reader);
// test two list
var accesses = new List<HashSet<ProtoId<AccessLevelPrototype>>>() {
new HashSet<ProtoId<AccessLevelPrototype>> () { "A" },
new HashSet<ProtoId<AccessLevelPrototype>> () { "B", "C" }
};
_system.TryAddAccesses(reader, accesses);
Assert.Multiple(() =>
{
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "C", "B" }, reader), Is.True);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "C", "B", "A" }, reader), Is.True);
Assert.That(_system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
_system.TryClearAccesses(reader);
// test deny list
_system.TryAddAccess(reader, new HashSet<ProtoId<AccessLevelPrototype>> { "A" });
_system.AddDenyTag(reader, "B");
Assert.Multiple(() =>
{
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
Assert.That(_system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.False);
Assert.That(_system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
_system.TryClearAccesses(reader);
_system.ClearDenyTags(reader);
} }
} }
@@ -1,4 +1,7 @@
#nullable enable
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.IntegrationTests.Fixtures.Attributes;
using Content.Shared.Actions; using Content.Shared.Actions;
using Content.Shared.Eye; using Content.Shared.Eye;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
@@ -7,15 +10,18 @@ using Robust.Shared.GameObjects;
namespace Content.IntegrationTests.Tests.Actions; namespace Content.IntegrationTests.Tests.Actions;
[TestFixture] [TestFixture]
public sealed class ActionPvsDetachTest public sealed class ActionPvsDetachTest : GameTest
{ {
[SidedDependency(Side.Server)] private readonly SharedActionsSystem _sActionsSys = null!;
[SidedDependency(Side.Client)] private readonly SharedActionsSystem _cActionsSys = null!;
[Test] [Test]
public async Task TestActionDetach() public async Task TestActionDetach()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true }); var pair = Pair;
var (server, client) = pair; var (server, client) = (Server, Client);
var sys = server.System<SharedActionsSystem>(); var sys = _sActionsSys;
var cSys = client.System<SharedActionsSystem>(); var cSys = _cActionsSys;
// Spawn mob that has some actions // Spawn mob that has some actions
EntityUid ent = default; EntityUid ent = default;
@@ -60,6 +66,5 @@ public sealed class ActionPvsDetachTest
Assert.That(cSys.GetActions(cEnt).Count(), Is.EqualTo(initActions)); Assert.That(cSys.GetActions(cEnt).Count(), Is.EqualTo(initActions));
await server.WaitPost(() => server.EntMan.DeleteEntity(map.MapUid)); await server.WaitPost(() => server.EntMan.DeleteEntity(map.MapUid));
await pair.CleanReturnAsync();
} }
} }
@@ -1,4 +1,6 @@
#nullable enable
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.Shared.Actions; using Content.Shared.Actions;
using Content.Shared.Actions.Components; using Content.Shared.Actions.Components;
using Content.Shared.CombatMode; using Content.Shared.CombatMode;
@@ -11,15 +13,17 @@ namespace Content.IntegrationTests.Tests.Actions;
/// This tests checks that actions properly get added to an entity's actions component.. /// This tests checks that actions properly get added to an entity's actions component..
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public sealed class ActionsAddedTest public sealed class ActionsAddedTest : GameTest
{ {
public override PoolSettings PoolSettings => new PoolSettings { Connected = true, DummyTicker = false };
// TODO add magboot test (inventory action) // TODO add magboot test (inventory action)
// TODO add ghost toggle-fov test (client-side action) // TODO add ghost toggle-fov test (client-side action)
[Test] [Test]
public async Task TestCombatActionsAdded() public async Task TestCombatActionsAdded()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, DummyTicker = false }); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var client = pair.Client; var client = pair.Client;
var sEntMan = server.ResolveDependency<IEntityManager>(); var sEntMan = server.ResolveDependency<IEntityManager>();
@@ -67,7 +71,5 @@ public sealed class ActionsAddedTest
// required, because integration tests do not respect the [NonSerialized] attribute and will simply events by reference. // required, because integration tests do not respect the [NonSerialized] attribute and will simply events by reference.
Assert.That(ReferenceEquals(sAct.Comp, cAct.Comp), Is.False); Assert.That(ReferenceEquals(sAct.Comp, cAct.Comp), Is.False);
Assert.That(ReferenceEquals(sQuery.GetComponent(sAct).Event, cQuery.GetComponent(cAct).Event), Is.False); Assert.That(ReferenceEquals(sQuery.GetComponent(sAct).Event, cQuery.GetComponent(cAct).Event), Is.False);
await pair.CleanReturnAsync();
} }
} }
@@ -1,5 +1,7 @@
using System.Collections.Generic; #nullable enable
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Server.Database; using Content.Server.Database;
using Content.Server.GameTicking; using Content.Server.GameTicking;
@@ -12,9 +14,9 @@ namespace Content.IntegrationTests.Tests.Administration.Logs;
[TestFixture] [TestFixture]
[TestOf(typeof(AdminLogSystem))] [TestOf(typeof(AdminLogSystem))]
public sealed class AddTests public sealed class AddTests : GameTest
{ {
public static PoolSettings LogTestSettings = new() public override PoolSettings PoolSettings => new()
{ {
AdminLogsEnabled = true, AdminLogsEnabled = true,
DummyTicker = false, DummyTicker = false,
@@ -24,7 +26,7 @@ public sealed class AddTests
[Test] [Test]
public async Task AddAndGetSingleLog() public async Task AddAndGetSingleLog()
{ {
await using var pair = await PoolManager.GetServerClient(LogTestSettings); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>(); var sEntities = server.ResolveDependency<IEntityManager>();
@@ -33,7 +35,7 @@ public sealed class AddTests
var guid = Guid.NewGuid(); var guid = Guid.NewGuid();
await pair.CreateTestMap(); await pair.CreateTestMap();
var coordinates = pair.TestMap.GridCoords; var coordinates = pair.TestMap!.GridCoords;
await server.WaitPost(() => await server.WaitPost(() =>
{ {
var entity = sEntities.SpawnEntity(null, coordinates); var entity = sEntities.SpawnEntity(null, coordinates);
@@ -62,14 +64,12 @@ public sealed class AddTests
return false; return false;
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task AddAndGetUnformattedLog() public async Task AddAndGetUnformattedLog()
{ {
await using var pair = await PoolManager.GetServerClient(LogTestSettings); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var sDatabase = server.ResolveDependency<IServerDbManager>(); var sDatabase = server.ResolveDependency<IServerDbManager>();
@@ -127,15 +127,13 @@ public sealed class AddTests
json.Dispose(); json.Dispose();
} }
await pair.CleanReturnAsync();
} }
[Test] [Test]
[TestCase(500)] [TestCase(500)]
public async Task BulkAddLogs(int amount) public async Task BulkAddLogs(int amount)
{ {
await using var pair = await PoolManager.GetServerClient(LogTestSettings); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>(); var sEntities = server.ResolveDependency<IEntityManager>();
@@ -158,14 +156,12 @@ public sealed class AddTests
var messages = await sAdminLogSystem.CurrentRoundLogs(); var messages = await sAdminLogSystem.CurrentRoundLogs();
return messages.Count >= amount; return messages.Count >= amount;
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task AddPlayerSessionLog() public async Task AddPlayerSessionLog()
{ {
await using var pair = await PoolManager.GetServerClient(LogTestSettings); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var sPlayers = server.ResolveDependency<IPlayerManager>(); var sPlayers = server.ResolveDependency<IPlayerManager>();
@@ -195,20 +191,91 @@ public sealed class AddTests
Assert.That(logs.First().Players, Does.Contain(playerGuid)); Assert.That(logs.First().Players, Does.Contain(playerGuid));
return true; return true;
}); });
await pair.CleanReturnAsync();
} }
[Test]
public async Task DuplicatePlayerDoesNotThrowTest()
{
var pair = Pair;
var server = pair.Server;
var sPlayers = server.ResolveDependency<IPlayerManager>();
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
var guid = Guid.NewGuid();
await server.WaitPost(() =>
{
var player = sPlayers.Sessions.Single();
sAdminLogSystem.Add(LogType.Unknown, $"{player} {player} test log: {guid}");
});
await PoolManager.WaitUntil(server, async () =>
{
var logs = await sAdminLogSystem.CurrentRoundLogs(new LogFilter
{
Search = guid.ToString()
});
if (logs.Count == 0)
{
return false;
}
return true;
});
}
[Test]
public async Task DuplicatePlayerIdDoesNotThrowTest()
{
var pair = Pair;
var server = pair.Server;
var sPlayers = server.ResolveDependency<IPlayerManager>();
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
var guid = Guid.NewGuid();
await server.WaitPost(() =>
{
var player = sPlayers.Sessions.Single();
sAdminLogSystem.Add(LogType.Unknown, $"{player:first} {player:second} test log: {guid}");
});
await PoolManager.WaitUntil(server, async () =>
{
var logs = await sAdminLogSystem.CurrentRoundLogs(new LogFilter
{
Search = guid.ToString()
});
if (logs.Count == 0)
{
return false;
}
return true;
});
}
}
public sealed class PreRoundAddTests : GameTest
{
public override PoolSettings PoolSettings => new PoolSettings
{
Dirty = true,
InLobby = true,
AdminLogsEnabled = true
};
[Test] [Test]
public async Task PreRoundAddAndGetSingle() public async Task PreRoundAddAndGetSingle()
{ {
var setting = new PoolSettings var pair = Pair;
{
Dirty = true,
InLobby = true,
AdminLogsEnabled = true
};
await using var pair = await PoolManager.GetServerClient(setting);
var server = pair.Server; var server = pair.Server;
var sDatabase = server.ResolveDependency<IServerDbManager>(); var sDatabase = server.ResolveDependency<IServerDbManager>();
@@ -262,81 +329,6 @@ public sealed class AddTests
json.Dispose(); json.Dispose();
} }
await pair.CleanReturnAsync();
} }
[Test]
public async Task DuplicatePlayerDoesNotThrowTest()
{
await using var pair = await PoolManager.GetServerClient(LogTestSettings);
var server = pair.Server;
var sPlayers = server.ResolveDependency<IPlayerManager>();
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
var guid = Guid.NewGuid();
await server.WaitPost(() =>
{
var player = sPlayers.Sessions.Single();
sAdminLogSystem.Add(LogType.Unknown, $"{player} {player} test log: {guid}");
});
await PoolManager.WaitUntil(server, async () =>
{
var logs = await sAdminLogSystem.CurrentRoundLogs(new LogFilter
{
Search = guid.ToString()
});
if (logs.Count == 0)
{
return false;
}
return true;
});
await pair.CleanReturnAsync();
Assert.Pass();
}
[Test]
public async Task DuplicatePlayerIdDoesNotThrowTest()
{
await using var pair = await PoolManager.GetServerClient(LogTestSettings);
var server = pair.Server;
var sPlayers = server.ResolveDependency<IPlayerManager>();
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
var guid = Guid.NewGuid();
await server.WaitPost(() =>
{
var player = sPlayers.Sessions.Single();
sAdminLogSystem.Add(LogType.Unknown, $"{player:first} {player:second} test log: {guid}");
});
await PoolManager.WaitUntil(server, async () =>
{
var logs = await sAdminLogSystem.CurrentRoundLogs(new LogFilter
{
Search = guid.ToString()
});
if (logs.Count == 0)
{
return false;
}
return true;
});
await pair.CleanReturnAsync();
Assert.Pass();
}
} }
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Shared.Administration.Logs; using Content.Shared.Administration.Logs;
using Content.Shared.Database; using Content.Shared.Database;
@@ -7,14 +8,21 @@ namespace Content.IntegrationTests.Tests.Administration.Logs;
[TestFixture] [TestFixture]
[TestOf(typeof(AdminLogSystem))] [TestOf(typeof(AdminLogSystem))]
public sealed class FilterTests public sealed class FilterTests : GameTest
{ {
public override PoolSettings PoolSettings => new()
{
AdminLogsEnabled = true,
DummyTicker = false,
Connected = true
};
[Test] [Test]
[TestCase(DateOrder.Ascending)] [TestCase(DateOrder.Ascending)]
[TestCase(DateOrder.Descending)] [TestCase(DateOrder.Descending)]
public async Task Date(DateOrder order) public async Task Date(DateOrder order)
{ {
await using var pair = await PoolManager.GetServerClient(AddTests.LogTestSettings); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var sEntities = server.ResolveDependency<IEntityManager>(); var sEntities = server.ResolveDependency<IEntityManager>();
@@ -96,6 +104,5 @@ public sealed class FilterTests
return firstFound && secondFound; return firstFound && secondFound;
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Shared.Database; using Content.Shared.Database;
@@ -11,12 +12,19 @@ namespace Content.IntegrationTests.Tests.Administration.Logs;
[TestFixture] [TestFixture]
[TestOf(typeof(AdminLogSystem))] [TestOf(typeof(AdminLogSystem))]
public sealed class QueryTests public sealed class QueryTests : GameTest
{ {
public override PoolSettings PoolSettings => new()
{
AdminLogsEnabled = true,
DummyTicker = false,
Connected = true
};
[Test] [Test]
public async Task QuerySingleLog() public async Task QuerySingleLog()
{ {
await using var pair = await PoolManager.GetServerClient(AddTests.LogTestSettings); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var sSystems = server.ResolveDependency<IEntitySystemManager>(); var sSystems = server.ResolveDependency<IEntitySystemManager>();
@@ -55,7 +63,5 @@ public sealed class QueryTests
return false; return false;
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Monitor;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -5,7 +6,7 @@ namespace Content.IntegrationTests.Tests.Atmos
{ {
[TestFixture] [TestFixture]
[TestOf(typeof(AtmosAlarmThreshold))] [TestOf(typeof(AtmosAlarmThreshold))]
public sealed class AlarmThresholdTest public sealed class AlarmThresholdTest : GameTest
{ {
private const string AlarmThresholdTestDummyId = "AlarmThresholdTestDummy"; private const string AlarmThresholdTestDummyId = "AlarmThresholdTestDummy";
@@ -26,7 +27,7 @@ namespace Content.IntegrationTests.Tests.Atmos
[Test] [Test]
public async Task TestAlarmThreshold() public async Task TestAlarmThreshold()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var prototypeManager = server.ResolveDependency<IPrototypeManager>(); var prototypeManager = server.ResolveDependency<IPrototypeManager>();
@@ -136,7 +137,6 @@ namespace Content.IntegrationTests.Tests.Atmos
Assert.That(alarmType, Is.EqualTo(AtmosAlarmType.Normal)); Assert.That(alarmType, Is.EqualTo(AtmosAlarmType.Normal));
} }
}); });
await pair.CleanReturnAsync();
} }
} }
} }
@@ -1,4 +1,5 @@
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Atmos.Prototypes; using Content.Shared.Atmos.Prototypes;
@@ -6,12 +7,12 @@ using Content.Shared.Atmos.Prototypes;
namespace Content.IntegrationTests.Tests.Atmos; namespace Content.IntegrationTests.Tests.Atmos;
[TestOf(typeof(Atmospherics))] [TestOf(typeof(Atmospherics))]
public sealed class ConstantsTest public sealed class ConstantsTest : GameTest
{ {
[Test] [Test]
public async Task TotalGasesTest() public async Task TotalGasesTest()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entityManager = server.EntMan; var entityManager = server.EntMan;
var protoManager = server.ProtoMan; var protoManager = server.ProtoMan;
@@ -34,9 +35,6 @@ public sealed class ConstantsTest
// enum mapping gases to their Id // enum mapping gases to their Id
Assert.That(Enum.GetValues<Gas>(), Has.Length.EqualTo(Atmospherics.TotalNumberOfGases), Assert.That(Enum.GetValues<Gas>(), Has.Length.EqualTo(Atmospherics.TotalNumberOfGases),
$"Gas enum size is not equal to TotalNumberOfGases."); $"Gas enum size is not equal to TotalNumberOfGases.");
// localized abbreviations for UI purposes
Assert.That(Atmospherics.GasAbbreviations, Has.Count.EqualTo(Atmospherics.TotalNumberOfGases),
$"GasAbbreviations size is not equal to TotalNumberOfGases.");
// the ID for each gas has to correspond to a value in the Gas enum (converted to a string) // the ID for each gas has to correspond to a value in the Gas enum (converted to a string)
foreach (var gas in gasProtos) foreach (var gas in gasProtos)
@@ -45,7 +43,6 @@ public sealed class ConstantsTest
} }
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,4 +1,5 @@
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Atmos.Components; using Content.Shared.Atmos.Components;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -8,7 +9,7 @@ namespace Content.IntegrationTests.Tests.Atmos;
[TestFixture] [TestFixture]
[TestOf(typeof(Atmospherics))] [TestOf(typeof(Atmospherics))]
public sealed class GasArrayTest public sealed class GasArrayTest : GameTest
{ {
private const string GasTankTestDummyId = "GasTankTestDummy"; private const string GasTankTestDummyId = "GasTankTestDummy";
@@ -42,7 +43,7 @@ public sealed class GasArrayTest
[Test] [Test]
public async Task TestGasArrayDeserialization() public async Task TestGasArrayDeserialization()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var compFactory = server.ResolveDependency<IComponentFactory>(); var compFactory = server.ResolveDependency<IComponentFactory>();
@@ -80,6 +81,5 @@ public sealed class GasArrayTest
} }
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,4 +1,5 @@
using Content.Server.Atmos; using Content.IntegrationTests.Fixtures;
using Content.Server.Atmos;
using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -7,12 +8,12 @@ namespace Content.IntegrationTests.Tests.Atmos
{ {
[TestFixture] [TestFixture]
[TestOf(typeof(GasMixture))] [TestOf(typeof(GasMixture))]
public sealed class GasMixtureTest public sealed class GasMixtureTest : GameTest
{ {
[Test] [Test]
public async Task TestMerge() public async Task TestMerge()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var atmosphereSystem = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<AtmosphereSystem>(); var atmosphereSystem = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<AtmosphereSystem>();
@@ -56,8 +57,6 @@ namespace Content.IntegrationTests.Tests.Atmos
Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(50)); Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(50));
}); });
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
@@ -69,7 +68,7 @@ namespace Content.IntegrationTests.Tests.Atmos
[TestCase(Atmospherics.BreathPercentage)] [TestCase(Atmospherics.BreathPercentage)]
public async Task RemoveRatio(float ratio) public async Task RemoveRatio(float ratio)
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
await server.WaitAssertion(() => await server.WaitAssertion(() =>
@@ -103,8 +102,6 @@ namespace Content.IntegrationTests.Tests.Atmos
Assert.That(a.GetMoles(Gas.Nitrogen), Is.EqualTo(100 - b.GetMoles(Gas.Nitrogen))); Assert.That(a.GetMoles(Gas.Nitrogen), Is.EqualTo(100 - b.GetMoles(Gas.Nitrogen)));
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
} }
@@ -1,4 +1,5 @@
using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.EntitySystems;
using Content.IntegrationTests.Fixtures;
using Content.Server.Atmos.Piping.EntitySystems; using Content.Server.Atmos.Piping.EntitySystems;
using Content.Shared.Atmos.Components; using Content.Shared.Atmos.Components;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -6,14 +7,14 @@ using Robust.Shared.GameObjects;
namespace Content.IntegrationTests.Tests.Atmos; namespace Content.IntegrationTests.Tests.Atmos;
[TestFixture] [TestFixture]
public sealed class GridJoinTest public sealed class GridJoinTest : GameTest
{ {
private const string CanisterProtoId = "AirCanister"; private const string CanisterProtoId = "AirCanister";
[Test] [Test]
public async Task TestGridJoinAtmosphere() public async Task TestGridJoinAtmosphere()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entMan = server.EntMan; var entMan = server.EntMan;
@@ -46,7 +47,5 @@ public sealed class GridJoinTest
// Make sure that the canister is now properly tracked as on-grid // Make sure that the canister is now properly tracked as on-grid
Assert.That(atmosDeviceSystem.IsJoinedOffGrid(canisterEnt), Is.False); Assert.That(atmosDeviceSystem.IsJoinedOffGrid(canisterEnt), Is.False);
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -37,7 +37,7 @@ public sealed class SharedGasSpecificHeatsTest
{ {
Connected = true, Connected = true,
}; };
_pair = await PoolManager.GetServerClient(poolSettings); _pair = await PoolManager.GetServerClient(poolSettings, new NUnitTestContextWrap(TestContext.CurrentContext, TestContext.Out));
_sEntMan = Server.ResolveDependency<IEntityManager>(); _sEntMan = Server.ResolveDependency<IEntityManager>();
_cEntMan = Client.ResolveDependency<IEntityManager>(); _cEntMan = Client.ResolveDependency<IEntityManager>();
@@ -62,12 +62,12 @@ public sealed class SharedGasSpecificHeatsTest
var clientSpecificHeats = Array.Empty<float>(); var clientSpecificHeats = Array.Empty<float>();
await Server.WaitPost(delegate await Server.WaitPost(delegate
{ {
serverSpecificHeats = _sAtmos.GasSpecificHeats; serverSpecificHeats = _sAtmos.GasMolarHeatCapacities;
}); });
await Client.WaitPost(delegate await Client.WaitPost(delegate
{ {
clientSpecificHeats = _cAtmos.GasSpecificHeats; clientSpecificHeats = _cAtmos.GasMolarHeatCapacities;
}); });
Assert.That(serverSpecificHeats, Assert.That(serverSpecificHeats,
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.Shared.Body; using Content.Shared.Body;
using Content.Shared.Gibbing; using Content.Shared.Gibbing;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -6,7 +7,7 @@ namespace Content.IntegrationTests.Tests.Body;
[TestFixture] [TestFixture]
[TestOf(typeof(GibbableOrganSystem))] [TestOf(typeof(GibbableOrganSystem))]
public sealed class GibletTest public sealed class GibletTest : GameTest
{ {
[TestPrototypes] [TestPrototypes]
private const string Prototypes = @" private const string Prototypes = @"
@@ -33,7 +34,7 @@ public sealed class GibletTest
[Test] [Test]
public async Task GibletCountTest() public async Task GibletCountTest()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
await server.WaitIdleAsync(); await server.WaitIdleAsync();
@@ -54,7 +55,5 @@ public sealed class GibletTest
Assert.That(entityManager.HasComponent<GibbableOrganComponent>(giblet), Is.True); Assert.That(entityManager.HasComponent<GibbableOrganComponent>(giblet), Is.True);
} }
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.Shared.Body; using Content.Shared.Body;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Robust.Shared.Containers; using Robust.Shared.Containers;
@@ -9,7 +10,7 @@ namespace Content.IntegrationTests.Tests.Body;
[TestFixture] [TestFixture]
[TestOf(typeof(HandOrganSystem))] [TestOf(typeof(HandOrganSystem))]
public sealed class HandOrganTest public sealed class HandOrganTest : GameTest
{ {
[TestPrototypes] [TestPrototypes]
private const string Prototypes = @" private const string Prototypes = @"
@@ -46,7 +47,7 @@ public sealed class HandOrganTest
[Test] [Test]
public async Task HandInsertionAndRemovalTest() public async Task HandInsertionAndRemovalTest()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
await server.WaitIdleAsync(); await server.WaitIdleAsync();
@@ -81,7 +82,5 @@ public sealed class HandOrganTest
Assert.That(hands.Count, Is.EqualTo(expectedCount)); Assert.That(hands.Count, Is.EqualTo(expectedCount));
} }
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -12,7 +12,7 @@ public sealed partial class BuckleTest
[Test] [Test]
public async Task BuckleInteractUnbuckleOther() public async Task BuckleInteractUnbuckleOther()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>(); var entMan = server.ResolveDependency<IServerEntityManager>();
@@ -55,14 +55,12 @@ public sealed partial class BuckleTest
Assert.That(strap.BuckledEntities, Does.Not.Contain(victim)); Assert.That(strap.BuckledEntities, Does.Not.Contain(victim));
}); });
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task BuckleInteractBuckleUnbuckleSelf() public async Task BuckleInteractBuckleUnbuckleSelf()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>(); var entMan = server.ResolveDependency<IServerEntityManager>();
@@ -102,7 +100,5 @@ public sealed partial class BuckleTest
Assert.That(strap.BuckledEntities, Does.Not.Contain(user)); Assert.That(strap.BuckledEntities, Does.Not.Contain(user));
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,4 +1,5 @@
using System.Numerics; using System.Numerics;
using Content.IntegrationTests.Fixtures;
using Content.Shared.Buckle; using Content.Shared.Buckle;
using Content.Shared.ActionBlocker; using Content.Shared.ActionBlocker;
using Content.Shared.Buckle.Components; using Content.Shared.Buckle.Components;
@@ -12,7 +13,7 @@ namespace Content.IntegrationTests.Tests.Buckle
[TestFixture] [TestFixture]
[TestOf(typeof(BuckleComponent))] [TestOf(typeof(BuckleComponent))]
[TestOf(typeof(StrapComponent))] [TestOf(typeof(StrapComponent))]
public sealed partial class BuckleTest public sealed partial class BuckleTest : GameTest
{ {
private const string BuckleDummyId = "BuckleDummy"; private const string BuckleDummyId = "BuckleDummy";
private const string StrapDummyId = "StrapDummy"; private const string StrapDummyId = "StrapDummy";
@@ -50,7 +51,7 @@ namespace Content.IntegrationTests.Tests.Buckle
[Test] [Test]
public async Task BuckleUnbuckleCooldownRangeTest() public async Task BuckleUnbuckleCooldownRangeTest()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var testMap = await pair.CreateTestMap(); var testMap = await pair.CreateTestMap();
@@ -228,14 +229,12 @@ namespace Content.IntegrationTests.Tests.Buckle
Assert.That(strap.BuckledEntities, Is.Empty); Assert.That(strap.BuckledEntities, Is.Empty);
}); });
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task BuckledDyingDropItemsTest() public async Task BuckledDyingDropItemsTest()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var testMap = await pair.CreateTestMap(); var testMap = await pair.CreateTestMap();
@@ -298,14 +297,12 @@ namespace Content.IntegrationTests.Tests.Buckle
buckleSystem.Unbuckle(human, human); buckleSystem.Unbuckle(human, human);
Assert.That(buckle.Buckled, Is.False); Assert.That(buckle.Buckled, Is.False);
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task ForceUnbuckleBuckleTest() public async Task ForceUnbuckleBuckleTest()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var testMap = await pair.CreateTestMap(); var testMap = await pair.CreateTestMap();
@@ -373,7 +370,6 @@ namespace Content.IntegrationTests.Tests.Buckle
Assert.That(buckle.Buckled); Assert.That(buckle.Buckled);
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
} }
+8 -19
View File
@@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Content.IntegrationTests.Fixtures;
using Content.Server.Cargo.Components; using Content.Server.Cargo.Components;
using Content.Server.Cargo.Systems; using Content.Server.Cargo.Systems;
using Content.Server.Nutrition.Components; using Content.Server.Nutrition.Components;
@@ -17,7 +18,7 @@ using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests; namespace Content.IntegrationTests.Tests;
[TestFixture] [TestFixture]
public sealed class CargoTest public sealed class CargoTest : GameTest
{ {
private static readonly HashSet<ProtoId<CargoProductPrototype>> Ignored = private static readonly HashSet<ProtoId<CargoProductPrototype>> Ignored =
[ [
@@ -28,7 +29,7 @@ public sealed class CargoTest
[Test] [Test]
public async Task NoCargoOrderArbitrage() public async Task NoCargoOrderArbitrage()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var testMap = await pair.CreateTestMap(); var testMap = await pair.CreateTestMap();
@@ -54,13 +55,11 @@ public sealed class CargoTest
} }
}); });
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task NoCargoBountyArbitrageTest() public async Task NoCargoBountyArbitrageTest()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var testMap = await pair.CreateTestMap(); var testMap = await pair.CreateTestMap();
@@ -94,14 +93,12 @@ public sealed class CargoTest
mapSystem.DeleteMap(mapId); mapSystem.DeleteMap(mapId);
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task NoStaticPriceAndStackPrice() public async Task NoStaticPriceAndStackPrice()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var protoManager = server.ProtoMan; var protoManager = server.ProtoMan;
@@ -133,8 +130,6 @@ public sealed class CargoTest
} }
} }
}); });
await pair.CleanReturnAsync();
} }
/// <summary> /// <summary>
@@ -144,7 +139,7 @@ public sealed class CargoTest
[Test] [Test]
public async Task NoSliceableBountyArbitrageTest() public async Task NoSliceableBountyArbitrageTest()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var testMap = await pair.CreateTestMap(); var testMap = await pair.CreateTestMap();
@@ -209,8 +204,6 @@ public sealed class CargoTest
} }
mapSystem.DeleteMap(mapId); mapSystem.DeleteMap(mapId);
}); });
await pair.CleanReturnAsync();
} }
[TestPrototypes] [TestPrototypes]
@@ -233,7 +226,7 @@ public sealed class CargoTest
[Test] [Test]
public async Task StackPrice() public async Task StackPrice()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entManager = server.ResolveDependency<IEntityManager>(); var entManager = server.ResolveDependency<IEntityManager>();
@@ -245,14 +238,12 @@ public sealed class CargoTest
var price = priceSystem.GetPrice(ent); var price = priceSystem.GetPrice(ent);
Assert.That(price, Is.EqualTo(100.0)); Assert.That(price, Is.EqualTo(100.0));
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task MobPrice() public async Task MobPrice()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var componentFactory = pair.Server.ResolveDependency<IComponentFactory>(); var componentFactory = pair.Server.ResolveDependency<IComponentFactory>();
@@ -266,7 +257,5 @@ public sealed class CargoTest
} }
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.IntegrationTests.Tests.Interaction; using Content.IntegrationTests.Tests.Interaction;
using Content.Shared.Chemistry.Reagent; using Content.Shared.Chemistry.Reagent;
using Robust.Shared.Reflection; using Robust.Shared.Reflection;
@@ -8,12 +9,12 @@ namespace Content.IntegrationTests.Tests.Chemistry;
[TestFixture] [TestFixture]
[TestOf(typeof(ReagentData))] [TestOf(typeof(ReagentData))]
public sealed class ReagentDataTest public sealed class ReagentDataTest : GameTest
{ {
[Test] [Test]
public async Task ReagentDataIsSerializable() public async Task ReagentDataIsSerializable()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var reflection = pair.Server.ResolveDependency<IReflectionManager>(); var reflection = pair.Server.ResolveDependency<IReflectionManager>();
Assert.Multiple(() => Assert.Multiple(() =>
@@ -24,7 +25,5 @@ public sealed class ReagentDataTest
Assert.That(instance.HasCustomAttribute<SerializableAttribute>(), $"{instance} must have the serializable attribute."); Assert.That(instance.HasCustomAttribute<SerializableAttribute>(), $"{instance} must have the serializable attribute.");
} }
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Reaction; using Content.Shared.Chemistry.Reaction;
@@ -9,7 +10,7 @@ namespace Content.IntegrationTests.Tests.Chemistry;
[TestFixture] [TestFixture]
[TestOf(typeof(ChemicalReactionSystem))] [TestOf(typeof(ChemicalReactionSystem))]
public sealed class SolutionRoundingTest public sealed class SolutionRoundingTest : GameTest
{ {
// This test tests two things: // This test tests two things:
// * A rounding error in reaction code while I was making chloral hydrate // * A rounding error in reaction code while I was making chloral hydrate
@@ -72,7 +73,7 @@ public sealed class SolutionRoundingTest
[Test] [Test]
public async Task Test() public async Task Test()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var testMap = await pair.CreateTestMap(); var testMap = await pair.CreateTestMap();
@@ -121,7 +122,5 @@ public sealed class SolutionRoundingTest
Is.EqualTo((FixedPoint2) 30)); Is.EqualTo((FixedPoint2) 30));
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
@@ -12,7 +13,7 @@ namespace Content.IntegrationTests.Tests.Chemistry;
// reactions can change this assumption // reactions can change this assumption
[TestFixture] [TestFixture]
[TestOf(typeof(SharedSolutionContainerSystem))] [TestOf(typeof(SharedSolutionContainerSystem))]
public sealed class SolutionSystemTests public sealed class SolutionSystemTests : GameTest
{ {
[TestPrototypes] [TestPrototypes]
private const string Prototypes = @" private const string Prototypes = @"
@@ -53,7 +54,7 @@ public sealed class SolutionSystemTests
[Test] [Test]
public async Task TryAddTwoNonReactiveReagent() public async Task TryAddTwoNonReactiveReagent()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>(); var entityManager = server.ResolveDependency<IEntityManager>();
@@ -88,8 +89,6 @@ public sealed class SolutionSystemTests
Assert.That(oil, Is.EqualTo(oilQuantity)); Assert.That(oil, Is.EqualTo(oilQuantity));
}); });
}); });
await pair.CleanReturnAsync();
} }
// This test mimics current behavior // This test mimics current behavior
@@ -97,7 +96,7 @@ public sealed class SolutionSystemTests
[Test] [Test]
public async Task TryAddTooMuchNonReactiveReagent() public async Task TryAddTooMuchNonReactiveReagent()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var testMap = await pair.CreateTestMap(); var testMap = await pair.CreateTestMap();
@@ -133,15 +132,13 @@ public sealed class SolutionSystemTests
Assert.That(oil, Is.EqualTo(FixedPoint2.Zero)); Assert.That(oil, Is.EqualTo(FixedPoint2.Zero));
}); });
}); });
await pair.CleanReturnAsync();
} }
// Unlike TryAddSolution this adds and two solution without then splits leaving only threshold in original // Unlike TryAddSolution this adds and two solution without then splits leaving only threshold in original
[Test] [Test]
public async Task TryMixAndOverflowTooMuchReagent() public async Task TryMixAndOverflowTooMuchReagent()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
@@ -188,15 +185,13 @@ public sealed class SolutionSystemTests
Assert.That(oilOverFlow, Is.EqualTo(oilQuantity - oilMix)); Assert.That(oilOverFlow, Is.EqualTo(oilQuantity - oilMix));
}); });
}); });
await pair.CleanReturnAsync();
} }
// TryMixAndOverflow will fail if Threshold larger than MaxVolume // TryMixAndOverflow will fail if Threshold larger than MaxVolume
[Test] [Test]
public async Task TryMixAndOverflowTooBigOverflow() public async Task TryMixAndOverflowTooBigOverflow()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>(); var entityManager = server.ResolveDependency<IEntityManager>();
@@ -226,14 +221,12 @@ public sealed class SolutionSystemTests
.TryMixAndOverflow(solutionEnt.Value, oilAdded, threshold, out _), .TryMixAndOverflow(solutionEnt.Value, oilAdded, threshold, out _),
Is.False); Is.False);
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task TestTemperatureCalculations() public async Task TestTemperatureCalculations()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>(); var protoMan = server.ResolveDependency<IPrototypeManager>();
const float temp = 100.0f; const float temp = 100.0f;
@@ -264,7 +257,5 @@ public sealed class SolutionSystemTests
solutionOne.AddSolution(solutionTwo, protoMan); solutionOne.AddSolution(solutionTwo, protoMan);
Assert.That(solutionOne.GetHeatCapacity(protoMan) * solutionOne.Temperature, Is.EqualTo(thermalEnergyOne + thermalEnergyTwo)); Assert.That(solutionOne.GetHeatCapacity(protoMan) * solutionOne.Temperature, Is.EqualTo(thermalEnergyOne + thermalEnergyTwo));
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -5,6 +5,7 @@ using Robust.Shared.Map;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.IntegrationTests.Utility; using Content.IntegrationTests.Utility;
using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.EntitySystems;
@@ -12,7 +13,7 @@ namespace Content.IntegrationTests.Tests.Chemistry
{ {
[TestFixture] [TestFixture]
[TestOf(typeof(ReactionPrototype))] [TestOf(typeof(ReactionPrototype))]
public sealed class TryAllReactionsTest public sealed class TryAllReactionsTest : GameTest
{ {
[TestPrototypes] [TestPrototypes]
private const string Prototypes = @" private const string Prototypes = @"
@@ -33,7 +34,7 @@ namespace Content.IntegrationTests.Tests.Chemistry
[Description("Tries an individual reaction to see if it succeeds.")] [Description("Tries an individual reaction to see if it succeeds.")]
public async Task TryReaction(string reaction) public async Task TryReaction(string reaction)
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entityManager = server.ResolveDependency<IEntityManager>(); var entityManager = server.ResolveDependency<IEntityManager>();
@@ -134,8 +135,6 @@ namespace Content.IntegrationTests.Tests.Chemistry
server.EntMan.DeleteEntity(beaker); server.EntMan.DeleteEntity(beaker);
}); });
await pair.CleanReturnAsync();
} }
} }
} }
@@ -1,35 +1,37 @@
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.Server.Administration.UI; using Content.Server.Administration.UI;
using Content.Server.EUI; using Content.Server.EUI;
using Robust.Server.Player; using Robust.Server.Player;
namespace Content.IntegrationTests.Tests.Cleanup; namespace Content.IntegrationTests.Tests.Cleanup;
public sealed class EuiManagerTest public sealed class EuiManagerTest : GameTest
{ {
public override PoolSettings PoolSettings => new PoolSettings
{
Connected = true,
Dirty = true
};
[Test] [Test]
[Retry(2)]
// Even though we are using the server EUI here, we actually want to see if the client EUIManager crashes
public async Task EuiManagerRecycleWithOpenWindowTest() public async Task EuiManagerRecycleWithOpenWindowTest()
{ {
// Even though we are using the server EUI here, we actually want to see if the client EUIManager crashes var pair = Pair;
for (var i = 0; i < 2; i++) var server = pair.Server;
var sPlayerManager = server.ResolveDependency<IPlayerManager>();
var eui = server.ResolveDependency<EuiManager>();
await server.WaitAssertion(() =>
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings var clientSession = sPlayerManager.Sessions.Single();
{ var ui = new AdminAnnounceEui();
Connected = true, eui.OpenEui(ui, clientSession);
Dirty = true });
});
var server = pair.Server;
var sPlayerManager = server.ResolveDependency<IPlayerManager>(); await RunUntilSynced();
var eui = server.ResolveDependency<EuiManager>();
await server.WaitAssertion(() =>
{
var clientSession = sPlayerManager.Sessions.Single();
var ui = new AdminAnnounceEui();
eui.OpenEui(ui, clientSession);
});
await pair.CleanReturnAsync();
}
} }
} }
@@ -1,5 +1,6 @@
using System.Numerics; using System.Numerics;
using Content.Client.Clickable; using Content.Client.Clickable;
using Content.IntegrationTests.Fixtures;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -7,7 +8,7 @@ using Robust.Shared.GameObjects;
namespace Content.IntegrationTests.Tests namespace Content.IntegrationTests.Tests
{ {
[TestFixture] [TestFixture]
public sealed class ClickableTest public sealed class ClickableTest : GameTest
{ {
private const double DirSouth = 0; private const double DirSouth = 0;
private const double DirNorth = Math.PI; private const double DirNorth = Math.PI;
@@ -44,7 +45,7 @@ namespace Content.IntegrationTests.Tests
[TestCase("ClickTestRotatingCornerInvisibleNoRot", 0.25f, 0.25f, DirSouthEastJustShy, 1, ExpectedResult = true)] [TestCase("ClickTestRotatingCornerInvisibleNoRot", 0.25f, 0.25f, DirSouthEastJustShy, 1, ExpectedResult = true)]
public async Task<bool> Test(string prototype, float clickPosX, float clickPosY, double angle, float scale) public async Task<bool> Test(string prototype, float clickPosX, float clickPosY, double angle, float scale)
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true }); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var client = pair.Client; var client = pair.Client;
@@ -66,7 +67,7 @@ namespace Content.IntegrationTests.Tests
}); });
// Let client sync up. // Let client sync up.
await pair.RunTicksSync(5); await RunUntilSynced();
var hit = false; var hit = false;
var clientEnt = clientEntManager.GetEntity(serverEntManager.GetNetEntity(serverEnt)); var clientEnt = clientEntManager.GetEntity(serverEntManager.GetNetEntity(serverEnt));
@@ -89,8 +90,6 @@ namespace Content.IntegrationTests.Tests
serverEntManager.DeleteEntity(serverEnt); serverEntManager.DeleteEntity(serverEnt);
}); });
await pair.CleanReturnAsync();
return hit; return hit;
} }
} }
@@ -1,8 +1,9 @@
using Content.IntegrationTests.Fixtures;
using Content.Shared.Cloning; using Content.Shared.Cloning;
namespace Content.IntegrationTests.Tests.Cloning; namespace Content.IntegrationTests.Tests.Cloning;
public sealed class CloningSettingsPrototypeTest public sealed class CloningSettingsPrototypeTest : GameTest
{ {
/// <summary> /// <summary>
/// Checks that the components named in every <see cref="CloningSettingsPrototype"/> are valid components known to the server. /// Checks that the components named in every <see cref="CloningSettingsPrototype"/> are valid components known to the server.
@@ -12,7 +13,7 @@ public sealed class CloningSettingsPrototypeTest
[Test] [Test]
public async Task ValidatePrototypes() public async Task ValidatePrototypes()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var protoMan = server.ProtoMan; var protoMan = server.ProtoMan;
var compFactory = server.EntMan.ComponentFactory; var compFactory = server.EntMan.ComponentFactory;
@@ -40,7 +41,5 @@ public sealed class CloningSettingsPrototypeTest
} }
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.Server.Maps; using Content.Server.Maps;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
@@ -6,7 +7,7 @@ using Robust.Shared.Console;
namespace Content.IntegrationTests.Tests.Commands; namespace Content.IntegrationTests.Tests.Commands;
[TestFixture] [TestFixture]
public sealed class ForceMapTest public sealed class ForceMapTest : GameTest
{ {
private const string DefaultMapName = "Empty"; private const string DefaultMapName = "Empty";
private const string BadMapName = "asdf_asd-fa__sdfAsd_f"; // Hopefully no one ever names a map this... private const string BadMapName = "asdf_asd-fa__sdfAsd_f"; // Hopefully no one ever names a map this...
@@ -44,7 +45,7 @@ public sealed class ForceMapTest
[Test] [Test]
public async Task TestForceMapCommand() public async Task TestForceMapCommand()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entMan = server.EntMan; var entMan = server.EntMan;
@@ -82,7 +83,5 @@ public sealed class ForceMapTest
// Cleanup // Cleanup
configManager.SetCVar(CCVars.GameMap, DefaultMapName); configManager.SetCVar(CCVars.GameMap, DefaultMapName);
await pair.CleanReturnAsync();
} }
} }
@@ -1,5 +1,6 @@
#nullable enable #nullable enable
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.Server.Objectives; using Content.Server.Objectives;
using Content.Shared.Mind; using Content.Shared.Mind;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -7,7 +8,7 @@ using Robust.Shared.Player;
namespace Content.IntegrationTests.Tests.Commands; namespace Content.IntegrationTests.Tests.Commands;
public sealed class ObjectiveCommandsTest public sealed class ObjectiveCommandsTest : GameTest
{ {
private const string ObjectiveProtoId = "MindCommandsTestObjective"; private const string ObjectiveProtoId = "MindCommandsTestObjective";
@@ -27,6 +28,11 @@ public sealed class ObjectiveCommandsTest
- type: DieCondition - type: DieCondition
"""; """;
public override PoolSettings PoolSettings => new ()
{
Connected = false
};
/// <summary> /// <summary>
/// Creates a dummy session, and assigns it a mind, then /// Creates a dummy session, and assigns it a mind, then
/// tests using <c>addobjective</c>, <c>lsobjectives</c>, /// tests using <c>addobjective</c>, <c>lsobjectives</c>,
@@ -35,7 +41,7 @@ public sealed class ObjectiveCommandsTest
[Test] [Test]
public async Task AddListRemoveObjectiveTest() public async Task AddListRemoveObjectiveTest()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entMan = server.EntMan; var entMan = server.EntMan;
var playerMan = server.ResolveDependency<ISharedPlayerManager>(); var playerMan = server.ResolveDependency<ISharedPlayerManager>();
@@ -66,7 +72,5 @@ public sealed class ObjectiveCommandsTest
await pair.WaitCommand($"rmobjective {playerSession.Name} 0"); await pair.WaitCommand($"rmobjective {playerSession.Name} 0");
Assert.That(mindComp.Objectives, Is.Empty, "rmobjective failed to remove objective"); Assert.That(mindComp.Objectives, Is.Empty, "rmobjective failed to remove objective");
await pair.CleanReturnAsync();
} }
} }
@@ -1,4 +1,5 @@
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.Server.Database; using Content.Server.Database;
using Robust.Server.Console; using Robust.Server.Console;
using Robust.Server.Player; using Robust.Server.Player;
@@ -8,14 +9,14 @@ namespace Content.IntegrationTests.Tests.Commands
{ {
[TestFixture] [TestFixture]
[TestOf(typeof(PardonCommand))] [TestOf(typeof(PardonCommand))]
public sealed class PardonCommand public sealed class PardonCommand : GameTest
{ {
private static readonly TimeSpan MarginOfError = TimeSpan.FromMinutes(1); private static readonly TimeSpan MarginOfError = TimeSpan.FromMinutes(1);
[Test] [Test]
public async Task PardonTest() public async Task PardonTest()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true }); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var client = pair.Client; var client = pair.Client;
@@ -148,8 +149,6 @@ namespace Content.IntegrationTests.Tests.Commands
await client.WaitPost(() => netMan.ClientConnect(null!, 0, null!)); await client.WaitPost(() => netMan.ClientConnect(null!, 0, null!));
await pair.RunTicksSync(5); await pair.RunTicksSync(5);
Assert.That(sPlayerManager.Sessions, Has.Length.EqualTo(1)); Assert.That(sPlayerManager.Sessions, Has.Length.EqualTo(1));
await pair.CleanReturnAsync();
} }
} }
} }
@@ -1,4 +1,5 @@
using Content.Shared.Administration.Systems; using Content.IntegrationTests.Fixtures;
using Content.Shared.Administration.Systems;
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.Damage.Components; using Content.Shared.Damage.Components;
using Content.Shared.Damage.Prototypes; using Content.Shared.Damage.Prototypes;
@@ -14,7 +15,7 @@ namespace Content.IntegrationTests.Tests.Commands
{ {
[TestFixture] [TestFixture]
[TestOf(typeof(RejuvenateSystem))] [TestOf(typeof(RejuvenateSystem))]
public sealed class RejuvenateTest public sealed class RejuvenateTest : GameTest
{ {
private static readonly ProtoId<DamageGroupPrototype> TestDamageGroup = "Toxin"; private static readonly ProtoId<DamageGroupPrototype> TestDamageGroup = "Toxin";
@@ -36,7 +37,7 @@ namespace Content.IntegrationTests.Tests.Commands
[Test] [Test]
public async Task RejuvenateDeadTest() public async Task RejuvenateDeadTest()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var entManager = server.ResolveDependency<IEntityManager>(); var entManager = server.ResolveDependency<IEntityManager>();
var prototypeManager = server.ResolveDependency<IPrototypeManager>(); var prototypeManager = server.ResolveDependency<IPrototypeManager>();
@@ -92,7 +93,6 @@ namespace Content.IntegrationTests.Tests.Commands
Assert.That(damSystem.GetTotalDamage((human, damageable)), Is.EqualTo(FixedPoint2.Zero)); Assert.That(damSystem.GetTotalDamage((human, damageable)), Is.EqualTo(FixedPoint2.Zero));
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
} }
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Server.GameTicking.Commands; using Content.Server.GameTicking.Commands;
using Content.Shared.CCVar; using Content.Shared.CCVar;
@@ -10,25 +11,27 @@ namespace Content.IntegrationTests.Tests.Commands
{ {
[TestFixture] [TestFixture]
[TestOf(typeof(RestartRoundNowCommand))] [TestOf(typeof(RestartRoundNowCommand))]
public sealed class RestartRoundNowTest public sealed class RestartRoundNowTest : GameTest
{ {
public override PoolSettings PoolSettings => new PoolSettings
{
DummyTicker = false,
Dirty = true
};
[Test] [Test]
[TestCase(true)] [TestCase(true)]
[TestCase(false)] [TestCase(false)]
public async Task RestartRoundAfterStart(bool lobbyEnabled) public async Task RestartRoundAfterStart(bool lobbyEnabled)
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings var pair = Pair;
{
DummyTicker = false,
Dirty = true
});
var server = pair.Server; var server = pair.Server;
var configManager = server.ResolveDependency<IConfigurationManager>(); var configManager = server.ResolveDependency<IConfigurationManager>();
var entityManager = server.ResolveDependency<IEntityManager>(); var entityManager = server.ResolveDependency<IEntityManager>();
var gameTicker = entityManager.System<GameTicker>(); var gameTicker = entityManager.System<GameTicker>();
await pair.RunTicksSync(5); await pair.RunUntilSynced();
GameTick tickBeforeRestart = default; GameTick tickBeforeRestart = default;
@@ -58,8 +61,7 @@ namespace Content.IntegrationTests.Tests.Commands
Assert.That(tickBeforeRestart, Is.LessThan(tickAfterRestart)); Assert.That(tickBeforeRestart, Is.LessThan(tickAfterRestart));
}); });
await pair.RunTicksSync(5); await pair.RunUntilSynced();
await pair.CleanReturnAsync();
} }
} }
} }
@@ -1,4 +1,5 @@
using System.Linq; using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.Damage.Components; using Content.Shared.Damage.Components;
using Content.Shared.Damage.Prototypes; using Content.Shared.Damage.Prototypes;
@@ -21,7 +22,7 @@ using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests.Commands; namespace Content.IntegrationTests.Tests.Commands;
[TestFixture] [TestFixture]
public sealed class SuicideCommandTests public sealed class SuicideCommandTests : GameTest
{ {
[TestPrototypes] [TestPrototypes]
@@ -57,6 +58,13 @@ public sealed class SuicideCommandTests
private static readonly ProtoId<TagPrototype> CannotSuicideTag = "CannotSuicide"; private static readonly ProtoId<TagPrototype> CannotSuicideTag = "CannotSuicide";
private static readonly ProtoId<DamageTypePrototype> DamageType = "Slash"; private static readonly ProtoId<DamageTypePrototype> DamageType = "Slash";
public override PoolSettings PoolSettings => new PoolSettings
{
Connected = true,
Dirty = true,
DummyTicker = false
};
/// <summary> /// <summary>
/// Run the suicide command in the console /// Run the suicide command in the console
/// Should successfully kill the player and ghost them /// Should successfully kill the player and ghost them
@@ -64,12 +72,7 @@ public sealed class SuicideCommandTests
[Test] [Test]
public async Task TestSuicide() public async Task TestSuicide()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings var pair = Pair;
{
Connected = true,
Dirty = true,
DummyTicker = false
});
var server = pair.Server; var server = pair.Server;
var consoleHost = server.ResolveDependency<IConsoleHost>(); var consoleHost = server.ResolveDependency<IConsoleHost>();
var entManager = server.ResolveDependency<IEntityManager>(); var entManager = server.ResolveDependency<IEntityManager>();
@@ -104,8 +107,6 @@ public sealed class SuicideCommandTests
!ghostComp.CanReturnToBody); !ghostComp.CanReturnToBody);
}); });
}); });
await pair.CleanReturnAsync();
} }
/// <summary> /// <summary>
@@ -115,12 +116,7 @@ public sealed class SuicideCommandTests
[Test] [Test]
public async Task TestSuicideWhileDamaged() public async Task TestSuicideWhileDamaged()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings var pair = Pair;
{
Connected = true,
Dirty = true,
DummyTicker = false
});
var server = pair.Server; var server = pair.Server;
var consoleHost = server.ResolveDependency<IConsoleHost>(); var consoleHost = server.ResolveDependency<IConsoleHost>();
var entManager = server.ResolveDependency<IEntityManager>(); var entManager = server.ResolveDependency<IEntityManager>();
@@ -166,8 +162,6 @@ public sealed class SuicideCommandTests
Assert.That(damageableSystem.GetTotalDamage(player), Is.EqualTo(lethalDamageThreshold)); Assert.That(damageableSystem.GetTotalDamage(player), Is.EqualTo(lethalDamageThreshold));
}); });
}); });
await pair.CleanReturnAsync();
} }
/// <summary> /// <summary>
@@ -177,12 +171,7 @@ public sealed class SuicideCommandTests
[Test] [Test]
public async Task TestSuicideWhenCannotSuicide() public async Task TestSuicideWhenCannotSuicide()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings var pair = Pair;
{
Connected = true,
Dirty = true,
DummyTicker = false
});
var server = pair.Server; var server = pair.Server;
var consoleHost = server.ResolveDependency<IConsoleHost>(); var consoleHost = server.ResolveDependency<IConsoleHost>();
var entManager = server.ResolveDependency<IEntityManager>(); var entManager = server.ResolveDependency<IEntityManager>();
@@ -217,8 +206,6 @@ public sealed class SuicideCommandTests
!ghostComp.CanReturnToBody); !ghostComp.CanReturnToBody);
}); });
}); });
await pair.CleanReturnAsync();
} }
@@ -228,12 +215,7 @@ public sealed class SuicideCommandTests
[Test] [Test]
public async Task TestSuicideByHeldItem() public async Task TestSuicideByHeldItem()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings var pair = Pair;
{
Connected = true,
Dirty = true,
DummyTicker = false
});
var server = pair.Server; var server = pair.Server;
var consoleHost = server.ResolveDependency<IConsoleHost>(); var consoleHost = server.ResolveDependency<IConsoleHost>();
var entManager = server.ResolveDependency<IEntityManager>(); var entManager = server.ResolveDependency<IEntityManager>();
@@ -292,8 +274,6 @@ public sealed class SuicideCommandTests
Assert.That(damageableSystem.GetAllDamage((player, damageableComp)).DamageDict["Slash"], Is.EqualTo(lethalDamageThreshold)); Assert.That(damageableSystem.GetAllDamage((player, damageableComp)).DamageDict["Slash"], Is.EqualTo(lethalDamageThreshold));
}); });
}); });
await pair.CleanReturnAsync();
} }
/// <summary> /// <summary>
@@ -303,12 +283,7 @@ public sealed class SuicideCommandTests
[Test] [Test]
public async Task TestSuicideByHeldItemSpreadDamage() public async Task TestSuicideByHeldItemSpreadDamage()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings var pair = Pair;
{
Connected = true,
Dirty = true,
DummyTicker = false
});
var server = pair.Server; var server = pair.Server;
var consoleHost = server.ResolveDependency<IConsoleHost>(); var consoleHost = server.ResolveDependency<IConsoleHost>();
var entManager = server.ResolveDependency<IEntityManager>(); var entManager = server.ResolveDependency<IEntityManager>();
@@ -367,7 +342,5 @@ public sealed class SuicideCommandTests
Assert.That(damageableSystem.GetAllDamage((player, damageableComp)).DamageDict["Slash"], Is.EqualTo(lethalDamageThreshold / 2)); Assert.That(damageableSystem.GetAllDamage((player, damageableComp)).DamageDict["Slash"], Is.EqualTo(lethalDamageThreshold / 2));
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Content.IntegrationTests.Fixtures;
using Content.Server.Entry; using Content.Server.Entry;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.ContentPack; using Robust.Shared.ContentPack;
@@ -7,12 +8,12 @@ using Robust.Shared.ContentPack;
namespace Content.IntegrationTests.Tests; namespace Content.IntegrationTests.Tests;
[TestFixture] [TestFixture]
public sealed class ConfigPresetTests public sealed class ConfigPresetTests : GameTest
{ {
[Test] [Test]
public async Task TestLoadAll() public async Task TestLoadAll()
{ {
var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var resources = server.ResolveDependency<IResourceManager>(); var resources = server.ResolveDependency<IResourceManager>();
@@ -70,7 +71,5 @@ public sealed class ConfigPresetTests
Assert.Fail($"CVar {name} was not reset to its original value."); Assert.Fail($"CVar {name} was not reset to its original value.");
} }
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,4 +1,5 @@
using System.Text; using System.Text;
using Content.IntegrationTests.Fixtures;
using Content.Server.Construction.Completions; using Content.Server.Construction.Completions;
using Content.Shared.Construction; using Content.Shared.Construction;
using Content.Shared.Construction.Prototypes; using Content.Shared.Construction.Prototypes;
@@ -7,7 +8,7 @@ using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests.Construction namespace Content.IntegrationTests.Tests.Construction
{ {
[TestFixture] [TestFixture]
public sealed class ConstructionActionValid public sealed class ConstructionActionValid : GameTest
{ {
private bool IsValid(IGraphAction action, IPrototypeManager protoMan, out string prototype) private bool IsValid(IGraphAction action, IPrototypeManager protoMan, out string prototype)
{ {
@@ -47,7 +48,7 @@ namespace Content.IntegrationTests.Tests.Construction
[Test] [Test]
public async Task ConstructionGraphSpawnPrototypeValid() public async Task ConstructionGraphSpawnPrototypeValid()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>(); var protoMan = server.ResolveDependency<IPrototypeManager>();
@@ -84,13 +85,12 @@ namespace Content.IntegrationTests.Tests.Construction
}); });
Assert.That(valid, Is.True, $"One or more SpawnPrototype actions specified invalid entity prototypes!\n{message}"); Assert.That(valid, Is.True, $"One or more SpawnPrototype actions specified invalid entity prototypes!\n{message}");
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task ConstructionGraphEdgeValid() public async Task ConstructionGraphEdgeValid()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>(); var protoMan = server.ResolveDependency<IPrototypeManager>();
@@ -118,7 +118,6 @@ namespace Content.IntegrationTests.Tests.Construction
}); });
Assert.That(valid, Is.True, $"One or more edges specified invalid node targets!\n{message}"); Assert.That(valid, Is.True, $"One or more edges specified invalid node targets!\n{message}");
await pair.CleanReturnAsync();
} }
} }
} }
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.IntegrationTests.Utility; using Content.IntegrationTests.Utility;
using Content.Server.Construction.Components; using Content.Server.Construction.Components;
using Content.Shared.Construction.Prototypes; using Content.Shared.Construction.Prototypes;
@@ -7,7 +8,7 @@ using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests.Construction namespace Content.IntegrationTests.Tests.Construction
{ {
[TestFixture] [TestFixture]
public sealed class ConstructionPrototypeTest public sealed class ConstructionPrototypeTest : GameTest
{ {
// discount linter for construction graphs // discount linter for construction graphs
// TODO: Create serialization validators for these? // TODO: Create serialization validators for these?
@@ -25,7 +26,7 @@ namespace Content.IntegrationTests.Tests.Construction
[Description("Tests that a given entity specifies a valid node for construction, and optionally a valid one for deconstruction.")] [Description("Tests that a given entity specifies a valid node for construction, and optionally a valid one for deconstruction.")]
public async Task ConstructionComponentValid(string protoKey) public async Task ConstructionComponentValid(string protoKey)
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>(); var protoMan = server.ResolveDependency<IPrototypeManager>();
@@ -49,8 +50,6 @@ namespace Content.IntegrationTests.Tests.Construction
$"Invalid deconstruction node \"{target}\" on graph \"{graph.ID}\" for construction entity \"{proto.ID}\"!"); $"Invalid deconstruction node \"{target}\" on graph \"{graph.ID}\" for construction entity \"{proto.ID}\"!");
} }
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
@@ -59,7 +58,7 @@ namespace Content.IntegrationTests.Tests.Construction
[Description("Tests that a given construction prototype has a valid starting and target node, and a valid path between them.")] [Description("Tests that a given construction prototype has a valid starting and target node, and a valid path between them.")]
public async Task ConstructionFormsValidGraph(string protoKey) public async Task ConstructionFormsValidGraph(string protoKey)
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>(); var protoMan = server.ResolveDependency<IPrototypeManager>();
@@ -95,7 +94,6 @@ namespace Content.IntegrationTests.Tests.Construction
$"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) specified an entity prototype ({next.Entity}) without a ConstructionComponent."); $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) specified an entity prototype ({next.Entity}) without a ConstructionComponent.");
#pragma warning restore NUnit2045 #pragma warning restore NUnit2045
}); });
await pair.CleanReturnAsync();
} }
} }
} }
@@ -1,4 +1,5 @@
using System.Numerics; using System.Numerics;
using Content.IntegrationTests.Fixtures;
using Content.Server.Storage.EntitySystems; using Content.Server.Storage.EntitySystems;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -7,7 +8,7 @@ using Robust.Shared.Maths;
namespace Content.IntegrationTests.Tests namespace Content.IntegrationTests.Tests
{ {
public sealed class ContainerOcclusionTest public sealed class ContainerOcclusionTest : GameTest
{ {
[TestPrototypes] [TestPrototypes]
private const string Prototypes = @" private const string Prototypes = @"
@@ -34,7 +35,7 @@ namespace Content.IntegrationTests.Tests
[Test] [Test]
public async Task TestA() public async Task TestA()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true }); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var client = pair.Client; var client = pair.Client;
@@ -69,14 +70,12 @@ namespace Content.IntegrationTests.Tests
Assert.That(light.ContainerOccluded); Assert.That(light.ContainerOccluded);
}); });
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task TestB() public async Task TestB()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true }); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var client = pair.Client; var client = pair.Client;
@@ -112,14 +111,12 @@ namespace Content.IntegrationTests.Tests
Assert.That(light.ContainerOccluded, Is.False); Assert.That(light.ContainerOccluded, Is.False);
}); });
}); });
await pair.CleanReturnAsync();
} }
[Test] [Test]
public async Task TestAb() public async Task TestAb()
{ {
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true }); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var client = pair.Client; var client = pair.Client;
@@ -157,8 +154,6 @@ namespace Content.IntegrationTests.Tests
Assert.That(light.ContainerOccluded); Assert.That(light.ContainerOccluded);
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
} }
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.Shared.Contraband; using Content.Shared.Contraband;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -5,12 +6,12 @@ using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests; namespace Content.IntegrationTests.Tests;
[TestFixture] [TestFixture]
public sealed class ContrabandTest public sealed class ContrabandTest : GameTest
{ {
[Test] [Test]
public async Task EntityShowDepartmentsAndJobs() public async Task EntityShowDepartmentsAndJobs()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var client = pair.Client; var client = pair.Client;
var protoMan = client.ResolveDependency<IPrototypeManager>(); var protoMan = client.ResolveDependency<IPrototypeManager>();
var componentFactory = client.ResolveDependency<IComponentFactory>(); var componentFactory = client.ResolveDependency<IComponentFactory>();
@@ -41,7 +42,5 @@ public sealed class ContrabandTest
} }
}); });
}); });
await pair.CleanReturnAsync();
} }
} }
@@ -1,3 +1,4 @@
using Content.IntegrationTests.Fixtures;
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.Damage.Components; using Content.Shared.Damage.Components;
using Content.Shared.Damage.Prototypes; using Content.Shared.Damage.Prototypes;
@@ -12,7 +13,7 @@ namespace Content.IntegrationTests.Tests.Damageable
[TestFixture] [TestFixture]
[TestOf(typeof(DamageableComponent))] [TestOf(typeof(DamageableComponent))]
[TestOf(typeof(DamageableSystem))] [TestOf(typeof(DamageableSystem))]
public sealed class DamageableTest public sealed class DamageableTest : GameTest
{ {
private const string TestDamageableEntityId = "TestDamageableEntityId"; private const string TestDamageableEntityId = "TestDamageableEntityId";
private const string TestGroup1 = "TestGroup1"; private const string TestGroup1 = "TestGroup1";
@@ -95,7 +96,7 @@ namespace Content.IntegrationTests.Tests.Damageable
[Test] [Test]
public async Task TestDamageableComponents() public async Task TestDamageableComponents()
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var sEntityManager = server.ResolveDependency<IEntityManager>(); var sEntityManager = server.ResolveDependency<IEntityManager>();
@@ -254,7 +255,6 @@ namespace Content.IntegrationTests.Tests.Damageable
sDamageableSystem.ChangeDamage(uid, new DamageSpecifier(group3, -100)); sDamageableSystem.ChangeDamage(uid, new DamageSpecifier(group3, -100));
Assert.That(sDamageableSystem.GetTotalDamage(ent), Is.EqualTo(FixedPoint2.Zero)); Assert.That(sDamageableSystem.GetTotalDamage(ent), Is.EqualTo(FixedPoint2.Zero));
}); });
await pair.CleanReturnAsync();
} }
} }
} }
@@ -1,10 +1,11 @@
using Content.IntegrationTests.Fixtures;
using Content.IntegrationTests.Utility; using Content.IntegrationTests.Utility;
using Content.Shared.Alert; using Content.Shared.Alert;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
namespace Content.IntegrationTests.Tests.Damageable; namespace Content.IntegrationTests.Tests.Damageable;
public sealed class MobThresholdsTest public sealed class MobThresholdsTest : GameTest
{ {
private static string[] _entitiesWithThresholds = GameDataScrounger.EntitiesWithComponent("MobThresholds"); private static string[] _entitiesWithThresholds = GameDataScrounger.EntitiesWithComponent("MobThresholds");
@@ -14,7 +15,7 @@ public sealed class MobThresholdsTest
[Description("Ensures every entity with mob thresholds has valid mob state configuration corresponding to some AlertPrototype.")] [Description("Ensures every entity with mob thresholds has valid mob state configuration corresponding to some AlertPrototype.")]
public async Task ValidateMobThresholds(string protoKey) public async Task ValidateMobThresholds(string protoKey)
{ {
await using var pair = await PoolManager.GetServerClient(); var pair = Pair;
var server = pair.Server; var server = pair.Server;
var protoMan = server.ProtoMan; var protoMan = server.ProtoMan;
@@ -33,7 +34,5 @@ public sealed class MobThresholdsTest
Assert.That(alertStates, Does.Contain(state), $"{proto.ID} does not have an alert state for mob state {state}"); Assert.That(alertStates, Does.Contain(state), $"{proto.ID} does not have an alert state for mob state {state}");
} }
}); });
await pair.CleanReturnAsync();
} }
} }

Some files were not shown because too many files have changed in this diff Show More