diff --git a/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs b/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs index eede3a6217..d60094ad89 100644 --- a/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs +++ b/Content.Client/Administration/UI/SpawnExplosion/ExplosionDebugOverlay.cs @@ -25,7 +25,7 @@ public sealed class ExplosionDebugOverlay : Overlay public override OverlaySpace Space => OverlaySpace.WorldSpace | OverlaySpace.ScreenSpace; - public Matrix3 SpaceMatrix; + public Matrix3x2 SpaceMatrix; public MapId Map; private readonly Font _font; @@ -78,7 +78,8 @@ private void DrawScreen(OverlayDrawArgs args) if (SpaceTiles == null) return; - gridBounds = Matrix3.Invert(SpaceMatrix).TransformBox(args.WorldBounds); + Matrix3x2.Invert(SpaceMatrix, out var invSpace); + gridBounds = invSpace.TransformBox(args.WorldBounds); DrawText(handle, gridBounds, SpaceMatrix, SpaceTiles, SpaceTileSize); } @@ -86,7 +87,7 @@ private void DrawScreen(OverlayDrawArgs args) private void DrawText( DrawingHandleScreen handle, Box2 gridBounds, - Matrix3 transform, + Matrix3x2 transform, Dictionary> tileSets, ushort tileSize) { @@ -103,7 +104,7 @@ private void DrawText( if (!gridBounds.Contains(centre)) continue; - var worldCenter = transform.Transform(centre); + var worldCenter = Vector2.Transform(centre, transform); var screenCenter = _eyeManager.WorldToScreen(worldCenter); @@ -119,7 +120,7 @@ private void DrawText( if (tileSets.TryGetValue(0, out var set)) { var epicenter = set.First(); - var worldCenter = transform.Transform((epicenter + Vector2Helpers.Half) * tileSize); + var worldCenter = Vector2.Transform((epicenter + Vector2Helpers.Half) * tileSize, transform); var screenCenter = _eyeManager.WorldToScreen(worldCenter) + new Vector2(-24, -24); var text = $"{Intensity[0]:F2}\nΣ={TotalIntensity:F1}\nΔ={Slope:F1}"; handle.DrawString(_font, screenCenter, text); @@ -148,11 +149,12 @@ private void DrawWorld(in OverlayDrawArgs args) if (SpaceTiles == null) return; - gridBounds = Matrix3.Invert(SpaceMatrix).TransformBox(args.WorldBounds).Enlarged(2); + Matrix3x2.Invert(SpaceMatrix, out var invSpace); + gridBounds = invSpace.TransformBox(args.WorldBounds).Enlarged(2); handle.SetTransform(SpaceMatrix); DrawTiles(handle, gridBounds, SpaceTiles, SpaceTileSize); - handle.SetTransform(Matrix3.Identity); + handle.SetTransform(Matrix3x2.Identity); } private void DrawTiles( diff --git a/Content.Client/Atmos/EntitySystems/GasTileOverlaySystem.cs b/Content.Client/Atmos/EntitySystems/GasTileOverlaySystem.cs index 78185ce6b0..86cf0a9eb8 100644 --- a/Content.Client/Atmos/EntitySystems/GasTileOverlaySystem.cs +++ b/Content.Client/Atmos/EntitySystems/GasTileOverlaySystem.cs @@ -1,4 +1,5 @@ using Content.Client.Atmos.Overlays; +using Content.Shared.Atmos; using Content.Shared.Atmos.Components; using Content.Shared.Atmos.EntitySystems; using JetBrains.Annotations; @@ -36,28 +37,38 @@ public override void Shutdown() private void OnHandleState(EntityUid gridUid, GasTileOverlayComponent comp, ref ComponentHandleState args) { - if (args.Current is not GasTileOverlayState state) - return; + Dictionary modifiedChunks; - // is this a delta or full state? - if (!state.FullState) + switch (args.Current) { - foreach (var index in comp.Chunks.Keys) + // is this a delta or full state? + case GasTileOverlayDeltaState delta: { - if (!state.AllChunks!.Contains(index)) - comp.Chunks.Remove(index); + modifiedChunks = delta.ModifiedChunks; + foreach (var index in comp.Chunks.Keys) + { + if (!delta.AllChunks.Contains(index)) + comp.Chunks.Remove(index); + } + + break; } - } - else - { - foreach (var index in comp.Chunks.Keys) + case GasTileOverlayState state: { - if (!state.Chunks.ContainsKey(index)) - comp.Chunks.Remove(index); + modifiedChunks = state.Chunks; + foreach (var index in comp.Chunks.Keys) + { + if (!state.Chunks.ContainsKey(index)) + comp.Chunks.Remove(index); + } + + break; } + default: + return; } - foreach (var (index, data) in state.Chunks) + foreach (var (index, data) in modifiedChunks) { comp.Chunks[index] = data; } diff --git a/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs b/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs index 6dfbc326ec..c85dbd2051 100644 --- a/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs +++ b/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs @@ -66,7 +66,7 @@ protected override void Draw(in OverlayDrawArgs args) DrawData(msg, handle); } - handle.SetTransform(Matrix3.Identity); + handle.SetTransform(Matrix3x2.Identity); } private void DrawData(DebugMessage msg, diff --git a/Content.Client/Atmos/Overlays/GasTileOverlay.cs b/Content.Client/Atmos/Overlays/GasTileOverlay.cs index f4dc274a4e..17027525e5 100644 --- a/Content.Client/Atmos/Overlays/GasTileOverlay.cs +++ b/Content.Client/Atmos/Overlays/GasTileOverlay.cs @@ -190,7 +190,7 @@ protected override void Draw(in OverlayDrawArgs args) var (_, _, worldMatrix, invMatrix) = gridXform.GetWorldPositionRotationMatrixWithInv(); state.drawHandle.SetTransform(worldMatrix); - var floatBounds = invMatrix.TransformBox(in state.WorldBounds).Enlarged(grid.TileSize); + var floatBounds = invMatrix.TransformBox(state.WorldBounds).Enlarged(grid.TileSize); var localBounds = new Box2i( (int) MathF.Floor(floatBounds.Left), (int) MathF.Floor(floatBounds.Bottom), @@ -249,7 +249,7 @@ protected override void Draw(in OverlayDrawArgs args) }); drawHandle.UseShader(null); - drawHandle.SetTransform(Matrix3.Identity); + drawHandle.SetTransform(Matrix3x2.Identity); } private void DrawMapOverlay( diff --git a/Content.Client/Clickable/ClickableComponent.cs b/Content.Client/Clickable/ClickableComponent.cs index cfbd1a99d6..6f75df4683 100644 --- a/Content.Client/Clickable/ClickableComponent.cs +++ b/Content.Client/Clickable/ClickableComponent.cs @@ -38,9 +38,9 @@ public bool CheckClick(SpriteComponent sprite, TransformComponent transform, Ent renderOrder = sprite.RenderOrder; var (spritePos, spriteRot) = transform.GetWorldPositionRotation(xformQuery); var spriteBB = sprite.CalculateRotatedBoundingBox(spritePos, spriteRot, eye.Rotation); - bottom = Matrix3.CreateRotation(eye.Rotation).TransformBox(spriteBB).Bottom; + bottom = Matrix3Helpers.CreateRotation(eye.Rotation).TransformBox(spriteBB).Bottom; - var invSpriteMatrix = Matrix3.Invert(sprite.GetLocalMatrix()); + Matrix3x2.Invert(sprite.GetLocalMatrix(), out var invSpriteMatrix); // This should have been the rotation of the sprite relative to the screen, but this is not the case with no-rot or directional sprites. var relativeRotation = (spriteRot + eye.Rotation).Reduced().FlipPositive(); @@ -48,8 +48,8 @@ public bool CheckClick(SpriteComponent sprite, TransformComponent transform, Ent Angle cardinalSnapping = sprite.SnapCardinals ? relativeRotation.GetCardinalDir().ToAngle() : Angle.Zero; // First we get `localPos`, the clicked location in the sprite-coordinate frame. - var entityXform = Matrix3.CreateInverseTransform(transform.WorldPosition, sprite.NoRotation ? -eye.Rotation : spriteRot - cardinalSnapping); - var localPos = invSpriteMatrix.Transform(entityXform.Transform(worldPos)); + var entityXform = Matrix3Helpers.CreateInverseTransform(transform.WorldPosition, sprite.NoRotation ? -eye.Rotation : spriteRot - cardinalSnapping); + var localPos = Vector2.Transform(Vector2.Transform(worldPos, entityXform), invSpriteMatrix); // Check explicitly defined click-able bounds if (CheckDirBound(sprite, relativeRotation, localPos)) @@ -79,8 +79,8 @@ public bool CheckClick(SpriteComponent sprite, TransformComponent transform, Ent // convert to layer-local coordinates layer.GetLayerDrawMatrix(dir, out var matrix); - var inverseMatrix = Matrix3.Invert(matrix); - var layerLocal = inverseMatrix.Transform(localPos); + Matrix3x2.Invert(matrix, out var inverseMatrix); + var layerLocal = Vector2.Transform(localPos, inverseMatrix); // Convert to image coordinates var layerImagePos = (Vector2i) (layerLocal * EyeManager.PixelsPerMeter * new Vector2(1, -1) + rsiState.Size / 2f); diff --git a/Content.Client/Decals/DecalSystem.cs b/Content.Client/Decals/DecalSystem.cs index 901ab270fb..41e5f39c28 100644 --- a/Content.Client/Decals/DecalSystem.cs +++ b/Content.Client/Decals/DecalSystem.cs @@ -56,34 +56,43 @@ protected override void OnDecalRemoved(EntityUid gridId, uint decalId, DecalGrid private void OnHandleState(EntityUid gridUid, DecalGridComponent gridComp, ref ComponentHandleState args) { - if (args.Current is not DecalGridState state) - return; - // is this a delta or full state? _removedChunks.Clear(); + Dictionary modifiedChunks; - if (!state.FullState) + switch (args.Current) { - foreach (var key in gridComp.ChunkCollection.ChunkCollection.Keys) + case DecalGridDeltaState delta: { - if (!state.AllChunks!.Contains(key)) - _removedChunks.Add(key); + modifiedChunks = delta.ModifiedChunks; + foreach (var key in gridComp.ChunkCollection.ChunkCollection.Keys) + { + if (!delta.AllChunks.Contains(key)) + _removedChunks.Add(key); + } + + break; } - } - else - { - foreach (var key in gridComp.ChunkCollection.ChunkCollection.Keys) + case DecalGridState state: { - if (!state.Chunks.ContainsKey(key)) - _removedChunks.Add(key); + modifiedChunks = state.Chunks; + foreach (var key in gridComp.ChunkCollection.ChunkCollection.Keys) + { + if (!state.Chunks.ContainsKey(key)) + _removedChunks.Add(key); + } + + break; } + default: + return; } if (_removedChunks.Count > 0) RemoveChunks(gridUid, gridComp, _removedChunks); - if (state.Chunks.Count > 0) - UpdateChunks(gridUid, gridComp, state.Chunks); + if (modifiedChunks.Count > 0) + UpdateChunks(gridUid, gridComp, modifiedChunks); } private void OnChunkUpdate(DecalChunkUpdateEvent ev) diff --git a/Content.Client/Decals/Overlays/DecalOverlay.cs b/Content.Client/Decals/Overlays/DecalOverlay.cs index d9904ae80b..0de3301e58 100644 --- a/Content.Client/Decals/Overlays/DecalOverlay.cs +++ b/Content.Client/Decals/Overlays/DecalOverlay.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Shared.Decals; using Robust.Client.GameObjects; using Robust.Client.Graphics; @@ -113,7 +114,7 @@ protected override void Draw(in OverlayDrawArgs args) handle.DrawTexture(cache.Texture, decal.Coordinates, angle, decal.Color); } - handle.SetTransform(Matrix3.Identity); + handle.SetTransform(Matrix3x2.Identity); } } } diff --git a/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs b/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs index be277448ed..845bd7c03d 100644 --- a/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs +++ b/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs @@ -51,7 +51,7 @@ protected override void Draw(in OverlayDrawArgs args) var handle = args.WorldHandle; handle.SetTransform(worldMatrix); - var localPos = invMatrix.Transform(mousePos.Position); + var localPos = Vector2.Transform(mousePos.Position, invMatrix); if (snap) { @@ -63,6 +63,6 @@ protected override void Draw(in OverlayDrawArgs args) var box = new Box2Rotated(aabb, rotation, localPos); handle.DrawTextureRect(_sprite.Frame0(decal.Sprite), box, color); - handle.SetTransform(Matrix3.Identity); + handle.SetTransform(Matrix3x2.Identity); } } diff --git a/Content.Client/DoAfter/DoAfterOverlay.cs b/Content.Client/DoAfter/DoAfterOverlay.cs index 45981159f0..dfbbf10891 100644 --- a/Content.Client/DoAfter/DoAfterOverlay.cs +++ b/Content.Client/DoAfter/DoAfterOverlay.cs @@ -56,8 +56,8 @@ protected override void Draw(in OverlayDrawArgs args) // If you use the display UI scale then need to set max(1f, displayscale) because 0 is valid. const float scale = 1f; - var scaleMatrix = Matrix3.CreateScale(new Vector2(scale, scale)); - var rotationMatrix = Matrix3.CreateRotation(-rotation); + var scaleMatrix = Matrix3Helpers.CreateScale(new Vector2(scale, scale)); + var rotationMatrix = Matrix3Helpers.CreateRotation(-rotation); var curTime = _timing.CurTime; @@ -91,9 +91,9 @@ protected override void Draw(in OverlayDrawArgs args) ? curTime - _meta.GetPauseTime(uid, meta) : curTime; - var worldMatrix = Matrix3.CreateTranslation(worldPosition); - Matrix3.Multiply(scaleMatrix, worldMatrix, out var scaledWorld); - Matrix3.Multiply(rotationMatrix, scaledWorld, out var matty); + var worldMatrix = Matrix3Helpers.CreateTranslation(worldPosition); + var scaledWorld = Matrix3x2.Multiply(scaleMatrix, worldMatrix); + var matty = Matrix3x2.Multiply(rotationMatrix, scaledWorld); handle.SetTransform(matty); var offset = 0f; @@ -151,7 +151,7 @@ protected override void Draw(in OverlayDrawArgs args) } handle.UseShader(null); - handle.SetTransform(Matrix3.Identity); + handle.SetTransform(Matrix3x2.Identity); } public Color GetProgressColor(float progress, float alpha = 1f) diff --git a/Content.Client/Explosion/ExplosionOverlay.cs b/Content.Client/Explosion/ExplosionOverlay.cs index 2d8c15f1b9..8cf7447a5d 100644 --- a/Content.Client/Explosion/ExplosionOverlay.cs +++ b/Content.Client/Explosion/ExplosionOverlay.cs @@ -48,7 +48,7 @@ protected override void Draw(in OverlayDrawArgs args) DrawExplosion(drawHandle, args.WorldBounds, visuals, index, xforms, textures); } - drawHandle.SetTransform(Matrix3.Identity); + drawHandle.SetTransform(Matrix3x2.Identity); drawHandle.UseShader(null); } @@ -78,7 +78,8 @@ private void DrawExplosion( if (visuals.SpaceTiles == null) return; - gridBounds = Matrix3.Invert(visuals.SpaceMatrix).TransformBox(worldBounds).Enlarged(2); + Matrix3x2.Invert(visuals.SpaceMatrix, out var invSpace); + gridBounds = invSpace.TransformBox(worldBounds).Enlarged(2); drawHandle.SetTransform(visuals.SpaceMatrix); DrawTiles(drawHandle, gridBounds, index, visuals.SpaceTiles, visuals, visuals.SpaceTileSize, textures); diff --git a/Content.Client/Fluids/PuddleOverlay.cs b/Content.Client/Fluids/PuddleOverlay.cs index ac6661cfdd..a8c1d35510 100644 --- a/Content.Client/Fluids/PuddleOverlay.cs +++ b/Content.Client/Fluids/PuddleOverlay.cs @@ -1,4 +1,5 @@ -using Content.Shared.FixedPoint; +using System.Numerics; +using Content.Shared.FixedPoint; using Robust.Client.Graphics; using Robust.Client.ResourceManagement; using Robust.Shared.Enums; @@ -73,7 +74,7 @@ private void DrawWorld(in OverlayDrawArgs args) } } - drawHandle.SetTransform(Matrix3.Identity); + drawHandle.SetTransform(Matrix3x2.Identity); } private void DrawScreen(in OverlayDrawArgs args) @@ -99,7 +100,7 @@ private void DrawScreen(in OverlayDrawArgs args) if (!gridBounds.Contains(centre)) continue; - var screenCenter = _eyeManager.WorldToScreen(matrix.Transform(centre)); + var screenCenter = _eyeManager.WorldToScreen(Vector2.Transform(centre, matrix)); drawHandle.DrawString(_font, screenCenter, debugOverlayData.CurrentVolume.ToString(), Color.White); } diff --git a/Content.Client/FootPrint/FootPrintsVisualizerSystem.cs b/Content.Client/FootPrint/FootPrintsVisualizerSystem.cs new file mode 100644 index 0000000000..3998d6b3c1 --- /dev/null +++ b/Content.Client/FootPrint/FootPrintsVisualizerSystem.cs @@ -0,0 +1,65 @@ +using Content.Shared.FootPrint; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Shared.Random; + +namespace Content.Client.FootPrint; + +public sealed class FootPrintsVisualizerSystem : VisualizerSystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly IRobustRandom _random = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInitialized); + SubscribeLocalEvent(OnShutdown); + } + + private void OnInitialized(EntityUid uid, FootPrintComponent comp, ComponentInit args) + { + if (!TryComp(uid, out var sprite)) + return; + + sprite.LayerMapReserveBlank(FootPrintVisualLayers.Print); + UpdateAppearance(uid, comp, sprite); + } + + private void OnShutdown(EntityUid uid, FootPrintComponent comp, ComponentShutdown args) + { + if (TryComp(uid, out var sprite) + && sprite.LayerMapTryGet(FootPrintVisualLayers.Print, out var layer)) + sprite.RemoveLayer(layer); + } + + private void UpdateAppearance(EntityUid uid, FootPrintComponent component, SpriteComponent sprite) + { + if (!sprite.LayerMapTryGet(FootPrintVisualLayers.Print, out var layer) + || !TryComp(component.PrintOwner, out var printsComponent) + || !TryComp(uid, out var appearance) + || !_appearance.TryGetData(uid, FootPrintVisualState.State, out var printVisuals, appearance)) + return; + + sprite.LayerSetState(layer, new RSI.StateId(printVisuals switch + { + FootPrintVisuals.BareFootPrint => printsComponent.RightStep ? printsComponent.RightBarePrint : printsComponent.LeftBarePrint, + FootPrintVisuals.ShoesPrint => printsComponent.ShoesPrint, + FootPrintVisuals.SuitPrint => printsComponent.SuitPrint, + FootPrintVisuals.Dragging => _random.Pick(printsComponent.DraggingPrint), + _ => throw new ArgumentOutOfRangeException($"Unknown {printVisuals} parameter.") + }), printsComponent.RsiPath); + + if (_appearance.TryGetData(uid, FootPrintVisualState.Color, out var printColor, appearance)) + sprite.LayerSetColor(layer, printColor); + } + + protected override void OnAppearanceChange (EntityUid uid, FootPrintComponent component, ref AppearanceChangeEvent args) + { + if (args.Sprite is not { } sprite) + return; + + UpdateAppearance(uid, component, sprite); + } +} diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml index 401f976862..e070af95d8 100644 --- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml +++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml @@ -1,48 +1,64 @@  + MaxHeight="525" + MinWidth="300"> diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs index fcf6d4551f..e889a7b64a 100644 --- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs +++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs @@ -1,12 +1,20 @@ using System.Linq; using System.Numerics; +using Content.Client.Message; using Content.Shared.Atmos; using Content.Client.UserInterface.Controls; +using Content.Shared.Alert; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; using Content.Shared.FixedPoint; +using Content.Shared.Humanoid; +using Content.Shared.Humanoid.Prototypes; using Content.Shared.IdentityManagement; +using Content.Shared.Inventory; using Content.Shared.MedicalScanner; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; using Content.Shared.Nutrition.Components; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.XAML; @@ -28,9 +36,6 @@ public sealed partial class HealthAnalyzerWindow : FancyWindow private readonly IPrototypeManager _prototypes; private readonly IResourceCache _cache; - private const int AnalyzerHeight = 430; - private const int AnalyzerWidth = 300; - public HealthAnalyzerWindow() { RobustXamlLoader.Load(this); @@ -44,8 +49,6 @@ public HealthAnalyzerWindow() public void Populate(HealthAnalyzerScannedUserMessage msg) { - GroupsContainer.RemoveAllChildren(); - var target = _entityManager.GetEntity(msg.TargetEntity); if (target == null @@ -57,82 +60,115 @@ public void Populate(HealthAnalyzerScannedUserMessage msg) NoPatientDataText.Visible = false; - string entityName = Loc.GetString("health-analyzer-window-entity-unknown-text"); - if (_entityManager.HasComponent(target.Value)) - { - entityName = Identity.Name(target.Value, _entityManager); - } + // Scan Mode - if (msg.ScanMode.HasValue) - { - ScanModePanel.Visible = true; - ScanModeText.Text = Loc.GetString(msg.ScanMode.Value ? "health-analyzer-window-scan-mode-active" : "health-analyzer-window-scan-mode-inactive"); - ScanModeText.FontColorOverride = msg.ScanMode.Value ? Color.Green : Color.Red; - } - else - { - ScanModePanel.Visible = false; - } + ScanModeLabel.Text = msg.ScanMode.HasValue + ? msg.ScanMode.Value + ? Loc.GetString("health-analyzer-window-scan-mode-active") + : Loc.GetString("health-analyzer-window-scan-mode-inactive") + : Loc.GetString("health-analyzer-window-entity-unknown-text"); - PatientName.Text = Loc.GetString( - "health-analyzer-window-entity-health-text", - ("entityName", entityName) - ); + ScanModeLabel.FontColorOverride = msg.ScanMode.HasValue && msg.ScanMode.Value ? Color.Green : Color.Red; - Temperature.Text = Loc.GetString("health-analyzer-window-entity-temperature-text", - ("temperature", float.IsNaN(msg.Temperature) ? "N/A" : $"{msg.Temperature - Atmospherics.T0C:F1} °C ({msg.Temperature:F1} K)") - ); + // Patient Information - BloodLevel.Text = Loc.GetString("health-analyzer-window-entity-blood-level-text", - ("bloodLevel", float.IsNaN(msg.BloodLevel) ? "N/A" : $"{msg.BloodLevel * 100:F1} %") - ); + SpriteView.SetEntity(target.Value); + SpriteView.Visible = msg.ScanMode.HasValue && msg.ScanMode.Value; + NoDataTex.Visible = !SpriteView.Visible; - if (msg.Bleeding == true) + var name = new FormattedMessage(); + name.PushColor(Color.White); + name.AddText(_entityManager.HasComponent(target.Value) + ? Identity.Name(target.Value, _entityManager) + : Loc.GetString("health-analyzer-window-entity-unknown-text")); + NameLabel.SetMessage(name); + + SpeciesLabel.Text = + _entityManager.TryGetComponent(target.Value, + out var humanoidAppearanceComponent) + ? Loc.GetString(_prototypes.Index(humanoidAppearanceComponent.Species).Name) + : Loc.GetString("health-analyzer-window-entity-unknown-species-text"); + + // Basic Diagnostic + + TemperatureLabel.Text = !float.IsNaN(msg.Temperature) + ? $"{msg.Temperature - Atmospherics.T0C:F1} °C ({msg.Temperature:F1} K)" + : Loc.GetString("health-analyzer-window-entity-unknown-value-text"); + + BloodLabel.Text = !float.IsNaN(msg.BloodLevel) + ? $"{msg.BloodLevel * 100:F1} %" + : Loc.GetString("health-analyzer-window-entity-unknown-value-text"); + + StatusLabel.Text = + _entityManager.TryGetComponent(target.Value, out var mobStateComponent) + ? GetStatus(mobStateComponent.CurrentState) + : Loc.GetString("health-analyzer-window-entity-unknown-text"); + + // Total Damage + + DamageLabel.Text = damageable.TotalDamage.ToString(); + + // Alerts + + var showAlerts = msg.Unrevivable == true || msg.Bleeding == true; + + AlertsDivider.Visible = showAlerts; + AlertsContainer.Visible = showAlerts; + + if (showAlerts) + AlertsContainer.DisposeAllChildren(); + + if (msg.Unrevivable == true) // Right now this does nothing, but we have it just for parity :) { - Bleeding.Text = Loc.GetString("health-analyzer-window-entity-bleeding-text"); - Bleeding.FontColorOverride = Color.Red; + var unrevivableLabel = new RichTextLabel + { + Margin = new Thickness(0, 4), + MaxWidth = 300 + }; + unrevivableLabel.SetMessage(Loc.GetString("health-analyzer-window-entity-unrevivable-text"), defaultColor: Color.Red); + AlertsContainer.AddChild(unrevivableLabel); } - else + + if (msg.Bleeding == true) { - Bleeding.Text = string.Empty; // Clear the text + var bleedingLabel = new RichTextLabel + { + Margin = new Thickness(0, 4), + MaxWidth = 300 + }; + bleedingLabel.SetMessage(Loc.GetString("health-analyzer-window-entity-bleeding-text"), defaultColor: Color.Red); + AlertsContainer.AddChild(bleedingLabel); } - patientDamageAmount.Text = Loc.GetString( - "health-analyzer-window-entity-damage-total-text", - ("amount", damageable.TotalDamage) - ); + // Damage Groups var damageSortedGroups = - damageable.DamagePerGroup.OrderBy(damage => damage.Value) + damageable.DamagePerGroup.OrderByDescending(damage => damage.Value) .ToDictionary(x => x.Key, x => x.Value); + IReadOnlyDictionary damagePerType = damageable.Damage.DamageDict; DrawDiagnosticGroups(damageSortedGroups, damagePerType); + } - if (_entityManager.TryGetComponent(target, out HungerComponent? hunger) - && hunger.StarvationDamage != null - && hunger.CurrentThreshold <= HungerThreshold.Starving) + private static string GetStatus(MobState mobState) + { + return mobState switch { - var box = new Control { Margin = new Thickness(0, 0, 0, 15) }; - - box.AddChild(CreateDiagnosticGroupTitle( - Loc.GetString("health-analyzer-window-malnutrition"), - "malnutrition")); - - GroupsContainer.AddChild(box); - } - - SetHeight = AnalyzerHeight; - SetWidth = AnalyzerWidth; + MobState.Alive => Loc.GetString("health-analyzer-window-entity-alive-text"), + MobState.Critical => Loc.GetString("health-analyzer-window-entity-critical-text"), + MobState.Dead => Loc.GetString("health-analyzer-window-entity-dead-text"), + _ => Loc.GetString("health-analyzer-window-entity-unknown-text"), + }; } private void DrawDiagnosticGroups( - Dictionary groups, IReadOnlyDictionary damageDict) + Dictionary groups, + IReadOnlyDictionary damageDict) { - HashSet shownTypes = new(); + GroupsContainer.RemoveAllChildren(); - // Show the total damage and type breakdown for each damage group. - foreach (var (damageGroupId, damageAmount) in groups.Reverse()) + foreach (var (damageGroupId, damageAmount) in groups) { if (damageAmount == 0) continue; @@ -145,7 +181,6 @@ private void DrawDiagnosticGroups( var groupContainer = new BoxContainer { - Margin = new Thickness(0, 0, 0, 15), Align = BoxContainer.AlignMode.Begin, Orientation = BoxContainer.LayoutOrientation.Vertical, }; @@ -159,23 +194,16 @@ private void DrawDiagnosticGroups( foreach (var type in group.DamageTypes) { - if (damageDict.TryGetValue(type, out var typeAmount) && typeAmount > 0) - { - // If damage types are allowed to belong to more than one damage group, - // they may appear twice here. Mark them as duplicate. - if (shownTypes.Contains(type)) - continue; - - shownTypes.Add(type); - - var damageString = Loc.GetString( - "health-analyzer-window-damage-type-text", - ("damageType", _prototypes.Index(type).LocalizedName), - ("amount", typeAmount) - ); - - groupContainer.AddChild(CreateDiagnosticItemLabel(damageString.Insert(0, "- "))); - } + if (!damageDict.TryGetValue(type, out var typeAmount) || typeAmount <= 0) + continue; + + var damageString = Loc.GetString( + "health-analyzer-window-damage-type-text", + ("damageType", Loc.GetString("health-analyzer-window-damage-type-" + type)), + ("amount", typeAmount) + ); + + groupContainer.AddChild(CreateDiagnosticItemLabel(damageString.Insert(0, " · "))); } } } @@ -198,7 +226,6 @@ private static Label CreateDiagnosticItemLabel(string text) { return new Label { - Margin = new Thickness(2, 2), Text = text, }; } @@ -207,13 +234,13 @@ private BoxContainer CreateDiagnosticGroupTitle(string text, string id) { var rootContainer = new BoxContainer { + Margin = new Thickness(0, 6, 0, 0), VerticalAlignment = VAlignment.Bottom, - Orientation = BoxContainer.LayoutOrientation.Horizontal + Orientation = BoxContainer.LayoutOrientation.Horizontal, }; rootContainer.AddChild(new TextureRect { - Margin = new Thickness(0, 3), SetSize = new Vector2(30, 30), Texture = GetTexture(id.ToLower()) }); diff --git a/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs b/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs index 2a846ff708..0f5729f55b 100644 --- a/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs +++ b/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs @@ -37,14 +37,8 @@ public InstrumentBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, u protected override void ReceiveMessage(BoundUserInterfaceMessage message) { - switch (message) - { - case InstrumentBandResponseBuiMessage bandRx: - _bandMenu?.Populate(bandRx.Nearby, EntMan); - break; - default: - break; - } + if (message is InstrumentBandResponseBuiMessage bandRx) + _bandMenu?.Populate(bandRx.Nearby, EntMan); } protected override void Open() diff --git a/Content.Client/Interactable/InteractionSystem.cs b/Content.Client/Interactable/InteractionSystem.cs index 0af8830e9a..ff0a607920 100644 --- a/Content.Client/Interactable/InteractionSystem.cs +++ b/Content.Client/Interactable/InteractionSystem.cs @@ -4,24 +4,6 @@ namespace Content.Client.Interactable { - public sealed class InteractionSystem : SharedInteractionSystem - { - [Dependency] private readonly SharedContainerSystem _container = default!; - - public override bool CanAccessViaStorage(EntityUid user, EntityUid target) - { - if (!EntityManager.EntityExists(target)) - return false; - - if (!_container.TryGetContainingContainer(target, out var container)) - return false; - - if (!HasComp(container.Owner)) - return false; - - // we don't check if the user can access the storage entity itself. This should be handed by the UI system. - // Need to return if UI is open or not - return true; - } - } + // TODO Remove Shared prefix + public sealed class InteractionSystem : SharedInteractionSystem; } diff --git a/Content.Client/Maps/GridDraggingSystem.cs b/Content.Client/Maps/GridDraggingSystem.cs index 16357c8983..3c4912a187 100644 --- a/Content.Client/Maps/GridDraggingSystem.cs +++ b/Content.Client/Maps/GridDraggingSystem.cs @@ -101,7 +101,7 @@ public override void Update(float frameTime) if (!_mapManager.TryFindGridAt(mousePos, out var gridUid, out var grid)) return; - StartDragging(gridUid, Transform(gridUid).InvWorldMatrix.Transform(mousePos.Position)); + StartDragging(gridUid, Vector2.Transform(mousePos.Position, Transform(gridUid).InvWorldMatrix)); } if (!TryComp(_dragging, out var xform)) @@ -116,7 +116,7 @@ public override void Update(float frameTime) return; } - var localToWorld = xform.WorldMatrix.Transform(_localPosition); + var localToWorld = Vector2.Transform(_localPosition, xform.WorldMatrix); if (localToWorld.EqualsApprox(mousePos.Position, 0.01f)) return; diff --git a/Content.Client/NPC/PathfindingSystem.cs b/Content.Client/NPC/PathfindingSystem.cs index 709601a57b..d3ae509152 100644 --- a/Content.Client/NPC/PathfindingSystem.cs +++ b/Content.Client/NPC/PathfindingSystem.cs @@ -223,7 +223,7 @@ private void DrawScreen(OverlayDrawArgs args, DrawingHandleScreen screenHandle) foreach (var crumb in chunk.Value) { - var crumbMapPos = worldMatrix.Transform(_system.GetCoordinate(chunk.Key, crumb.Coordinates)); + var crumbMapPos = Vector2.Transform(_system.GetCoordinate(chunk.Key, crumb.Coordinates), worldMatrix); var distance = (crumbMapPos - mouseWorldPos.Position).Length(); if (distance < nearestDistance) @@ -292,7 +292,7 @@ private void DrawScreen(OverlayDrawArgs args, DrawingHandleScreen screenHandle) foreach (var poly in tile) { - if (poly.Box.Contains(invGridMatrix.Transform(mouseWorldPos.Position))) + if (poly.Box.Contains(Vector2.Transform(mouseWorldPos.Position, invGridMatrix))) { nearest = poly; break; @@ -488,7 +488,7 @@ private void DrawWorld(OverlayDrawArgs args, DrawingHandleWorld worldHandle) if (neighborMap.MapId != args.MapId) continue; - neighborPos = invMatrix.Transform(neighborMap.Position); + neighborPos = Vector2.Transform(neighborMap.Position, invMatrix); } else { @@ -576,7 +576,7 @@ private void DrawWorld(OverlayDrawArgs args, DrawingHandleWorld worldHandle) } } - worldHandle.SetTransform(Matrix3.Identity); + worldHandle.SetTransform(Matrix3x2.Identity); } } } diff --git a/Content.Client/NodeContainer/NodeVisualizationOverlay.cs b/Content.Client/NodeContainer/NodeVisualizationOverlay.cs index 691bcb41db..4e8a4a10ca 100644 --- a/Content.Client/NodeContainer/NodeVisualizationOverlay.cs +++ b/Content.Client/NodeContainer/NodeVisualizationOverlay.cs @@ -199,7 +199,7 @@ private void DrawWorld(in OverlayDrawArgs overlayDrawArgs) } - handle.SetTransform(Matrix3.Identity); + handle.SetTransform(Matrix3x2.Identity); _gridIndex.Clear(); } diff --git a/Content.Client/Overlays/ColorTintOverlay.cs b/Content.Client/Overlays/ColorTintOverlay.cs index f40a8d7342..fc47b82789 100644 --- a/Content.Client/Overlays/ColorTintOverlay.cs +++ b/Content.Client/Overlays/ColorTintOverlay.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Enums; @@ -22,7 +23,7 @@ public sealed class ColorTintOverlay : Overlay /// /// The color to tint the screen to as RGB on a scale of 0-1. /// - public Vector3? TintColor = null; + public Robust.Shared.Maths.Vector3? TintColor = null; /// /// The percent to tint the screen by on a scale of 0-1. /// @@ -49,15 +50,15 @@ protected override void Draw(in OverlayDrawArgs args) _shader.SetParameter("SCREEN_TEXTURE", ScreenTexture); if (TintColor != null) - _shader.SetParameter("tint_color", (Vector3) TintColor); + _shader.SetParameter("tint_color", (Robust.Shared.Maths.Vector3) TintColor); if (TintAmount != null) _shader.SetParameter("tint_amount", (float) TintAmount); var worldHandle = args.WorldHandle; var viewport = args.WorldBounds; - worldHandle.SetTransform(Matrix3.Identity); + worldHandle.SetTransform(Matrix3x2.Identity); worldHandle.UseShader(_shader); worldHandle.DrawRect(viewport, Color.White); worldHandle.UseShader(null); } -} \ No newline at end of file +} diff --git a/Content.Client/Overlays/DogVisionOverlay.cs b/Content.Client/Overlays/DogVisionOverlay.cs index 91f5521f7f..022a31d696 100644 --- a/Content.Client/Overlays/DogVisionOverlay.cs +++ b/Content.Client/Overlays/DogVisionOverlay.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Enums; @@ -41,7 +42,7 @@ protected override void Draw(in OverlayDrawArgs args) var worldHandle = args.WorldHandle; var viewport = args.WorldBounds; - worldHandle.SetTransform(Matrix3.Identity); + worldHandle.SetTransform(Matrix3x2.Identity); worldHandle.UseShader(_dogVisionShader); worldHandle.DrawRect(viewport, Color.White); worldHandle.UseShader(null); diff --git a/Content.Client/Overlays/EntityHealthBarOverlay.cs b/Content.Client/Overlays/EntityHealthBarOverlay.cs index c1c0ae93ec..c96225c0c6 100644 --- a/Content.Client/Overlays/EntityHealthBarOverlay.cs +++ b/Content.Client/Overlays/EntityHealthBarOverlay.cs @@ -43,8 +43,8 @@ protected override void Draw(in OverlayDrawArgs args) var xformQuery = _entManager.GetEntityQuery(); const float scale = 1f; - var scaleMatrix = Matrix3.CreateScale(new Vector2(scale, scale)); - var rotationMatrix = Matrix3.CreateRotation(-rotation); + var scaleMatrix = Matrix3Helpers.CreateScale(new Vector2(scale, scale)); + var rotationMatrix = Matrix3Helpers.CreateRotation(-rotation); var query = _entManager.AllEntityQueryEnumerator(); while (query.MoveNext(out var uid, @@ -80,10 +80,10 @@ protected override void Draw(in OverlayDrawArgs args) } var worldPosition = _transform.GetWorldPosition(xform); - var worldMatrix = Matrix3.CreateTranslation(worldPosition); + var worldMatrix = Matrix3Helpers.CreateTranslation(worldPosition); - Matrix3.Multiply(scaleMatrix, worldMatrix, out var scaledWorld); - Matrix3.Multiply(rotationMatrix, scaledWorld, out var matty); + var scaledWorld = Matrix3x2.Multiply(scaleMatrix, worldMatrix); + var matty = Matrix3x2.Multiply(rotationMatrix, scaledWorld); handle.SetTransform(matty); @@ -116,7 +116,7 @@ protected override void Draw(in OverlayDrawArgs args) handle.DrawRect(pixelDarken, Black.WithAlpha(128)); } - handle.SetTransform(Matrix3.Identity); + handle.SetTransform(Matrix3x2.Identity); } /// diff --git a/Content.Client/Overlays/EtherealOverlay.cs b/Content.Client/Overlays/EtherealOverlay.cs index 3d771de8ce..594a3656c8 100644 --- a/Content.Client/Overlays/EtherealOverlay.cs +++ b/Content.Client/Overlays/EtherealOverlay.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Enums; @@ -40,9 +41,9 @@ protected override void Draw(in OverlayDrawArgs args) var worldHandle = args.WorldHandle; var viewport = args.WorldBounds; - worldHandle.SetTransform(Matrix3.Identity); + worldHandle.SetTransform(Matrix3x2.Identity); worldHandle.UseShader(_shader); worldHandle.DrawRect(viewport, Color.White); worldHandle.UseShader(null); } -} \ No newline at end of file +} diff --git a/Content.Client/Overlays/SaturationScaleOverlay.cs b/Content.Client/Overlays/SaturationScaleOverlay.cs index 50656d3bc1..d3a27a9724 100644 --- a/Content.Client/Overlays/SaturationScaleOverlay.cs +++ b/Content.Client/Overlays/SaturationScaleOverlay.cs @@ -1,4 +1,5 @@ -using Robust.Client.Graphics; +using System.Numerics; +using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Enums; using Robust.Shared.Prototypes; @@ -45,7 +46,7 @@ protected override void Draw(in OverlayDrawArgs args) _shader.SetParameter("saturation", Saturation); var handle = args.WorldHandle; - handle.SetTransform(Matrix3.Identity); + handle.SetTransform(Matrix3x2.Identity); handle.UseShader(_shader); handle.DrawRect(args.WorldBounds, Color.White); handle.UseShader(null); diff --git a/Content.Client/Overlays/StencilOverlay.RestrictedRange.cs b/Content.Client/Overlays/StencilOverlay.RestrictedRange.cs index 9581fec37b..d29564caa9 100644 --- a/Content.Client/Overlays/StencilOverlay.RestrictedRange.cs +++ b/Content.Client/Overlays/StencilOverlay.RestrictedRange.cs @@ -7,7 +7,7 @@ namespace Content.Client.Overlays; public sealed partial class StencilOverlay { - private void DrawRestrictedRange(in OverlayDrawArgs args, RestrictedRangeComponent rangeComp, Matrix3 invMatrix) + private void DrawRestrictedRange(in OverlayDrawArgs args, RestrictedRangeComponent rangeComp, Matrix3x2 invMatrix) { var worldHandle = args.WorldHandle; var renderScale = args.Viewport.RenderScale.X; @@ -16,7 +16,7 @@ private void DrawRestrictedRange(in OverlayDrawArgs args, RestrictedRangeCompone var length = zoom.X; var bufferRange = MathF.Min(10f, rangeComp.Range); - var pixelCenter = invMatrix.Transform(rangeComp.Origin); + var pixelCenter = Vector2.Transform(rangeComp.Origin, invMatrix); // Something something offset? var vertical = args.Viewport.Size.Y; @@ -44,7 +44,7 @@ private void DrawRestrictedRange(in OverlayDrawArgs args, RestrictedRangeCompone worldHandle.DrawRect(localAABB, Color.White); }, Color.Transparent); - worldHandle.SetTransform(Matrix3.Identity); + worldHandle.SetTransform(Matrix3x2.Identity); worldHandle.UseShader(_protoManager.Index("StencilMask").Instance()); worldHandle.DrawTextureRect(_blep!.Texture, worldBounds); var curTime = _timing.RealTime; diff --git a/Content.Client/Overlays/StencilOverlay.Weather.cs b/Content.Client/Overlays/StencilOverlay.Weather.cs index 31bc88af45..29ed157a79 100644 --- a/Content.Client/Overlays/StencilOverlay.Weather.cs +++ b/Content.Client/Overlays/StencilOverlay.Weather.cs @@ -10,7 +10,7 @@ public sealed partial class StencilOverlay { private List> _grids = new(); - private void DrawWeather(in OverlayDrawArgs args, WeatherPrototype weatherProto, float alpha, Matrix3 invMatrix) + private void DrawWeather(in OverlayDrawArgs args, WeatherPrototype weatherProto, float alpha, Matrix3x2 invMatrix) { var worldHandle = args.WorldHandle; var mapId = args.MapId; @@ -32,7 +32,7 @@ private void DrawWeather(in OverlayDrawArgs args, WeatherPrototype weatherProto, foreach (var grid in _grids) { var matrix = _transform.GetWorldMatrix(grid, xformQuery); - Matrix3.Multiply(in matrix, in invMatrix, out var matty); + var matty = Matrix3x2.Multiply(matrix, invMatrix); worldHandle.SetTransform(matty); foreach (var tile in grid.Comp.GetTilesIntersecting(worldAABB)) @@ -52,7 +52,7 @@ private void DrawWeather(in OverlayDrawArgs args, WeatherPrototype weatherProto, }, Color.Transparent); - worldHandle.SetTransform(Matrix3.Identity); + worldHandle.SetTransform(Matrix3x2.Identity); worldHandle.UseShader(_protoManager.Index("StencilMask").Instance()); worldHandle.DrawTextureRect(_blep!.Texture, worldBounds); var curTime = _timing.RealTime; @@ -62,7 +62,7 @@ private void DrawWeather(in OverlayDrawArgs args, WeatherPrototype weatherProto, worldHandle.UseShader(_protoManager.Index("StencilDraw").Instance()); _parallax.DrawParallax(worldHandle, worldAABB, sprite, curTime, position, Vector2.Zero, modulate: (weatherProto.Color ?? Color.White).WithAlpha(alpha)); - worldHandle.SetTransform(Matrix3.Identity); + worldHandle.SetTransform(Matrix3x2.Identity); worldHandle.UseShader(null); } } diff --git a/Content.Client/Overlays/StencilOverlay.cs b/Content.Client/Overlays/StencilOverlay.cs index e475dca759..78b1c4d2b1 100644 --- a/Content.Client/Overlays/StencilOverlay.cs +++ b/Content.Client/Overlays/StencilOverlay.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Client.Parallax; using Content.Client.Weather; using Content.Shared.Salvage; @@ -72,6 +73,6 @@ protected override void Draw(in OverlayDrawArgs args) } args.WorldHandle.UseShader(null); - args.WorldHandle.SetTransform(Matrix3.Identity); + args.WorldHandle.SetTransform(Matrix3x2.Identity); } } diff --git a/Content.Client/Overlays/UltraVisionOverlay.cs b/Content.Client/Overlays/UltraVisionOverlay.cs index fe9317e365..a12aa94ea8 100644 --- a/Content.Client/Overlays/UltraVisionOverlay.cs +++ b/Content.Client/Overlays/UltraVisionOverlay.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Enums; @@ -41,7 +42,7 @@ protected override void Draw(in OverlayDrawArgs args) var worldHandle = args.WorldHandle; var viewport = args.WorldBounds; - worldHandle.SetTransform(Matrix3.Identity); + worldHandle.SetTransform(Matrix3x2.Identity); worldHandle.UseShader(_ultraVisionShader); worldHandle.DrawRect(viewport, Color.White); worldHandle.UseShader(null); diff --git a/Content.Client/Paper/UI/StampLabel.xaml.cs b/Content.Client/Paper/UI/StampLabel.xaml.cs index 6a8eb5f98f..be6d52baea 100644 --- a/Content.Client/Paper/UI/StampLabel.xaml.cs +++ b/Content.Client/Paper/UI/StampLabel.xaml.cs @@ -50,7 +50,7 @@ protected override void Draw(DrawingHandleScreen handle) base.Draw(handle); // Restore a sane transform+shader - handle.SetTransform(Matrix3.Identity); + handle.SetTransform(Matrix3x2.Identity); handle.UseShader(null); } } diff --git a/Content.Client/Paper/UI/StampWidget.xaml.cs b/Content.Client/Paper/UI/StampWidget.xaml.cs index a04508aeba..487e0732b4 100644 --- a/Content.Client/Paper/UI/StampWidget.xaml.cs +++ b/Content.Client/Paper/UI/StampWidget.xaml.cs @@ -53,7 +53,7 @@ protected override void Draw(DrawingHandleScreen handle) base.Draw(handle); // Restore a sane transform+shader - handle.SetTransform(Matrix3.Identity); + handle.SetTransform(Matrix3x2.Identity); handle.UseShader(null); } } diff --git a/Content.Client/Pinpointer/NavMapSystem.cs b/Content.Client/Pinpointer/NavMapSystem.cs index e33bc5d329..9aeb792a42 100644 --- a/Content.Client/Pinpointer/NavMapSystem.cs +++ b/Content.Client/Pinpointer/NavMapSystem.cs @@ -14,27 +14,40 @@ public override void Initialize() private void OnHandleState(EntityUid uid, NavMapComponent component, ref ComponentHandleState args) { - if (args.Current is not NavMapComponentState state) - return; + Dictionary modifiedChunks; + Dictionary beacons; - if (!state.FullState) + switch (args.Current) { - foreach (var index in component.Chunks.Keys) + case NavMapDeltaState delta: { - if (!state.AllChunks!.Contains(index)) - component.Chunks.Remove(index); + modifiedChunks = delta.ModifiedChunks; + beacons = delta.Beacons; + foreach (var index in component.Chunks.Keys) + { + if (!delta.AllChunks!.Contains(index)) + component.Chunks.Remove(index); + } + + break; } - } - else - { - foreach (var index in component.Chunks.Keys) + case NavMapState state: { - if (!state.Chunks.ContainsKey(index)) - component.Chunks.Remove(index); + modifiedChunks = state.Chunks; + beacons = state.Beacons; + foreach (var index in component.Chunks.Keys) + { + if (!state.Chunks.ContainsKey(index)) + component.Chunks.Remove(index); + } + + break; } + default: + return; } - foreach (var (origin, chunk) in state.Chunks) + foreach (var (origin, chunk) in modifiedChunks) { var newChunk = new NavMapChunk(origin); Array.Copy(chunk, newChunk.TileData, chunk.Length); @@ -42,7 +55,7 @@ private void OnHandleState(EntityUid uid, NavMapComponent component, ref Compone } component.Beacons.Clear(); - foreach (var (nuid, beacon) in state.Beacons) + foreach (var (nuid, beacon) in beacons) { component.Beacons[nuid] = beacon; } diff --git a/Content.Client/Pinpointer/UI/NavMapControl.cs b/Content.Client/Pinpointer/UI/NavMapControl.cs index f4d2f8e2fb..3c99a18818 100644 --- a/Content.Client/Pinpointer/UI/NavMapControl.cs +++ b/Content.Client/Pinpointer/UI/NavMapControl.cs @@ -218,7 +218,7 @@ protected override void KeyBindUp(GUIBoundKeyEventArgs args) // Convert to a world position var unscaledPosition = (localPosition - MidPointVector) / MinimapScale; - var worldPosition = _transformSystem.GetWorldMatrix(_xform).Transform(new Vector2(unscaledPosition.X, -unscaledPosition.Y) + offset); + var worldPosition = Vector2.Transform(new Vector2(unscaledPosition.X, -unscaledPosition.Y) + offset, _transformSystem.GetWorldMatrix(_xform)); // Find closest tracked entity in range var closestEntity = NetEntity.Invalid; @@ -401,7 +401,7 @@ protected override void Draw(DrawingHandleScreen handle) if (mapPos.MapId != MapId.Nullspace) { - var position = _transformSystem.GetInvWorldMatrix(_xform).Transform(mapPos.Position) - offset; + var position = Vector2.Transform(mapPos.Position, _transformSystem.GetInvWorldMatrix(_xform)) - offset; position = ScalePosition(new Vector2(position.X, -position.Y)); handle.DrawCircle(position, float.Sqrt(MinimapScale) * 2f, value.Color); @@ -422,7 +422,7 @@ protected override void Draw(DrawingHandleScreen handle) if (mapPos.MapId != MapId.Nullspace) { - var position = _transformSystem.GetInvWorldMatrix(_xform).Transform(mapPos.Position) - offset; + var position = Vector2.Transform(mapPos.Position, _transformSystem.GetInvWorldMatrix(_xform)) - offset; position = ScalePosition(new Vector2(position.X, -position.Y)); var scalingCoefficient = MinmapScaleModifier * float.Sqrt(MinimapScale); diff --git a/Content.Client/Popups/PopupOverlay.cs b/Content.Client/Popups/PopupOverlay.cs index fb6bb3bf56..77eeb611f5 100644 --- a/Content.Client/Popups/PopupOverlay.cs +++ b/Content.Client/Popups/PopupOverlay.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Shared.Examine; using Robust.Client.Graphics; using Robust.Client.Player; @@ -55,7 +56,7 @@ protected override void Draw(in OverlayDrawArgs args) if (args.ViewportControl == null) return; - args.DrawingHandle.SetTransform(Matrix3.Identity); + args.DrawingHandle.SetTransform(Matrix3x2.Identity); args.DrawingHandle.UseShader(_shader); var scale = _configManager.GetCVar(CVars.DisplayUIScale); @@ -90,7 +91,7 @@ private void DrawWorld(DrawingHandleScreen worldHandle, OverlayDrawArgs args, fl e => e == popup.InitialPos.EntityId || e == ourEntity, entMan: _entManager)) continue; - var pos = matrix.Transform(mapPos.Position); + var pos = Vector2.Transform(mapPos.Position, matrix); _controller.DrawPopup(popup, worldHandle, pos, scale); } } diff --git a/Content.Client/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs b/Content.Client/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs index 7086fd0541..d5154a87be 100644 --- a/Content.Client/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs +++ b/Content.Client/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Shared.Shuttles.Events; using Content.Shared.Shuttles.Systems; using Robust.Client.Graphics; @@ -75,6 +76,6 @@ protected override void Draw(in OverlayDrawArgs args) args.WorldHandle.SetTransform(xform.WorldMatrix); args.WorldHandle.DrawRect(Position.Value, Color.Red.WithAlpha(100)); - args.WorldHandle.SetTransform(Matrix3.Identity); + args.WorldHandle.SetTransform(Matrix3x2.Identity); } } diff --git a/Content.Client/Shuttles/UI/BaseShuttleControl.xaml.cs b/Content.Client/Shuttles/UI/BaseShuttleControl.xaml.cs index 8774c1dfb5..b50d8fa6b2 100644 --- a/Content.Client/Shuttles/UI/BaseShuttleControl.xaml.cs +++ b/Content.Client/Shuttles/UI/BaseShuttleControl.xaml.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Client.UserInterface.Controls; using Content.Shared.Shuttles.Components; using Robust.Client.AutoGenerated; @@ -115,7 +116,7 @@ protected void DrawCircles(DrawingHandleScreen handle) } } - protected void DrawGrid(DrawingHandleScreen handle, Matrix3 matrix, Entity grid, Color color, float alpha = 0.01f) + protected void DrawGrid(DrawingHandleScreen handle, Matrix3x2 matrix, Entity grid, Color color, float alpha = 0.01f) { var rator = Maps.GetAllTilesEnumerator(grid.Owner, grid.Comp); var minimapScale = MinimapScale; @@ -289,7 +290,7 @@ private record struct GridDrawJob : IParallelRobustJob public float MinimapScale; public Vector2 MidPoint; - public Matrix3 Matrix; + public Matrix3x2 Matrix; public List Vertices; public Vector2[] ScaledVertices; @@ -297,7 +298,7 @@ private record struct GridDrawJob : IParallelRobustJob public void Execute(int index) { var vert = Vertices[index]; - var adjustedVert = Matrix.Transform(vert); + var adjustedVert = Vector2.Transform(vert, Matrix); adjustedVert = adjustedVert with { Y = -adjustedVert.Y }; var scaledVert = ScalePosition(adjustedVert, MinimapScale, MidPoint); diff --git a/Content.Client/Shuttles/UI/NavScreen.xaml.cs b/Content.Client/Shuttles/UI/NavScreen.xaml.cs index b7b757ea48..91d95aaa04 100644 --- a/Content.Client/Shuttles/UI/NavScreen.xaml.cs +++ b/Content.Client/Shuttles/UI/NavScreen.xaml.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Shared.Shuttles.BUIStates; using Robust.Client.AutoGenerated; using Robust.Client.Graphics; @@ -68,7 +69,7 @@ protected override void Draw(DrawingHandleScreen handle) } var (_, worldRot, worldMatrix) = _xformSystem.GetWorldPositionRotationMatrix(gridXform); - var worldPos = worldMatrix.Transform(gridBody.LocalCenter); + var worldPos = Vector2.Transform(gridBody.LocalCenter, worldMatrix); // Get the positive reduced angle. var displayRot = -worldRot.Reduced(); diff --git a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs index f03c440295..31f0eecad7 100644 --- a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs @@ -108,10 +108,10 @@ protected override void Draw(DrawingHandleScreen handle) var gridNent = EntManager.GetNetEntity(GridEntity); var mapPos = _xformSystem.ToMapCoordinates(_coordinates.Value); var ourGridMatrix = _xformSystem.GetWorldMatrix(gridXform.Owner); - var dockMatrix = Matrix3.CreateTransform(_coordinates.Value.Position, Angle.Zero); - Matrix3.Multiply(dockMatrix, ourGridMatrix, out var offsetMatrix); + var dockMatrix = Matrix3Helpers.CreateTransform(_coordinates.Value.Position, Angle.Zero); + var worldFromDock = Matrix3x2.Multiply(dockMatrix, ourGridMatrix); - offsetMatrix = offsetMatrix.Invert(); + Matrix3x2.Invert(worldFromDock, out var offsetMatrix); // Draw nearby grids var controlBounds = PixelSizeBox; @@ -137,7 +137,7 @@ protected override void Draw(DrawingHandleScreen handle) continue; var gridMatrix = _xformSystem.GetWorldMatrix(grid.Owner); - Matrix3.Multiply(in gridMatrix, in offsetMatrix, out var matty); + var matty = Matrix3x2.Multiply(gridMatrix, offsetMatrix); var color = _shuttles.GetIFFColor(grid.Owner, grid.Owner == GridEntity, component: iffComp); DrawGrid(handle, matty, grid, color); @@ -151,23 +151,23 @@ protected override void Draw(DrawingHandleScreen handle) if (ViewedDock == dock.Entity) continue; - var position = matty.Transform(dock.Coordinates.Position); + var position = Vector2.Transform(dock.Coordinates.Position, matty); - var otherDockRotation = Matrix3.CreateRotation(dock.Angle); + var otherDockRotation = Matrix3Helpers.CreateRotation(dock.Angle); var scaledPos = ScalePosition(position with {Y = -position.Y}); if (!controlBounds.Contains(scaledPos.Floored())) continue; // Draw the dock's collision - var collisionBL = matty.Transform(dock.Coordinates.Position + - otherDockRotation.Transform(new Vector2(-0.2f, -0.7f))); - var collisionBR = matty.Transform(dock.Coordinates.Position + - otherDockRotation.Transform(new Vector2(0.2f, -0.7f))); - var collisionTR = matty.Transform(dock.Coordinates.Position + - otherDockRotation.Transform(new Vector2(0.2f, -0.5f))); - var collisionTL = matty.Transform(dock.Coordinates.Position + - otherDockRotation.Transform(new Vector2(-0.2f, -0.5f))); + var collisionBL = Vector2.Transform(dock.Coordinates.Position + + Vector2.Transform(new Vector2(-0.2f, -0.7f), otherDockRotation), matty); + var collisionBR = Vector2.Transform(dock.Coordinates.Position + + Vector2.Transform(new Vector2(0.2f, -0.7f), otherDockRotation), matty); + var collisionTR = Vector2.Transform(dock.Coordinates.Position + + Vector2.Transform(new Vector2(0.2f, -0.5f), otherDockRotation), matty); + var collisionTL = Vector2.Transform(dock.Coordinates.Position + + Vector2.Transform(new Vector2(-0.2f, -0.5f), otherDockRotation), matty); var verts = new[] { @@ -195,10 +195,10 @@ protected override void Draw(DrawingHandleScreen handle) handle.DrawPrimitives(DrawPrimitiveTopology.LineList, verts, otherDockConnection); // Draw the dock itself - var dockBL = matty.Transform(dock.Coordinates.Position + new Vector2(-0.5f, -0.5f)); - var dockBR = matty.Transform(dock.Coordinates.Position + new Vector2(0.5f, -0.5f)); - var dockTR = matty.Transform(dock.Coordinates.Position + new Vector2(0.5f, 0.5f)); - var dockTL = matty.Transform(dock.Coordinates.Position + new Vector2(-0.5f, 0.5f)); + var dockBL = Vector2.Transform(dock.Coordinates.Position + new Vector2(-0.5f, -0.5f), matty); + var dockBR = Vector2.Transform(dock.Coordinates.Position + new Vector2(0.5f, -0.5f), matty); + var dockTR = Vector2.Transform(dock.Coordinates.Position + new Vector2(0.5f, 0.5f), matty); + var dockTL = Vector2.Transform(dock.Coordinates.Position + new Vector2(-0.5f, 0.5f), matty); verts = new[] { @@ -308,14 +308,14 @@ protected override void Draw(DrawingHandleScreen handle) // Draw the dock's collision var invertedPosition = Vector2.Zero; invertedPosition.Y = -invertedPosition.Y; - var rotation = Matrix3.CreateRotation(-_angle.Value + MathF.PI); + var rotation = Matrix3Helpers.CreateRotation(-_angle.Value + MathF.PI); var ourDockConnection = new UIBox2( - ScalePosition(rotation.Transform(new Vector2(-0.2f, -0.7f))), - ScalePosition(rotation.Transform(new Vector2(0.2f, -0.5f)))); + ScalePosition(Vector2.Transform(new Vector2(-0.2f, -0.7f), rotation)), + ScalePosition(Vector2.Transform(new Vector2(0.2f, -0.5f), rotation))); var ourDock = new UIBox2( - ScalePosition(rotation.Transform(new Vector2(-0.5f, 0.5f))), - ScalePosition(rotation.Transform(new Vector2(0.5f, -0.5f)))); + ScalePosition(Vector2.Transform(new Vector2(-0.5f, 0.5f), rotation)), + ScalePosition(Vector2.Transform(new Vector2(0.5f, -0.5f), rotation))); var dockColor = Color.Magenta; var connectionColor = Color.Pink; diff --git a/Content.Client/Shuttles/UI/ShuttleMapControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleMapControl.xaml.cs index 2f35a8dffd..8bd4a338cb 100644 --- a/Content.Client/Shuttles/UI/ShuttleMapControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleMapControl.xaml.cs @@ -114,7 +114,7 @@ protected override void KeyBindUp(GUIBoundKeyEventArgs args) var beaconsOnly = EntManager.TryGetComponent(mapUid, out FTLDestinationComponent? destComp) && destComp.BeaconsOnly; - var mapTransform = Matrix3.CreateInverseTransform(Offset, Angle.Zero); + var mapTransform = Matrix3Helpers.CreateInverseTransform(Offset, Angle.Zero); if (beaconsOnly && TryGetBeacon(_beacons, mapTransform, args.RelativePixelPosition, PixelRect, out var foundBeacon, out _)) { @@ -203,7 +203,7 @@ private void DrawParallax(DrawingHandleScreen handle) /// /// /// - private List GetViewportMapObjects(Matrix3 matty, List mapObjects) + private List GetViewportMapObjects(Matrix3x2 matty, List mapObjects) { var results = new List(); var enlargement = new Vector2i((int) (16 * UIScale), (int) (16 * UIScale)); @@ -217,7 +217,7 @@ private List GetViewportMapObjects(Matrix3 matty, List m var mapCoords = _shuttles.GetMapCoordinates(mapObj); - var relativePos = matty.Transform(mapCoords.Position); + var relativePos = Vector2.Transform(mapCoords.Position, matty); relativePos = relativePos with { Y = -relativePos.Y }; var uiPosition = ScalePosition(relativePos); @@ -250,7 +250,7 @@ protected override void Draw(DrawingHandleScreen handle) DrawParallax(handle); var viewedMapUid = _mapManager.GetMapEntityId(ViewingMap); - var matty = Matrix3.CreateInverseTransform(Offset, Angle.Zero); + var matty = Matrix3Helpers.CreateInverseTransform(Offset, Angle.Zero); var realTime = _timing.RealTime; var viewBox = new Box2(Offset - WorldRangeVector, Offset + WorldRangeVector); var viewportObjects = GetViewportMapObjects(matty, mapObjects); @@ -267,7 +267,7 @@ protected override void Draw(DrawingHandleScreen handle) var (gridPos, gridRot) = _xformSystem.GetWorldPositionRotation(shuttleXform); gridPos = Maps.GetGridPosition((gridUid, gridPhysics), gridPos, gridRot); - var gridRelativePos = matty.Transform(gridPos); + var gridRelativePos = Vector2.Transform(gridPos, matty); gridRelativePos = gridRelativePos with { Y = -gridRelativePos.Y }; var gridUiPos = ScalePosition(gridRelativePos); @@ -296,7 +296,7 @@ protected override void Draw(DrawingHandleScreen handle) continue; } - var adjustedPos = matty.Transform(mapCoords.Position); + var adjustedPos = Vector2.Transform(mapCoords.Position, matty); var localPos = ScalePosition(adjustedPos with { Y = -adjustedPos.Y}); handle.DrawCircle(localPos, exclusion.Range * MinimapScale, exclusionColor.WithAlpha(0.05f)); handle.DrawCircle(localPos, exclusion.Range * MinimapScale, exclusionColor, filled: false); @@ -319,7 +319,7 @@ protected override void Draw(DrawingHandleScreen handle) foreach (var (beaconName, coords, mapO) in GetBeacons(viewportObjects, matty, controlLocalBounds)) { - var localPos = matty.Transform(coords.Position); + var localPos = Vector2.Transform(coords.Position, matty); localPos = localPos with { Y = -localPos.Y }; var beaconUiPos = ScalePosition(localPos); var mapObject = GetMapObject(localPos, Angle.Zero, scale: 0.75f, scalePosition: true); @@ -360,7 +360,7 @@ protected override void Draw(DrawingHandleScreen handle) var (gridPos, gridRot) = _xformSystem.GetWorldPositionRotation(grid.Owner); gridPos = Maps.GetGridPosition((grid, gridPhysics), gridPos, gridRot); - var gridRelativePos = matty.Transform(gridPos); + var gridRelativePos = Vector2.Transform(gridPos, matty); gridRelativePos = gridRelativePos with { Y = -gridRelativePos.Y }; var gridUiPos = ScalePosition(gridRelativePos); @@ -439,7 +439,7 @@ protected override void Draw(DrawingHandleScreen handle) var color = ftlFree ? Color.LimeGreen : Color.Magenta; - var gridRelativePos = matty.Transform(gridPos); + var gridRelativePos = Vector2.Transform(gridPos, matty); gridRelativePos = gridRelativePos with { Y = -gridRelativePos.Y }; var gridUiPos = ScalePosition(gridRelativePos); @@ -512,7 +512,7 @@ private void AddMapObject(List edges, List verts, ValueList /// Returns the beacons that intersect the viewport. /// - private IEnumerable<(string Beacon, MapCoordinates Coordinates, IMapObject MapObject)> GetBeacons(List mapObjs, Matrix3 mapTransform, UIBox2i area) + private IEnumerable<(string Beacon, MapCoordinates Coordinates, IMapObject MapObject)> GetBeacons(List mapObjs, Matrix3x2 mapTransform, UIBox2i area) { foreach (var mapO in mapObjs) { @@ -520,7 +520,7 @@ private void AddMapObject(List edges, List verts, ValueList GetMapObject(Vector2 localPos, Angle angle, float sca return mapObj; } - private bool TryGetBeacon(IEnumerable mapObjects, Matrix3 mapTransform, Vector2 mousePos, UIBox2i area, out ShuttleBeaconObject foundBeacon, out Vector2 foundLocalPos) + private bool TryGetBeacon(IEnumerable mapObjects, Matrix3x2 mapTransform, Vector2 mousePos, UIBox2i area, out ShuttleBeaconObject foundBeacon, out Vector2 foundLocalPos) { // In pixels const float BeaconSnapRange = 32f; @@ -579,7 +579,7 @@ private bool TryGetBeacon(IEnumerable mapObjects, Matrix3 mapTransfo if (!_shuttles.CanFTLBeacon(beaconObj.Coordinates)) continue; - var position = mapTransform.Transform(beaconCoords.Position); + var position = Vector2.Transform(beaconCoords.Position, mapTransform); var localPos = ScalePosition(position with {Y = -position.Y}); // If beacon not on screen then ignore it. diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs index 00ee6890b2..0b8720add2 100644 --- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs @@ -137,10 +137,10 @@ protected override void Draw(DrawingHandleScreen handle) var mapPos = _transform.ToMapCoordinates(_coordinates.Value); var offset = _coordinates.Value.Position; - var posMatrix = Matrix3.CreateTransform(offset, _rotation.Value); + var posMatrix = Matrix3Helpers.CreateTransform(offset, _rotation.Value); var (_, ourEntRot, ourEntMatrix) = _transform.GetWorldPositionRotationMatrix(_coordinates.Value.EntityId); - Matrix3.Multiply(posMatrix, ourEntMatrix, out var ourWorldMatrix); - var ourWorldMatrixInvert = ourWorldMatrix.Invert(); + var ourWorldMatrix = Matrix3x2.Multiply(posMatrix, ourEntMatrix); + Matrix3x2.Invert(ourWorldMatrix, out var ourWorldMatrixInvert); // Draw our grid in detail var ourGridId = xform.GridUid; @@ -148,7 +148,7 @@ protected override void Draw(DrawingHandleScreen handle) fixturesQuery.HasComponent(ourGridId.Value)) { var ourGridMatrix = _transform.GetWorldMatrix(ourGridId.Value); - Matrix3.Multiply(in ourGridMatrix, in ourWorldMatrixInvert, out var matrix); + var matrix = Matrix3x2.Multiply(ourGridMatrix, ourWorldMatrixInvert); var color = _shuttles.GetIFFColor(ourGridId.Value, self: true); DrawGrid(handle, matrix, (ourGridId.Value, ourGrid), color); @@ -194,7 +194,7 @@ protected override void Draw(DrawingHandleScreen handle) continue; var gridMatrix = _transform.GetWorldMatrix(gUid); - Matrix3.Multiply(in gridMatrix, in ourWorldMatrixInvert, out var matty); + var matty = Matrix3x2.Multiply(gridMatrix, ourWorldMatrixInvert); var color = _shuttles.GetIFFColor(grid, self: false, iff); // Others default: @@ -207,7 +207,7 @@ protected override void Draw(DrawingHandleScreen handle) { var gridBounds = grid.Comp.LocalAABB; - var gridCentre = matty.Transform(gridBody.LocalCenter); + var gridCentre = Vector2.Transform(gridBody.LocalCenter, matty); gridCentre.Y = -gridCentre.Y; var distance = gridCentre.Length(); var labelText = Loc.GetString("shuttle-console-iff-label", ("name", labelName), @@ -242,7 +242,7 @@ protected override void Draw(DrawingHandleScreen handle) } } - private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3 matrix) + private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3x2 matrix) { if (!ShowDocks) return; @@ -255,7 +255,7 @@ private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3 matrix foreach (var state in docks) { var position = state.Coordinates.Position; - var uiPosition = matrix.Transform(position); + var uiPosition = Vector2.Transform(position, matrix); if (uiPosition.Length() > (WorldRange * 2f) - DockScale) continue; @@ -264,10 +264,10 @@ private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3 matrix var verts = new[] { - matrix.Transform(position + new Vector2(-DockScale, -DockScale)), - matrix.Transform(position + new Vector2(DockScale, -DockScale)), - matrix.Transform(position + new Vector2(DockScale, DockScale)), - matrix.Transform(position + new Vector2(-DockScale, DockScale)), + Vector2.Transform(position + new Vector2(-DockScale, -DockScale), matrix), + Vector2.Transform(position + new Vector2(DockScale, -DockScale), matrix), + Vector2.Transform(position + new Vector2(DockScale, DockScale), matrix), + Vector2.Transform(position + new Vector2(-DockScale, DockScale), matrix), }; for (var i = 0; i < verts.Length; i++) diff --git a/Content.Client/StatusIcon/StatusIconOverlay.cs b/Content.Client/StatusIcon/StatusIconOverlay.cs index f8381afdbe..372bd04f57 100644 --- a/Content.Client/StatusIcon/StatusIconOverlay.cs +++ b/Content.Client/StatusIcon/StatusIconOverlay.cs @@ -39,8 +39,8 @@ protected override void Draw(in OverlayDrawArgs args) var eyeRot = args.Viewport.Eye?.Rotation ?? default; var xformQuery = _entity.GetEntityQuery(); - var scaleMatrix = Matrix3.CreateScale(new Vector2(1, 1)); - var rotationMatrix = Matrix3.CreateRotation(-eyeRot); + var scaleMatrix = Matrix3Helpers.CreateScale(new Vector2(1, 1)); + var rotationMatrix = Matrix3Helpers.CreateRotation(-eyeRot); var query = _entity.AllEntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp, out var sprite, out var xform, out var meta)) @@ -59,9 +59,9 @@ protected override void Draw(in OverlayDrawArgs args) if (icons.Count == 0) continue; - var worldMatrix = Matrix3.CreateTranslation(worldPos); - Matrix3.Multiply(scaleMatrix, worldMatrix, out var scaledWorld); - Matrix3.Multiply(rotationMatrix, scaledWorld, out var matty); + var worldMatrix = Matrix3Helpers.CreateTranslation(worldPos); + var scaledWorld = Matrix3x2.Multiply(scaleMatrix, worldMatrix); + var matty = Matrix3x2.Multiply(rotationMatrix, scaledWorld); handle.SetTransform(matty); var countL = 0; diff --git a/Content.Client/Storage/Systems/StorageSystem.cs b/Content.Client/Storage/Systems/StorageSystem.cs index 8bf0dcd981..b80a855f98 100644 --- a/Content.Client/Storage/Systems/StorageSystem.cs +++ b/Content.Client/Storage/Systems/StorageSystem.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Linq; +using System.Numerics; using Content.Client.Animations; using Content.Shared.Hands; using Content.Shared.Storage; @@ -149,7 +150,7 @@ public void PickupAnimation(EntityUid item, EntityCoordinates initialCoords, Ent } var finalMapPos = finalCoords.ToMapPos(EntityManager, TransformSystem); - var finalPos = TransformSystem.GetInvWorldMatrix(initialCoords.EntityId).Transform(finalMapPos); + var finalPos = Vector2.Transform(finalMapPos, TransformSystem.GetInvWorldMatrix(initialCoords.EntityId)); _entityPickupAnimation.AnimateEntityPickup(item, initialCoords, finalPos, initialAngle); } diff --git a/Content.Client/UserInterface/Controls/DirectionIcon.cs b/Content.Client/UserInterface/Controls/DirectionIcon.cs index a6cc428091..c8fd63b43c 100644 --- a/Content.Client/UserInterface/Controls/DirectionIcon.cs +++ b/Content.Client/UserInterface/Controls/DirectionIcon.cs @@ -65,7 +65,7 @@ protected override void Draw(DrawingHandleScreen handle) if (_rotation != null) { var offset = (-_rotation.Value).RotateVec(Size * UIScale / 2) - Size * UIScale / 2; - handle.SetTransform(Matrix3.CreateTransform(GlobalPixelPosition - offset, -_rotation.Value)); + handle.SetTransform(Matrix3Helpers.CreateTransform(GlobalPixelPosition - offset, -_rotation.Value)); } base.Draw(handle); diff --git a/Content.Client/UserInterface/Controls/MapGridControl.xaml.cs b/Content.Client/UserInterface/Controls/MapGridControl.xaml.cs index f6b0929f3b..a10155f3e8 100644 --- a/Content.Client/UserInterface/Controls/MapGridControl.xaml.cs +++ b/Content.Client/UserInterface/Controls/MapGridControl.xaml.cs @@ -169,7 +169,7 @@ protected Vector2 InverseMapPosition(Vector2 value) var inversePos = (value - MidPointVector) / MinimapScale; inversePos = inversePos with { Y = -inversePos.Y }; - inversePos = Matrix3.CreateTransform(Offset, Angle.Zero).Transform(inversePos); + inversePos = Vector2.Transform(inversePos, Matrix3Helpers.CreateTransform(Offset, Angle.Zero)); return inversePos; } diff --git a/Content.Client/Viewport/ScalingViewport.cs b/Content.Client/Viewport/ScalingViewport.cs index 1fa8f17161..ccd9636d77 100644 --- a/Content.Client/Viewport/ScalingViewport.cs +++ b/Content.Client/Viewport/ScalingViewport.cs @@ -277,8 +277,8 @@ public MapCoordinates ScreenToMap(Vector2 coords) EnsureViewportCreated(); - var matrix = Matrix3.Invert(GetLocalToScreenMatrix()); - coords = matrix.Transform(coords); + Matrix3x2.Invert(GetLocalToScreenMatrix(), out var matrix); + coords = Vector2.Transform(coords, matrix); return _viewport!.LocalToWorld(coords); } @@ -291,8 +291,8 @@ public MapCoordinates PixelToMap(Vector2 coords) EnsureViewportCreated(); - var matrix = Matrix3.Invert(GetLocalToScreenMatrix()); - coords = matrix.Transform(coords); + Matrix3x2.Invert(GetLocalToScreenMatrix(), out var matrix); + coords = Vector2.Transform(coords, matrix); var ev = new PixelToMapEvent(coords, this, _viewport!); _entityManager.EventBus.RaiseEvent(EventSource.Local, ref ev); @@ -311,16 +311,16 @@ public Vector2 WorldToScreen(Vector2 map) var matrix = GetLocalToScreenMatrix(); - return matrix.Transform(vpLocal); + return Vector2.Transform(vpLocal, matrix); } - public Matrix3 GetWorldToScreenMatrix() + public Matrix3x2 GetWorldToScreenMatrix() { EnsureViewportCreated(); return _viewport!.GetWorldToLocalMatrix() * GetLocalToScreenMatrix(); } - public Matrix3 GetLocalToScreenMatrix() + public Matrix3x2 GetLocalToScreenMatrix() { EnsureViewportCreated(); @@ -329,9 +329,9 @@ public Matrix3 GetLocalToScreenMatrix() if (scaleFactor.X == 0 || scaleFactor.Y == 0) // Basically a nonsense scenario, at least make sure to return something that can be inverted. - return Matrix3.Identity; + return Matrix3x2.Identity; - return Matrix3.CreateTransform(GlobalPixelPosition + drawBox.TopLeft, 0, scaleFactor); + return Matrix3Helpers.CreateTransform(GlobalPixelPosition + drawBox.TopLeft, 0, scaleFactor); } private void EnsureViewportCreated() diff --git a/Content.Client/Weapons/Melee/MeleeWeaponSystem.Effects.cs b/Content.Client/Weapons/Melee/MeleeWeaponSystem.Effects.cs index baac42d193..3e1a4b1906 100644 --- a/Content.Client/Weapons/Melee/MeleeWeaponSystem.Effects.cs +++ b/Content.Client/Weapons/Melee/MeleeWeaponSystem.Effects.cs @@ -81,7 +81,7 @@ public override void DoLunge(EntityUid user, EntityUid weapon, Angle angle, Vect case WeaponArcAnimation.None: var (mapPos, mapRot) = TransformSystem.GetWorldPositionRotation(userXform); var worldPos = mapPos + (mapRot - userXform.LocalRotation).RotateVec(localPos); - var newLocalPos = TransformSystem.GetInvWorldMatrix(xform.ParentUid).Transform(worldPos); + var newLocalPos = Vector2.Transform(worldPos, TransformSystem.GetInvWorldMatrix(xform.ParentUid)); TransformSystem.SetLocalPositionNoLerp(animationUid, newLocalPos, xform); if (arcComponent.Fadeout) _animation.Play(animationUid, GetFadeAnimation(sprite, 0f, 0.15f), FadeAnimationKey); diff --git a/Content.Client/Weapons/Ranged/ItemStatus/BulletRender.cs b/Content.Client/Weapons/Ranged/ItemStatus/BulletRender.cs index 8aea5d7ee6..e6cb596b94 100644 --- a/Content.Client/Weapons/Ranged/ItemStatus/BulletRender.cs +++ b/Content.Client/Weapons/Ranged/ItemStatus/BulletRender.cs @@ -1,4 +1,4 @@ -using System.Numerics; +using System.Numerics; using Content.Client.Resources; using Robust.Client.Graphics; using Robust.Client.ResourceManagement; @@ -53,7 +53,7 @@ protected override void Draw(DrawingHandleScreen handle) { // Scale rendering in this control by UIScale. var currentTransform = handle.GetTransform(); - handle.SetTransform(Matrix3.CreateScale(new Vector2(UIScale)) * currentTransform); + handle.SetTransform(Matrix3Helpers.CreateScale(new Vector2(UIScale)) * currentTransform); var countPerRow = CountPerRow(Size.X); diff --git a/Content.IntegrationTests/Tests/EntityTest.cs b/Content.IntegrationTests/Tests/EntityTest.cs index d3b1fb4722..926374cf05 100644 --- a/Content.IntegrationTests/Tests/EntityTest.cs +++ b/Content.IntegrationTests/Tests/EntityTest.cs @@ -19,6 +19,8 @@ namespace Content.IntegrationTests.Tests [TestOf(typeof(EntityUid))] public sealed class EntityTest { + private static readonly ProtoId SpawnerCategory = "Spawner"; + [Test] public async Task SpawnAndDeleteAllEntitiesOnDifferentMaps() { @@ -234,14 +236,6 @@ public async Task SpawnAndDeleteEntityCountTest() "StationEvent", "TimedDespawn", - // Spawner entities - "DragonRift", - "RandomHumanoidSpawner", - "RandomSpawner", - "ConditionalSpawner", - "GhostRoleMobSpawner", - "NukeOperativeSpawner", - "TimedSpawner", // makes an announcement on mapInit. "AnnounceOnSpawn", }; @@ -253,6 +247,7 @@ public async Task SpawnAndDeleteEntityCountTest() .Where(p => !p.Abstract) .Where(p => !pair.IsTestPrototype(p)) .Where(p => !excluded.Any(p.Components.ContainsKey)) + .Where(p => p.Categories.All(x => x.ID != SpawnerCategory)) .Select(p => p.ID) .ToList(); @@ -350,8 +345,12 @@ public async Task AllComponentsOneToOneDeleteTest() "DebrisFeaturePlacerController", // Above. "LoadedChunk", // Worldgen chunk loading malding. "BiomeSelection", // Whaddya know, requires config. + "ActivatableUI", // Requires enum key }; + // TODO TESTS + // auto ignore any components that have a "required" data field. + await using var pair = await PoolManager.GetServerClient(); var server = pair.Server; var entityManager = server.ResolveDependency(); diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 8afaafa358..d743a83ef4 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -879,6 +879,9 @@ public string WrapMessage(LocId wrapId, InGameICChatType chatType, EntityUid sou var color = DefaultSpeakColor; if (language.SpeechOverride.Color is { } colorOverride) color = Color.InterpolateBetween(color, colorOverride, colorOverride.A); + var languageDisplay = language.IsVisibleLanguage + ? $"{language.ChatName} | " + : ""; return Loc.GetString(wrapId, ("color", color), @@ -886,7 +889,8 @@ public string WrapMessage(LocId wrapId, InGameICChatType chatType, EntityUid sou ("verb", Loc.GetString(verbId)), ("fontType", language.SpeechOverride.FontId ?? speech.FontId), ("fontSize", language.SpeechOverride.FontSize ?? speech.FontSize), - ("message", message)); + ("message", message), + ("language", languageDisplay)); } /// diff --git a/Content.Server/Communications/CommunicationsConsoleSystem.cs b/Content.Server/Communications/CommunicationsConsoleSystem.cs index 1cffcf5816..0fcac27c19 100644 --- a/Content.Server/Communications/CommunicationsConsoleSystem.cs +++ b/Content.Server/Communications/CommunicationsConsoleSystem.cs @@ -200,13 +200,11 @@ private bool CanUse(EntityUid user, EntityUid console) private bool CanCallOrRecall(CommunicationsConsoleComponent comp) { // Defer to what the round end system thinks we should be able to do. - if (_emergency.EmergencyShuttleArrived || !_roundEndSystem.CanCallOrRecall()) + if (_emergency.EmergencyShuttleArrived + || !_roundEndSystem.CanCallOrRecall() + || !comp.CanShuttle) return false; - // Calling shuttle checks - if (_roundEndSystem.ExpectedCountdownEnd is null) - return comp.CanShuttle; - // Recalling shuttle checks var recallThreshold = _cfg.GetCVar(CCVars.EmergencyRecallTurningPoint); diff --git a/Content.Server/Configurable/ConfigurationSystem.cs b/Content.Server/Configurable/ConfigurationSystem.cs index 2683bf4e09..5f5f1ef7d1 100644 --- a/Content.Server/Configurable/ConfigurationSystem.cs +++ b/Content.Server/Configurable/ConfigurationSystem.cs @@ -24,6 +24,7 @@ public override void Initialize() private void OnInteractUsing(EntityUid uid, ConfigurationComponent component, InteractUsingEvent args) { + // TODO use activatable ui system if (args.Handled) return; diff --git a/Content.Server/Explosion/EntitySystems/ExplosionGridTileFlood.cs b/Content.Server/Explosion/EntitySystems/ExplosionGridTileFlood.cs index 7db1f513f7..2ddcc052d8 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionGridTileFlood.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionGridTileFlood.cs @@ -14,7 +14,7 @@ public sealed class ExplosionGridTileFlood : ExplosionTileFlood public MapGridComponent Grid; private bool _needToTransform = false; - private Matrix3 _matrix = Matrix3.Identity; + private Matrix3x2 _matrix = Matrix3x2.Identity; private Vector2 _offset; // Tiles which neighbor an exploding tile, but have not yet had the explosion spread to them due to an @@ -44,7 +44,7 @@ public ExplosionGridTileFlood( int typeIndex, Dictionary edgeTiles, EntityUid? referenceGrid, - Matrix3 spaceMatrix, + Matrix3x2 spaceMatrix, Angle spaceAngle) { Grid = grid; @@ -72,9 +72,10 @@ public ExplosionGridTileFlood( var transform = IoCManager.Resolve().GetComponent(Grid.Owner); var size = (float) Grid.TileSize; - _matrix.R0C2 = size / 2; - _matrix.R1C2 = size / 2; - _matrix *= transform.WorldMatrix * Matrix3.Invert(spaceMatrix); + _matrix.M31 = size / 2; + _matrix.M32 = size / 2; + Matrix3x2.Invert(spaceMatrix, out var invSpace); + _matrix *= transform.WorldMatrix * invSpace; var relativeAngle = transform.WorldRotation - spaceAngle; _offset = relativeAngle.RotateVec(new Vector2(size / 4, size / 4)); } @@ -228,7 +229,7 @@ private void JumpToSpace(Vector2i tile) return; } - var center = _matrix.Transform(tile); + var center = Vector2.Transform(tile, _matrix); SpaceJump.Add(new((int) MathF.Floor(center.X + _offset.X), (int) MathF.Floor(center.Y + _offset.Y))); SpaceJump.Add(new((int) MathF.Floor(center.X - _offset.Y), (int) MathF.Floor(center.Y + _offset.X))); SpaceJump.Add(new((int) MathF.Floor(center.X - _offset.X), (int) MathF.Floor(center.Y - _offset.Y))); diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs index 719a2eca79..556fe7c141 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs @@ -60,7 +60,7 @@ private void OnGridRemoved(GridRemovalEvent ev) { Dictionary transformedEdges = new(); - var targetMatrix = Matrix3.Identity; + var targetMatrix = Matrix3x2.Identity; Angle targetAngle = new(); var tileSize = DefaultTileSize; var maxDistanceSq = (int) (maxDistance * maxDistance); @@ -75,9 +75,9 @@ private void OnGridRemoved(GridRemovalEvent ev) tileSize = targetGrid.TileSize; } - var offsetMatrix = Matrix3.Identity; - offsetMatrix.R0C2 = tileSize / 2f; - offsetMatrix.R1C2 = tileSize / 2f; + var offsetMatrix = Matrix3x2.Identity; + offsetMatrix.M31 = tileSize / 2f; + offsetMatrix.M32 = tileSize / 2f; // Here we can end up with a triple nested for loop: // foreach other grid @@ -106,7 +106,7 @@ private void OnGridRemoved(GridRemovalEvent ev) var xform = xforms.GetComponent(gridToTransform); var (_, gridWorldRotation, gridWorldMatrix, invGridWorldMatrid) = xform.GetWorldPositionRotationMatrixWithInv(xforms); - var localEpicentre = (Vector2i) invGridWorldMatrid.Transform(epicentre.Position); + var localEpicentre = (Vector2i) Vector2.Transform(epicentre.Position, invGridWorldMatrid); var matrix = offsetMatrix * gridWorldMatrix * targetMatrix; var angle = gridWorldRotation - targetAngle; @@ -119,7 +119,7 @@ private void OnGridRemoved(GridRemovalEvent ev) if (delta.X * delta.X + delta.Y * delta.Y > maxDistanceSq) // no Vector2.Length??? continue; - var center = matrix.Transform(tile); + var center = Vector2.Transform(tile, matrix); if ((dir & NeighborFlag.Cardinal) == 0) { diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs index 835e3174fc..19f33e3fdd 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs @@ -295,8 +295,8 @@ private static bool GridQueryCallback( /// Same as , but for SPAAAAAAACE. /// internal void ExplodeSpace(BroadphaseComponent lookup, - Matrix3 spaceMatrix, - Matrix3 invSpaceMatrix, + Matrix3x2 spaceMatrix, + Matrix3x2 invSpaceMatrix, Vector2i tile, float throwForce, DamageSpecifier damage, @@ -337,7 +337,7 @@ internal void ExplodeSpace(BroadphaseComponent lookup, } private static bool SpaceQueryCallback( - ref (List<(EntityUid, TransformComponent)> List, HashSet Processed, Matrix3 InvSpaceMatrix, EntityUid LookupOwner, EntityQuery XformQuery, Box2 GridBox, SharedTransformSystem System) state, + ref (List<(EntityUid, TransformComponent)> List, HashSet Processed, Matrix3x2 InvSpaceMatrix, EntityUid LookupOwner, EntityQuery XformQuery, Box2 GridBox, SharedTransformSystem System) state, in EntityUid uid) { if (state.Processed.Contains(uid)) @@ -348,7 +348,7 @@ private static bool SpaceQueryCallback( if (xform.ParentUid == state.LookupOwner) { // parented directly to the map, use local position - if (state.GridBox.Contains(state.InvSpaceMatrix.Transform(xform.LocalPosition))) + if (state.GridBox.Contains(Vector2.Transform(xform.LocalPosition, state.InvSpaceMatrix))) state.List.Add((uid, xform)); return true; @@ -356,14 +356,14 @@ private static bool SpaceQueryCallback( // finally check if it intersects our tile var wpos = state.System.GetWorldPosition(xform); - if (state.GridBox.Contains(state.InvSpaceMatrix.Transform(wpos))) + if (state.GridBox.Contains(Vector2.Transform(wpos, state.InvSpaceMatrix))) state.List.Add((uid, xform)); return true; } private static bool SpaceQueryCallback( - ref (List<(EntityUid, TransformComponent)> List, HashSet Processed, Matrix3 InvSpaceMatrix, EntityUid LookupOwner, EntityQuery XformQuery, Box2 GridBox, SharedTransformSystem System) state, + ref (List<(EntityUid, TransformComponent)> List, HashSet Processed, Matrix3x2 InvSpaceMatrix, EntityUid LookupOwner, EntityQuery XformQuery, Box2 GridBox, SharedTransformSystem System) state, in FixtureProxy proxy) { var uid = proxy.Entity; @@ -569,12 +569,12 @@ struct ExplosionData /// /// The matrix that defines the reference frame for the explosion in space. /// - private readonly Matrix3 _spaceMatrix; + private readonly Matrix3x2 _spaceMatrix; /// /// Inverse of /// - private readonly Matrix3 _invSpaceMatrix; + private readonly Matrix3x2 _invSpaceMatrix; /// /// Have all the tiles on all the grids been processed? @@ -640,7 +640,7 @@ public Explosion(ExplosionSystem system, List gridData, List tileSetIntensity, MapCoordinates epicenter, - Matrix3 spaceMatrix, + Matrix3x2 spaceMatrix, int area, float tileBreakScale, int maxTileBreak, @@ -679,7 +679,7 @@ public Explosion(ExplosionSystem system, }); _spaceMatrix = spaceMatrix; - _invSpaceMatrix = Matrix3.Invert(spaceMatrix); + Matrix3x2.Invert(spaceMatrix, out _invSpaceMatrix); } foreach (var grid in gridData) diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.TileFill.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.TileFill.cs index a42dd11083..8b4c0e14c5 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.TileFill.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.TileFill.cs @@ -26,7 +26,7 @@ public sealed partial class ExplosionSystem : EntitySystem /// The maximum intensity that the explosion can have at any given tile. This /// effectively caps the damage that this explosion can do. /// A list of tile-sets and a list of intensity values which describe the explosion. - private (int, List, ExplosionSpaceTileFlood?, Dictionary, Matrix3)? GetExplosionTiles( + private (int, List, ExplosionSpaceTileFlood?, Dictionary, Matrix3x2)? GetExplosionTiles( MapCoordinates epicenter, string typeID, float totalIntensity, @@ -84,7 +84,7 @@ public sealed partial class ExplosionSystem : EntitySystem Dictionary>? previousGridJump; // variables for transforming between grid and space-coordinates - var spaceMatrix = Matrix3.Identity; + var spaceMatrix = Matrix3x2.Identity; var spaceAngle = Angle.Zero; if (referenceGrid != null) { diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Visuals.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Visuals.cs index d332531502..5db8b55bf9 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Visuals.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Visuals.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Shared.Explosion; using Content.Shared.Explosion.Components; using Robust.Server.GameObjects; @@ -35,7 +36,7 @@ private void OnGetState(EntityUid uid, ExplosionVisualsComponent component, ref /// /// Constructor for the shared using the server-exclusive explosion classes. /// - private EntityUid CreateExplosionVisualEntity(MapCoordinates epicenter, string prototype, Matrix3 spaceMatrix, ExplosionSpaceTileFlood? spaceData, IEnumerable gridData, List iterationIntensity) + private EntityUid CreateExplosionVisualEntity(MapCoordinates epicenter, string prototype, Matrix3x2 spaceMatrix, ExplosionSpaceTileFlood? spaceData, IEnumerable gridData, List iterationIntensity) { var explosionEntity = Spawn(null, MapCoordinates.Nullspace); var comp = AddComp(explosionEntity); diff --git a/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs b/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs index d88f46968a..3d0996a380 100644 --- a/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs +++ b/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Server.Chemistry.Containers.EntitySystems; using Content.Server.Popups; using Content.Shared.Chemistry.Components; @@ -317,7 +318,7 @@ private bool TryPuddleInteract(EntityUid user, EntityUid used, EntityUid target, var userXform = Transform(user); var targetPos = _transform.GetWorldPosition(target); - var localPos = _transform.GetInvWorldMatrix(userXform).Transform(targetPos); + var localPos = Vector2.Transform(targetPos, _transform.GetInvWorldMatrix(userXform)); localPos = userXform.LocalRotation.RotateVec(localPos); _melee.DoLunge(user, used, Angle.Zero, localPos, null, false); diff --git a/Content.Server/FootPrint/FootPrintsSystem.cs b/Content.Server/FootPrint/FootPrintsSystem.cs new file mode 100644 index 0000000000..0e45acff5c --- /dev/null +++ b/Content.Server/FootPrint/FootPrintsSystem.cs @@ -0,0 +1,122 @@ +using Content.Server.Atmos.Components; +using Content.Shared.Inventory; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Content.Shared.FootPrint; +using Content.Shared.Standing; +using Content.Shared.Chemistry.Components.SolutionManager; +using Content.Shared.Chemistry.EntitySystems; +using Robust.Shared.Map; +using Robust.Shared.Random; + +namespace Content.Server.FootPrint; + +public sealed class FootPrintsSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly IMapManager _map = default!; + + [Dependency] private readonly SharedSolutionContainerSystem _solution = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + + private EntityQuery _transformQuery; + private EntityQuery _mobThresholdQuery; + private EntityQuery _appearanceQuery; + private EntityQuery _layingQuery; + + public override void Initialize() + { + base.Initialize(); + + _transformQuery = GetEntityQuery(); + _mobThresholdQuery = GetEntityQuery(); + _appearanceQuery = GetEntityQuery(); + _layingQuery = GetEntityQuery(); + + SubscribeLocalEvent(OnStartupComponent); + SubscribeLocalEvent(OnMove); + } + + private void OnStartupComponent(EntityUid uid, FootPrintsComponent component, ComponentStartup args) + { + component.StepSize = Math.Max(0f, component.StepSize + _random.NextFloat(-0.05f, 0.05f)); + } + + private void OnMove(EntityUid uid, FootPrintsComponent component, ref MoveEvent args) + { + if (component.PrintsColor.A <= 0f + || !_transformQuery.TryComp(uid, out var transform) + || !_mobThresholdQuery.TryComp(uid, out var mobThreshHolds) + || !_map.TryFindGridAt(_transform.GetMapCoordinates((uid, transform)), out var gridUid, out _)) + return; + + var dragging = mobThreshHolds.CurrentThresholdState is MobState.Critical or MobState.Dead + || _layingQuery.TryComp(uid, out var laying) && laying.IsCrawlingUnder; + var distance = (transform.LocalPosition - component.StepPos).Length(); + var stepSize = dragging ? component.DragSize : component.StepSize; + + if (!(distance > stepSize)) + return; + + component.RightStep = !component.RightStep; + + var entity = Spawn(component.StepProtoId, CalcCoords(gridUid, component, transform, dragging)); + var footPrintComponent = EnsureComp(entity); + + footPrintComponent.PrintOwner = uid; + Dirty(entity, footPrintComponent); + + if (_appearanceQuery.TryComp(entity, out var appearance)) + { + _appearance.SetData(entity, FootPrintVisualState.State, PickState(uid, dragging), appearance); + _appearance.SetData(entity, FootPrintVisualState.Color, component.PrintsColor, appearance); + } + + if (!_transformQuery.TryComp(entity, out var stepTransform)) + return; + + stepTransform.LocalRotation = dragging + ? (transform.LocalPosition - component.StepPos).ToAngle() + Angle.FromDegrees(-90f) + : transform.LocalRotation + Angle.FromDegrees(180f); + + component.PrintsColor = component.PrintsColor.WithAlpha(Math.Max(0f, component.PrintsColor.A - component.ColorReduceAlpha)); + component.StepPos = transform.LocalPosition; + + if (!TryComp(entity, out var solutionContainer) + || !_solution.ResolveSolution((entity, solutionContainer), footPrintComponent.SolutionName, ref footPrintComponent.Solution, out var solution) + || string.IsNullOrWhiteSpace(component.ReagentToTransfer) || solution.Volume >= 1) + return; + + _solution.TryAddReagent(footPrintComponent.Solution.Value, component.ReagentToTransfer, 1, out _); + } + + private EntityCoordinates CalcCoords(EntityUid uid, FootPrintsComponent component, TransformComponent transform, bool state) + { + if (state) + return new EntityCoordinates(uid, transform.LocalPosition); + + var offset = component.RightStep + ? new Angle(Angle.FromDegrees(180f) + transform.LocalRotation).RotateVec(component.OffsetPrint) + : new Angle(transform.LocalRotation).RotateVec(component.OffsetPrint); + + return new EntityCoordinates(uid, transform.LocalPosition + offset); + } + + private FootPrintVisuals PickState(EntityUid uid, bool dragging) + { + var state = FootPrintVisuals.BareFootPrint; + + if (_inventory.TryGetSlotEntity(uid, "shoes", out _)) + state = FootPrintVisuals.ShoesPrint; + + if (_inventory.TryGetSlotEntity(uid, "outerClothing", out var suit) && TryComp(suit, out _)) + state = FootPrintVisuals.SuitPrint; + + if (dragging) + state = FootPrintVisuals.Dragging; + + return state; + } +} diff --git a/Content.Server/FootPrint/PuddleFootPrintsSystem.cs b/Content.Server/FootPrint/PuddleFootPrintsSystem.cs new file mode 100644 index 0000000000..706ba25359 --- /dev/null +++ b/Content.Server/FootPrint/PuddleFootPrintsSystem.cs @@ -0,0 +1,52 @@ +using System.Linq; +using Content.Shared.FootPrint; +using Content.Shared.Chemistry.Components.SolutionManager; +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Fluids; +using Content.Shared.Fluids.Components; +using Robust.Shared.Physics.Events; + +namespace Content.Server.FootPrint; + +public sealed class PuddleFootPrintsSystem : EntitySystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnStepTrigger); + } + + private void OnStepTrigger(EntityUid uid, PuddleFootPrintsComponent component, ref EndCollideEvent args) + { + if (!TryComp(uid, out var appearance) + || !TryComp(uid, out var puddle) + || !TryComp(args.OtherEntity, out var tripper) + || !TryComp(uid, out var solutionManager) + || !_solutionContainer.ResolveSolution((uid, solutionManager), puddle.SolutionName, ref puddle.Solution, out var solutions)) + return; + + var totalSolutionQuantity = solutions.Contents.Sum(sol => (float) sol.Quantity); + var waterQuantity = (from sol in solutions.Contents where sol.Reagent.Prototype == "Water" select (float) sol.Quantity).FirstOrDefault(); + + if (waterQuantity / (totalSolutionQuantity / 100f) > component.OffPercent || solutions.Contents.Count <= 0) + return; + + tripper.ReagentToTransfer = + solutions.Contents.Aggregate((l, r) => l.Quantity > r.Quantity ? l : r).Reagent.Prototype; + + if (_appearance.TryGetData(uid, PuddleVisuals.SolutionColor, out var color, appearance) + && _appearance.TryGetData(uid, PuddleVisuals.CurrentVolume, out var volume, appearance)) + AddColor((Color) color, (float) volume * component.SizeRatio, tripper); + + _solutionContainer.RemoveEachReagent(puddle.Solution.Value, 1); + } + + private void AddColor(Color col, float quantity, FootPrintsComponent component) + { + component.PrintsColor = component.ColorQuantity == 0f ? col : Color.InterpolateBetween(component.PrintsColor, col, component.ColorInterpolationFactor); + component.ColorQuantity += quantity; + } +} diff --git a/Content.Server/GameTicking/GameTicker.Spawning.cs b/Content.Server/GameTicking/GameTicker.Spawning.cs index 2e526b4d13..3016195f4b 100644 --- a/Content.Server/GameTicking/GameTicker.Spawning.cs +++ b/Content.Server/GameTicking/GameTicker.Spawning.cs @@ -498,7 +498,7 @@ public EntityCoordinates GetObserverSpawnPoint() { var gridXform = Transform(gridUid); - return new EntityCoordinates(gridUid, gridXform.InvWorldMatrix.Transform(toMap.Position)); + return new EntityCoordinates(gridUid, Vector2.Transform(toMap.Position, gridXform.InvWorldMatrix)); } return spawn; diff --git a/Content.Server/GameTicking/Rules/Components/NukeOperativeSpawnerComponent.cs b/Content.Server/GameTicking/Rules/Components/NukeOperativeSpawnerComponent.cs index bb1b7c8746..54eaa6e32e 100644 --- a/Content.Server/GameTicking/Rules/Components/NukeOperativeSpawnerComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/NukeOperativeSpawnerComponent.cs @@ -1,3 +1,5 @@ +using Robust.Shared.Prototypes; + namespace Content.Server.GameTicking.Rules.Components; /// @@ -5,6 +7,5 @@ namespace Content.Server.GameTicking.Rules.Components; /// and providing loadout + name for the operative on spawn. /// TODO: Remove once systems can request spawns from the ghost role system directly. /// -[RegisterComponent] +[RegisterComponent, EntityCategory("Spawner")] public sealed partial class NukeOperativeSpawnerComponent : Component; - diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index f4e6a4d607..254d478bb0 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -154,8 +154,8 @@ private void OnGhostStartup(EntityUid uid, GhostComponent component, ComponentSt if (_ticker.RunLevel != GameRunLevel.PostRound) { - _visibilitySystem.AddLayer(uid, visibility, (int) VisibilityFlags.Ghost, false); - _visibilitySystem.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); + _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Normal, false); _visibilitySystem.RefreshVisibility(uid, visibilityComponent: visibility); } @@ -174,8 +174,8 @@ private void OnGhostShutdown(EntityUid uid, GhostComponent component, ComponentS // Entity can't be seen by ghosts anymore. if (TryComp(uid, out VisibilityComponent? visibility)) { - _visibilitySystem.RemoveLayer(uid, visibility, (int) VisibilityFlags.Ghost, false); - _visibilitySystem.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); + _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Normal, false); _visibilitySystem.RefreshVisibility(uid, visibilityComponent: visibility); } @@ -382,13 +382,13 @@ public void MakeVisible(bool visible) { if (visible) { - _visibilitySystem.AddLayer(uid, vis, (int) VisibilityFlags.Normal, false); - _visibilitySystem.RemoveLayer(uid, vis, (int) VisibilityFlags.Ghost, false); + _visibilitySystem.AddLayer((uid, vis), (int) VisibilityFlags.Normal, false); + _visibilitySystem.RemoveLayer((uid, vis), (int) VisibilityFlags.Ghost, false); } else { - _visibilitySystem.AddLayer(uid, vis, (int) VisibilityFlags.Ghost, false); - _visibilitySystem.RemoveLayer(uid, vis, (int) VisibilityFlags.Normal, false); + _visibilitySystem.AddLayer((uid, vis), (int) VisibilityFlags.Ghost, false); + _visibilitySystem.RemoveLayer((uid, vis), (int) VisibilityFlags.Normal, false); } _visibilitySystem.RefreshVisibility(uid, visibilityComponent: vis); } diff --git a/Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs b/Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs index 6c2a6986fc..6116173f90 100644 --- a/Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs +++ b/Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs @@ -5,7 +5,7 @@ namespace Content.Server.Ghost.Roles.Components /// /// Allows a ghost to take this role, spawning a new entity. /// - [RegisterComponent] + [RegisterComponent, EntityCategory("Spawner")] [Access(typeof(GhostRoleSystem))] public sealed partial class GhostRoleMobSpawnerComponent : Component { diff --git a/Content.Server/Humanoid/Components/RandomHumanoidSpawnerComponent.cs b/Content.Server/Humanoid/Components/RandomHumanoidSpawnerComponent.cs index b56664fe19..bb38e94e04 100644 --- a/Content.Server/Humanoid/Components/RandomHumanoidSpawnerComponent.cs +++ b/Content.Server/Humanoid/Components/RandomHumanoidSpawnerComponent.cs @@ -8,7 +8,7 @@ namespace Content.Server.Humanoid.Components; /// This is added to a marker entity in order to spawn a randomized /// humanoid ingame. /// -[RegisterComponent] +[RegisterComponent, EntityCategory("Spawner")] public sealed partial class RandomHumanoidSpawnerComponent : Component { [DataField("settings", customTypeSerializer: typeof(PrototypeIdSerializer))] diff --git a/Content.Server/Interaction/InteractionSystem.cs b/Content.Server/Interaction/InteractionSystem.cs index 4eac7e9ef1..9ac82b2185 100644 --- a/Content.Server/Interaction/InteractionSystem.cs +++ b/Content.Server/Interaction/InteractionSystem.cs @@ -7,31 +7,6 @@ namespace Content.Server.Interaction { - /// - /// Governs interactions during clicking on entities - /// - [UsedImplicitly] - public sealed partial class InteractionSystem : SharedInteractionSystem - { - [Dependency] private readonly SharedContainerSystem _container = default!; - [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; - - public override bool CanAccessViaStorage(EntityUid user, EntityUid target) - { - if (Deleted(target)) - return false; - - if (!_container.TryGetContainingContainer(target, out var container)) - return false; - - if (!TryComp(container.Owner, out StorageComponent? storage)) - return false; - - if (storage.Container?.ID != container.ID) - return false; - - // we don't check if the user can access the storage entity itself. This should be handed by the UI system. - return _uiSystem.IsUiOpen(container.Owner, StorageComponent.StorageUiKey.Key, user); - } - } + // TODO Remove Shared prefix + public sealed class InteractionSystem : SharedInteractionSystem; } diff --git a/Content.Server/Jobs/AddComponentSpecial.cs b/Content.Server/Jobs/AddComponentSpecial.cs index c57d734354..3264c54cd5 100644 --- a/Content.Server/Jobs/AddComponentSpecial.cs +++ b/Content.Server/Jobs/AddComponentSpecial.cs @@ -8,8 +8,7 @@ namespace Content.Server.Jobs [UsedImplicitly] public sealed partial class AddComponentSpecial : JobSpecial { - [DataField("components")] - [AlwaysPushInheritance] + [DataField, AlwaysPushInheritance] public ComponentRegistry Components { get; private set; } = new(); public override void AfterEquip(EntityUid mob) diff --git a/Content.Server/LifeDrainer/LifeDrainerSystem.cs b/Content.Server/LifeDrainer/LifeDrainerSystem.cs index 900438ff71..439a5dcf45 100644 --- a/Content.Server/LifeDrainer/LifeDrainerSystem.cs +++ b/Content.Server/LifeDrainer/LifeDrainerSystem.cs @@ -107,7 +107,7 @@ public bool IsDraining(LifeDrainerComponent comp) public bool TryDrain(Entity ent, EntityUid target) { var (uid, comp) = ent; - if (!CanDrain(ent, target) || !_actionBlocker.CanInteract(uid, target) || !_interaction.InRangeUnobstructed(ent, target, popup: true)) + if (!CanDrain(ent, target) || !_actionBlocker.CanInteract(uid, target) || !_interaction.InRangeUnobstructed(ent.Owner, target, popup: true)) return false; _popup.PopupEntity(Loc.GetString("life-drain-second-start", ("drainer", uid)), target, target, PopupType.LargeCaution); diff --git a/Content.Server/Medical/CryoPodSystem.cs b/Content.Server/Medical/CryoPodSystem.cs index e693274fa3..023a2e4083 100644 --- a/Content.Server/Medical/CryoPodSystem.cs +++ b/Content.Server/Medical/CryoPodSystem.cs @@ -206,6 +206,7 @@ private void OnActivateUI(Entity entity, ref AfterActivatableU ? bloodSolution.FillFraction : 0, null, + null, null )); } diff --git a/Content.Server/Medical/HealthAnalyzerSystem.cs b/Content.Server/Medical/HealthAnalyzerSystem.cs index 76616ac801..76d09c42f0 100644 --- a/Content.Server/Medical/HealthAnalyzerSystem.cs +++ b/Content.Server/Medical/HealthAnalyzerSystem.cs @@ -3,6 +3,8 @@ using Content.Server.Medical.Components; using Content.Server.PowerCell; using Content.Server.Temperature.Components; +using Content.Server.Traits.Assorted; +using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Damage; using Content.Shared.DoAfter; using Content.Shared.Interaction; @@ -186,6 +188,7 @@ public void UpdateScannedUser(EntityUid healthAnalyzer, EntityUid target, bool s var bloodAmount = float.NaN; var bleeding = false; + var unrevivable = false; if (TryComp(target, out var bloodstream) && _solutionContainerSystem.ResolveSolution(target, bloodstream.BloodSolutionName, @@ -195,12 +198,16 @@ public void UpdateScannedUser(EntityUid healthAnalyzer, EntityUid target, bool s bleeding = bloodstream.BleedAmount > 0; } + /*if (HasComp(target)) Somehow we dont have unrevivable??? + unrevivable = true; + */ _uiSystem.ServerSendUiMessage(healthAnalyzer, HealthAnalyzerUiKey.Key, new HealthAnalyzerScannedUserMessage( GetNetEntity(target), bodyTemperature, bloodAmount, scanMode, - bleeding + bleeding, + unrevivable )); } } diff --git a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs index 0ec75790a4..bd904a03b0 100644 --- a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs +++ b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Server.Access.Systems; using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Components; @@ -371,8 +372,8 @@ public void SetSensor(EntityUid uid, SuitSensorMode mode, EntityUid? userUid = n if (transform.GridUid != null) { coordinates = new EntityCoordinates(transform.GridUid.Value, - _transform.GetInvWorldMatrix(xformQuery.GetComponent(transform.GridUid.Value), xformQuery) - .Transform(_transform.GetWorldPosition(transform, xformQuery))); + Vector2.Transform(_transform.GetWorldPosition(transform, xformQuery), + _transform.GetInvWorldMatrix(xformQuery.GetComponent(transform.GridUid.Value), xformQuery))); } else if (transform.MapUid != null) { diff --git a/Content.Server/NPC/Pathfinding/PathfindingSystem.Distance.cs b/Content.Server/NPC/Pathfinding/PathfindingSystem.Distance.cs index 95d5c9c465..35deb6a0ca 100644 --- a/Content.Server/NPC/Pathfinding/PathfindingSystem.Distance.cs +++ b/Content.Server/NPC/Pathfinding/PathfindingSystem.Distance.cs @@ -36,7 +36,7 @@ private Vector2 GetDiff(PathPoly start, PathPoly end) return Vector2.Zero; } - endPos = startXform.InvWorldMatrix.Transform(endXform.WorldMatrix.Transform(endPos)); + endPos = Vector2.Transform(Vector2.Transform(endPos, endXform.WorldMatrix), startXform.InvWorldMatrix); } // TODO: Numerics when we changeover. diff --git a/Content.Server/NPC/Pathfinding/PathfindingSystem.Grid.cs b/Content.Server/NPC/Pathfinding/PathfindingSystem.Grid.cs index 6462c10fe5..35122e3e62 100644 --- a/Content.Server/NPC/Pathfinding/PathfindingSystem.Grid.cs +++ b/Content.Server/NPC/Pathfinding/PathfindingSystem.Grid.cs @@ -395,7 +395,7 @@ private Vector2i GetOrigin(Vector2 localPos) private Vector2i GetOrigin(EntityCoordinates coordinates, EntityUid gridUid) { - var localPos = _transform.GetInvWorldMatrix(gridUid).Transform(coordinates.ToMapPos(EntityManager, _transform)); + var localPos = Vector2.Transform(coordinates.ToMapPos(EntityManager, _transform), _transform.GetInvWorldMatrix(gridUid)); return new Vector2i((int) Math.Floor(localPos.X / ChunkSize), (int) Math.Floor(localPos.Y / ChunkSize)); } diff --git a/Content.Server/NPC/Pathfinding/PathfindingSystem.cs b/Content.Server/NPC/Pathfinding/PathfindingSystem.cs index a59af88ff5..af9c44a1ef 100644 --- a/Content.Server/NPC/Pathfinding/PathfindingSystem.cs +++ b/Content.Server/NPC/Pathfinding/PathfindingSystem.cs @@ -405,7 +405,7 @@ public async void GetPathEvent( return null; } - var localPos = xform.InvWorldMatrix.Transform(coordinates.ToMapPos(EntityManager, _transform)); + var localPos = Vector2.Transform(coordinates.ToMapPos(EntityManager, _transform), xform.InvWorldMatrix); var origin = GetOrigin(localPos); if (!TryGetChunk(origin, comp, out var chunk)) diff --git a/Content.Server/Pointing/EntitySystems/PointingSystem.cs b/Content.Server/Pointing/EntitySystems/PointingSystem.cs index 9b2e14eff8..c9e86772fb 100644 --- a/Content.Server/Pointing/EntitySystems/PointingSystem.cs +++ b/Content.Server/Pointing/EntitySystems/PointingSystem.cs @@ -171,7 +171,7 @@ public bool TryPoint(ICommonSession? session, EntityCoordinates coordsPointed, E { var arrowVisibility = EntityManager.EnsureComponent(arrow); layer = playerVisibility.Layer; - _visibilitySystem.SetLayer(arrow, arrowVisibility, layer); + _visibilitySystem.SetLayer((arrow, arrowVisibility), (ushort) layer); } // Get players that are in range and whose visibility layer matches the arrow's. diff --git a/Content.Server/Power/EntitySystems/PowerNetSystem.cs b/Content.Server/Power/EntitySystems/PowerNetSystem.cs index 07ecc2eafb..2d80c810e2 100644 --- a/Content.Server/Power/EntitySystems/PowerNetSystem.cs +++ b/Content.Server/Power/EntitySystems/PowerNetSystem.cs @@ -3,9 +3,11 @@ using Content.Server.Power.Components; using Content.Server.Power.NodeGroups; using Content.Server.Power.Pow3r; +using Content.Shared.CCVar; using Content.Shared.Power; using JetBrains.Annotations; using Robust.Server.GameObjects; +using Robust.Shared.Configuration; using Robust.Shared.Threading; namespace Content.Server.Power.EntitySystems @@ -18,19 +20,21 @@ public sealed class PowerNetSystem : EntitySystem { [Dependency] private readonly AppearanceSystem _appearance = default!; [Dependency] private readonly PowerNetConnectorSystem _powerNetConnector = default!; + [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IParallelManager _parMan = default!; private readonly PowerState _powerState = new(); private readonly HashSet _powerNetReconnectQueue = new(); private readonly HashSet _apcNetReconnectQueue = new(); - private readonly BatteryRampPegSolver _solver = new(); + private BatteryRampPegSolver _solver = new(); public override void Initialize() { base.Initialize(); UpdatesAfter.Add(typeof(NodeGroupSystem)); + _solver = new(_cfg.GetCVar(CCVars.DebugPow3rDisableParallel)); SubscribeLocalEvent(ApcPowerReceiverInit); SubscribeLocalEvent(ApcPowerReceiverShutdown); @@ -52,6 +56,13 @@ public override void Initialize() SubscribeLocalEvent(PowerSupplierShutdown); SubscribeLocalEvent(PowerSupplierPaused); SubscribeLocalEvent(PowerSupplierUnpaused); + + Subs.CVar(_cfg, CCVars.DebugPow3rDisableParallel, DebugPow3rDisableParallelChanged); + } + + private void DebugPow3rDisableParallelChanged(bool val) + { + _solver = new(val); } private void ApcPowerReceiverInit(EntityUid uid, ApcPowerReceiverComponent component, ComponentInit args) diff --git a/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs b/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs index 5d52bde377..34ed2695f5 100644 --- a/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs +++ b/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs @@ -8,9 +8,11 @@ namespace Content.Server.Power.Pow3r public sealed class BatteryRampPegSolver : IPowerSolver { private UpdateNetworkJob _networkJob; + private bool _disableParallel; - public BatteryRampPegSolver() + public BatteryRampPegSolver(bool disableParallel = false) { + _disableParallel = disableParallel; _networkJob = new() { Solver = this, @@ -54,7 +56,10 @@ public void Tick(float frameTime, PowerState state, IParallelManager parallel) // suppliers + discharger) Then decide based on total layer size whether its worth parallelizing that // layer? _networkJob.Networks = group; - parallel.ProcessNow(_networkJob, group.Count); + if (_disableParallel) + parallel.ProcessSerialNow(_networkJob, group.Count); + else + parallel.ProcessNow(_networkJob, group.Count); } ClearBatteries(state); diff --git a/Content.Server/Procedural/DungeonJob.PrefabDunGen.cs b/Content.Server/Procedural/DungeonJob.PrefabDunGen.cs index 1783a56790..a19f7e4701 100644 --- a/Content.Server/Procedural/DungeonJob.PrefabDunGen.cs +++ b/Content.Server/Procedural/DungeonJob.PrefabDunGen.cs @@ -19,7 +19,7 @@ private async Task GeneratePrefabDungeon(PrefabDunGen prefab, EntityUid var gen = _prototype.Index(preset); var dungeonRotation = _dungeon.GetDungeonRotation(seed); - var dungeonTransform = Matrix3.CreateTransform(_position, dungeonRotation); + var dungeonTransform = Matrix3Helpers.CreateTransform(_position, dungeonRotation); var roomPackProtos = new Dictionary>(); foreach (var pack in _prototype.EnumeratePrototypes()) @@ -69,7 +69,7 @@ private async Task GeneratePrefabDungeon(PrefabDunGen prefab, EntityUid var dungeon = new Dungeon(); var availablePacks = new List(); var chosenPacks = new DungeonRoomPackPrototype?[gen.RoomPacks.Count]; - var packTransforms = new Matrix3[gen.RoomPacks.Count]; + var packTransforms = new Matrix3x2[gen.RoomPacks.Count]; var packRotations = new Angle[gen.RoomPacks.Count]; // Actually pick the room packs and rooms @@ -97,7 +97,7 @@ private async Task GeneratePrefabDungeon(PrefabDunGen prefab, EntityUid // Iterate every pack random.Shuffle(availablePacks); - Matrix3 packTransform = default!; + Matrix3x2 packTransform = default!; var found = false; DungeonRoomPackPrototype pack = default!; @@ -128,7 +128,7 @@ private async Task GeneratePrefabDungeon(PrefabDunGen prefab, EntityUid var aRotation = dir.AsDir().ToAngle(); // Use this pack - packTransform = Matrix3.CreateTransform(bounds.Center, aRotation); + packTransform = Matrix3Helpers.CreateTransform(bounds.Center, aRotation); packRotations[i] = aRotation; pack = aPack; break; @@ -168,7 +168,7 @@ private async Task GeneratePrefabDungeon(PrefabDunGen prefab, EntityUid { var roomDimensions = new Vector2i(roomSize.Width, roomSize.Height); Angle roomRotation = Angle.Zero; - Matrix3 matty; + Matrix3x2 matty; if (!roomProtos.TryGetValue(roomDimensions, out var roomProto)) { @@ -176,13 +176,13 @@ private async Task GeneratePrefabDungeon(PrefabDunGen prefab, EntityUid if (!roomProtos.TryGetValue(roomDimensions, out roomProto)) { - Matrix3.Multiply(packTransform, dungeonTransform, out matty); + matty = Matrix3x2.Multiply(packTransform, dungeonTransform); for (var x = roomSize.Left; x < roomSize.Right; x++) { for (var y = roomSize.Bottom; y < roomSize.Top; y++) { - var index = matty.Transform(new Vector2(x, y) + grid.TileSizeHalfVector - packCenter).Floored(); + var index = Vector2.Transform(new Vector2(x, y) + grid.TileSizeHalfVector - packCenter, matty).Floored(); tiles.Add((index, new Tile(_tileDefManager["FloorPlanetGrass"].TileId))); } } @@ -209,10 +209,10 @@ private async Task GeneratePrefabDungeon(PrefabDunGen prefab, EntityUid roomRotation += Math.PI; } - var roomTransform = Matrix3.CreateTransform(roomSize.Center - packCenter, roomRotation); + var roomTransform = Matrix3Helpers.CreateTransform(roomSize.Center - packCenter, roomRotation); - Matrix3.Multiply(roomTransform, packTransform, out matty); - Matrix3.Multiply(matty, dungeonTransform, out var dungeonMatty); + matty = Matrix3x2.Multiply(roomTransform, packTransform); + var dungeonMatty = Matrix3x2.Multiply(matty, dungeonTransform); // The expensive bit yippy. _dungeon.SpawnRoom(gridUid, grid, dungeonMatty, room); @@ -232,7 +232,7 @@ private async Task GeneratePrefabDungeon(PrefabDunGen prefab, EntityUid continue; } - var tilePos = dungeonMatty.Transform(new Vector2i(x + room.Offset.X, y + room.Offset.Y) + tileOffset); + var tilePos = Vector2.Transform(new Vector2i(x + room.Offset.X, y + room.Offset.Y) + tileOffset, dungeonMatty); exterior.Add(tilePos.Floored()); } } @@ -244,7 +244,7 @@ private async Task GeneratePrefabDungeon(PrefabDunGen prefab, EntityUid for (var y = 0; y < room.Size.Y; y++) { var roomTile = new Vector2i(x + room.Offset.X, y + room.Offset.Y); - var tilePos = dungeonMatty.Transform(roomTile + tileOffset); + var tilePos = Vector2.Transform(roomTile + tileOffset, dungeonMatty); var tileIndex = tilePos.Floored(); roomTiles.Add(tileIndex); diff --git a/Content.Server/Procedural/DungeonSystem.Rooms.cs b/Content.Server/Procedural/DungeonSystem.Rooms.cs index 03bcc2b4b1..5b4de34906 100644 --- a/Content.Server/Procedural/DungeonSystem.Rooms.cs +++ b/Content.Server/Procedural/DungeonSystem.Rooms.cs @@ -67,7 +67,7 @@ public void SpawnRoom( bool clearExisting = false, bool rotation = false) { - var originTransform = Matrix3.CreateTranslation(origin); + var originTransform = Matrix3Helpers.CreateTranslation(origin.X, origin.Y); var roomRotation = Angle.Zero; if (rotation) @@ -75,8 +75,8 @@ public void SpawnRoom( roomRotation = GetRoomRotation(room, random); } - var roomTransform = Matrix3.CreateTransform((Vector2) room.Size / 2f, roomRotation); - Matrix3.Multiply(roomTransform, originTransform, out var finalTransform); + var roomTransform = Matrix3Helpers.CreateTransform((Vector2) room.Size / 2f, roomRotation); + var finalTransform = Matrix3x2.Multiply(roomTransform, originTransform); SpawnRoom(gridUid, grid, finalTransform, room, clearExisting); } @@ -101,7 +101,7 @@ public Angle GetRoomRotation(DungeonRoomPrototype room, Random random) public void SpawnRoom( EntityUid gridUid, MapGridComponent grid, - Matrix3 roomTransform, + Matrix3x2 roomTransform, DungeonRoomPrototype room, bool clearExisting = false) { @@ -116,7 +116,7 @@ public void SpawnRoom( // go BRRNNTTT on existing stuff if (clearExisting) { - var gridBounds = new Box2(roomTransform.Transform(Vector2.Zero), roomTransform.Transform(room.Size)); + var gridBounds = new Box2(Vector2.Transform(Vector2.Zero, roomTransform), Vector2.Transform(room.Size, roomTransform)); _entitySet.Clear(); // Polygon skin moment gridBounds = gridBounds.Enlarged(-0.05f); @@ -148,7 +148,7 @@ public void SpawnRoom( var indices = new Vector2i(x + room.Offset.X, y + room.Offset.Y); var tileRef = _maps.GetTileRef(templateMapUid, templateGrid, indices); - var tilePos = roomTransform.Transform(indices + tileOffset); + var tilePos = Vector2.Transform(indices + tileOffset, roomTransform); var rounded = tilePos.Floored(); _tiles.Add((rounded, tileRef.Tile)); } @@ -164,7 +164,7 @@ public void SpawnRoom( foreach (var templateEnt in _lookup.GetEntitiesIntersecting(templateMapUid, bounds, LookupFlags.Uncontained)) { var templateXform = _xformQuery.GetComponent(templateEnt); - var childPos = roomTransform.Transform(templateXform.LocalPosition - roomCenter); + var childPos = Vector2.Transform(templateXform.LocalPosition - roomCenter, roomTransform); var childRot = templateXform.LocalRotation + finalRoomRotation; var protoId = _metaQuery.GetComponent(templateEnt).EntityPrototype?.ID; @@ -192,7 +192,7 @@ public void SpawnRoom( // Offset by 0.5 because decals are offset from bot-left corner // So we convert it to center of tile then convert it back again after transform. // Do these shenanigans because 32x32 decals assume as they are centered on bottom-left of tiles. - var position = roomTransform.Transform(decal.Coordinates + Vector2Helpers.Half - roomCenter); + var position = Vector2.Transform(decal.Coordinates + Vector2Helpers.Half - roomCenter, roomTransform); position -= Vector2Helpers.Half; // Umm uhh I love decals so uhhhh idk what to do about this diff --git a/Content.Server/Psionics/Invisibility/PsionicInvisibilitySystem.cs b/Content.Server/Psionics/Invisibility/PsionicInvisibilitySystem.cs index 751dc28f8c..b9aac6ccee 100644 --- a/Content.Server/Psionics/Invisibility/PsionicInvisibilitySystem.cs +++ b/Content.Server/Psionics/Invisibility/PsionicInvisibilitySystem.cs @@ -78,8 +78,8 @@ private void OnInvisInit(EntityUid uid, PsionicallyInvisibleComponent component, { var visibility = EntityManager.EnsureComponent(uid); - _visibilitySystem.AddLayer(uid, visibility, (int) VisibilityFlags.PsionicInvisibility, false); - _visibilitySystem.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.PsionicInvisibility, false); + _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Normal, false); _visibilitySystem.RefreshVisibility(uid, visibility); } @@ -88,8 +88,8 @@ private void OnInvisShutdown(EntityUid uid, PsionicallyInvisibleComponent compon { if (TryComp(uid, out var visibility)) { - _visibilitySystem.RemoveLayer(uid, visibility, (int) VisibilityFlags.PsionicInvisibility, false); - _visibilitySystem.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.PsionicInvisibility, false); + _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Normal, false); _visibilitySystem.RefreshVisibility(uid, visibility); } } diff --git a/Content.Server/Punpun/PunpunComponent.cs b/Content.Server/Punpun/PunpunComponent.cs new file mode 100644 index 0000000000..19d2da42c9 --- /dev/null +++ b/Content.Server/Punpun/PunpunComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Server.Punpun; + +[RegisterComponent] +public sealed partial class PunpunComponent : Component +{ + /// How many rounds Punpun will be around for before disappearing with a note + [DataField] + public int Lifetime = 14; +} diff --git a/Content.Server/Punpun/PunpunSystem.cs b/Content.Server/Punpun/PunpunSystem.cs new file mode 100644 index 0000000000..5f1f22b42a --- /dev/null +++ b/Content.Server/Punpun/PunpunSystem.cs @@ -0,0 +1,114 @@ +using System.Linq; +using Content.Server.GameTicking; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Inventory; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Robust.Server.GameObjects; + +namespace Content.Server.Punpun; + +public sealed class PunpunSystem : EntitySystem +{ + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly ServerMetaDataSystem _meta = default!; + + private (int, string, string, string) _punpunData = (1, string.Empty, string.Empty, string.Empty); + + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnRoundStart); + SubscribeLocalEvent(OnRoundEnd); + } + + + // Checks if the Punpun data has any items to equip, and names the Punpun upon initialization + private void OnRoundStart(EntityUid uid, PunpunComponent component, ComponentStartup args) + { + if (_punpunData.Item1 > component.Lifetime) + { + EntityManager.SpawnEntity("PaperWrittenPunpunNote", Transform(uid).Coordinates); + EntityManager.QueueDeleteEntity(uid); + _punpunData = (1, string.Empty, string.Empty, string.Empty); + + return; + } + + var meta = MetaData(uid); + _meta.SetEntityName(uid, $"{meta.EntityName} {ToRomanNumeral(_punpunData.Item1)}", meta); + + if (!EntityManager.TryGetComponent(uid, out _)) + return; + EquipItem(uid, "head", _punpunData.Item2); + EquipItem(uid, "mask", _punpunData.Item3); + EquipItem(uid, "jumpsuit", _punpunData.Item4); + } + + // Checks if Punpun exists, and is alive at round end + // If so, stores the items and increments the Punpun count + private void OnRoundEnd(RoundEndTextAppendEvent ev) + { + // I couldn't find a method to get a single entity, so this just enumerates over the first and disposes it + var punpunComponents = EntityManager.EntityQueryEnumerator(); + punpunComponents.MoveNext(out var punpun, out _); + + if (!EntityManager.TryGetComponent(punpun, out var mobState) + || mobState.CurrentState == MobState.Dead) + _punpunData = (1, string.Empty, string.Empty, string.Empty); + + _punpunData.Item1++; + + if (EntityManager.HasComponent(punpun)) + { + _punpunData.Item2 = CheckSlot(punpun, "head"); + _punpunData.Item3 = CheckSlot(punpun, "mask"); + _punpunData.Item4 = CheckSlot(punpun, "jumpsuit"); + } + + punpunComponents.Dispose(); + } + + // Equips an item to a slot, and names it. + private void EquipItem(EntityUid uid, string slot, string item) + { + if (item == string.Empty) + return; + + var itemEnt = EntityManager.SpawnEntity(item, EntityManager.GetComponent(uid).Coordinates); + if (_inventory.TryEquip(uid, itemEnt, slot, true, true)) + _meta.SetEntityName(itemEnt, $"{MetaData(uid).EntityName}'s {MetaData(itemEnt).EntityName}"); + else + EntityManager.DeleteEntity(itemEnt); + } + + // Checks if an item exists in a slot, and returns its name + private string CheckSlot(EntityUid uid, string slot) + { + return _inventory.TryGetSlotEntity(uid, slot, out var item) + ? EntityManager.GetComponent(item.Value).EntityPrototype!.ID + : string.Empty; + } + + + // Punpun, the lord of Roman Numerals + public static List RomanNumerals = new() { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" }; + public static List Numerals = new() { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }; + + public static string ToRomanNumeral(int number) + { + var romanNumeral = string.Empty; + while (number > 0) + { + // Find the biggest numeral that is less than equal to number + var index = Numerals.FindIndex(x => x <= number); + // Subtract its value from your number + number -= Numerals[index]; + // Add it onto the end of your roman numeral + romanNumeral += RomanNumerals[index]; + } + return romanNumeral; + } +} diff --git a/Content.Server/Radiation/Systems/RadiationSystem.GridCast.cs b/Content.Server/Radiation/Systems/RadiationSystem.GridCast.cs index b8193c4d2f..ccee7cf227 100644 --- a/Content.Server/Radiation/Systems/RadiationSystem.GridCast.cs +++ b/Content.Server/Radiation/Systems/RadiationSystem.GridCast.cs @@ -195,11 +195,11 @@ private RadiationRay Gridcast(Entity grid, RadiationRay ray, b Vector2 srcLocal = sourceTrs.ParentUid == grid.Owner ? sourceTrs.LocalPosition - : gridTrs.InvLocalMatrix.Transform(ray.Source); + : Vector2.Transform(ray.Source, gridTrs.InvLocalMatrix); Vector2 dstLocal = destTrs.ParentUid == grid.Owner ? destTrs.LocalPosition - : gridTrs.InvLocalMatrix.Transform(ray.Destination); + : Vector2.Transform(ray.Destination, gridTrs.InvLocalMatrix); Vector2i sourceGrid = new( (int) Math.Floor(srcLocal.X / grid.Comp.TileSize), diff --git a/Content.Server/Radio/EntitySystems/RadioSystem.cs b/Content.Server/Radio/EntitySystems/RadioSystem.cs index 023b660ef8..71fb4ff502 100644 --- a/Content.Server/Radio/EntitySystems/RadioSystem.cs +++ b/Content.Server/Radio/EntitySystems/RadioSystem.cs @@ -166,6 +166,9 @@ private string WrapRadioMessage(EntityUid source, RadioChannelPrototype channel, var languageColor = channel.Color; if (language.SpeechOverride.Color is { } colorOverride) languageColor = Color.InterpolateBetween(languageColor, colorOverride, colorOverride.A); + var languageDisplay = language.IsVisibleLanguage + ? $"{language.ChatName} | " + : ""; return Loc.GetString(speech.Bold ? "chat-radio-message-wrap-bold" : "chat-radio-message-wrap", ("color", channel.Color), @@ -175,7 +178,8 @@ private string WrapRadioMessage(EntityUid source, RadioChannelPrototype channel, ("verb", Loc.GetString(_random.Pick(speech.SpeechVerbStrings))), ("channel", $"\\[{channel.LocalizedName}\\]"), ("name", name), - ("message", message)); + ("message", message), + ("language", languageDisplay)); } /// diff --git a/Content.Server/Revenant/EntitySystems/CorporealSystem.cs b/Content.Server/Revenant/EntitySystems/CorporealSystem.cs index 1d43cb3ac8..5f31a2f280 100644 --- a/Content.Server/Revenant/EntitySystems/CorporealSystem.cs +++ b/Content.Server/Revenant/EntitySystems/CorporealSystem.cs @@ -1,4 +1,4 @@ -using Content.Server.GameTicking; +using Content.Server.GameTicking; using Content.Shared.Eye; using Content.Shared.Revenant.Components; using Content.Shared.Revenant.EntitySystems; @@ -17,8 +17,8 @@ public override void OnStartup(EntityUid uid, CorporealComponent component, Comp if (TryComp(uid, out var visibility)) { - _visibilitySystem.RemoveLayer(uid, visibility, (int) VisibilityFlags.Ghost, false); - _visibilitySystem.AddLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); + _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Normal, false); _visibilitySystem.RefreshVisibility(uid, visibility); } } @@ -29,8 +29,8 @@ public override void OnShutdown(EntityUid uid, CorporealComponent component, Com if (TryComp(uid, out var visibility) && _ticker.RunLevel != GameRunLevel.PostRound) { - _visibilitySystem.AddLayer(uid, visibility, (int) VisibilityFlags.Ghost, false); - _visibilitySystem.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); + _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Normal, false); _visibilitySystem.RefreshVisibility(uid, visibility); } } diff --git a/Content.Server/Revenant/EntitySystems/RevenantSystem.cs b/Content.Server/Revenant/EntitySystems/RevenantSystem.cs index 86be70c41f..428d1ecb75 100644 --- a/Content.Server/Revenant/EntitySystems/RevenantSystem.cs +++ b/Content.Server/Revenant/EntitySystems/RevenantSystem.cs @@ -77,8 +77,8 @@ private void OnStartup(EntityUid uid, RevenantComponent component, ComponentStar if (_ticker.RunLevel == GameRunLevel.PostRound && TryComp(uid, out var visibility)) { - _visibility.AddLayer(uid, visibility, (int) VisibilityFlags.Ghost, false); - _visibility.RemoveLayer(uid, visibility, (int) VisibilityFlags.Normal, false); + _visibility.AddLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); + _visibility.RemoveLayer((uid, visibility), (int) VisibilityFlags.Normal, false); _visibility.RefreshVisibility(uid, visibility); } @@ -191,13 +191,13 @@ public void MakeVisible(bool visible) { if (visible) { - _visibility.AddLayer(uid, vis, (int) VisibilityFlags.Normal, false); - _visibility.RemoveLayer(uid, vis, (int) VisibilityFlags.Ghost, false); + _visibility.AddLayer((uid, vis), (int) VisibilityFlags.Normal, false); + _visibility.RemoveLayer((uid, vis), (int) VisibilityFlags.Ghost, false); } else { - _visibility.AddLayer(uid, vis, (int) VisibilityFlags.Ghost, false); - _visibility.RemoveLayer(uid, vis, (int) VisibilityFlags.Normal, false); + _visibility.AddLayer((uid, vis), (int) VisibilityFlags.Ghost, false); + _visibility.RemoveLayer((uid, vis), (int) VisibilityFlags.Normal, false); } _visibility.RefreshVisibility(uid, vis); } diff --git a/Content.Server/Salvage/FultonSystem.cs b/Content.Server/Salvage/FultonSystem.cs index a24bab4584..8c656790e9 100644 --- a/Content.Server/Salvage/FultonSystem.cs +++ b/Content.Server/Salvage/FultonSystem.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Shared.Salvage.Fulton; using Robust.Shared.Containers; using Robust.Shared.Map; @@ -61,8 +62,9 @@ private void Fulton(EntityUid uid, FultonedComponent component) var metadata = MetaData(uid); var oldCoords = xform.Coordinates; var offset = _random.NextVector2(1.5f); - var localPos = TransformSystem.GetInvWorldMatrix(beaconXform.ParentUid) - .Transform(TransformSystem.GetWorldPosition(beaconXform)) + offset; + var localPos = Vector2.Transform( + TransformSystem.GetWorldPosition(beaconXform), + TransformSystem.GetInvWorldMatrix(beaconXform.ParentUid)) + offset; TransformSystem.SetCoordinates(uid, new EntityCoordinates(beaconXform.ParentUid, localPos)); diff --git a/Content.Server/Shuttles/Events/FTLStartedEvent.cs b/Content.Server/Shuttles/Events/FTLStartedEvent.cs index 965da7f0c5..eafbeddd5c 100644 --- a/Content.Server/Shuttles/Events/FTLStartedEvent.cs +++ b/Content.Server/Shuttles/Events/FTLStartedEvent.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Robust.Shared.Map; namespace Content.Server.Shuttles.Events; @@ -6,4 +7,4 @@ namespace Content.Server.Shuttles.Events; /// Raised when a shuttle has moved to FTL space. /// [ByRefEvent] -public readonly record struct FTLStartedEvent(EntityUid Entity, EntityCoordinates TargetCoordinates, EntityUid? FromMapUid, Matrix3 FTLFrom, Angle FromRotation); +public readonly record struct FTLStartedEvent(EntityUid Entity, EntityCoordinates TargetCoordinates, EntityUid? FromMapUid, Matrix3x2 FTLFrom, Angle FromRotation); diff --git a/Content.Server/Shuttles/Systems/ArrivalsSystem.cs b/Content.Server/Shuttles/Systems/ArrivalsSystem.cs index fef671fc30..62fe3e13ff 100644 --- a/Content.Server/Shuttles/Systems/ArrivalsSystem.cs +++ b/Content.Server/Shuttles/Systems/ArrivalsSystem.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Numerics; using Content.Server.Administration; using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Systems; @@ -278,7 +279,7 @@ private void DumpChildren(EntityUid uid, ref FTLStartedEvent args) foreach (var (ent, xform) in toDump) { var rotation = xform.LocalRotation; - _transform.SetCoordinates(ent, new EntityCoordinates(args.FromMapUid!.Value, args.FTLFrom.Transform(xform.LocalPosition))); + _transform.SetCoordinates(ent, new EntityCoordinates(args.FromMapUid!.Value, Vector2.Transform(xform.LocalPosition, args.FTLFrom))); _transform.SetWorldRotation(ent, args.FromRotation + rotation); } } diff --git a/Content.Server/Shuttles/Systems/DockingSystem.Shuttle.cs b/Content.Server/Shuttles/Systems/DockingSystem.Shuttle.cs index e46a7c715f..1a95ef9cb2 100644 --- a/Content.Server/Shuttles/Systems/DockingSystem.Shuttle.cs +++ b/Content.Server/Shuttles/Systems/DockingSystem.Shuttle.cs @@ -46,13 +46,13 @@ private bool CanDock( FixturesComponent shuttleFixtures, MapGridComponent grid, bool isMap, - out Matrix3 matty, + out Matrix3x2 matty, out Box2 shuttleDockedAABB, out Angle gridRotation) { shuttleDockedAABB = Box2.UnitCentered; gridRotation = Angle.Zero; - matty = Matrix3.Identity; + matty = Matrix3x2.Identity; if (shuttleDock.Docked || gridDock.Docked || @@ -71,9 +71,9 @@ private bool CanDock( var gridDockAngle = gridDockXform.LocalRotation.Opposite(); var offsetAngle = gridDockAngle - shuttleDockAngle; - var stationDockMatrix = Matrix3.CreateInverseTransform(stationDockPos, shuttleDockAngle); - var gridXformMatrix = Matrix3.CreateTransform(gridDockXform.LocalPosition, gridDockAngle); - Matrix3.Multiply(in stationDockMatrix, in gridXformMatrix, out matty); + var stationDockMatrix = Matrix3Helpers.CreateInverseTransform(stationDockPos, shuttleDockAngle); + var gridXformMatrix = Matrix3Helpers.CreateTransform(gridDockXform.LocalPosition, gridDockAngle); + matty = Matrix3x2.Multiply(stationDockMatrix, gridXformMatrix); if (!ValidSpawn(grid, matty, offsetAngle, shuttleFixtures, isMap)) return false; @@ -193,7 +193,7 @@ private List GetDockingConfigs( } // Can't just use the AABB as we want to get bounds as tight as possible. - var gridPosition = new EntityCoordinates(targetGrid, matty.Transform(Vector2.Zero)); + var gridPosition = new EntityCoordinates(targetGrid, Vector2.Transform(Vector2.Zero, matty)); var spawnPosition = new EntityCoordinates(targetGridXform.MapUid!.Value, gridPosition.ToMapPos(EntityManager, _transform)); // TODO: use tight bounds @@ -303,9 +303,9 @@ private List GetDockingConfigs( /// /// Checks whether the shuttle can warp to the specified position. /// - private bool ValidSpawn(MapGridComponent grid, Matrix3 matty, Angle angle, FixturesComponent shuttleFixturesComp, bool isMap) + private bool ValidSpawn(MapGridComponent grid, Matrix3x2 matty, Angle angle, FixturesComponent shuttleFixturesComp, bool isMap) { - var transform = new Transform(matty.Transform(Vector2.Zero), angle); + var transform = new Transform(Vector2.Transform(Vector2.Zero, matty), angle); // Because some docking bounds are tight af need to check each chunk individually foreach (var fix in shuttleFixturesComp.Fixtures.Values) diff --git a/Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs index f346398cda..8a8d2d883d 100644 --- a/Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs +++ b/Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Server.Shuttles.Components; using Content.Shared.Audio; using Robust.Shared.Audio; @@ -38,8 +39,8 @@ private void OnShuttleCollide(EntityUid uid, ShuttleComponent component, ref Sta var otherXform = Transform(args.OtherEntity); - var ourPoint = ourXform.InvWorldMatrix.Transform(args.WorldPoint); - var otherPoint = otherXform.InvWorldMatrix.Transform(args.WorldPoint); + var ourPoint = Vector2.Transform(args.WorldPoint, ourXform.InvWorldMatrix); + var otherPoint = Vector2.Transform(args.WorldPoint, otherXform.InvWorldMatrix); var ourVelocity = _physics.GetLinearVelocity(uid, ourPoint, ourBody, ourXform); var otherVelocity = _physics.GetLinearVelocity(args.OtherEntity, otherPoint, otherBody, otherXform); diff --git a/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs b/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs index f1d0af6f90..779b2f5971 100644 --- a/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs +++ b/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Content.Server.Atmos.Components; using Content.Server.Singularity.Components; using Content.Shared.Ghost; @@ -126,7 +127,7 @@ private bool CanGravPulseAffect(EntityUid entity) /// The minimum distance at which entities can be affected by the gravity pulse. /// The base velocity added to any entities within affected by the gravity pulse scaled by the displacement of those entities from the epicenter. /// (optional) The transform of the entity at the epicenter of the gravitational pulse. - public void GravPulse(EntityUid uid, float maxRange, float minRange, in Matrix3 baseMatrixDeltaV, TransformComponent? xform = null) + public void GravPulse(EntityUid uid, float maxRange, float minRange, in Matrix3x2 baseMatrixDeltaV, TransformComponent? xform = null) { if (Resolve(uid, ref xform)) GravPulse(xform.Coordinates, maxRange, minRange, in baseMatrixDeltaV); @@ -154,7 +155,7 @@ public void GravPulse(EntityUid uid, float maxRange, float minRange, float baseR /// The maximum distance at which entities can be affected by the gravity pulse. /// The minimum distance at which entities can be affected by the gravity pulse. /// The base velocity added to any entities within affected by the gravity pulse scaled by the displacement of those entities from the epicenter. - public void GravPulse(EntityCoordinates entityPos, float maxRange, float minRange, in Matrix3 baseMatrixDeltaV) + public void GravPulse(EntityCoordinates entityPos, float maxRange, float minRange, in Matrix3x2 baseMatrixDeltaV) => GravPulse(entityPos.ToMap(EntityManager, _transform), maxRange, minRange, in baseMatrixDeltaV); /// @@ -175,7 +176,7 @@ public void GravPulse(EntityCoordinates entityPos, float maxRange, float minRang /// The maximum distance at which entities can be affected by the gravity pulse. /// The minimum distance at which entities can be affected by the gravity pulse. Exists to prevent div/0 errors. /// The base velocity added to any entities within affected by the gravity pulse scaled by the displacement of those entities from the epicenter. - public void GravPulse(MapCoordinates mapPos, float maxRange, float minRange, in Matrix3 baseMatrixDeltaV) + public void GravPulse(MapCoordinates mapPos, float maxRange, float minRange, in Matrix3x2 baseMatrixDeltaV) { if (mapPos == MapCoordinates.Nullspace) return; // No gravpulses in nullspace please. @@ -205,7 +206,7 @@ public void GravPulse(MapCoordinates mapPos, float maxRange, float minRange, in continue; var scaling = (1f / distance2) * physics.Mass; // TODO: Variable falloff gradiants. - _physics.ApplyLinearImpulse(entity, (displacement * baseMatrixDeltaV) * scaling, body: physics); + _physics.ApplyLinearImpulse(entity, Vector2.Transform(displacement, baseMatrixDeltaV) * scaling, body: physics); } } @@ -218,10 +219,9 @@ public void GravPulse(MapCoordinates mapPos, float maxRange, float minRange, in /// The base amount of velocity that will be added to entities in range towards the epicenter of the pulse. /// The base amount of velocity that will be added to entities in range counterclockwise relative to the epicenter of the pulse. public void GravPulse(MapCoordinates mapPos, float maxRange, float minRange = 0.0f, float baseRadialDeltaV = 0.0f, float baseTangentialDeltaV = 0.0f) - => GravPulse(mapPos, maxRange, minRange, new Matrix3( - baseRadialDeltaV, +baseTangentialDeltaV, 0.0f, - -baseTangentialDeltaV, baseRadialDeltaV, 0.0f, - 0.0f, 0.0f, 1.0f + => GravPulse(mapPos, maxRange, minRange, new Matrix3x2( + baseRadialDeltaV, -baseTangentialDeltaV, 0.0f, + +baseTangentialDeltaV, baseRadialDeltaV, 0.0f )); #endregion GravPulse diff --git a/Content.Server/Spawners/Components/ConditionalSpawnerComponent.cs b/Content.Server/Spawners/Components/ConditionalSpawnerComponent.cs index 5b98989bb3..1b06367b0d 100644 --- a/Content.Server/Spawners/Components/ConditionalSpawnerComponent.cs +++ b/Content.Server/Spawners/Components/ConditionalSpawnerComponent.cs @@ -2,7 +2,7 @@ namespace Content.Server.Spawners.Components { - [RegisterComponent] + [RegisterComponent, EntityCategory("Spawner")] [Virtual] public partial class ConditionalSpawnerComponent : Component { diff --git a/Content.Server/Spawners/Components/RandomSpawnerComponent.cs b/Content.Server/Spawners/Components/RandomSpawnerComponent.cs index 9bf4d6d253..e6a597f365 100644 --- a/Content.Server/Spawners/Components/RandomSpawnerComponent.cs +++ b/Content.Server/Spawners/Components/RandomSpawnerComponent.cs @@ -2,7 +2,7 @@ namespace Content.Server.Spawners.Components { - [RegisterComponent] + [RegisterComponent, EntityCategory("Spawner")] public sealed partial class RandomSpawnerComponent : ConditionalSpawnerComponent { [ViewVariables(VVAccess.ReadWrite)] diff --git a/Content.Server/Spawners/Components/TimedSpawnerComponent.cs b/Content.Server/Spawners/Components/TimedSpawnerComponent.cs index b60afbc88b..828e541717 100644 --- a/Content.Server/Spawners/Components/TimedSpawnerComponent.cs +++ b/Content.Server/Spawners/Components/TimedSpawnerComponent.cs @@ -9,7 +9,7 @@ namespace Content.Server.Spawners.Components; /// Can configure the set of entities, spawn timing, spawn chance, /// and min/max number of entities to spawn. /// -[RegisterComponent] +[RegisterComponent, EntityCategory("Spawner")] public sealed partial class TimedSpawnerComponent : Component, ISerializationHooks { /// diff --git a/Content.Server/StationEvents/Events/ImmovableRodRule.cs b/Content.Server/StationEvents/Events/ImmovableRodRule.cs index 781d0368f4..45d6c18189 100644 --- a/Content.Server/StationEvents/Events/ImmovableRodRule.cs +++ b/Content.Server/StationEvents/Events/ImmovableRodRule.cs @@ -23,7 +23,9 @@ protected override void Started(EntityUid uid, ImmovableRodRuleComponent compone var proto = _prototypeManager.Index(component.RodPrototype); if (proto.TryGetComponent(out var rod) && proto.TryGetComponent(out var despawn)) { - TryFindRandomTile(out _, out _, out _, out var targetCoords); + if (!TryFindRandomTile(out _, out _, out _, out var targetCoords)) + return; + var speed = RobustRandom.NextFloat(rod.MinSpeed, rod.MaxSpeed); var angle = RobustRandom.NextAngle(); var direction = angle.ToVec(); diff --git a/Content.Server/Traits/TraitSystem.Functions.cs b/Content.Server/Traits/TraitSystem.Functions.cs new file mode 100644 index 0000000000..528cb4f918 --- /dev/null +++ b/Content.Server/Traits/TraitSystem.Functions.cs @@ -0,0 +1,265 @@ +using Content.Shared.Traits; +using JetBrains.Annotations; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.Manager; +using Content.Shared.Implants; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; +using Content.Shared.Actions; +using Content.Server.Abilities.Psionics; +using Content.Shared.Psionics; +using Content.Server.Language; +using Content.Shared.Mood; +using Content.Server.NPC.Systems; + +namespace Content.Server.Traits; + +/// Used for traits that add a Component upon spawning in, overwriting the pre-existing component if it already exists. +[UsedImplicitly] +public sealed partial class TraitReplaceComponent : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public ComponentRegistry Components { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + foreach (var (_, data) in Components) + { + var comp = (Component) serializationManager.CreateCopy(data.Component, notNullableOverride: true); + comp.Owner = uid; + entityManager.AddComponent(uid, comp, true); + } + } +} + +/// +/// Used for traits that add a Component upon spawning in. +/// This will do nothing if the Component already exists. +/// +[UsedImplicitly] +public sealed partial class TraitAddComponent : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public ComponentRegistry Components { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + foreach (var entry in Components.Values) + { + if (entityManager.HasComponent(uid, entry.Component.GetType())) + continue; + + var comp = (Component) serializationManager.CreateCopy(entry.Component, notNullableOverride: true); + comp.Owner = uid; + entityManager.AddComponent(uid, comp); + } + } +} + +/// Used for traits that remove a component upon a player spawning in. +[UsedImplicitly] +public sealed partial class TraitRemoveComponent : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public ComponentRegistry Components { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + foreach (var (name, _) in Components) + entityManager.RemoveComponent(uid, (Component) factory.GetComponent(name)); + } +} + +/// Used for traits that add an action upon a player spawning in. +[UsedImplicitly] +public sealed partial class TraitAddActions : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public List Actions { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var actionSystem = entityManager.System(); + + foreach (var id in Actions) + { + EntityUid? actionId = null; + if (actionSystem.AddAction(uid, ref actionId, id)) + actionSystem.StartUseDelay(actionId); + } + } +} + +/// Used for traits that add an Implant upon spawning in. +[UsedImplicitly] +public sealed partial class TraitAddImplant : TraitFunction +{ + [DataField(customTypeSerializer: typeof(PrototypeIdHashSetSerializer))] + [AlwaysPushInheritance] + public HashSet Implants { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var implantSystem = entityManager.System(); + implantSystem.AddImplants(uid, Implants); + } +} + +/// +/// If a trait includes any Psionic Powers, this enters the powers into PsionicSystem to be initialized. +/// If the lack of logic here seems startling, it's okay. All of the logic necessary for adding Psionics is handled by InitializePsionicPower. +/// +[UsedImplicitly] +public sealed partial class TraitAddPsionics : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public List> PsionicPowers { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var prototype = IoCManager.Resolve(); + var psionic = entityManager.System(); + + foreach (var powerProto in PsionicPowers) + if (prototype.TryIndex(powerProto, out var psionicPower)) + psionic.InitializePsionicPower(uid, psionicPower, false); + } +} + +/// Handles all modification of Known Languages. Removes languages before adding them. +[UsedImplicitly] +public sealed partial class TraitModifyLanguages : TraitFunction +{ + /// The list of all Spoken Languages that this trait adds. + [DataField, AlwaysPushInheritance] + public List? LanguagesSpoken { get; private set; } = default!; + + /// The list of all Understood Languages that this trait adds. + [DataField, AlwaysPushInheritance] + public List? LanguagesUnderstood { get; private set; } = default!; + + /// The list of all Spoken Languages that this trait removes. + [DataField, AlwaysPushInheritance] + public List? RemoveLanguagesSpoken { get; private set; } = default!; + + /// The list of all Understood Languages that this trait removes. + [DataField, AlwaysPushInheritance] + public List? RemoveLanguagesUnderstood { get; private set; } = default!; + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var language = entityManager.System(); + + if (RemoveLanguagesSpoken is not null) + foreach (var lang in RemoveLanguagesSpoken) + language.RemoveLanguage(uid, lang, true, false); + + if (RemoveLanguagesUnderstood is not null) + foreach (var lang in RemoveLanguagesUnderstood) + language.RemoveLanguage(uid, lang, false, true); + + if (LanguagesSpoken is not null) + foreach (var lang in LanguagesSpoken) + language.AddLanguage(uid, lang, true, false); + + if (LanguagesUnderstood is not null) + foreach (var lang in LanguagesUnderstood) + language.AddLanguage(uid, lang, false, true); + } +} + +/// Handles adding Moodlets to a player character upon spawning in. Typically used for permanent moodlets or drug addictions. +[UsedImplicitly] +public sealed partial class TraitAddMoodlets : TraitFunction +{ + /// The list of all Moodlets that this trait adds. + [DataField, AlwaysPushInheritance] + public List> MoodEffects { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var prototype = IoCManager.Resolve(); + + foreach (var moodProto in MoodEffects) + if (prototype.TryIndex(moodProto, out var moodlet)) + entityManager.EventBus.RaiseLocalEvent(uid, new MoodEffectEvent(moodlet.ID)); + } +} + +/// Add or remove Factions from a player upon spawning in. +[UsedImplicitly] +public sealed partial class TraitModifyFactions : TraitFunction +{ + /// + /// The list of all Factions that this trait removes. + /// + /// + /// I can't actually Validate these because the proto lives in Shared. + /// + [DataField, AlwaysPushInheritance] + public List RemoveFactions { get; private set; } = new(); + + /// + /// The list of all Factions that this trait adds. + /// + /// + /// I can't actually Validate these because the proto lives in Shared. + /// + [DataField, AlwaysPushInheritance] + public List AddFactions { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var factionSystem = entityManager.System(); + + foreach (var faction in RemoveFactions) + factionSystem.RemoveFaction(uid, faction); + + foreach (var faction in AddFactions) + factionSystem.AddFaction(uid, faction); + } +} + +/// Only use this if you know what you're doing. This function directly writes to any arbitrary component. +[UsedImplicitly] +public sealed partial class TraitVVEdit : TraitFunction +{ + [DataField, AlwaysPushInheritance] + public Dictionary VVEdit { get; private set; } = new(); + + public override void OnPlayerSpawn(EntityUid uid, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager) + { + var vvm = IoCManager.Resolve(); + foreach (var (path, value) in VVEdit) + vvm.WritePath(path, value); + } +} diff --git a/Content.Server/Traits/TraitSystem.cs b/Content.Server/Traits/TraitSystem.cs index afdf01524d..75771a5743 100644 --- a/Content.Server/Traits/TraitSystem.cs +++ b/Content.Server/Traits/TraitSystem.cs @@ -1,5 +1,4 @@ using System.Linq; -using Content.Shared.Actions; using Content.Server.GameTicking; using Content.Server.Players.PlayTimeTracking; using Content.Shared.Customization.Systems; @@ -10,11 +9,6 @@ using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager; using Robust.Shared.Utility; -using Content.Server.Abilities.Psionics; -using Content.Shared.Psionics; -using Content.Server.Language; -using Content.Shared.Mood; -using Content.Server.NPC.Systems; namespace Content.Server.Traits; @@ -25,11 +19,7 @@ public sealed class TraitSystem : EntitySystem [Dependency] private readonly CharacterRequirementsSystem _characterRequirements = default!; [Dependency] private readonly PlayTimeTrackingManager _playTimeTracking = default!; [Dependency] private readonly IConfigurationManager _configuration = default!; - [Dependency] private readonly SharedActionsSystem _actions = default!; - [Dependency] private readonly PsionicAbilitiesSystem _psionicAbilities = default!; [Dependency] private readonly IComponentFactory _componentFactory = default!; - [Dependency] private readonly LanguageSystem _languageSystem = default!; - [Dependency] private readonly NpcFactionSystem _factionSystem = default!; public override void Initialize() { @@ -66,191 +56,7 @@ private void OnPlayerSpawnComplete(PlayerSpawnCompleteEvent args) /// public void AddTrait(EntityUid uid, TraitPrototype traitPrototype) { - RemoveTraitComponents(uid, traitPrototype); - AddTraitComponents(uid, traitPrototype); - AddTraitActions(uid, traitPrototype); - AddTraitPsionics(uid, traitPrototype); - AddTraitLanguage(uid, traitPrototype); - RemoveTraitLanguage(uid, traitPrototype); - AddTraitMoodlets(uid, traitPrototype); - RemoveTraitFactions(uid, traitPrototype); - AddTraitFactions(uid, traitPrototype); - } - - /// - /// Removes all components defined by a Trait. It's not possible to validate component removals, - /// so if an incorrect string is given, it's basically a skill issue. - /// - /// - /// This comes before AddTraitComponents for a good reason. - /// It allows for a component to optionally be fully wiped and replaced with a new component. - /// - public void RemoveTraitComponents(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.ComponentRemovals is null) - return; - - foreach (var entry in traitPrototype.ComponentRemovals) - { - if (!_componentFactory.TryGetRegistration(entry, out var comp)) - continue; - - EntityManager.RemoveComponent(uid, comp.Type); - } - } - - /// - /// Adds all Components included with a Trait. - /// - public void AddTraitComponents(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.Components is null) - return; - - foreach (var entry in traitPrototype.Components.Values) - { - if (HasComp(uid, entry.Component.GetType())) - continue; - - var comp = (Component) _serialization.CreateCopy(entry.Component, notNullableOverride: true); - comp.Owner = uid; - EntityManager.AddComponent(uid, comp); - } - } - - /// - /// Add all actions associated with a specific Trait - /// - public void AddTraitActions(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.Actions is null) - return; - - foreach (var id in traitPrototype.Actions) - { - EntityUid? actionId = null; - if (_actions.AddAction(uid, ref actionId, id)) - { - _actions.StartUseDelay(actionId); - } - } - } - - /// - /// If a trait includes any Psionic Powers, this enters the powers into PsionicSystem to be initialized. - /// If the lack of logic here seems startling, it's okay. All of the logic necessary for adding Psionics is handled by InitializePsionicPower. - /// - public void AddTraitPsionics(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.PsionicPowers is null) - return; - - foreach (var powerProto in traitPrototype.PsionicPowers) - if (_prototype.TryIndex(powerProto, out var psionicPower)) - _psionicAbilities.InitializePsionicPower(uid, psionicPower, false); - } - - /// - /// Initialize languages given by a Trait. - /// - private void AddTraitLanguage(EntityUid uid, TraitPrototype traitPrototype) - { - AddTraitLanguagesSpoken(uid, traitPrototype); - AddTraitLanguagesUnderstood(uid, traitPrototype); - } - - /// - /// If a trait includes any Spoken Languages, this sends them to LanguageSystem to be initialized. - /// - public void AddTraitLanguagesSpoken(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.LanguagesSpoken is null) - return; - - foreach (var language in traitPrototype.LanguagesSpoken) - _languageSystem.AddLanguage(uid, language, true, false); - } - - /// - /// If a trait includes any Understood Languages, this sends them to LanguageSystem to be initialized. - /// - public void AddTraitLanguagesUnderstood(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.LanguagesUnderstood is null) - return; - - foreach (var language in traitPrototype.LanguagesUnderstood) - _languageSystem.AddLanguage(uid, language, false, true); - } - - /// - /// Remove Languages given by a Trait. - /// - private void RemoveTraitLanguage(EntityUid uid, TraitPrototype traitPrototype) - { - RemoveTraitLanguagesSpoken(uid, traitPrototype); - RemoveTraitLanguagesUnderstood(uid, traitPrototype); - } - - /// - /// Removes any Spoken Languages if defined by a trait. - /// - public void RemoveTraitLanguagesSpoken(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.RemoveLanguagesSpoken is null) - return; - - foreach (var language in traitPrototype.RemoveLanguagesSpoken) - _languageSystem.RemoveLanguage(uid, language, true, false); - } - - /// - /// Removes any Understood Languages if defined by a trait. - /// - public void RemoveTraitLanguagesUnderstood(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.RemoveLanguagesUnderstood is null) - return; - - foreach (var language in traitPrototype.RemoveLanguagesUnderstood) - _languageSystem.RemoveLanguage(uid, language, false, true); - } - - /// - /// If a trait includes any moodlets, this adds the moodlets to the receiving entity. - /// While I can't stop you, you shouldn't use this to add temporary moodlets. - /// - public void AddTraitMoodlets(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.MoodEffects is null) - return; - - foreach (var moodProto in traitPrototype.MoodEffects) - if (_prototype.TryIndex(moodProto, out var moodlet)) - RaiseLocalEvent(uid, new MoodEffectEvent(moodlet.ID)); - } - - /// - /// If a trait includes any faction removals, this removes the faction from the receiving entity. - /// - public void RemoveTraitFactions(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.RemoveFactions is null) - return; - - foreach (var faction in traitPrototype.RemoveFactions) - _factionSystem.RemoveFaction(uid, faction); - } - - /// - /// If a trait includes any factions to add, this adds the factions to the receiving entity. - /// - public void AddTraitFactions(EntityUid uid, TraitPrototype traitPrototype) - { - if (traitPrototype.AddFactions is null) - return; - - foreach (var faction in traitPrototype.AddFactions) - _factionSystem.AddFaction(uid, faction); + foreach (var function in traitPrototype.Functions) + function.OnPlayerSpawn(uid, _componentFactory, EntityManager, _serialization); } } diff --git a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs index 7e611d1ded..74e76f0dd5 100644 --- a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs @@ -185,15 +185,10 @@ protected override bool InRange(EntityUid user, EntityUid target, float range, I if (session is { } pSession) { (targetCoordinates, targetLocalAngle) = _lag.GetCoordinatesAngle(target, pSession); - } - else - { - var xform = Transform(target); - targetCoordinates = xform.Coordinates; - targetLocalAngle = xform.LocalRotation; + return Interaction.InRangeUnobstructed(user, target, targetCoordinates, targetLocalAngle, range); } - return Interaction.InRangeUnobstructed(user, target, targetCoordinates, targetLocalAngle, range); + return Interaction.InRangeUnobstructed(user, target, range); } protected override void DoDamageEffect(List targets, EntityUid? user, TransformComponent targetXform) diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs index 53993e4b35..cbbfc289cf 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs @@ -399,7 +399,7 @@ private void FireEffects(EntityCoordinates fromCoordinates, float distance, Angl var (_, gridRot, gridInvMatrix) = TransformSystem.GetWorldPositionRotationInvMatrix(gridXform, xformQuery); fromCoordinates = new EntityCoordinates(gridUid.Value, - gridInvMatrix.Transform(fromCoordinates.ToMapPos(EntityManager, TransformSystem))); + Vector2.Transform(fromCoordinates.ToMapPos(EntityManager, TransformSystem), gridInvMatrix)); // Use the fallback angle I guess? angle -= gridRot; diff --git a/Content.Shared/Actions/BaseActionComponent.cs b/Content.Shared/Actions/BaseActionComponent.cs index 57c145a0ec..9156f747f5 100644 --- a/Content.Shared/Actions/BaseActionComponent.cs +++ b/Content.Shared/Actions/BaseActionComponent.cs @@ -1,14 +1,16 @@ using Robust.Shared.Audio; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Utility; namespace Content.Shared.Actions; -// TODO ACTIONS make this a seprate component and remove the inheritance stuff. +// TODO ACTIONS make this a separate component and remove the inheritance stuff. // TODO ACTIONS convert to auto comp state? // TODO add access attribute. Need to figure out what to do with decal & mapping actions. // [Access(typeof(SharedActionsSystem))] +[EntityCategory("Actions")] public abstract partial class BaseActionComponent : Component { public abstract BaseActionEvent? BaseEvent { get; } diff --git a/Content.Shared/Actions/SharedActionsSystem.cs b/Content.Shared/Actions/SharedActionsSystem.cs index 0a4755bf10..6445039b9c 100644 --- a/Content.Shared/Actions/SharedActionsSystem.cs +++ b/Content.Shared/Actions/SharedActionsSystem.cs @@ -505,13 +505,7 @@ private bool ValidateEntityTargetBase(EntityUid user, EntityUid target, EntityTa return distance <= action.Range; } - if (_interactionSystem.InRangeUnobstructed(user, target, range: action.Range) - && _containerSystem.IsInSameOrParentContainer(user, target)) - { - return true; - } - - return _interactionSystem.CanAccessViaStorage(user, target); + return _interactionSystem.InRangeAndAccessible(user, target, range: action.Range); } public bool ValidateWorldTarget(EntityUid user, EntityCoordinates coords, Entity action) diff --git a/Content.Shared/Atmos/Components/GasTileOverlayComponent.cs b/Content.Shared/Atmos/Components/GasTileOverlayComponent.cs index e72a1d6758..2c3149b11a 100644 --- a/Content.Shared/Atmos/Components/GasTileOverlayComponent.cs +++ b/Content.Shared/Atmos/Components/GasTileOverlayComponent.cs @@ -1,7 +1,6 @@ using Robust.Shared.GameStates; using Robust.Shared.Serialization; using Robust.Shared.Timing; -using Robust.Shared.Utility; namespace Content.Shared.Atmos.Components; @@ -24,55 +23,47 @@ public sealed partial class GasTileOverlayComponent : Component public GameTick ForceTick { get; set; } } - [Serializable, NetSerializable] -public sealed class GasTileOverlayState : ComponentState, IComponentDeltaState +public sealed class GasTileOverlayState(Dictionary chunks) : ComponentState { - public readonly Dictionary Chunks; - public bool FullState => AllChunks == null; - - // required to infer deleted/missing chunks for delta states - public HashSet? AllChunks; + public readonly Dictionary Chunks = chunks; +} - public GasTileOverlayState(Dictionary chunks) - { - Chunks = chunks; - } +[Serializable, NetSerializable] +public sealed class GasTileOverlayDeltaState( + Dictionary modifiedChunks, + HashSet allChunks) + : ComponentState, IComponentDeltaState +{ + public readonly Dictionary ModifiedChunks = modifiedChunks; + public readonly HashSet AllChunks = allChunks; - public void ApplyToFullState(IComponentState fullState) + public void ApplyToFullState(GasTileOverlayState state) { - DebugTools.Assert(!FullState); - var state = (GasTileOverlayState) fullState; - DebugTools.Assert(state.FullState); - foreach (var key in state.Chunks.Keys) { - if (!AllChunks!.Contains(key)) + if (!AllChunks.Contains(key)) state.Chunks.Remove(key); } - foreach (var (chunk, data) in Chunks) + foreach (var (chunk, data) in ModifiedChunks) { state.Chunks[chunk] = new(data); } } - public IComponentState CreateNewFullState(IComponentState fullState) + public GasTileOverlayState CreateNewFullState(GasTileOverlayState state) { - DebugTools.Assert(!FullState); - var state = (GasTileOverlayState) fullState; - DebugTools.Assert(state.FullState); - - var chunks = new Dictionary(state.Chunks.Count); + var chunks = new Dictionary(AllChunks.Count); - foreach (var (chunk, data) in Chunks) + foreach (var (chunk, data) in ModifiedChunks) { chunks[chunk] = new(data); } foreach (var (chunk, data) in state.Chunks) { - if (AllChunks!.Contains(chunk)) + if (AllChunks.Contains(chunk)) chunks.TryAdd(chunk, new(data)); } diff --git a/Content.Shared/Atmos/EntitySystems/SharedGasTileOverlaySystem.cs b/Content.Shared/Atmos/EntitySystems/SharedGasTileOverlaySystem.cs index f468724db3..8e7dfdedaf 100644 --- a/Content.Shared/Atmos/EntitySystems/SharedGasTileOverlaySystem.cs +++ b/Content.Shared/Atmos/EntitySystems/SharedGasTileOverlaySystem.cs @@ -55,7 +55,7 @@ private void OnGetState(EntityUid uid, GasTileOverlayComponent component, ref Co data[index] = chunk; } - args.State = new GasTileOverlayState(data) { AllChunks = new(component.Chunks.Keys) }; + args.State = new GasTileOverlayDeltaState(data, new(component.Chunks.Keys)); } public static Vector2i GetGasChunkIndices(Vector2i indices) diff --git a/Content.Shared/Body/Prototypes/BodyPrototypeSerializer.cs b/Content.Shared/Body/Prototypes/BodyPrototypeSerializer.cs index e2b54bf951..ae09976704 100644 --- a/Content.Shared/Body/Prototypes/BodyPrototypeSerializer.cs +++ b/Content.Shared/Body/Prototypes/BodyPrototypeSerializer.cs @@ -182,7 +182,7 @@ public BodyPrototype Read(ISerializationManager serializationManager, MappingDat foreach (var (slotId, (part, connections, organs)) in allConnections) { - var slot = new BodyPrototypeSlot(part != null ? new EntProtoId(part) : null!, connections ?? new HashSet(), organs ?? new Dictionary()); + var slot = new BodyPrototypeSlot(part, connections ?? new HashSet(), organs ?? new Dictionary()); slots.Add(slotId, slot); } diff --git a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs index bc039c03e6..c07d90b3a2 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs @@ -61,7 +61,7 @@ private void OnBuckleMove(EntityUid uid, BuckleComponent component, ref MoveEven return; var strapPosition = Transform(strapUid).Coordinates; - if (ev.NewPosition.InRange(EntityManager, _transform, strapPosition, strapComp.MaxBuckleDistance)) + if (ev.NewPosition.EntityId.IsValid() && ev.NewPosition.InRange(EntityManager, _transform, strapPosition, strapComp.MaxBuckleDistance)) return; TryUnbuckle(uid, uid, true, component); diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 0e59972e5c..b069eea28d 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -2634,5 +2634,11 @@ public static readonly CVarDef CVarDef.Create("ghost.allow_same_character", true, CVar.SERVERONLY); #endregion + + /// + /// Set to true to disable parallel processing in the pow3r solver. + /// + public static readonly CVarDef DebugPow3rDisableParallel = + CVarDef.Create("debug.pow3r_disable_parallel", true, CVar.SERVERONLY); } } diff --git a/Content.Shared/Decals/DecalGridComponent.cs b/Content.Shared/Decals/DecalGridComponent.cs index 8ac05cb280..67a9c03769 100644 --- a/Content.Shared/Decals/DecalGridComponent.cs +++ b/Content.Shared/Decals/DecalGridComponent.cs @@ -62,46 +62,37 @@ public record DecalGridChunkCollection(Dictionary ChunkCol } [Serializable, NetSerializable] - public sealed class DecalGridState : ComponentState, IComponentDeltaState + public sealed class DecalGridState(Dictionary chunks) : ComponentState { - public Dictionary Chunks; - public bool FullState => AllChunks == null; - - // required to infer deleted/missing chunks for delta states - public HashSet? AllChunks; + public Dictionary Chunks = chunks; + } - public DecalGridState(Dictionary chunks) - { - Chunks = chunks; - } + [Serializable, NetSerializable] + public sealed class DecalGridDeltaState(Dictionary modifiedChunks, HashSet allChunks) + : ComponentState, IComponentDeltaState + { + public Dictionary ModifiedChunks = modifiedChunks; + public HashSet AllChunks = allChunks; - public void ApplyToFullState(IComponentState fullState) + public void ApplyToFullState(DecalGridState state) { - DebugTools.Assert(!FullState); - var state = (DecalGridState) fullState; - DebugTools.Assert(state.FullState); - foreach (var key in state.Chunks.Keys) { if (!AllChunks!.Contains(key)) state.Chunks.Remove(key); } - foreach (var (chunk, data) in Chunks) + foreach (var (chunk, data) in ModifiedChunks) { state.Chunks[chunk] = new(data); } } - public IComponentState CreateNewFullState(IComponentState fullState) + public DecalGridState CreateNewFullState(DecalGridState state) { - DebugTools.Assert(!FullState); - var state = (DecalGridState) fullState; - DebugTools.Assert(state.FullState); - var chunks = new Dictionary(state.Chunks.Count); - foreach (var (chunk, data) in Chunks) + foreach (var (chunk, data) in ModifiedChunks) { chunks[chunk] = new(data); } diff --git a/Content.Shared/Decals/SharedDecalSystem.cs b/Content.Shared/Decals/SharedDecalSystem.cs index 76fa9d64db..9dbef60f0d 100644 --- a/Content.Shared/Decals/SharedDecalSystem.cs +++ b/Content.Shared/Decals/SharedDecalSystem.cs @@ -49,7 +49,7 @@ private void OnGetState(EntityUid uid, DecalGridComponent component, ref Compone data[index] = chunk; } - args.State = new DecalGridState(data) { AllChunks = new(component.ChunkCollection.ChunkCollection.Keys) }; + args.State = new DecalGridDeltaState(data, new(component.ChunkCollection.ChunkCollection.Keys)); } private void OnGridInitialize(GridInitializeEvent msg) diff --git a/Content.Shared/Dragon/SharedDragonRiftComponent.cs b/Content.Shared/Dragon/SharedDragonRiftComponent.cs index 0d2bf44018..8377dbfee7 100644 --- a/Content.Shared/Dragon/SharedDragonRiftComponent.cs +++ b/Content.Shared/Dragon/SharedDragonRiftComponent.cs @@ -1,9 +1,10 @@ using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; namespace Content.Shared.Dragon; -[NetworkedComponent] +[NetworkedComponent, EntityCategory("Spawner")] public abstract partial class SharedDragonRiftComponent : Component { [DataField("state")] diff --git a/Content.Shared/Explosion/Components/ExplosionVisualsComponent.cs b/Content.Shared/Explosion/Components/ExplosionVisualsComponent.cs index 7477b6c26e..88e81c93c5 100644 --- a/Content.Shared/Explosion/Components/ExplosionVisualsComponent.cs +++ b/Content.Shared/Explosion/Components/ExplosionVisualsComponent.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Serialization; @@ -15,7 +16,7 @@ public sealed partial class ExplosionVisualsComponent : Component public Dictionary>> Tiles = new(); public List Intensity = new(); public string ExplosionType = string.Empty; - public Matrix3 SpaceMatrix; + public Matrix3x2 SpaceMatrix; public ushort SpaceTileSize; } @@ -27,7 +28,7 @@ public sealed class ExplosionVisualsState : ComponentState public Dictionary>> Tiles; public List Intensity; public string ExplosionType = string.Empty; - public Matrix3 SpaceMatrix; + public Matrix3x2 SpaceMatrix; public ushort SpaceTileSize; public ExplosionVisualsState( @@ -36,7 +37,7 @@ public ExplosionVisualsState( List intensity, Dictionary>? spaceTiles, Dictionary>> tiles, - Matrix3 spaceMatrix, + Matrix3x2 spaceMatrix, ushort spaceTileSize) { Epicenter = epicenter; diff --git a/Content.Shared/Footprint/FootPrintComponent.cs b/Content.Shared/Footprint/FootPrintComponent.cs new file mode 100644 index 0000000000..e1f9716057 --- /dev/null +++ b/Content.Shared/Footprint/FootPrintComponent.cs @@ -0,0 +1,23 @@ +using Content.Shared.Chemistry.Components; +using Robust.Shared.GameStates; + +namespace Content.Shared.FootPrint; + +/// +/// This is used for marking footsteps, handling footprint drawing. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class FootPrintComponent : Component +{ + /// + /// Owner (with ) of a print (this component). + /// + [AutoNetworkedField] + public EntityUid PrintOwner; + + [DataField] + public string SolutionName = "step"; + + [DataField] + public Entity? Solution; +} diff --git a/Content.Shared/Footprint/FootPrintVisuals.cs b/Content.Shared/Footprint/FootPrintVisuals.cs new file mode 100644 index 0000000000..f980f60a6d --- /dev/null +++ b/Content.Shared/Footprint/FootPrintVisuals.cs @@ -0,0 +1,25 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.FootPrint; + +[Serializable, NetSerializable] +public enum FootPrintVisuals : byte +{ + BareFootPrint, + ShoesPrint, + SuitPrint, + Dragging +} + +[Serializable, NetSerializable] +public enum FootPrintVisualState : byte +{ + State, + Color +} + +[Serializable, NetSerializable] +public enum FootPrintVisualLayers : byte +{ + Print +} diff --git a/Content.Shared/Footprint/FootPrintsComponent.cs b/Content.Shared/Footprint/FootPrintsComponent.cs new file mode 100644 index 0000000000..2b2c4ed66e --- /dev/null +++ b/Content.Shared/Footprint/FootPrintsComponent.cs @@ -0,0 +1,88 @@ +using System.Numerics; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; + +namespace Content.Shared.FootPrint; + +[RegisterComponent] +public sealed partial class FootPrintsComponent : Component +{ + [ViewVariables(VVAccess.ReadOnly), DataField] + public ResPath RsiPath = new("/Textures/Effects/footprints.rsi"); + + // all of those are set as a layer + [ViewVariables(VVAccess.ReadOnly), DataField] + public string LeftBarePrint = "footprint-left-bare-human"; + + [ViewVariables(VVAccess.ReadOnly), DataField] + public string RightBarePrint = "footprint-right-bare-human"; + + [ViewVariables(VVAccess.ReadOnly), DataField] + public string ShoesPrint = "footprint-shoes"; + + [ViewVariables(VVAccess.ReadOnly), DataField] + public string SuitPrint = "footprint-suit"; + + [ViewVariables(VVAccess.ReadOnly), DataField] + public string[] DraggingPrint = + [ + "dragging-1", + "dragging-2", + "dragging-3", + "dragging-4", + "dragging-5", + ]; + // yea, those + + [ViewVariables(VVAccess.ReadOnly), DataField] + public EntProtoId StepProtoId = "Footstep"; + + [ViewVariables(VVAccess.ReadOnly), DataField] + public Color PrintsColor = Color.FromHex("#00000000"); + + /// + /// The size scaling factor for footprint steps. Must be positive. + /// + [DataField] + public float StepSize = 0.7f; + + /// + /// The size scaling factor for drag marks. Must be positive. + /// + [DataField] + public float DragSize = 0.5f; + + /// + /// The amount of color to transfer from the source (e.g., puddle) to the footprint. + /// + [DataField] + public float ColorQuantity; + + /// + /// The factor by which the alpha channel is reduced in subsequent footprints. + /// + [DataField] + public float ColorReduceAlpha = 0.1f; + + [DataField] + public string? ReagentToTransfer; + + [DataField] + public Vector2 OffsetPrint = new(0.1f, 0f); + + /// + /// Tracks which foot should make the next print. True for right foot, false for left. + /// + public bool RightStep = true; + + /// + /// The position of the last footprint in world coordinates. + /// + public Vector2 StepPos = Vector2.Zero; + + /// + /// Controls how quickly the footprint color transitions between steps. + /// Value between 0 and 1, where higher values mean faster color changes. + /// + public float ColorInterpolationFactor = 0.2f; +} diff --git a/Content.Shared/Footprint/PuddleFootPrintsComponent.cs b/Content.Shared/Footprint/PuddleFootPrintsComponent.cs new file mode 100644 index 0000000000..0e2ddfe383 --- /dev/null +++ b/Content.Shared/Footprint/PuddleFootPrintsComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Shared.FootPrint; + +[RegisterComponent] +public sealed partial class PuddleFootPrintsComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite)] + public float SizeRatio = 0.2f; + + [ViewVariables(VVAccess.ReadWrite)] + public float OffPercent = 80f; +} diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 1f421d0e6f..940d8ffbb0 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -1,11 +1,10 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Shared.ActionBlocker; -using Content.Shared.Administration; using Content.Shared.Administration.Logs; -using Content.Shared.Administration.Managers; using Content.Shared.CombatMode; using Content.Shared.Database; +using Content.Shared.Ghost; using Content.Shared.Hands; using Content.Shared.Hands.Components; using Content.Shared.Input; @@ -15,12 +14,13 @@ using Content.Shared.Inventory.Events; using Content.Shared.Item; using Content.Shared.Movement.Components; -using Content.Shared.Movement.Pulling.Components; using Content.Shared.Movement.Pulling.Systems; using Content.Shared.Physics; using Content.Shared.Popups; +using Content.Shared.Storage; using Content.Shared.Tag; using Content.Shared.Timing; +using Content.Shared.UserInterface; using Content.Shared.Verbs; using Content.Shared.Wall; using JetBrains.Annotations; @@ -36,6 +36,7 @@ using Robust.Shared.Random; using Robust.Shared.Serialization; using Robust.Shared.Timing; +using Robust.Shared.Utility; #pragma warning disable 618 @@ -50,12 +51,11 @@ public abstract partial class SharedInteractionSystem : EntitySystem [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly INetManager _net = default!; [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly ISharedAdminManager _adminManager = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; [Dependency] private readonly RotateToFaceSystem _rotateToFaceSystem = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!; - [Dependency] private readonly SharedPhysicsSystem _sharedBroadphaseSystem = default!; + [Dependency] private readonly SharedPhysicsSystem _broadphase = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedVerbSystem _verbSystem = default!; [Dependency] private readonly SharedPopupSystem _popupSystem = default!; @@ -64,6 +64,18 @@ public abstract partial class SharedInteractionSystem : EntitySystem [Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly TagSystem _tagSystem = default!; + [Dependency] private readonly SharedUserInterfaceSystem _ui = default!; + + private EntityQuery _ignoreUiRangeQuery; + private EntityQuery _fixtureQuery; + private EntityQuery _itemQuery; + private EntityQuery _physicsQuery; + private EntityQuery _handsQuery; + private EntityQuery _relayQuery; + private EntityQuery _combatQuery; + private EntityQuery _wallMountQuery; + private EntityQuery _delayQuery; + private EntityQuery _uiQuery; private const CollisionGroup InRangeUnobstructedMask = CollisionGroup.Impassable | CollisionGroup.InteractImpassable; @@ -76,6 +88,17 @@ public abstract partial class SharedInteractionSystem : EntitySystem public override void Initialize() { + _ignoreUiRangeQuery = GetEntityQuery(); + _fixtureQuery = GetEntityQuery(); + _itemQuery = GetEntityQuery(); + _physicsQuery = GetEntityQuery(); + _handsQuery = GetEntityQuery(); + _relayQuery = GetEntityQuery(); + _combatQuery = GetEntityQuery(); + _wallMountQuery = GetEntityQuery(); + _delayQuery = GetEntityQuery(); + _uiQuery = GetEntityQuery(); + SubscribeLocalEvent(HandleUserInterfaceRangeCheck); SubscribeLocalEvent(OnBoundInterfaceInteractAttempt); @@ -111,29 +134,57 @@ public override void Shutdown() /// private void OnBoundInterfaceInteractAttempt(BoundUserInterfaceMessageAttempt ev) { - var user = ev.Actor; + _uiQuery.TryComp(ev.Target, out var uiComp); + if (!_actionBlockerSystem.CanInteract(ev.Actor, ev.Target)) + { + // We permit ghosts to open uis unless explicitly blocked + if (ev.Message is not OpenBoundInterfaceMessage || !HasComp(ev.Actor) || uiComp?.BlockSpectators == true) + { + ev.Cancel(); + return; + } + } + + var range = _ui.GetUiRange(ev.Target, ev.UiKey); - if (!_actionBlockerSystem.CanInteract(user, ev.Target)) + // As long as range>0, the UI frame updates should have auto-closed the UI if it is out of range. + DebugTools.Assert(range <= 0 || UiRangeCheck(ev.Actor, ev.Target, range)); + + if (range <= 0 && !IsAccessible(ev.Actor, ev.Target)) { ev.Cancel(); return; } - // Check if the bound entity is accessible. Note that we allow admins to ignore this restriction, so that - // they can fiddle with UI's that people can't normally interact with (e.g., placing things directly into - // other people's backpacks). - if (!_containerSystem.IsInSameOrParentContainer(user, ev.Target) - && !CanAccessViaStorage(user, ev.Target) - && !_adminManager.HasAdminFlag(user, AdminFlags.Admin)) + if (uiComp == null) + return; + + if (uiComp.SingleUser && uiComp.CurrentSingleUser != ev.Actor) { ev.Cancel(); return; } - if (!InRangeUnobstructed(user, ev.Target)) - { + if (!uiComp.RequireHands) + return; + + if (!_handsQuery.TryComp(ev.Actor, out var hands) || hands.Hands.Count == 0) ev.Cancel(); - } + } + + private bool UiRangeCheck(Entity user, Entity target, float range) + { + if (!Resolve(target, ref target.Comp)) + return false; + + if (user.Owner == target.Owner) + return true; + + // Fast check: if the user is the parent of the entity (e.g., holding it), we always assume that it is in range + if (target.Comp.ParentUid == user.Owner) + return true; + + return InRangeAndAccessible(user, target, range) || _ignoreUiRangeQuery.HasComp(user); } /// @@ -190,10 +241,7 @@ private bool HandleTryPullObject(ICommonSession? session, EntityCoordinates coor if (!InRangeUnobstructed(userEntity.Value, uid, popup: true)) return false; - if (!TryComp(uid, out PullableComponent? pull)) - return false; - - _pullSystem.TogglePull(uid, userEntity.Value, pull); + _pullSystem.TogglePull(uid, userEntity.Value); return false; } @@ -269,7 +317,7 @@ private bool ShouldCheckAccess(EntityUid user) public bool CombatModeCanHandInteract(EntityUid user, EntityUid? target) { // Always allow attack in these cases - if (target == null || !TryComp(user, out var hands) || hands.ActiveHand?.HeldEntity is not null) + if (target == null || !_handsQuery.TryComp(user, out var hands) || hands.ActiveHand?.HeldEntity is not null) return false; // Only eat input if: @@ -277,7 +325,7 @@ public bool CombatModeCanHandInteract(EntityUid user, EntityUid? target) // - Target doesn't cancel should-interact event // This is intended to allow items to be picked up in combat mode, // but to also allow items to force attacks anyway (like mobs which are items, e.g. mice) - if (!HasComp(target)) + if (!_itemQuery.HasComp(target)) return false; var combatEv = new CombatModeShouldHandInteractEvent(); @@ -307,7 +355,7 @@ public void UserInteraction( bool checkAccess = true, bool checkCanUse = true) { - if (TryComp(user, out var relay) && relay.RelayEntity is not null) + if (_relayQuery.TryComp(user, out var relay) && relay.RelayEntity is not null) { // TODO this needs to be handled better. This probably bypasses many complex can-interact checks in weird roundabout ways. if (_actionBlockerSystem.CanInteract(user, target)) @@ -321,7 +369,7 @@ public void UserInteraction( if (target != null && Deleted(target.Value)) return; - if (!altInteract && TryComp(user, out var combatMode) && combatMode.IsInCombatMode) + if (!altInteract && _combatQuery.TryComp(user, out var combatMode) && combatMode.IsInCombatMode) { if (!CombatModeCanHandInteract(user, target)) return; @@ -343,10 +391,7 @@ public void UserInteraction( // Check if interacted entity is in the same container, the direct child, or direct parent of the user. // Also checks if the item is accessible via some storage UI (e.g., open backpack) - if (checkAccess - && target != null - && !_containerSystem.IsInSameOrParentContainer(user, target.Value) - && !CanAccessViaStorage(user, target.Value)) + if (checkAccess && target != null && !IsAccessible(user, target.Value)) return; var inRangeUnobstructed = target == null @@ -354,7 +399,7 @@ public void UserInteraction( : !checkAccess || InRangeUnobstructed(user, target.Value); // permits interactions with wall mounted entities // Does the user have hands? - if (!TryComp(user, out var hands) || hands.ActiveHand == null) + if (!_handsQuery.TryComp(user, out var hands) || hands.ActiveHand == null) { var ev = new InteractNoHandEvent(user, target, coordinates); RaiseLocalEvent(user, ev); @@ -494,7 +539,7 @@ public float UnobstructedDistance( predicate ??= _ => false; var ray = new CollisionRay(origin.Position, dir.Normalized(), collisionMask); - var rayResults = _sharedBroadphaseSystem.IntersectRayWithPredicate(origin.MapId, ray, dir.Length(), predicate.Invoke, false).ToList(); + var rayResults = _broadphase.IntersectRayWithPredicate(origin.MapId, ray, dir.Length(), predicate.Invoke, false).ToList(); if (rayResults.Count == 0) return dir.Length(); @@ -557,23 +602,29 @@ public bool InRangeUnobstructed( } var ray = new CollisionRay(origin.Position, dir.Normalized(), (int) collisionMask); - var rayResults = _sharedBroadphaseSystem.IntersectRayWithPredicate(origin.MapId, ray, length, predicate.Invoke, false).ToList(); + var rayResults = _broadphase.IntersectRayWithPredicate(origin.MapId, ray, length, predicate.Invoke, false).ToList(); return rayResults.Count == 0; } public bool InRangeUnobstructed( - EntityUid origin, - EntityUid other, + Entity origin, + Entity other, float range = InteractionRange, CollisionGroup collisionMask = InRangeUnobstructedMask, Ignored? predicate = null, bool popup = false) { - if (!TryComp(other, out var otherXform)) + if (!Resolve(other, ref other.Comp)) return false; - return InRangeUnobstructed(origin, other, otherXform.Coordinates, otherXform.LocalRotation, range, collisionMask, predicate, + return InRangeUnobstructed(origin, + other, + other.Comp.Coordinates, + other.Comp.LocalRotation, + range, + collisionMask, + predicate, popup); } @@ -605,8 +656,8 @@ public bool InRangeUnobstructed( /// True if the two points are within a given range without being obstructed. /// public bool InRangeUnobstructed( - EntityUid origin, - EntityUid other, + Entity origin, + Entity other, EntityCoordinates otherCoordinates, Angle otherAngle, float range = InteractionRange, @@ -614,10 +665,10 @@ public bool InRangeUnobstructed( Ignored? predicate = null, bool popup = false) { - Ignored combinedPredicate = e => e == origin || (predicate?.Invoke(e) ?? false); + Ignored combinedPredicate = e => e == origin.Owner || (predicate?.Invoke(e) ?? false); var inRange = true; MapCoordinates originPos = default; - var targetPos = otherCoordinates.ToMap(EntityManager, _transform); + var targetPos = _transform.ToMapCoordinates(otherCoordinates); Angle targetRot = default; // So essentially: @@ -627,23 +678,30 @@ public bool InRangeUnobstructed( // Alternatively we could check centre distances first though // that means we wouldn't be able to easily check overlap interactions. if (range > 0f && - TryComp(origin, out var fixtureA) && + _fixtureQuery.TryComp(origin, out var fixtureA) && // These fixture counts are stuff that has the component but no fixtures for (e.g. buttons). // At least until they get removed. fixtureA.FixtureCount > 0 && - TryComp(other, out var fixtureB) && + _fixtureQuery.TryComp(other, out var fixtureB) && fixtureB.FixtureCount > 0 && - TryComp(origin, out var xformA)) + Resolve(origin, ref origin.Comp)) { - var (worldPosA, worldRotA) = xformA.GetWorldPositionRotation(); + var (worldPosA, worldRotA) = origin.Comp.GetWorldPositionRotation(); var xfA = new Transform(worldPosA, worldRotA); var parentRotB = _transform.GetWorldRotation(otherCoordinates.EntityId); var xfB = new Transform(targetPos.Position, parentRotB + otherAngle); // Different map or the likes. - if (!_sharedBroadphaseSystem.TryGetNearest(origin, other, - out _, out _, out var distance, - xfA, xfB, fixtureA, fixtureB)) + if (!_broadphase.TryGetNearest( + origin, + other, + out _, + out _, + out var distance, + xfA, + xfB, + fixtureA, + fixtureB)) { inRange = false; } @@ -665,15 +723,15 @@ public bool InRangeUnobstructed( else { // We'll still do the raycast from the centres but we'll bump the range as we know they're in range. - originPos = xformA.MapPosition; + originPos = _transform.GetMapCoordinates(origin, xform: origin.Comp); range = (originPos.Position - targetPos.Position).Length(); } } // No fixtures, e.g. wallmounts. else { - originPos = Transform(origin).MapPosition; - var otherParent = Transform(other).ParentUid; + originPos = _transform.GetMapCoordinates(origin, origin); + var otherParent = (other.Comp ?? Transform(other)).ParentUid; targetRot = otherParent.IsValid() ? Transform(otherParent).LocalRotation + otherAngle : otherAngle; } @@ -724,13 +782,13 @@ private Ignored GetPredicate( { HashSet ignored = new(); - if (HasComp(target) && TryComp(target, out PhysicsComponent? physics) && physics.CanCollide) + if (_itemQuery.HasComp(target) && _physicsQuery.TryComp(target, out var physics) && physics.CanCollide) { // If the target is an item, we ignore any colliding entities. Currently done so that if items get stuck // inside of walls, users can still pick them up. - ignored.UnionWith(_sharedBroadphaseSystem.GetEntitiesIntersectingBody(target, (int) collisionMask, false, physics)); + ignored.UnionWith(_broadphase.GetEntitiesIntersectingBody(target, (int) collisionMask, false, physics)); } - else if (TryComp(target, out WallMountComponent? wallMount)) + else if (_wallMountQuery.TryComp(target, out var wallMount)) { // wall-mount exemptions may be restricted to a specific angle range.da @@ -748,13 +806,7 @@ private Ignored GetPredicate( ignored.UnionWith(grid.GetAnchoredEntities(targetCoords)); } - Ignored combinedPredicate = e => - { - return e == target - || (predicate?.Invoke(e) ?? false) - || ignored.Contains(e); - }; - + Ignored combinedPredicate = e => e == target || (predicate?.Invoke(e) ?? false) || ignored.Contains(e); return combinedPredicate; } @@ -951,10 +1003,8 @@ public bool InteractionActivate( bool checkUseDelay = true, bool checkAccess = true) { - UseDelayComponent? delayComponent = null; - if (checkUseDelay - && TryComp(used, out delayComponent) - && _useDelay.IsDelayed((used, delayComponent))) + _delayQuery.TryComp(used, out var delayComponent); + if (checkUseDelay && delayComponent != null && _useDelay.IsDelayed((used, delayComponent))) return false; if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, used)) @@ -965,11 +1015,11 @@ public bool InteractionActivate( // Check if interacted entity is in the same container, the direct child, or direct parent of the user. // This is bypassed IF the interaction happened through an item slot (e.g., backpack UI) - if (checkAccess && !_containerSystem.IsInSameOrParentContainer(user, used) && !CanAccessViaStorage(user, used)) + if (checkAccess && !IsAccessible(user, used)) return false; // Does the user have hands? - if (!HasComp(user)) + if (!_handsQuery.HasComp(user)) return false; var activateMsg = new ActivateInWorldEvent(user, used); @@ -979,7 +1029,9 @@ public bool InteractionActivate( DoContactInteraction(user, used, activateMsg); // Still need to call this even without checkUseDelay in case this gets relayed from Activate. - _useDelay.TryResetDelay(used, component: delayComponent); + if (delayComponent != null) + _useDelay.TryResetDelay(used, component: delayComponent); + if (!activateMsg.WasLogged) _adminLogger.Add(LogType.InteractActivate, LogImpact.Low, $"{ToPrettyString(user):user} activated {ToPrettyString(used):used}"); return true; @@ -1000,11 +1052,8 @@ public bool UseInHandInteraction( bool checkCanInteract = true, bool checkUseDelay = true) { - UseDelayComponent? delayComponent = null; - - if (checkUseDelay - && TryComp(used, out delayComponent) - && _useDelay.IsDelayed((used, delayComponent))) + _delayQuery.TryComp(used, out var delayComponent); + if (checkUseDelay && delayComponent != null && _useDelay.IsDelayed((used, delayComponent))) return true; // if the item is on cooldown, we consider this handled. if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, used)) @@ -1066,11 +1115,60 @@ public void DroppedInteraction(EntityUid user, EntityUid item) } #endregion + /// + /// Check if a user can access a target (stored in the same containers) and is in range without obstructions. + /// + public bool InRangeAndAccessible( + Entity user, + Entity target, + float range = InteractionRange, + CollisionGroup collisionMask = InRangeUnobstructedMask, + Ignored? predicate = null) + { + if (user == target) + return true; + + if (!Resolve(user, ref user.Comp)) + return false; + + if (!Resolve(target, ref target.Comp)) + return false; + + return IsAccessible(user, target) && InRangeUnobstructed(user, target, range, collisionMask, predicate); + } + + /// + /// Check if a user can access a target or if they are stored in different containers. + /// + public bool IsAccessible(Entity user, Entity target) + { + if (_containerSystem.IsInSameOrParentContainer(user, target, out _, out var container)) + return true; + + return container != null && CanAccessViaStorage(user, target, container); + } + /// /// If a target is in range, but not in the same container as the user, it may be inside of a backpack. This /// checks if the user can access the item in these situations. /// - public abstract bool CanAccessViaStorage(EntityUid user, EntityUid target); + public bool CanAccessViaStorage(EntityUid user, EntityUid target) + { + if (!_containerSystem.TryGetContainingContainer(target, out var container)) + return false; + + return CanAccessViaStorage(user, target, container); + } + + /// + public bool CanAccessViaStorage(EntityUid user, EntityUid target, BaseContainer container) + { + if (StorageComponent.ContainerId != container.ID) + return false; + + // we don't check if the user can access the storage entity itself. This should be handed by the UI system. + return _ui.IsUiOpen(target, StorageComponent.StorageUiKey.Key, user); + } /// /// Checks whether an entity currently equipped by another player is accessible to some user. This shouldn't @@ -1151,19 +1249,15 @@ public void DoContactInteraction(EntityUid uidA, EntityUid? uidB, HandledEntityE RaiseLocalEvent(uidB.Value, new ContactInteractionEvent(uidA)); } + private void HandleUserInterfaceRangeCheck(ref BoundUserInterfaceCheckRangeEvent ev) { if (ev.Result == BoundUserInterfaceRangeResult.Fail) return; - if (InRangeUnobstructed(ev.Actor, ev.Target, ev.Data.InteractionRange)) - { - ev.Result = BoundUserInterfaceRangeResult.Pass; - } - else - { - ev.Result = BoundUserInterfaceRangeResult.Fail; - } + ev.Result = UiRangeCheck(ev.Actor!, ev.Target, ev.Data.InteractionRange) + ? BoundUserInterfaceRangeResult.Pass + : BoundUserInterfaceRangeResult.Fail; } } diff --git a/Content.Shared/Inventory/InventorySystem.Equip.cs b/Content.Shared/Inventory/InventorySystem.Equip.cs index 68308d2b88..12435eba89 100644 --- a/Content.Shared/Inventory/InventorySystem.Equip.cs +++ b/Content.Shared/Inventory/InventorySystem.Equip.cs @@ -211,11 +211,7 @@ public bool CanAccess(EntityUid actor, EntityUid target, EntityUid itemUid) return false; // Can the actor reach the item? - if (_interactionSystem.InRangeUnobstructed(actor, itemUid) && _containerSystem.IsInSameOrParentContainer(actor, itemUid)) - return true; - - // Is the item in an open storage UI, i.e., is the user quick-equipping from an open backpack? - if (_interactionSystem.CanAccessViaStorage(actor, itemUid)) + if (_interactionSystem.InRangeAndAccessible(actor, itemUid)) return true; // Is the actor currently stripping the target? Here we could check if the actor has the stripping UI open, but diff --git a/Content.Shared/Item/SharedItemSystem.cs b/Content.Shared/Item/SharedItemSystem.cs index 29e82f8ade..5eaa25f484 100644 --- a/Content.Shared/Item/SharedItemSystem.cs +++ b/Content.Shared/Item/SharedItemSystem.cs @@ -192,7 +192,7 @@ public IReadOnlyList GetAdjustedItemShape(Entity entity, var shapes = GetItemShape(entity); var boundingShape = shapes.GetBoundingBox(); var boundingCenter = ((Box2) boundingShape).Center; - var matty = Matrix3.CreateTransform(boundingCenter, rotation); + var matty = Matrix3Helpers.CreateTransform(boundingCenter, rotation); var drift = boundingShape.BottomLeft - matty.TransformBox(boundingShape).BottomLeft; var adjustedShapes = new List(); diff --git a/Content.Shared/Language/LanguagePrototype.cs b/Content.Shared/Language/LanguagePrototype.cs index 3b2b24c4b2..dbc53c65d4 100644 --- a/Content.Shared/Language/LanguagePrototype.cs +++ b/Content.Shared/Language/LanguagePrototype.cs @@ -7,7 +7,13 @@ namespace Content.Shared.Language; public sealed partial class LanguagePrototype : IPrototype { [IdDataField] - public string ID { get; private set; } = default!; + public string ID { get; private set; } = default!; + + /// + /// Whether this language will display its name in chat behind a player's name. + /// + [DataField] + public bool IsVisibleLanguage { get; set; } /// /// Obfuscation method used by this language. By default, uses @@ -27,6 +33,11 @@ public sealed partial class LanguagePrototype : IPrototype /// public string Name => Loc.GetString($"language-{ID}-name"); + /// + /// The in-world chat abbreviation of this language, localized. + /// + public string ChatName => Loc.GetString($"chat-language-{ID}-name"); + /// /// The in-world description of this language, localized. /// diff --git a/Content.Shared/MagicMirror/SharedMagicMirrorSystem.cs b/Content.Shared/MagicMirror/SharedMagicMirrorSystem.cs index f9c941ffe3..ea5838a723 100644 --- a/Content.Shared/MagicMirror/SharedMagicMirrorSystem.cs +++ b/Content.Shared/MagicMirror/SharedMagicMirrorSystem.cs @@ -2,6 +2,7 @@ using Content.Shared.Humanoid.Markings; using Content.Shared.Interaction; using Robust.Shared.Serialization; +using Robust.Shared.Utility; namespace Content.Shared.MagicMirror; @@ -17,10 +18,13 @@ public override void Initialize() private void OnMirrorRangeCheck(EntityUid uid, MagicMirrorComponent component, ref BoundUserInterfaceCheckRangeEvent args) { - if (!Exists(component.Target) || !_interaction.InRangeUnobstructed(uid, component.Target.Value)) - { + if (args.Result == BoundUserInterfaceRangeResult.Fail) + return; + + DebugTools.Assert(component.Target != null && Exists(component.Target)); + + if (!_interaction.InRangeUnobstructed(uid, component.Target.Value)) args.Result = BoundUserInterfaceRangeResult.Fail; - } } } diff --git a/Content.Shared/Maps/TurfSystem.cs b/Content.Shared/Maps/TurfSystem.cs index ad8b3ddea8..8a4bbf68be 100644 --- a/Content.Shared/Maps/TurfSystem.cs +++ b/Content.Shared/Maps/TurfSystem.cs @@ -44,7 +44,7 @@ public bool IsTileBlocked(EntityUid gridUid, var size = grid.TileSize; var localPos = new Vector2(indices.X * size + (size / 2f), indices.Y * size + (size / 2f)); - var worldPos = matrix.Transform(localPos); + var worldPos = Vector2.Transform(localPos, matrix); // This is scaled to 95 % so it doesn't encompass walls on other tiles. var tileAabb = Box2.UnitCentered.Scale(0.95f * size); diff --git a/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs b/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs index 78f26ed5c0..08af1a36a7 100644 --- a/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs +++ b/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs @@ -13,14 +13,16 @@ public sealed class HealthAnalyzerScannedUserMessage : BoundUserInterfaceMessage public float BloodLevel; public bool? ScanMode; public bool? Bleeding; + public bool? Unrevivable; - public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding) + public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding, bool? unrevivable) { TargetEntity = targetEntity; Temperature = temperature; BloodLevel = bloodLevel; ScanMode = scanMode; Bleeding = bleeding; + Unrevivable = unrevivable; } } diff --git a/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs b/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs index 33dde399a5..4bf53c8dbd 100644 --- a/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs +++ b/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs @@ -456,14 +456,17 @@ public bool CanPull(EntityUid puller, EntityUid pullableUid, PullerComponent? pu return !startPull.Cancelled && !getPulled.Cancelled; } - public bool TogglePull(EntityUid pullableUid, EntityUid pullerUid, PullableComponent pullable) + public bool TogglePull(Entity pullable, EntityUid pullerUid) { - if (pullable.Puller == pullerUid) + if (!Resolve(pullable, ref pullable.Comp, false)) + return false; + + if (pullable.Comp.Puller == pullerUid) { - return TryStopPull(pullableUid, pullable); + return TryStopPull(pullable, pullable.Comp); } - return TryStartPull(pullerUid, pullableUid, pullableComp: pullable); + return TryStartPull(pullerUid, pullable, pullableComp: pullable); } public bool TogglePull(EntityUid pullerUid, PullerComponent puller) @@ -471,7 +474,7 @@ public bool TogglePull(EntityUid pullerUid, PullerComponent puller) if (!TryComp(puller.Pulling, out var pullable)) return false; - return TogglePull(puller.Pulling.Value, pullerUid, pullable); + return TogglePull((puller.Pulling.Value, pullable), pullerUid); } public bool TryStartPull(EntityUid pullerUid, EntityUid pullableUid, diff --git a/Content.Shared/Pinpointer/SharedNavMapSystem.cs b/Content.Shared/Pinpointer/SharedNavMapSystem.cs index ffe81c2d0e..7c12321b5d 100644 --- a/Content.Shared/Pinpointer/SharedNavMapSystem.cs +++ b/Content.Shared/Pinpointer/SharedNavMapSystem.cs @@ -96,7 +96,7 @@ private void OnGetState(EntityUid uid, NavMapComponent component, ref ComponentG chunks.Add(origin, chunk.TileData); } - args.State = new NavMapComponentState(chunks, component.Beacons); + args.State = new NavMapState(chunks, component.Beacons); return; } @@ -109,12 +109,7 @@ private void OnGetState(EntityUid uid, NavMapComponent component, ref ComponentG chunks.Add(origin, chunk.TileData); } - args.State = new NavMapComponentState(chunks, component.Beacons) - { - // TODO NAVMAP cache a single AllChunks hashset in the component. - // Or maybe just only send them if a chunk gets removed. - AllChunks = new(component.Chunks.Keys), - }; + args.State = new NavMapDeltaState(chunks, component.Beacons, new(component.Chunks.Keys)); } #endregion @@ -122,32 +117,35 @@ private void OnGetState(EntityUid uid, NavMapComponent component, ref ComponentG #region: System messages [Serializable, NetSerializable] - protected sealed class NavMapComponentState( + protected sealed class NavMapState( Dictionary chunks, Dictionary beacons) - : ComponentState, IComponentDeltaState + : ComponentState { public Dictionary Chunks = chunks; public Dictionary Beacons = beacons; + } - // Required to infer deleted/missing chunks for delta states - public HashSet? AllChunks; - - public bool FullState => AllChunks == null; + [Serializable, NetSerializable] + protected sealed class NavMapDeltaState( + Dictionary modifiedChunks, + Dictionary beacons, + HashSet allChunks) + : ComponentState, IComponentDeltaState + { + public Dictionary ModifiedChunks = modifiedChunks; + public Dictionary Beacons = beacons; + public HashSet AllChunks = allChunks; - public void ApplyToFullState(IComponentState fullState) + public void ApplyToFullState(NavMapState state) { - DebugTools.Assert(!FullState); - var state = (NavMapComponentState) fullState; - DebugTools.Assert(state.FullState); - foreach (var key in state.Chunks.Keys) { if (!AllChunks!.Contains(key)) state.Chunks.Remove(key); } - foreach (var (index, data) in Chunks) + foreach (var (index, data) in ModifiedChunks) { if (!state.Chunks.TryGetValue(index, out var stateValue)) state.Chunks[index] = stateValue = new int[data.Length]; @@ -162,12 +160,8 @@ public void ApplyToFullState(IComponentState fullState) } } - public IComponentState CreateNewFullState(IComponentState fullState) + public NavMapState CreateNewFullState(NavMapState state) { - DebugTools.Assert(!FullState); - var state = (NavMapComponentState) fullState; - DebugTools.Assert(state.FullState); - var chunks = new Dictionary(state.Chunks.Count); foreach (var (index, data) in state.Chunks) { @@ -176,13 +170,13 @@ public IComponentState CreateNewFullState(IComponentState fullState) var newData = chunks[index] = new int[ArraySize]; - if (Chunks.TryGetValue(index, out var updatedData)) + if (ModifiedChunks.TryGetValue(index, out var updatedData)) Array.Copy(newData, updatedData, ArraySize); else Array.Copy(newData, data, ArraySize); } - return new NavMapComponentState(chunks, new(Beacons)); + return new NavMapState(chunks, new(Beacons)); } } diff --git a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs index f0d1ab7d17..2e800c386b 100644 --- a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs @@ -1091,7 +1091,7 @@ public bool PlayerInsertHeldEntity(EntityUid uid, EntityUid player, StorageCompo /// true if inserted, false otherwise public bool PlayerInsertEntityInWorld(Entity uid, EntityUid player, EntityUid toInsert) { - if (!Resolve(uid, ref uid.Comp) || !_interactionSystem.InRangeUnobstructed(player, uid)) + if (!Resolve(uid, ref uid.Comp) || !_interactionSystem.InRangeUnobstructed(player, uid.Owner)) return false; if (!Insert(uid, toInsert, out _, user: player, uid.Comp)) diff --git a/Content.Shared/Traits/Assorted/Components/SingerComponent.cs b/Content.Shared/Traits/Assorted/Components/SingerComponent.cs index f36969e742..9e737c04ac 100644 --- a/Content.Shared/Traits/Assorted/Components/SingerComponent.cs +++ b/Content.Shared/Traits/Assorted/Components/SingerComponent.cs @@ -9,7 +9,7 @@ public sealed partial class SingerComponent : Component { // Traits are server-only, and is this is added via traits, it must be replicated to the client. [DataField(required: true), AutoNetworkedField] - public ProtoId Proto = string.Empty; + public ProtoId? Proto; [DataField(serverOnly: true)] public EntProtoId? MidiActionId = "ActionHarpyPlayMidi"; diff --git a/Content.Shared/Traits/Prototypes/TraitPrototype.cs b/Content.Shared/Traits/Prototypes/TraitPrototype.cs index fb8ccf5464..8ee3c55637 100644 --- a/Content.Shared/Traits/Prototypes/TraitPrototype.cs +++ b/Content.Shared/Traits/Prototypes/TraitPrototype.cs @@ -1,8 +1,7 @@ using Content.Shared.Customization.Systems; -using Content.Shared.Mood; -using Content.Shared.Psionics; using Robust.Shared.Prototypes; -using Robust.Shared.Utility; +using Robust.Shared.Serialization.Manager; +using Robust.Shared.Serialization; namespace Content.Shared.Traits; @@ -33,76 +32,17 @@ public sealed partial class TraitPrototype : IPrototype [DataField] public List Requirements = new(); - /// - /// The components that get added to the player when they pick this trait. - /// - [DataField] - public ComponentRegistry? Components { get; private set; } = default!; - - /// - /// The components that will be removed from a player when they pick this trait. - /// Primarily used to remove species innate traits. - /// - [DataField] - public List? ComponentRemovals { get; private set; } = default!; - - /// - /// The list of each Action that this trait adds in the form of ActionId and ActionEntity - /// - [DataField] - public List? Actions { get; private set; } = default!; - - /// - /// The list of all Psionic Powers that this trait adds. If this list is not empty, the trait will also Ensure that a player is Psionic. - /// - [DataField] - public List? PsionicPowers { get; private set; } = default!; - - /// - /// The list of all Spoken Languages that this trait adds. - /// - [DataField] - public List? LanguagesSpoken { get; private set; } = default!; - - /// - /// The list of all Understood Languages that this trait adds. - /// - [DataField] - public List? LanguagesUnderstood { get; private set; } = default!; - - /// - /// The list of all Spoken Languages that this trait removes. - /// - [DataField] - public List? RemoveLanguagesSpoken { get; private set; } = default!; - - /// - /// The list of all Understood Languages that this trait removes. - /// - [DataField] - public List? RemoveLanguagesUnderstood { get; private set; } = default!; - - /// - /// The list of all Moodlets that this trait adds. - /// - [DataField] - public List>? MoodEffects { get; private set; } = default!; - - /// - /// The list of all Factions that this trait removes. - /// - /// - /// I can't actually Validate these because the proto lives in Shared. - /// - [DataField] - public List? RemoveFactions { get; private set; } = default!; + [DataField(serverOnly: true)] + public TraitFunction[] Functions { get; private set; } = Array.Empty(); +} - /// - /// The list of all Factions that this trait adds. - /// - /// - /// I can't actually Validate these because the proto lives in Shared. - /// - [DataField] - public List? AddFactions { get; private set; } = default!; +/// This serves as a hook for trait functions to modify a player character upon spawning in. +[ImplicitDataDefinitionForInheritors] +public abstract partial class TraitFunction +{ + public abstract void OnPlayerSpawn( + EntityUid mob, + IComponentFactory factory, + IEntityManager entityManager, + ISerializationManager serializationManager); } diff --git a/Content.Shared/UserInterface/ActivatableUIComponent.cs b/Content.Shared/UserInterface/ActivatableUIComponent.cs index 3f83816b7d..93f05acac0 100644 --- a/Content.Shared/UserInterface/ActivatableUIComponent.cs +++ b/Content.Shared/UserInterface/ActivatableUIComponent.cs @@ -57,7 +57,7 @@ public sealed partial class ActivatableUIComponent : Component /// [ViewVariables(VVAccess.ReadWrite)] [DataField] - public bool AllowSpectator = true; + public bool BlockSpectators; /// /// Whether the item must be in the user's currently selected/active hand. diff --git a/Content.Shared/UserInterface/ActivatableUISystem.cs b/Content.Shared/UserInterface/ActivatableUISystem.cs index 3ac8835dd0..14ce4f20dc 100644 --- a/Content.Shared/UserInterface/ActivatableUISystem.cs +++ b/Content.Shared/UserInterface/ActivatableUISystem.cs @@ -8,7 +8,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.Popups; using Content.Shared.Verbs; -using Robust.Shared.Containers; +using Robust.Shared.Utility; namespace Content.Shared.UserInterface; @@ -19,15 +19,12 @@ public sealed partial class ActivatableUISystem : EntitySystem [Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!; [Dependency] private readonly SharedPopupSystem _popupSystem = default!; [Dependency] private readonly SharedHandsSystem _hands = default!; - [Dependency] private readonly SharedContainerSystem _container = default!; - [Dependency] private readonly SharedInteractionSystem _interaction = default!; - - private readonly List _toClose = new(); public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(OnActivate); SubscribeLocalEvent(OnInteractUsing); @@ -37,28 +34,24 @@ public override void Initialize() SubscribeLocalEvent>(GetActivationVerb); SubscribeLocalEvent>(GetVerb); - // TODO ActivatableUI - // Add UI-user component, and listen for user container changes. - // I.e., should lose a computer UI if a player gets shut into a locker. - SubscribeLocalEvent(OnGotInserted); - SubscribeLocalEvent(OnGotRemoved); - - SubscribeLocalEvent(OnBoundInterfaceInteractAttempt); SubscribeLocalEvent(OnActionPerform); InitializePower(); } - private void OnBoundInterfaceInteractAttempt(BoundUserInterfaceMessageAttempt ev) + private void OnStartup(Entity ent, ref ComponentStartup args) { - if (!TryComp(ev.Target, out ActivatableUIComponent? comp)) - return; - - if (!comp.RequireHands) + if (ent.Comp.Key == null) + { + Log.Error($"Missing UI Key for entity: {ToPrettyString(ent)}"); return; + } - if (!TryComp(ev.Actor, out HandsComponent? hands) || hands.Hands.Count == 0) - ev.Cancel(); + // TODO BUI + // set interaction range to zero to avoid constant range checks. + // + // if (ent.Comp.InHandsOnly && _uiSystem.TryGetInterfaceData(ent.Owner, ent.Comp.Key, out var data)) + // data.InteractionRange = 0; } private void OnActionPerform(EntityUid uid, UserInterfaceComponent component, OpenUiActionEvent args) @@ -77,9 +70,10 @@ private void GetActivationVerb(EntityUid uid, ActivatableUIComponent component, args.Verbs.Add(new ActivationVerb { - // TODO VERBS add "open UI" icon Act = () => InteractUI(args.User, uid, component), - Text = Loc.GetString(component.VerbText) + Text = Loc.GetString(component.VerbText), + // TODO VERB ICON find a better icon + Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/settings.svg.192dpi.png")), }); } @@ -90,9 +84,10 @@ private void GetVerb(EntityUid uid, ActivatableUIComponent component, GetVerbsEv args.Verbs.Add(new Verb { - // TODO VERBS add "open UI" icon Act = () => InteractUI(args.User, uid, component), - Text = Loc.GetString(component.VerbText) + Text = Loc.GetString(component.VerbText), + // TODO VERB ICON find a better icon + Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/settings.svg.192dpi.png")), }); } @@ -119,7 +114,7 @@ private bool ShouldAddVerb(EntityUid uid, ActivatableUIComponent component, G } } - return args.CanInteract || component.AllowSpectator && HasComp(args.User); + return args.CanInteract || HasComp(args.User) && !component.BlockSpectators; } private void OnUseInHand(EntityUid uid, ActivatableUIComponent component, UseInHandEvent args) @@ -191,7 +186,7 @@ private bool InteractUI(EntityUid user, EntityUid uiEntity, ActivatableUICompone return true; } - if (!_blockerSystem.CanInteract(user, uiEntity) && (!aui.AllowSpectator || !HasComp(user))) + if (!_blockerSystem.CanInteract(user, uiEntity) && (!HasComp(user) || aui.BlockSpectators)) return false; if (aui.RequireHands) @@ -286,47 +281,4 @@ private void OnHandUnequipped(Entity ent, ref GotUnequip if (ent.Comp.RequireHands && ent.Comp.InHandsOnly) CloseAll(ent, ent); } - - private void OnGotInserted(Entity ent, ref EntGotInsertedIntoContainerMessage args) - { - CheckAccess((ent, ent)); - } - - private void OnGotRemoved(Entity ent, ref EntGotRemovedFromContainerMessage args) - { - CheckAccess((ent, ent)); - } - - public void CheckAccess(Entity ent) - { - if (!Resolve(ent, ref ent.Comp)) - return; - - if (ent.Comp.Key == null) - { - Log.Error($"Encountered null key in activatable ui on entity {ToPrettyString(ent)}"); - return; - } - - foreach (var user in _uiSystem.GetActors(ent.Owner, ent.Comp.Key)) - { - if (!_container.IsInSameOrParentContainer(user, ent) - && !_interaction.CanAccessViaStorage(user, ent)) - { - _toClose.Add(user); - continue; - - } - - if (!_interaction.InRangeUnobstructed(user, ent)) - _toClose.Add(user); - } - - foreach (var user in _toClose) - { - _uiSystem.CloseUi(ent.Owner, ent.Comp.Key, user); - } - - _toClose.Clear(); - } } diff --git a/Content.Shared/Verbs/SharedVerbSystem.cs b/Content.Shared/Verbs/SharedVerbSystem.cs index 60714aea8f..e78fe98f4c 100644 --- a/Content.Shared/Verbs/SharedVerbSystem.cs +++ b/Content.Shared/Verbs/SharedVerbSystem.cs @@ -72,19 +72,7 @@ public SortedSet GetLocalVerbs(EntityUid target, EntityUid user, List(); - IoCManager.Resolve().Initialize(); - var prototypeManager = IoCManager.Resolve(); - prototypeManager.Initialize(); - var factory = IoCManager.Resolve(); - factory.RegisterClass(); - prototypeManager.LoadFromStream(new StringReader(PROTOTYPES)); - prototypeManager.ResolveResults(); - - var entSys = entManager.EntitySysManager; - entSys.LoadExtraSystemType(); - - var alertsComponent = new AlertsComponent(); - alertsComponent = IoCManager.InjectDependencies(alertsComponent); - - Assert.That(EntitySystem.Get().TryGet(AlertType.LowPressure, out var lowpressure)); - Assert.That(EntitySystem.Get().TryGet(AlertType.HighPressure, out var highpressure)); - - EntitySystem.Get().ShowAlert(alertsComponent.Owner, AlertType.LowPressure, null, null); - - var getty = new ComponentGetState(); - entManager.EventBus.RaiseComponentEvent(alertsComponent, getty); - - var alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!; - Assert.That(alertState, Is.Not.Null); - Assert.That(alertState.Alerts.Count, Is.EqualTo(1)); - Assert.That(alertState.Alerts.ContainsKey(lowpressure.AlertKey)); - - EntitySystem.Get().ShowAlert(alertsComponent.Owner, AlertType.HighPressure, null, null); - - // Lazy - entManager.EventBus.RaiseComponentEvent(alertsComponent, getty); - alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!; - Assert.That(alertState.Alerts.Count, Is.EqualTo(1)); - Assert.That(alertState.Alerts.ContainsKey(highpressure.AlertKey)); - - EntitySystem.Get().ClearAlertCategory(alertsComponent.Owner, AlertCategory.Pressure); - - entManager.EventBus.RaiseComponentEvent(alertsComponent, getty); - alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!; - Assert.That(alertState.Alerts.Count, Is.EqualTo(0)); - } - } -} diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 59b9cbb957..789a4c1af2 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -7766,3 +7766,70 @@ Entries: id: 6504 time: '2024-11-02T16:24:46.0000000+00:00' url: https://github.com/Simple-Station/Einstein-Engines/pull/1176 +- author: VMSolidus + changes: + - type: Tweak + message: >- + Cargo Technicians and Salvage Techs can now process cargo orders. You + don't need to smash the fucking LO Locker with a pickaxe anymore. + id: 6505 + time: '2024-11-02T19:58:26.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/1177 +- author: VMSolidus + changes: + - type: Fix + message: >- + Communications Consoles that are marked as "Can't Recall The Shuttle" + now can't recall the shuttle. Previously they were still able to recall + it. + id: 6506 + time: '2024-11-05T04:12:36.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/1180 +- author: Mocho + changes: + - type: Tweak + message: Ported over Wizden's updated Health Analyzer UI. + id: 6507 + time: '2024-11-07T04:50:46.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/1183 +- author: VMSolidus + changes: + - type: Fix + message: Familiars can now be Dispelled. + - type: Tweak + message: Nerfed Remilia to have 30 HP. + - type: Tweak + message: Nerfed Base Familiar to have 50 HP. + id: 6508 + time: '2024-11-08T15:17:12.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/1184 +- author: VMSolidus + changes: + - type: Add + message: 'Languages are now shown in chat alongside character names. ' + id: 6509 + time: '2024-11-08T16:14:09.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/1165 +- author: Ichaie + changes: + - type: Fix + message: minor fixes on the maps Rad and Gax, fix te uranium crarte to filled + id: 6510 + time: '2024-11-08T18:54:13.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/1178 +- author: VMSolidus + changes: + - type: Add + message: 'Traits can now add Implants directly. ' + id: 6511 + time: '2024-11-08T18:58:04.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/1182 +- author: VMSolidus + changes: + - type: Remove + message: >- + Shadowkin have been temporarily disabled pending significant reworks and + balance updates. + id: 6512 + time: '2024-11-08T19:33:53.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/1187 diff --git a/Resources/Credits/GitHub.txt b/Resources/Credits/GitHub.txt index 7b0e97dea4..d8368cffba 100644 --- a/Resources/Credits/GitHub.txt +++ b/Resources/Credits/GitHub.txt @@ -1 +1 @@ -0x6273, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 4dplanner, 612git, 778b, Ablankmann, Acruid, actioninja, adamsong, Admiral-Obvious-001, Adrian16199, Aerocrux, Aexxie, africalimedrop, Agoichi, Ahion, Aidenkrz, AJCM-git, AjexRose, Alekshhh, AlexMorgan3817, AlmondFlour, AlphaQwerty, Altoids1, amylizzle, ancientpower, angelofallars, ArchPigeon, Arendian, arimah, Arteben, AruMoon, as334, AsikKEsel, asperger-sind, aspiringLich, avghdev, AzzyIsNotHere, BananaFlambe, BasedUser, beck-thompson, BGare, BingoJohnson-zz, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, BlueHNT, Boaz1111, BobdaBiscuit, brainfood1183, BramvanZijp, Brandon-Huu, Bribrooo, Bright0, brndd, BubblegumBlue, BYONDFuckery, c4llv07e, CaasGit, CakeQ, CaptainSqrBeard, Carbonhell, Carolyn3114, CatTheSystem, Centronias, chairbender, Charlese2, Cheackraze, cheesePizza2, Chief-Engineer, chromiumboy, Chronophylos, CilliePaint, clorl, Clyybber, CodedCrow, ColdAutumnRain, Colin-Tel, collinlunn, ComicIronic, coolmankid12345, corentt, crazybrain23, creadth, CrigCrag, Crotalus, CrudeWax, CrzyPotato, Cyberboss, d34d10cc, d4kii, Daemon, daerSeebaer, dahnte, dakamakat, DamianX, DangerRevolution, daniel-cr, Darkenson, DawBla, dch-GH, Deahaka, DEATHB4DEFEAT, DeathCamel58, deathride58, DebugOk, Decappi, Deeeeja, deepdarkdepths, Delete69, deltanedas, DeltaV-Bot, DerbyX, DoctorBeard, DogZeroX, dontbetank, dootythefrooty, Doru991, DoubleRiceEddiedd, DrMelon, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, Duddino, Dutch-VanDerLinde, Easypoller, eclips_e, EEASAS, Efruit, ElectroSR, elthundercloud, Emisse, EmoGarbage404, Endecc, enumerate0, eoineoineoin, ERORR404V1, Errant-4, estacaoespacialpirata, Evgencheg, exincore, exp111, Fahasor, FairlySadPanda, Fansana, ficcialfaint, Fildrance, FillerVK, Fishfish458, Flareguy, FluffiestFloof, FoLoKe, fooberticus, Fortune117, FoxxoTrystan, freeman2651, Fromoriss, FungiFellow, GalacticChimp, gbasood, Geekyhobo, geraeumig, Git-Nivrak, github-actions[bot], gituhabu, gluesniffler, Golinth, GoodWheatley, gradientvera, graevy, GreyMario, Guess-My-Name, gusxyz, h3half, Hanzdegloker, Hardly3D, harikattar, HerCoyote23, HoofedEar, Hoolny, hord-brayden, hubismal, Hugal31, Huxellberger, iacore, IamVelcroboy, icekot8, Ichaie, igorsaux, ike709, Illiux, Ilya246, IlyaElDunaev, Injazz, Insineer, Interrobang01, IProduceWidgets, ItsMeThom, Jackal298, Jackrost, jamessimo, janekvap, JerryImMouse, Jessetriesagain, jessicamaybe, Jezithyr, jicksaw, JiimBob, JoeHammad1844, JohnGinnane, johnku1, joshepvodka, Jrpl, juliangiebel, JustArt1m, JustCone14, JustinTrotter, KaiShibaa, kalane15, kalanosh, Kelrak, kerisargit, keronshb, KIBORG04, Killerqu00, KingFroozy, kira-er, Kit0vras, KittenColony, Ko4ergaPunk, komunre, koteq, Krunklehorn, kxvvv, Lamrr, LankLTE, lapatison, Leander-0, leonardo-dabepis, LetterN, Level10Cybermancer, lever1209, Lgibb18, liltenhead, LittleBuilderJane, Lomcastar, LordCarve, LordEclipse, LovelyLophi, Lukasz825700516, lunarcomets, luringens, lvvova1, lzimann, lzk228, MACMAN2003, Macoron, MagnusCrowe, ManelNavola, Matz05, MehimoNemo, MeltedPixel, MemeProof, Menshin, Mervill, metalgearsloth, mhamsterr, MilenVolf, Minty642, Mirino97, mirrorcult, misandrie, MishaUnity, MisterMecky, Mith-randalf, Mnemotechnician, Moneyl, Moomoobeef, moony, Morb0, Mr0maks, musicmanvr, Myakot, Myctai, N3X15, Nairodian, Naive817, namespace-Memory, NickPowers43, nikthechampiongr, Nimfar11, Nirnael, nmajask, nok-ko, notafet, notquitehadouken, noudoit, nuke-haus, NULL882, nyeogmi, OCOtheOmega, OctoRocket, OldDanceJacket, onoira, osjarw, Owai-Seek, pali6, Pangogie, paolordls, patrikturi, PaulRitter, Peptide90, peptron1, Phantom-Lily, PHCodes, PixelTheKermit, PJB3005, Plykiya, pofitlo, pointer-to-null, PolterTzi, PoorMansDreams, potato1234x, ProfanedBane, PrPleGoo, ps3moira, Pspritechologist, Psychpsyo, psykzz, PuroSlavKing, quatre, QuietlyWhisper, qwerltaz, Radosvik, Radrark, Rainbeon, Rainfey, Rane, ravage123321, rbertoche, Redict, RedlineTriad, RednoWCirabrab, RemberBM, RemieRichards, RemTim, Remuchi, rene-descartes2021, RiceMar1244, RieBi, Rinkashikachi, Rockdtben, rolfero, rosieposieeee, Saakra, Samsterious, SaphireLattice, ScalyChimp, scrato, Scribbles0, Serkket, ShadowCommander, ShatteredSwords, SignalWalker, SimpleStation14, Simyon264, Sirionaut, siyengar04, Skarletto, Skrauz, Skyedra, SlamBamActionman, slarticodefast, Slava0135, SleepyScarecrow, Snowni, snowsignal, SonicHDC, SoulSloth, SpaceManiac, SpeltIncorrectyl, spoogemonster, ssdaniel24, stalengd, Stealthbomber16, stellar-novas, StrawberryMoses, superjj18, SweptWasTaken, Szunti, TadJohnson00, takemysoult, TaralGit, Tayrtahn, tday93, TekuNut, TemporalOroboros, tentekal, tgrkzus, thatrandomcanadianguy, TheArturZh, theashtronaut, thedraccx, themias, theomund, theOperand, TheShuEd, TimrodDX, Titian3, tkdrg, Tmanzxd, tmtmtl30, TokenStyle, tom-leys, tomasalves8, Tomeno, Tornado-Technology, tosatur, Tryded, TsjipTsjip, Tunguso4ka, TurboTrackerss14, Tyler-IN, Tyzemol, UbaserB, UKNOWH, UltimateJester, UnicornOnLSD, Uriende, UristMcDorf, Vaaankas, Varen, VasilisThePikachu, veliebm, Veritius, Vermidia, Verslebas, VigersRay, Visne, VMSolidus, volundr-, Voomra, Vordenburg, vulppine, wafehling, WarMechanic, waylon531, weaversam8, whateverusername0, Willhelm53, Winkarst-cpu, wixoaGit, WlarusFromDaSpace, wrexbe, xRiriq, yathxyz, Ygg01, YotaXP, YuriyKiss, zach-hill, Zandario, Zap527, Zealith-Gamer, zelezniciar1, ZelteHonor, zerorulez, zionnBE, ZNixian, ZoldorfTheWizard, Zymem +0x6273, 13spacemen, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 2digitman, 4310v343k, 4dplanner, 612git, 778b, Ablankmann, abregado, Absolute-Potato, Acruid, actioninja, actually-reb, ada-please, adamsong, Adeinitas, Admiral-Obvious-001, adrian, Adrian16199, Aerocrux, Aexolott, Aexxie, africalimedrop, afrokada, Agoichi, Ahion, Aidenkrz, Aikakakah, aitorlogedo, AJCM-git, AjexRose, Alekshhh, alexkar598, AlexMorgan3817, alexumandxgabriel08x, Alithsko, AlmondFlour, ALMv1, AlphaQwerty, Altoids1, amylizzle, ancientpower, Andre19926, AndrewEyeke, angelofallars, Anzarot121, Appiah, ar4ill, ArchPigeon, areitpog, Arendian, arimah, Arkanic, armoks, Arteben, ArthurMousatov, AruMoon, as334, AsikKEsel, asperger-sind, aspiringLich, astriloqua, avghdev, AzzyIsNotHere, BananaFlambe, BasedPugilist, BasedUser, beck-thompson, benev0, BGare, bhespiritu, BingoJohnson-zz, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, bloodrizer, Bloody2372, blueDev2, BlueHNT, Boaz1111, BobdaBiscuit, BobTheSleder, boiled-water-tsar, botanySupremist, brainfood1183, BramvanZijp, Brandon-Huu, Bribrooo, Bright0, brndd, bryce0110, BubblegumBlue, buletsponge, BYONDFuckery, c0rigin, c4llv07e, CaasGit, CakeQ, capnsockless, CaptainSqrBeard, Carbonhell, Carolyn3114, Carou02, carteblanche4me, CatTheSystem, Centronias, chairbender, Charlese2, Cheackraze, cheesePizza2, Chief-Engineer, christhirtle, chromiumboy, Chronophylos, Chubbygummibear, CilliePaint, civilCornball, clorl, clyf, Clyybber, CMDR-Piboy314, CodedCrow, Cohnway, cojoke-dot, ColdAutumnRain, Colin-Tel, collinlunn, ComicIronic, coolmankid12345, corentt, CormosLemming, crazybrain23, creadth, CrigCrag, Crotalus, CrudeWax, CrzyPotato, Cyberboss, d34d10cc, d4kii, DadeKuma, Daemon, daerSeebaer, dahnte, dakamakat, DamianX, DangerRevolution, daniel-cr, DanSAussieITS, Daracke, DarkenedSynergy, Darkenson, DawBla, Daxxi3, dch-GH, Deahaka, dean, DEATHB4DEFEAT, DeathCamel58, deathride58, DebugOk, Decappi, Deeeeja, deepdarkdepths, degradka, Delete69, deltanedas, DeltaV-Bot, DerbyX, derek, dersheppard, dexlerxd, dffdff2423, dge21, digitalic, DinoWattz, DJB1gYAPPA, DjfjdfofdjfjD, docnite, DoctorBeard, DogZeroX, dolgovmi, dontbetank, dootythefrooty, Dorragon, Doru991, DoubleRiceEddiedd, DoutorWhite, drakewill-CRL, Drayff, dribblydrone, DrMelon, drongood12, DrSingh, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, Duddino, dukevanity, Dutch-VanDerLinde, dvir001, Dynexust, Easypoller, eclips_e, eden077, EEASAS, Efruit, efzapa, ElectroSR, elsie, elthundercloud, Emisse, emmafornash, EmoGarbage404, Endecc, enumerate0, eoineoineoin, eris, ERORR404V1, Errant-4, esguard, estacaoespacialpirata, eugene, Evgencheg, exincore, exp111, f0x-n3rd, FacePluslll, Fahasor, FairlySadPanda, Fansana, Feluk6174, fenndragon, ficcialfaint, Fiftyllama, Fildrance, FillerVK, FinnishPaladin, FirinMaLazors, Fishfish458, FL-OZ, Flareguy, FluffiestFloof, FluidRock, flybik, FoLoKe, fooberticus, ForestNoises, forgotmyotheraccount, forkeyboards, forthbridge, Fortune117, Fouin, foxhorn, FoxxoTrystan, freeman2651, freeze2222, Froffy025, Fromoriss, froozigiusz, FrostMando, FungiFellow, GalacticChimp, Gaxeer, gbasood, Geekyhobo, genderGeometries, GeneralGaws, Genkail, geraeumig, Ghagliiarghii, ghost581x, Git-Nivrak, gituhabu, GlassEclipse, gluesniffler, GNF54, Golinth, GoodWheatley, gradientvera, graevy, GraniteSidewalk, GreaseMonk, greenrock64, greggthefather, GreyMario, GTRsound, Guess-My-Name, gusxyz, h3half, Haltell, Hanzdegloker, Hardly3D, harikattar, Hebi, Henry, HerCoyote23, hiucko, Hmeister-fake, Hmeister-real, hobnob, HoidC, Holinka4ever, holyssss, HoofedEar, Hoolny, hord-brayden, hubismal, Hugal31, Huxellberger, Hyenh, i-justuser-i, iacore, IamVelcroboy, icekot8, icesickleone, Ichaie, iczero, iglov, igorsaux, ike709, illersaver, Illiux, Ilushkins33, Ilya246, IlyaElDunaev, indeano, Injazz, Insineer, IntegerTempest, Interrobang01, IProduceWidgets, ItsMeThom, Itzbenz, Jackal298, Jackrost, jacksonzck, Jackw2As, jamessimo, janekvap, Jark255, Jaskanbe, JasperJRoth, JerryImMouse, jerryimmouse, Jessetriesagain, jessicamaybe, Jezithyr, jicksaw, JiimBob, JimGamemaster, jjtParadox, JoeHammad1844, JohnGinnane, johnku1, joshepvodka, Jrpl, juliangiebel, JustArt1m, JustCone14, justin, justintether, JustinTrotter, justtne, k3yw, Kadeo64, KaiShibaa, kalane15, kalanosh, Keelin, Keer-Sar, KEEYNy, keikiru, Kelrak, kerisargit, keronshb, KIBORG04, Killerqu00, Kimpes, KingFroozy, kira-er, Kirillcas, Kistras, Kit0vras, KittenColony, klaypexx, Kmc2000, Ko4ergaPunk, kognise, komunre, koteq, Krunklehorn, Kukutis96513, Kupie, kxvvv, kzhanik, lajolico, Lamrr, LankLTE, laok233, lapatison, larryrussian, lawdog4817, Lazzi0706, Leander-0, leonardo-dabepis, leonsfriedrich, lettern, LetterN, Level10Cybermancer, LEVELcat, lever1209, Lgibb18, LightVillet, liltenhead, LinkUyx, LittleBuilderJane, lizelive, lleftTheDragon, localcc, Lomcastar, LordCarve, LordEclipse, LovelyLophi, luckyshotpictures, LudwigVonChesterfield, Lukasz825700516, lunarcomets, luringens, lvvova1, lzimann, lzk228, M3739, mac6na6na, MACMAN2003, Macoron, magmodius, MagnusCrowe, malchanceux, MaloTV, ManelNavola, Mangohydra, marboww, Markek1, Matz05, max, MaxNox7, MehimoNemo, MeltedPixel, MemeProof, MendaxxDev, Menshin, Mephisto72, Mervill, metalgearsloth, mhamsterr, michaelcu, micheel665, MilenVolf, Minty642, Mirino97, mirrorcult, misandrie, MishaUnity, MisterMecky, Mith-randalf, MjrLandWhale, MLGTASTICa, Mnemotechnician, moderatelyaware, mokiros, Moneyl, Moomoobeef, moony, Morb0, mr-bo-jangles, Mr0maks, MrFippik, musicmanvr, MWKane, Myakot, Myctai, N3X15, nails-n-tape, Nairodian, Naive817, namespace-Memory, Nannek, NickPowers43, nikthechampiongr, Nimfar11, Nirnael, NIXC, NkoKirkto, nmajask, noctyrnal, nok-ko, NonchalantNoob, NoobyLegion, not-gavnaed, notafet, notquitehadouken, noudoit, noverd, NuclearWinter, nukashimika, nuke-haus, NULL882, nullarmo, nyeogmi, Nylux, Nyranu, och-och, OCOtheOmega, OctoRocket, OldDanceJacket, onoira, osjarw, Ostaf, othymer, OttoMaticode, Owai-Seek, paigemaeforrest, pali6, Pangogie, panzer-iv1, paolordls, partyaddict, patrikturi, PaulRitter, Peptide90, peptron1, PeterFuto, PetMudstone, pewter-wiz, Phantom-Lily, PHCodes, Phill101, phunnyguy, pigeonpeas, PilgrimViis, Pill-U, Pireax, pissdemon, PixelTheKermit, PJB3005, Plasmaguy, PlasmaRaptor, plinyvic, Plykiya, pofitlo, pointer-to-null, PolterTzi, PoorMansDreams, potato1234x, PotentiallyTom, ProfanedBane, ProPandaBear, PrPleGoo, ps3moira, Pspritechologist, Psychpsyo, psykzz, PuceTint, PuroSlavKing, PursuitInAshes, Putnam3145, qrtDaniil, quatre, QuietlyWhisper, qwerltaz, RadioMull, Radosvik, Radrark, Rainbeon, Rainfey, Raitononai, randy10122, Rane, Ranger6012, Rapidgame7, ravage123321, rbertoche, Redict, RedlineTriad, RednoWCirabrab, RemberBM, RemieRichards, RemTim, Remuchi, rene-descartes2021, Renlou, retequizzle, RiceMar1244, rich-dunne, RieBi, riggleprime, RIKELOLDABOSS, Rinkashikachi, RobbyTheFish, Rockdtben, Rohesie, rok-povsic, rolfero, RomanNovo, rosieposieeee, router, RumiTiger, S1ss3l, Saakra, Salex08, sam, Samsterious, SaphireLattice, SapphicOverload, SaveliyM360, sBasalto, ScalyChimp, scrato, Scribbles0, scuffedjays, ScumbagDog, Segonist, sephtasm, Serkket, sewerpig, ShadowCommander, shadowtheprotogen546, shadowwailker, shaeone, shampunj, shariathotpatrol, ShatteredSwords, SignalWalker, siigiil, SimpleStation14, Simyon264, sirdragooon, Sirionaut, siyengar04, Sk1tch, SkaldetSkaeg, Skarletto, Skrauz, Skyedra, SlamBamActionman, slarticodefast, Slava0135, SleepyScarecrow, Slyfox333, snebl, sniperchance, Snowni, snowsignal, SonicHDC, SoulFN, SoulSloth, Soundwavesghost, SpaceManiac, SpaceyLady, spartak, SpartanKadence, Spatison, SpeltIncorrectyl, sphirai, SplinterGP, spoogemonster, sporekto, Squishy77, ssdaniel24, stalengd, stanberytrask, Stanislav4ix, StanTheCarpenter, Stealthbomber16, stellar-novas, stopbreaking, stopka-html, StrawberryMoses, Stray-Pyramid, Strol20, StStevens, Subversionary, sunbear-dev, superjj18, Supernorn, SweptWasTaken, Sybil, SYNCHRONIC, Szunti, TadJohnson00, takemysoult, TaralGit, Taran, Tayrtahn, tday93, TekuNut, telyonok, TemporalOroboros, tentekal, terezi4real, Terraspark4941, texcruize, tgrkzus, thatrandomcanadianguy, TheArturZh, theashtronaut, TheCze, TheDarkElites, thedraccx, TheEmber, TheIntoxicatedCat, thekilk, themias, theomund, theOperand, TherapyGoth, TheShuEd, thevinter, ThunderBear2006, Timemaster99, timothyteakettle, TimrodDX, tin-man-tim, Tirochora, Titian3, tk-a369, tkdrg, Tmanzxd, tmtmtl30, toasterpm87, TokenStyle, Tollhouse, tom-leys, tomasalves8, Tomeno, Tonydatguy, Tornado-Technology, tosatur, TotallyLemon, truepaintgit, Tryded, TsjipTsjip, Tunguso4ka, TurboTrackerss14, Tyler-IN, Tyzemol, UbaserB, ubis1, UBlueberry, UKNOWH, UltimateJester, Unbelievable-Salmon, underscorex5, UnicornOnLSD, unusualcrow, Uriende, UristMcDorf, user424242420, v0idRift, Vaaankas, valentfingerov, Varen, VasilisThePikachu, veliebm, VelonacepsCalyxEggs, veprolet, Veritius, Vermidia, vero5123, Verslebas, VigersRay, violet754, Visne, VMSolidus, volotomite, volundr-, Voomra, Vordenburg, vulppine, wafehling, Warentan, WarMechanic, Watermelon914, waylon531, weaversam8, wertanchik, whateverusername0, Willhelm53, WilliamECrew, willicassi, Winkarst-cpu, wirdal, wixoaGit, WlarusFromDaSpace, wrexbe, WTCWR68, xkreksx, xRiriq, YanehCheck, yathxyz, Ygg01, YotaXP, youarereadingthis, Yousifb26, yunii, yuriykiss, YuriyKiss, zach-hill, Zadeon, zamp, Zandario, Zap527, Zealith-Gamer, zelezniciar1, ZelteHonor, ZeroDiamond, zerorulez, ZeWaka, zionnBE, ZNixian, ZoldorfTheWizard, Zymem, zzylex diff --git a/Resources/Locale/en-US/Content/Power/batteryDrinker.ftl b/Resources/Locale/en-US/Content/Power/batteryDrinker.ftl deleted file mode 100644 index 950b321d40..0000000000 --- a/Resources/Locale/en-US/Content/Power/batteryDrinker.ftl +++ /dev/null @@ -1,2 +0,0 @@ -battery-drinker-verb-drink = Drain -battery-drinker-empty = {CAPATALIZE(THE($target))} is already empty! diff --git a/Resources/Locale/en-US/Content/Power/silicons.ftl b/Resources/Locale/en-US/Content/Power/silicons.ftl index f5d24bde07..4e047d3653 100644 --- a/Resources/Locale/en-US/Content/Power/silicons.ftl +++ b/Resources/Locale/en-US/Content/Power/silicons.ftl @@ -1,6 +1,3 @@ -silicon-overheating = You can feel your circuits burn! -silicon-crit = Integrated structure in critical state! -silicon-power-low = Low battery! ipc-recharge-tip = You charged a litte of your battery. dead-startup-button-verb = Reboot dead-startup-system-reboot-success = {$target}'s system was rebooted. diff --git a/Resources/Locale/en-US/abilities/psionic.ftl b/Resources/Locale/en-US/abilities/psionic.ftl index 91ae21233a..d0e8db72f8 100644 --- a/Resources/Locale/en-US/abilities/psionic.ftl +++ b/Resources/Locale/en-US/abilities/psionic.ftl @@ -25,9 +25,6 @@ accept-psionics-window-prompt-text-part = You rolled a psionic power! action-name-psionic-invisibility = Psionic Invisibility action-description-psionic-invisibility = Render yourself invisible to any entity that could potentially be psychic. Borgs, animals, and so on are not affected. -action-name-psionic-invisibility = Psionic Invisibility -action-description-psionic-invisibility = Render yourself invisible to any entity that could potentially be psychic. Borgs, animals, and so on are not affected. - action-name-psionic-invisibility-off = Turn Off Psionic Invisibility action-description-psionic-invisibility-off = Return to visibility, and receive a stun. diff --git a/Resources/Locale/en-US/accent/accents.ftl b/Resources/Locale/en-US/accent/accents.ftl index 301c589449..3c898f9cb1 100644 --- a/Resources/Locale/en-US/accent/accents.ftl +++ b/Resources/Locale/en-US/accent/accents.ftl @@ -98,7 +98,11 @@ accent-words-slimes-4 = Bluuump... accent-words-slimes-5 = Blabl blump! # Mothroach -accent-words-mothroach-1 = Chirp! +accent-words-mothroach-1 = Squeak! +accent-words-mothroach-2 = Chirp! +accent-words-mothroach-3 = Peep! +accent-words-mothroach-4 = Eeee! +accent-words-mothroach-5 = Eep! # Crab accent-words-crab-1 = Click. diff --git a/Resources/Locale/en-US/chat/managers/chat-language.ftl b/Resources/Locale/en-US/chat/managers/chat-language.ftl new file mode 100644 index 0000000000..f975160674 --- /dev/null +++ b/Resources/Locale/en-US/chat/managers/chat-language.ftl @@ -0,0 +1,15 @@ +chat-language-Universal-name = Universal +chat-language-Bubblish-name = Bubblish +chat-language-RootSpeak-name = Rootspeak +chat-language-Nekomimetic-name = Neko +chat-language-Draconic-name = Sinta'Unathi +chat-language-Azaziba-name = Sinta'Azaziba +chat-language-SolCommon-name = Sol Common +chat-language-TauCetiBasic-name = Basic +chat-language-Tradeband-name = Tradeband +chat-language-Freespeak-name = Freespeak +chat-language-Elyran-name = Elyran +chat-language-Canilunzt-name = Canilunzt +chat-language-Moffic-name = Moffic +chat-language-RobotTalk-name = Binary +chat-language-ValyrianStandard-name = Valyrian diff --git a/Resources/Locale/en-US/chat/managers/chat-manager.ftl b/Resources/Locale/en-US/chat/managers/chat-manager.ftl index e25522ac1d..f2b70e72a8 100644 --- a/Resources/Locale/en-US/chat/managers/chat-manager.ftl +++ b/Resources/Locale/en-US/chat/managers/chat-manager.ftl @@ -21,10 +21,10 @@ chat-manager-whisper-headset-on-message = You can't whisper on the radio! chat-manager-server-wrap-message = [bold]{$message}[/bold] chat-manager-sender-announcement-wrap-message = [font size=14][bold]{$sender} Announcement:[/font][font size=12] {$message}[/bold][/font] -chat-manager-entity-say-wrap-message = [BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] {$verb}, "[BubbleContent][font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font][/BubbleContent]" -chat-manager-entity-say-bold-wrap-message = [BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] {$verb}, "[BubbleContent][font="{$fontType}" size={$fontSize}][color={$color}][bold]{$message}[/bold][/color][/font][/BubbleContent]" +chat-manager-entity-say-wrap-message = [BubbleHeader][bold][Name]{ $language }{ $entityName }[/Name][/bold][/BubbleHeader] { $verb }, [font={ $fontType } size={ $fontSize } ]"[BubbleContent]{ $message }[/BubbleContent]"[/font] +chat-manager-entity-say-bold-wrap-message = [BubbleHeader][bold][Name]{ $language }{ $entityName }[/Name][/bold][/BubbleHeader] { $verb }, [font={ $fontType } size={ $fontSize }]"[BubbleContent][bold]{ $message }[/bold][/BubbleContent]"[/font] -chat-manager-entity-whisper-wrap-message = [font size=11][italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] whispers, "[BubbleContent][font="{$fontType}"][color={$color}]{$message}[/color][/font][/BubbleContent]"[/italic][/font] +chat-manager-entity-whisper-wrap-message = [font size=11][italic][BubbleHeader][Name]{ $language }{ $entityName }[/Name][/BubbleHeader] whispers,"[BubbleContent]{ $message }[/BubbleContent]"[/italic][/font] chat-manager-entity-whisper-unknown-wrap-message = [font size=11][italic][BubbleHeader]Someone[/BubbleHeader] whispers, "[BubbleContent][font="{$fontType}"][color={$color}]{$message}[/color][/font][/BubbleContent]"[/italic][/font] # THE() is not used here because the entity and its name can technically be disconnected if a nameOverride is passed... @@ -159,4 +159,4 @@ chat-speech-verb-electricity-1 = crackles chat-speech-verb-electricity-2 = buzzes chat-speech-verb-electricity-3 = screeches -chat-speech-verb-marish = Mars \ No newline at end of file +chat-speech-verb-marish = Mars diff --git a/Resources/Locale/en-US/deltav/flavors/flavor-profiles.ftl b/Resources/Locale/en-US/deltav/flavors/flavor-profiles.ftl index 98e04f2818..2cae678bc7 100644 --- a/Resources/Locale/en-US/deltav/flavors/flavor-profiles.ftl +++ b/Resources/Locale/en-US/deltav/flavors/flavor-profiles.ftl @@ -5,7 +5,6 @@ flavor-complex-enthralling = enthralling flavor-complex-sublime = sublime flavor-complex-holy = heavenly flavor-base-seeds = seeds -flavor-complex-cotton = like cotton flavor-complex-vanilla = like vanilla flavor-complex-soju = like bold, alcoholic rice flavor-complex-orangecreamcicle = like creamy, alcoholic orange juice @@ -26,4 +25,3 @@ flavor-complex-greengrass = like a holiday in the sun flavor-complex-daiquiri = fashionable flavor-complex-arsonistsbrew = like ash and flame flavor-complex-healthcodeviolation = ominous -flavor-complex-pumpkin = like pumpkin diff --git a/Resources/Locale/en-US/deltav/prototypes/catalog/cargo/cargo-fun.ftl b/Resources/Locale/en-US/deltav/prototypes/catalog/cargo/cargo-fun.ftl deleted file mode 100644 index 32d3ab61c3..0000000000 --- a/Resources/Locale/en-US/deltav/prototypes/catalog/cargo/cargo-fun.ftl +++ /dev/null @@ -1,2 +0,0 @@ -ent-CrateFunBBGun = { ent-CrateFunBBGun } - .desc = { ent-CrateFunBBGun.desc } diff --git a/Resources/Locale/en-US/entity-categories.ftl b/Resources/Locale/en-US/entity-categories.ftl new file mode 100644 index 0000000000..190fe5713a --- /dev/null +++ b/Resources/Locale/en-US/entity-categories.ftl @@ -0,0 +1 @@ +entity-category-name-actions = Actions diff --git a/Resources/Locale/en-US/headset/headset-component.ftl b/Resources/Locale/en-US/headset/headset-component.ftl index 75c83643d6..3f89dde13a 100644 --- a/Resources/Locale/en-US/headset/headset-component.ftl +++ b/Resources/Locale/en-US/headset/headset-component.ftl @@ -1,6 +1,6 @@ # Chat window radio wrap (prefix and postfix) -chat-radio-message-wrap = [color={$color}]{$channel} {$name} {$verb}, [font="{$fontType}" size={$fontSize}]"[/color][color={$languageColor}]{$message}[/color][color={$color}]"[/font][/color] -chat-radio-message-wrap-bold = [color={$color}]{$channel} {$name} {$verb}, [font="{$fontType}" size={$fontSize}][bold]"[/color][color={$languageColor}]{$message}[/color][color={$color}]"[/bold][/font][/color] +chat-radio-message-wrap = [color={ $color }]{ $channel } [bold]{ $language }{ $name }[/bold] { $verb }, [font={ $fontType } size={ $fontSize }]"{ $message }"[/font][/color] +chat-radio-message-wrap-bold = [color={ $color }]{ $channel } [bold]{ $language }{ $name }[/bold] { $verb }, [font={ $fontType } size={ $fontSize }][bold]"{ $message }"[/bold][/font][/color] examine-headset-default-channel = Use {$prefix} for the default channel ([color={$color}]{$channel}[/color]). diff --git a/Resources/Locale/en-US/loadouts/jobs/heads/captain.ftl b/Resources/Locale/en-US/loadouts/jobs/heads/captain.ftl index af5b90dd8d..27069b6ff8 100644 --- a/Resources/Locale/en-US/loadouts/jobs/heads/captain.ftl +++ b/Resources/Locale/en-US/loadouts/jobs/heads/captain.ftl @@ -7,6 +7,6 @@ loadout-description-LoadoutCommandCapOuterWinter = A warm coat for the cold of s loadout-description-LoadoutCommandCapGloves = The gloves of the captain. They are very nice gloves. loadout-description-LoadoutCommandCapHat = The hat of the captain. It is a very nice hat. loadout-description-LoadoutCommandCapHatCapcap = The Captain's cap, pretty nice. -loadout-description-LoadoutCommandCapHat = The Captain's beret, very nice. +loadout-description-LoadoutCommandCapHatBeret = The Captain's beret, very nice. loadout-description-LoadoutCommandCapMaskGas = Why would the captain need this? I don't know, but it looks cool. loadout-description-LoadoutCommandCapItemDrinkFlask = The finest of flasks, for the finest of drinks. diff --git a/Resources/Locale/en-US/markings/Kemonomimi_tails.ftl b/Resources/Locale/en-US/markings/Kemonomimi_tails.ftl index 303335cd2c..039aa699e0 100644 --- a/Resources/Locale/en-US/markings/Kemonomimi_tails.ftl +++ b/Resources/Locale/en-US/markings/Kemonomimi_tails.ftl @@ -17,7 +17,7 @@ marking-FoxThreeTails-foxthreetailstone1 = Inner marking-FoxThreeTails-foxthreetailstone2 = Outer marking-HorseTailCulty = Culty Horse Tail -marking-HorseTailCulty = Tail +marking-HorseTailCulty-horsetailculty = Tail marking-HorseTailLong = Long Horse Tail marking-HorseTailLong-horsetaillong = Tail diff --git a/Resources/Locale/en-US/markings/harpy.ftl b/Resources/Locale/en-US/markings/harpy.ftl index 724207c3ef..36ae7dd308 100644 --- a/Resources/Locale/en-US/markings/harpy.ftl +++ b/Resources/Locale/en-US/markings/harpy.ftl @@ -81,7 +81,7 @@ marking-HarpyTailForkedLong = Long Forked Tail (Whitescale) marking-HarpyTailForkedLong-forked_long = Tail marking-HarpyTailSwallow = Swallow Tail (Whitescale) -marking-HarpyTailForkedLong-forked_long = Tail +marking-HarpyTailSwallow-swallow_tail = Tail marking-HarpyChestDefault = Wing & Groin Under-Clothes marking-HarpyChestDefault-upper = Wing Under-Clothes diff --git a/Resources/Locale/en-US/medical/components/health-analyzer-component.ftl b/Resources/Locale/en-US/medical/components/health-analyzer-component.ftl index 8460bcc27b..97af759039 100644 --- a/Resources/Locale/en-US/medical/components/health-analyzer-component.ftl +++ b/Resources/Locale/en-US/medical/components/health-analyzer-component.ftl @@ -1,16 +1,50 @@ health-analyzer-window-no-patient-data-text = No patient data. -health-analyzer-window-entity-unknown-text = unknown -health-analyzer-window-entity-health-text = {$entityName}'s health: -health-analyzer-window-entity-temperature-text = Temperature: {$temperature} -health-analyzer-window-entity-blood-level-text = Blood Level: {$bloodLevel} -health-analyzer-window-entity-bleeding-text = Patient is bleeding! -health-analyzer-window-entity-damage-total-text = Total Damage: {$amount} +health-analyzer-window-entity-unknown-text = Unknown +health-analyzer-window-entity-unknown-species-text = Non-Humanoid +health-analyzer-window-entity-unknown-value-text = N/A + +health-analyzer-window-entity-alive-text = Alive +health-analyzer-window-entity-dead-text = Dead +health-analyzer-window-entity-critical-text = Critical + +health-analyzer-window-entity-temperature-text = Temperature: +health-analyzer-window-entity-blood-level-text = Blood Level: +health-analyzer-window-entity-status-text = Status: +health-analyzer-window-entity-damage-total-text = Total Damage: + health-analyzer-window-damage-group-text = {$damageGroup}: {$amount} health-analyzer-window-damage-type-text = {$damageType}: {$amount} health-analyzer-window-damage-type-duplicate-text = {$damageType}: {$amount} (duplicate) -health-analyzer-window-scan-mode-text = Scan Mode: -health-analyzer-window-scan-mode-active = ACTIVE -health-analyzer-window-scan-mode-inactive = INACTIVE +health-analyzer-window-damage-group-Brute = Brute +health-analyzer-window-damage-type-Blunt = Blunt +health-analyzer-window-damage-type-Slash = Slash +health-analyzer-window-damage-type-Piercing = Piercing + +health-analyzer-window-damage-group-Burn = Burn +health-analyzer-window-damage-type-Heat = Heat +health-analyzer-window-damage-type-Shock = Shock +health-analyzer-window-damage-type-Cold = Cold +health-analyzer-window-damage-type-Caustic = Caustic + +health-analyzer-window-damage-group-Airloss = Airloss +health-analyzer-window-damage-type-Asphyxiation = Asphyxiation +health-analyzer-window-damage-type-Bloodloss = Bloodloss + +health-analyzer-window-damage-group-Toxin = Toxin +health-analyzer-window-damage-type-Poison = Poison +health-analyzer-window-damage-type-Radiation = Radiation + +health-analyzer-window-damage-group-Genetic = Genetic +health-analyzer-window-damage-type-Cellular = Cellular health-analyzer-window-malnutrition = Severely malnourished + +health-analyzer-window-entity-unrevivable-text = Unique body composition detected! Patient can not be resuscitated by normal means! +health-analyzer-window-entity-bleeding-text = Patient is bleeding! + +health-analyzer-window-scan-mode-text = Scan Mode: +health-analyzer-window-scan-mode-active = Active +health-analyzer-window-scan-mode-inactive = Inactive + +health-analyzer-popup-scan-target = {CAPITALIZE(THE($user))} is trying to scan you! diff --git a/Resources/Locale/en-US/nyanotrasen/accent/accents.ftl b/Resources/Locale/en-US/nyanotrasen/accent/accents.ftl deleted file mode 100644 index 2699d71bc6..0000000000 --- a/Resources/Locale/en-US/nyanotrasen/accent/accents.ftl +++ /dev/null @@ -1,6 +0,0 @@ -# Mothroach -accent-words-mothroach-1 = Squeak! -accent-words-mothroach-2 = Chirp! -accent-words-mothroach-3 = Peep! -accent-words-mothroach-4 = Eeee! -accent-words-mothroach-5 = Eep! diff --git a/Resources/Locale/en-US/nyanotrasen/reagents/meta/consumable/drink/drink.ftl b/Resources/Locale/en-US/nyanotrasen/reagents/meta/consumable/drink/drink.ftl index e9d04bd951..eef7207132 100644 --- a/Resources/Locale/en-US/nyanotrasen/reagents/meta/consumable/drink/drink.ftl +++ b/Resources/Locale/en-US/nyanotrasen/reagents/meta/consumable/drink/drink.ftl @@ -7,11 +7,5 @@ reagent-desc-pinkdrink = Entire civilizations have crumbled trying to decide if reagent-name-bubbletea = bubble tea reagent-desc-bubbletea = Big straw not included. -reagent-name-the-martinez = The Martinez -reagent-desc-the-martinez = The edgerunner legend. Remembered by a drink, Forgotten by a drunk. - -reagent-name-holywater = holy water -reagent-desc-holywater = Water blessed by some otherworldly powers. - reagent-name-lean = lean reagent-desc-lean = A disgusting mixture of soda, booze, and cough syrup. diff --git a/Resources/Locale/en-US/nyanotrasen/tools/tool-qualities.ftl b/Resources/Locale/en-US/nyanotrasen/tools/tool-qualities.ftl deleted file mode 100644 index c3c4e6ad2f..0000000000 --- a/Resources/Locale/en-US/nyanotrasen/tools/tool-qualities.ftl +++ /dev/null @@ -1,2 +0,0 @@ -tool-quality-digging-name = Digging -tool-quality-digging-tool-name = Shovel diff --git a/Resources/Locale/en-US/prototypes/entities/clothing/head/hardsuit-helmets.ftl b/Resources/Locale/en-US/prototypes/entities/clothing/head/hardsuit-helmets.ftl index 4e003d2704..af0a836ce9 100644 --- a/Resources/Locale/en-US/prototypes/entities/clothing/head/hardsuit-helmets.ftl +++ b/Resources/Locale/en-US/prototypes/entities/clothing/head/hardsuit-helmets.ftl @@ -78,10 +78,6 @@ ent-ClothingHeadHelmetHardsuitPirateEVA = pirate helmet ent-ClothingHeadHelmetHardsuitPirateCap = pirate captain's tacsuit helmet .desc = A special hardsuit helmet, made for the captain of a pirate ship. .suffix = Pirate -ent-ClothingHeadHelmetHardsuitSyndieReverseEngineered = NTSA-122 helmet - .desc = A sturdy, lightweight helmet made by the special adquisitions department of Nanotrasen. -ent-ClothingHeadHelmetHardsuitJuggernautReverseEngineered = NTSA-126 helmet - .desc = A very sturdy helmet made by the special acquisitions department of Nanotrasen, based on the "Juggernaut" tacsuit's design. ent-ClothingHeadHelmetHardsuitERTCentcomm = NT-444c helmet .desc = A special tacsuit helmet worn by Central Command Officers. ent-ClothingHeadHelmetHardsuitERTLeader = NT-444l helmet @@ -103,4 +99,4 @@ ent-ClothingHeadHelmetHardsuitClown = clown vacsuit helmet ent-ClothingHeadHelmetHardsuitMime = mime vacsuit helmet .desc = A mime vacsuit helmet. On closer inspection, it appears to be a normal helmet painted with crayons, and a mime mask glued on top. ent-ClothingHeadHelmetHardsuitSanta = DNK-31 helmet - .desc = A festive-looking hardsuit helmet that provides the jolly gift-giver protection from low-pressure environments. \ No newline at end of file + .desc = A festive-looking hardsuit helmet that provides the jolly gift-giver protection from low-pressure environments. diff --git a/Resources/Locale/en-US/reagents/meta/physical-desc.ftl b/Resources/Locale/en-US/reagents/meta/physical-desc.ftl index 4adb7b9a49..a132a865a6 100644 --- a/Resources/Locale/en-US/reagents/meta/physical-desc.ftl +++ b/Resources/Locale/en-US/reagents/meta/physical-desc.ftl @@ -1,8 +1,5 @@ reagent-physical-desc-abrasive = abrasive reagent-physical-desc-acidic = acidic -reagent-physical-desc-soapy = soapy -reagent-physical-desc-ferrous = ferrous -reagent-physical-desc-nothing = nothing reagent-physical-desc-acrid = acrid reagent-physical-desc-alkaline = alkaline reagent-physical-desc-aromatic = aromatic @@ -86,7 +83,6 @@ reagent-physical-desc-spicy = spicy reagent-physical-desc-starchy = starchy reagent-physical-desc-starry = starry reagent-physical-desc-sticky = sticky -reagent-physical-desc-strong-smelling = strong smelling reagent-physical-desc-strong-smelling = strong-smelling reagent-physical-desc-sugary = sugary reagent-physical-desc-sweet = sweet diff --git a/Resources/Locale/en-US/silicons/cyberlimbs.ftl b/Resources/Locale/en-US/silicons/cyberlimbs.ftl index 7e6746764c..ed0212d042 100644 --- a/Resources/Locale/en-US/silicons/cyberlimbs.ftl +++ b/Resources/Locale/en-US/silicons/cyberlimbs.ftl @@ -134,7 +134,7 @@ marking-CyberLimbsMarkingXionLLeg-l_leg-1 = Primary Leg marking-CyberLimbsMarkingXionLLeg-l_leg-2 = Secondary Leg marking-CyberLimbsMarkingXionLFoot = Left Robotic Foot from Xion Manufacturing Group marking-CyberLimbsMarkingXionLFoot-l_foot-1 = Primary Foot -marking-CyberLimbsMarkingXionLFoot-l_foot-1 = Secondary Foot +marking-CyberLimbsMarkingXionLFoot-l_foot-2 = Secondary Foot marking-CyberLimbsMarkingXionRArm = Right Robotic Arm from Xion Manufacturing Group marking-CyberLimbsMarkingXionRArm-r_arm-1 = Primary Arm marking-CyberLimbsMarkingXionRArm-r_arm-2 = Secondary Arm @@ -146,7 +146,7 @@ marking-CyberLimbsMarkingXionRLeg-r_leg-1 = Primary Leg marking-CyberLimbsMarkingXionRLeg-r_leg-2 = Secondary Leg marking-CyberLimbsMarkingXionRFoot = Right Robotic Foot from Xion Manufacturing Group marking-CyberLimbsMarkingXionRFoot-r_foot-1 = Primary Foot -marking-CyberLimbsMarkingXionRFoot-r_foot-1 = Secondary Foot +marking-CyberLimbsMarkingXionRFoot-r_foot-2 = Secondary Foot marking-CyberLimbsMarkingShellguardHead = Operational Monitor from Shellguard Munitions marking-CyberLimbsMarkingShellguardHead-head-1 = Primary Head @@ -234,4 +234,4 @@ marking-CyberLimbsMarkingZenghuRLeg-r_leg-1 = Primary Leg marking-CyberLimbsMarkingZenghuRLeg-r_leg-2 = Secondary Leg marking-CyberLimbsMarkingZenghuRFoot = Right Robotic Foot from Zenghu Pharmaceuticals marking-CyberLimbsMarkingZenghuRFoot-r_foot-1 = Primary Foot -marking-CyberLimbsMarkingZenghuRFoot-r_foot-2 = Secondary Foot \ No newline at end of file +marking-CyberLimbsMarkingZenghuRFoot-r_foot-2 = Secondary Foot diff --git a/Resources/Maps/gaxstation.yml b/Resources/Maps/gaxstation.yml index e3e186a62d..42c0145ab1 100644 --- a/Resources/Maps/gaxstation.yml +++ b/Resources/Maps/gaxstation.yml @@ -130,7 +130,7 @@ entities: version: 6 -2,2: ind: -2,2 - tiles: eQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAAAAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAJgAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAATQAAAAAAeQAAAAAAeQAAAAAAAAAAAAAAAAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAeQAAAAAATQAAAAAATQAAAAAATQAAAAAATQAAAAAATQAAAAAAeQAAAAAAJgAAAAAAAAAAAAAAAAAAAAAAeAAAAAAAeQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAeQAAAAAATQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAATQAAAAAAeQAAAAAAeQAAAAAAAAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAeQAAAAAATQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAATQAAAAAAeQAAAAAAeQAAAAAAAAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAeQAAAAAAeQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAAAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAAA + tiles: eQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAAAAAAAAAeQAAAAAAeAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAJgAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAATQAAAAAAeQAAAAAAeQAAAAAAAAAAAAAAAAAAAAAAeAAAAAAAeQAAAAAAeQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAeQAAAAAATQAAAAAATQAAAAAATQAAAAAATQAAAAAATQAAAAAAeQAAAAAAJgAAAAAAAAAAAAAAAAAAAAAAeAAAAAAAeQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAeQAAAAAATQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAATQAAAAAAeQAAAAAAeQAAAAAAAAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAeQAAAAAATQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAATQAAAAAAeQAAAAAAeQAAAAAAAAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAeQAAAAAAeQAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAAAAAAAAAAAAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAeQAAAAAAWQAAAAAA version: 6 -3,2: ind: -3,2 @@ -7128,7 +7128,8 @@ entities: 9,16: 0: 3822 10,13: - 0: 20471 + 0: 19959 + 4: 512 10,14: 0: 61247 10,15: @@ -7252,7 +7253,7 @@ entities: -11,5: 1: 57444 -10,4: - 4: 119 + 5: 119 2: 28672 -10,5: 2: 119 @@ -7264,8 +7265,8 @@ entities: 1: 16 0: 4008 -10,3: - 4: 28672 - 5: 119 + 5: 28672 + 6: 119 -11,1: 1: 26304 -11,2: @@ -7277,7 +7278,7 @@ entities: 2: 28672 -10,2: 2: 119 - 5: 28672 + 6: 28672 -10,0: 1: 2048 -9,-1: @@ -7532,20 +7533,20 @@ entities: 5,2: 0: 65535 5,0: - 6: 2184 + 7: 2184 5,-1: - 6: 32768 + 7: 32768 0: 49 1: 8 6,0: - 6: 817 + 7: 817 0: 34944 6,1: 0: 61424 6,2: 0: 30578 6,-1: - 6: 4096 + 7: 4096 0: 57344 1: 138 7,0: @@ -7581,7 +7582,7 @@ entities: 6,-4: 0: 29696 1: 33314 - 6: 8 + 7: 8 6,-3: 1: 2816 0: 62708 @@ -7590,9 +7591,9 @@ entities: 0: 17476 6,-5: 1: 8739 - 6: 34952 + 7: 34952 7,-4: - 6: 255 + 7: 255 1: 61440 7,-3: 0: 4112 @@ -7601,9 +7602,9 @@ entities: 1: 62900 0: 64 7,-5: - 6: 65535 + 7: 65535 8,-4: - 6: 19 + 7: 19 1: 14472 0: 50176 8,-3: @@ -7615,7 +7616,7 @@ entities: 8,-1: 0: 43535 8,-5: - 6: 13107 + 7: 13107 1: 34952 9,-4: 0: 28672 @@ -7737,7 +7738,7 @@ entities: 0: 65535 13,1: 0: 4895 - 6: 52224 + 7: 52224 13,2: 0: 65520 13,-1: @@ -7778,7 +7779,7 @@ entities: 13,11: 0: 20479 13,12: - 6: 61439 + 7: 61439 14,9: 0: 65523 14,10: @@ -7794,7 +7795,8 @@ entities: 15,10: 0: 30567 15,11: - 0: 63255 + 0: 63251 + 8: 4 15,12: 0: 30471 16,8: @@ -7997,10 +7999,10 @@ entities: 0: 65358 8,-6: 0: 7 - 6: 13056 + 7: 13056 1: 34816 7,-6: - 6: 61696 + 7: 61696 0: 1093 9,-8: 0: 30529 @@ -8183,7 +8185,7 @@ entities: 6,-6: 1: 8977 0: 12 - 6: 34816 + 7: 34816 7,-9: 0: 65358 5,-10: @@ -8314,6 +8316,21 @@ entities: - 0 - 0 - 0 + - volume: 2500 + temperature: 293.14948 + moles: + - 18.472576 + - 69.49208 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 - volume: 2500 temperature: 293.15 moles: @@ -8359,6 +8376,21 @@ entities: - 0 - 0 - 0 + - volume: 2500 + temperature: 293.1495 + moles: + - 20.078888 + - 75.53487 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 chunkSize: 4 - type: GasTileOverlay - type: RadiationGridResistance @@ -9974,6 +10006,11 @@ entities: - type: Transform pos: 31.5,-38.5 parent: 2 + - uid: 20414 + components: + - type: Transform + pos: 51.5,7.5 + parent: 2 - proto: AirlockArmoryGlassLocked entities: - uid: 85 @@ -10010,6 +10047,11 @@ entities: rot: 1.5707963267948966 rad pos: -31.5,22.5 parent: 2 + - uid: 20361 + components: + - type: Transform + pos: -29.5,27.5 + parent: 2 - proto: AirlockAtmosphericsLocked entities: - uid: 92 @@ -14373,6 +14415,226 @@ entities: - type: Transform pos: 31.5,-20.5 parent: 2 + - uid: 20362 + components: + - type: Transform + pos: 27.5,-44.5 + parent: 2 + - uid: 20363 + components: + - type: Transform + pos: 33.5,-46.5 + parent: 2 + - uid: 20364 + components: + - type: Transform + pos: 29.5,-42.5 + parent: 2 + - uid: 20365 + components: + - type: Transform + pos: 27.5,-46.5 + parent: 2 + - uid: 20366 + components: + - type: Transform + pos: 31.5,-42.5 + parent: 2 + - uid: 20367 + components: + - type: Transform + pos: 28.5,-48.5 + parent: 2 + - uid: 20368 + components: + - type: Transform + pos: 27.5,-47.5 + parent: 2 + - uid: 20369 + components: + - type: Transform + pos: 30.5,-42.5 + parent: 2 + - uid: 20370 + components: + - type: Transform + pos: 33.5,-44.5 + parent: 2 + - uid: 20371 + components: + - type: Transform + pos: 28.5,-42.5 + parent: 2 + - uid: 20372 + components: + - type: Transform + pos: 33.5,-47.5 + parent: 2 + - uid: 20373 + components: + - type: Transform + pos: 33.5,-45.5 + parent: 2 + - uid: 20374 + components: + - type: Transform + pos: 27.5,-45.5 + parent: 2 + - uid: 20375 + components: + - type: Transform + pos: 29.5,-48.5 + parent: 2 + - uid: 20384 + components: + - type: Transform + pos: 31.5,-48.5 + parent: 2 + - uid: 20385 + components: + - type: Transform + pos: 32.5,-42.5 + parent: 2 + - uid: 20386 + components: + - type: Transform + pos: 33.5,-43.5 + parent: 2 + - uid: 20387 + components: + - type: Transform + pos: 30.5,-48.5 + parent: 2 + - uid: 20388 + components: + - type: Transform + pos: 32.5,-48.5 + parent: 2 + - uid: 20389 + components: + - type: Transform + pos: 27.5,-43.5 + parent: 2 + - uid: 20390 + components: + - type: Transform + pos: 28.5,-43.5 + parent: 2 + - uid: 20391 + components: + - type: Transform + pos: 29.5,-43.5 + parent: 2 + - uid: 20392 + components: + - type: Transform + pos: 30.5,-43.5 + parent: 2 + - uid: 20393 + components: + - type: Transform + pos: 31.5,-43.5 + parent: 2 + - uid: 20394 + components: + - type: Transform + pos: 32.5,-43.5 + parent: 2 + - uid: 20395 + components: + - type: Transform + pos: 32.5,-44.5 + parent: 2 + - uid: 20396 + components: + - type: Transform + pos: 32.5,-45.5 + parent: 2 + - uid: 20397 + components: + - type: Transform + pos: 32.5,-46.5 + parent: 2 + - uid: 20398 + components: + - type: Transform + pos: 32.5,-47.5 + parent: 2 + - uid: 20399 + components: + - type: Transform + pos: 31.5,-47.5 + parent: 2 + - uid: 20400 + components: + - type: Transform + pos: 30.5,-47.5 + parent: 2 + - uid: 20401 + components: + - type: Transform + pos: 29.5,-47.5 + parent: 2 + - uid: 20402 + components: + - type: Transform + pos: 28.5,-47.5 + parent: 2 + - uid: 20403 + components: + - type: Transform + pos: 28.5,-46.5 + parent: 2 + - uid: 20404 + components: + - type: Transform + pos: 28.5,-45.5 + parent: 2 + - uid: 20405 + components: + - type: Transform + pos: 28.5,-44.5 + parent: 2 + - uid: 20406 + components: + - type: Transform + pos: 29.5,-44.5 + parent: 2 + - uid: 20407 + components: + - type: Transform + pos: 30.5,-44.5 + parent: 2 + - uid: 20408 + components: + - type: Transform + pos: 31.5,-44.5 + parent: 2 + - uid: 20409 + components: + - type: Transform + pos: 31.5,-45.5 + parent: 2 + - uid: 20410 + components: + - type: Transform + pos: 31.5,-46.5 + parent: 2 + - uid: 20411 + components: + - type: Transform + pos: 30.5,-46.5 + parent: 2 + - uid: 20412 + components: + - type: Transform + pos: 29.5,-46.5 + parent: 2 + - uid: 20413 + components: + - type: Transform + pos: 29.5,-45.5 + parent: 2 - proto: AtmosFixNitrogenMarker entities: - uid: 680 @@ -15140,6 +15402,17 @@ entities: - type: Transform pos: -11.444434,33.764362 parent: 2 +- proto: BookJanitorTale + entities: + - uid: 20338 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: BookSecurity entities: - uid: 840 @@ -15297,6 +15570,17 @@ entities: - type: Transform pos: 3.362266,38.704063 parent: 2 +- proto: BoxBeanbag + entities: + - uid: 20350 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: BoxBodyBag entities: - uid: 864 @@ -15348,6 +15632,17 @@ entities: - type: Transform pos: 40.402996,38.55928 parent: 2 +- proto: BoxCleanerGrenades + entities: + - uid: 20332 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: BoxFolderBlue entities: - uid: 873 @@ -15593,6 +15888,26 @@ entities: - type: Transform pos: -14.780811,70.49523 parent: 2 +- proto: BoxMousetrap + entities: + - uid: 20339 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 20340 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: BoxSyringe entities: - uid: 918 @@ -15605,6 +15920,17 @@ entities: - type: Transform pos: 3.4579105,38.524853 parent: 2 +- proto: BoxTrashbag + entities: + - uid: 20330 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: BriefcaseBrownFilled entities: - uid: 920 @@ -15649,6 +15975,15 @@ entities: - type: Transform pos: 39.50665,52.551533 parent: 2 + - uid: 20342 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: CableApcExtension entities: - uid: 927 @@ -49116,13 +49451,6 @@ entities: - type: Transform pos: 42.5,52.5 parent: 2 -- proto: ClosetJanitorFilled - entities: - - uid: 7004 - components: - - type: Transform - pos: 41.5,54.5 - parent: 2 - proto: ClosetL3Filled entities: - uid: 7005 @@ -49700,6 +50028,17 @@ entities: - type: Transform pos: 26.635597,-23.75891 parent: 2 +- proto: ClothingHandsGlovesJanitor + entities: + - uid: 20329 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingHandsGlovesLatex entities: - uid: 7078 @@ -49749,6 +50088,39 @@ entities: - type: Transform pos: 34.46197,5.7214866 parent: 2 +- proto: ClothingHeadHatFlatcapBartenderIdris + entities: + - uid: 20346 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingHeadHatFlatcapBartenderNanotrasen + entities: + - uid: 20360 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingHeadHatFlatcapBartenderOrion + entities: + - uid: 20359 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingHeadHatMimesoft entities: - uid: 777 @@ -49934,6 +50306,17 @@ entities: - type: Transform pos: 14.541786,59.652855 parent: 2 +- proto: ClothingOuterApronBar + entities: + - uid: 20356 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingOuterClownPriest entities: - uid: 753 @@ -49981,6 +50364,17 @@ entities: - type: Transform pos: -11.458471,35.630077 parent: 2 +- proto: ClothingOuterWinterBar + entities: + - uid: 20358 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingOuterWinterCoat entities: - uid: 19805 @@ -50022,6 +50416,17 @@ entities: - type: Transform pos: 32.667603,5.6265497 parent: 2 +- proto: ClothingOuterWinterJani + entities: + - uid: 20341 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingOuterWinterMime entities: - uid: 783 @@ -50125,6 +50530,17 @@ entities: rot: -1.5707963267948966 rad pos: -6.3551354,3.3736491 parent: 2 +- proto: ClothingUniformJumpskirtBartender + entities: + - uid: 20353 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingUniformJumpskirtJanimaid entities: - uid: 7103 @@ -50137,6 +50553,37 @@ entities: - type: Transform pos: 44.51665,54.718178 parent: 2 + - uid: 20344 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpskirtJanimaidmini + entities: + - uid: 20335 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpskirtJanitor + entities: + - uid: 20331 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingUniformJumpskirtMime entities: - uid: 785 @@ -50169,6 +50616,72 @@ entities: - type: Transform pos: -10.3801365,21.533518 parent: 2 +- proto: ClothingUniformJumpsuitBartender + entities: + - uid: 20351 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitBartenderIdris + entities: + - uid: 20355 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitBartenderIdrisFlipped + entities: + - uid: 20347 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitBartenderNt + entities: + - uid: 20354 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitBartenderOrion + entities: + - uid: 20357 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitBartenderPurple + entities: + - uid: 20349 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingUniformJumpsuitClown entities: - uid: 759 @@ -50191,6 +50704,50 @@ entities: linearDamping: 0 canCollide: False - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitJanitor + entities: + - uid: 20336 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitJanitorIdris + entities: + - uid: 14549 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitJanitorNt + entities: + - uid: 20337 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitJanitorOrion + entities: + - uid: 20343 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingUniformJumpsuitMime entities: - uid: 786 @@ -51766,6 +52323,15 @@ entities: - type: Transform pos: 73.59081,62.54297 parent: 2 + - uid: 20334 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: CryogenicSleepUnitSpawnerLateJoin entities: - uid: 7330 @@ -94301,6 +94867,55 @@ entities: - type: Transform pos: -10.5,22.5 parent: 2 +- proto: LockerBartenderFilled + entities: + - uid: 20345 + components: + - type: Transform + pos: 62.5,44.5 + parent: 2 + - type: EntityStorage + air: + volume: 200 + immutable: False + temperature: 293.1465 + moles: + - 1.7459903 + - 6.568249 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - type: ContainerContainer + containers: + entity_storage: !type:Container + showEnts: False + occludes: True + ents: + - 20346 + - 20347 + - 20348 + - 20349 + - 20350 + - 20351 + - 20353 + - 20354 + - 20355 + - 20356 + - 20357 + - 20358 + - 20359 + - 20360 + paper_label: !type:ContainerSlot + showEnts: False + occludes: True + ent: null - proto: LockerBooze entities: - uid: 12705 @@ -94325,11 +94940,6 @@ entities: parent: 2 - proto: LockerBoozeFilled entities: - - uid: 12709 - components: - - type: Transform - pos: 62.5,44.5 - parent: 2 - uid: 12710 components: - type: Transform @@ -94580,6 +95190,60 @@ entities: - type: Transform pos: -20.5,55.5 parent: 2 +- proto: LockerJanitor + entities: + - uid: 7004 + components: + - type: Transform + pos: 41.5,54.5 + parent: 2 + - type: EntityStorage + air: + volume: 200 + immutable: False + temperature: 293.1462 + moles: + - 1.606311 + - 6.042789 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - type: ContainerContainer + containers: + entity_storage: !type:Container + showEnts: False + occludes: True + ents: + - 12709 + - 14549 + - 20328 + - 20329 + - 20330 + - 20331 + - 20332 + - 20333 + - 20334 + - 20335 + - 20336 + - 20337 + - 20338 + - 20339 + - 20340 + - 20341 + - 20342 + - 20343 + - 20344 + paper_label: !type:ContainerSlot + showEnts: False + occludes: True + ent: null - proto: LockerMedicalFilled entities: - uid: 12737 @@ -95657,6 +96321,15 @@ entities: - type: Transform pos: 39.470783,52.54626 parent: 2 + - uid: 20328 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: Morgue entities: - uid: 12903 @@ -96583,6 +97256,24 @@ entities: - type: Transform pos: 22.5,44.5 parent: 2 +- proto: PlushieMothBartender + entities: + - uid: 20376 + components: + - type: Transform + pos: 59.46184,43.62285 + parent: 2 +- proto: PlushieSlips + entities: + - uid: 20333 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: PlushieTrystan entities: - uid: 8274 @@ -108133,12 +108824,6 @@ entities: - type: Transform pos: 30.5,2.5 parent: 2 - - uid: 14549 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -30.5,29.5 - parent: 2 - proto: SignVirology entities: - uid: 18774 @@ -109267,6 +109952,41 @@ entities: - type: Transform pos: 59.519974,44.266804 parent: 2 + - uid: 20377 + components: + - type: Transform + pos: 59.53388,44.27 + parent: 2 + - uid: 20378 + components: + - type: Transform + pos: 59.53388,44.27 + parent: 2 + - uid: 20379 + components: + - type: Transform + pos: 59.53388,44.27 + parent: 2 + - uid: 20380 + components: + - type: Transform + pos: 59.53388,44.27 + parent: 2 + - uid: 20381 + components: + - type: Transform + pos: 59.53388,44.27 + parent: 2 + - uid: 20382 + components: + - type: Transform + pos: 59.53388,44.27 + parent: 2 + - uid: 20383 + components: + - type: Transform + pos: 59.53388,44.27 + parent: 2 - proto: SpaceHeaterAnchored entities: - uid: 18441 @@ -114103,6 +114823,17 @@ entities: - type: Transform pos: 29.482334,-45.373753 parent: 2 +- proto: ToyFigurineBartender + entities: + - uid: 20348 + components: + - type: Transform + parent: 20345 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ToyFigurineClown entities: - uid: 767 @@ -114114,6 +114845,17 @@ entities: linearDamping: 0 canCollide: False - type: InsideEntityStorage +- proto: ToyFigurineJanitor + entities: + - uid: 12709 + components: + - type: Transform + parent: 7004 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ToyRubberDuck entities: - uid: 15411 @@ -128426,6 +129168,31 @@ entities: - type: Transform pos: 88.5,19.5 parent: 2 + - uid: 20415 + components: + - type: Transform + pos: -37.5,42.5 + parent: 2 + - uid: 20416 + components: + - type: Transform + pos: -35.5,42.5 + parent: 2 + - uid: 20417 + components: + - type: Transform + pos: -33.5,42.5 + parent: 2 + - uid: 20418 + components: + - type: Transform + pos: -32.5,42.5 + parent: 2 + - uid: 20419 + components: + - type: Transform + pos: -30.5,42.5 + parent: 2 - proto: WardrobeBlackFilled entities: - uid: 17895 @@ -129371,7 +130138,7 @@ entities: lastSignals: DoorStatus: True - type: Door - secondsUntilStateChange: -86485.96 + secondsUntilStateChange: -87131.4 state: Opening - uid: 18112 components: diff --git a/Resources/Maps/glacier.yml b/Resources/Maps/glacier.yml index 5cf7518212..41acf60062 100644 --- a/Resources/Maps/glacier.yml +++ b/Resources/Maps/glacier.yml @@ -100779,181 +100779,6 @@ entities: - type: Transform pos: 30.5,22.5 parent: 2 - - type: Lathe - staticRecipes: - - ClothingUniformJumpsuitColorGrey - - ClothingUniformJumpskirtColorGrey - - ClothingUniformJumpsuitBartender - - ClothingUniformJumpskirtBartender - - ClothingHeadHatCapcap - - ClothingHeadHatCaptain - - ClothingUniformJumpsuitCaptain - - ClothingUniformJumpskirtCaptain - - ClothingUniformJumpsuitCapFormal - - ClothingUniformJumpskirtCapFormalDress - - ClothingUniformJumpsuitCargo - - ClothingUniformJumpskirtCargo - - ClothingUniformJumpsuitSalvageSpecialist - - ClothingHeadHatBeretEngineering - - ClothingUniformJumpsuitChiefEngineer - - ClothingUniformJumpskirtChiefEngineer - - ClothingUniformJumpsuitChiefEngineerTurtle - - ClothingUniformJumpskirtChiefEngineerTurtle - - ClothingUniformJumpsuitChaplain - - ClothingUniformJumpskirtChaplain - - ClothingUniformJumpsuitChef - - ClothingUniformJumpskirtChef - - ClothingUniformJumpsuitChemistry - - ClothingUniformJumpskirtChemistry - - ClothingUniformJumpsuitClown - - ClothingHeadHatBeretCmo - - ClothingUniformJumpsuitCMO - - ClothingUniformJumpskirtCMO - - ClothingUniformJumpsuitCMOTurtle - - ClothingUniformJumpskirtCMOTurtle - - ClothingUniformJumpsuitDetective - - ClothingUniformJumpskirtDetective - - ClothingUniformJumpsuitEngineering - - ClothingUniformJumpskirtEngineering - - ClothingUniformJumpsuitSeniorEngineer - - ClothingUniformJumpskirtSeniorEngineer - - ClothingHeadHatHopcap - - ClothingUniformJumpsuitHoP - - ClothingUniformJumpskirtHoP - - ClothingHeadHatBeretHoS - - ClothingHeadHatHoshat - - ClothingUniformJumpsuitHoS - - ClothingUniformJumpskirtHoS - - ClothingUniformJumpsuitHoSBlue - - ClothingUniformJumpskirtHoSBlue - - ClothingUniformJumpsuitHoSGrey - - ClothingUniformJumpskirtHoSGrey - - ClothingUniformJumpsuitHosFormal - - ClothingUniformJumpskirtHosFormal - - ClothingUniformJumpsuitHoSAlt - - ClothingUniformJumpskirtHoSAlt - - ClothingUniformJumpsuitHoSBlue - - ClothingUniformJumpsuitHoSGrey - - ClothingUniformJumpsuitHoSParadeMale - - ClothingUniformJumpskirtHoSParadeMale - - ClothingUniformJumpsuitHydroponics - - ClothingUniformJumpskirtHydroponics - - ClothingUniformJumpsuitJanitor - - ClothingUniformJumpskirtJanitor - - ClothingUniformJumpsuitLawyerBlack - - ClothingUniformJumpsuitLibrarian - - ClothingUniformJumpskirtColorLightBrown - - ClothingUniformCourier - - ClothingUniformSkirtCourier - - ClothingUniformJumpsuitMantis - - ClothingUniformSkirtMantis - - ClothingHeadHatBeretSeniorPhysician - - ClothingUniformJumpsuitMedicalDoctor - - ClothingUniformJumpskirtMedicalDoctor - - ClothingUniformJumpsuitSeniorPhysician - - ClothingUniformJumpskirtSeniorPhysician - - ClothingUniformJumpsuitMime - - ClothingUniformJumpskirtMime - - ClothingUniformJumpsuitMusician - - ClothingUniformJumpsuitParamedic - - ClothingUniformJumpskirtParamedic - - ClothingUniformJumpsuitSeniorOfficer - - ClothingUniformJumpskirtSeniorOfficer - - ClothingUniformJumpsuitPrisoner - - ClothingUniformJumpskirtPrisoner - - ClothingHeadHatQMsoft - - ClothingHeadHatBeretQM - - ClothingUniformJumpsuitQM - - ClothingUniformJumpskirtQM - - ClothingUniformJumpsuitQMTurtleneck - - ClothingUniformJumpskirtQMTurtleneck - - ClothingUniformJumpsuitQMFormal - - ClothingHeadHatBeretRND - - ClothingUniformJumpsuitResearchDirector - - ClothingUniformJumpskirtResearchDirector - - ClothingUniformJumpsuitScientist - - ClothingUniformJumpskirtScientist - - ClothingUniformJumpsuitSeniorResearcher - - ClothingUniformJumpskirtSeniorResearcher - - ClothingHeadHatBeretSecurity - - ClothingUniformJumpsuitSec - - ClothingUniformJumpskirtSec - - ClothingUniformJumpsuitSecBlue - - ClothingUniformJumpskirtSecBlue - - ClothingUniformJumpsuitSecGrey - - ClothingUniformJumpskirtSecGrey - - ClothingHeadHatBeretBrigmedic - - ClothingUniformJumpsuitBrigmedic - - ClothingUniformJumpskirtBrigmedic - - ClothingHeadHatBeretWarden - - ClothingHeadHatWarden - - ClothingUniformJumpsuitWarden - - ClothingUniformJumpskirtWarden - - ClothingUniformJumpsuitWardenBlue - - ClothingUniformJumpskirtWardenBlue - - ClothingUniformJumpsuitWardenGrey - - ClothingUniformJumpskirtWardenGrey - - ClothingHeadHatParamedicsoft - - ClothingOuterWinterCap - - ClothingOuterWinterCE - - ClothingOuterWinterCMO - - ClothingOuterWinterHoP - - ClothingOuterWinterHoSUnarmored - - ClothingOuterWinterWardenUnarmored - - ClothingOuterWinterQM - - ClothingOuterWinterRD - - ClothingNeckMantleCap - - ClothingNeckMantleCE - - ClothingNeckMantleCMO - - ClothingNeckMantleHOP - - ClothingNeckMantleHOS - - ClothingNeckMantleRD - - ClothingNeckMantleQM - - ClothingOuterStasecSweater - - ClothingOuterWinterMusician - - ClothingOuterWinterClown - - ClothingOuterWinterMime - - ClothingOuterWinterCoat - - ClothingOuterWinterJani - - ClothingOuterWinterBar - - ClothingOuterWinterChef - - ClothingOuterWinterHydro - - ClothingOuterWinterAtmos - - ClothingOuterWinterEngi - - ClothingOuterWinterCargo - - ClothingOuterWinterMiner - - ClothingOuterWinterMed - - ClothingOuterWinterPara - - ClothingOuterWinterChem - - ClothingOuterWinterGen - - ClothingOuterWinterViro - - ClothingOuterWinterSci - - ClothingOuterWinterRobo - - ClothingOuterWinterSec - - ClothingNeckTieRed - - ClothingNeckTieDet - - ClothingNeckTieSci - - ClothingNeckScarfStripedGreen - - ClothingNeckScarfStripedBlue - - ClothingNeckScarfStripedRed - - ClothingNeckScarfStripedBrown - - ClothingNeckScarfStripedLightBlue - - ClothingNeckScarfStripedOrange - - ClothingNeckScarfStripedBlack - - ClothingNeckScarfStripedPurple - - Carpet - - CarpetBlack - - CarpetPink - - CarpetBlue - - CarpetGreen - - CarpetOrange - - CarpetPurple - - CarpetCyan - - CarpetWhite - - type: MaterialStorage - materialWhiteList: - - Cloth - - Durathread - proto: UniformPrinterMachineCircuitboard entities: - uid: 14600 diff --git a/Resources/Maps/radstation.yml b/Resources/Maps/radstation.yml index ccd6233274..07dfe0f580 100644 --- a/Resources/Maps/radstation.yml +++ b/Resources/Maps/radstation.yml @@ -128,11 +128,11 @@ entities: version: 6 -3,-2: ind: -3,-2 - tiles: GwAAAAADGwAAAAACGwAAAAACGwAAAAADGwAAAAABGwAAAAAAGwAAAAABcQAAAAAAVAAAAAACcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABVAAAAAACVAAAAAADVAAAAAACGwAAAAACGwAAAAABGwAAAAACGwAAAAAAGwAAAAADGwAAAAABGwAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAACVAAAAAAAVAAAAAACVAAAAAADVAAAAAABGwAAAAADGwAAAAABGwAAAAADGwAAAAAAGwAAAAAAGwAAAAACGwAAAAACcQAAAAAAVAAAAAACcQAAAAAAcQAAAAAAVAAAAAABVAAAAAAAVAAAAAAAVAAAAAADVAAAAAADcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABcQAAAAAAVAAAAAAAVAAAAAAAVAAAAAABVAAAAAADVAAAAAADcQAAAAAAcQAAAAAAVAAAAAACcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAVAAAAAABcQAAAAAAVAAAAAADVAAAAAAAVAAAAAAAVAAAAAACVAAAAAABcQAAAAAAcQAAAAAAVAAAAAABcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABcQAAAAAAVAAAAAACcQAAAAAAcQAAAAAAVAAAAAADVAAAAAADVAAAAAADVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAABcQAAAAAAVAAAAAACcQAAAAAAcQAAAAAAVAAAAAACVAAAAAADVAAAAAACVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAADVAAAAAACVAAAAAADcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABcQAAAAAAAwAAAAAAVAAAAAACAwAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAVAAAAAADVAAAAAABVAAAAAABcQAAAAAAVAAAAAAAAwAAAAAAVAAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABVAAAAAACcQAAAAAAcQAAAAAAAwAAAAAAVAAAAAAAAwAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAAwAAAAAAVAAAAAADAwAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAACVAAAAAACVAAAAAAAcQAAAAAAVAAAAAADAwAAAAAAVAAAAAADcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAAAVAAAAAAAVAAAAAACVAAAAAACVAAAAAAAVAAAAAABAwAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAABVAAAAAACVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAACVAAAAAAAVAAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABVAAAAAABVAAAAAAAcQAAAAAAVAAAAAABVAAAAAABVAAAAAADcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAVAAAAAADVAAAAAAAVAAAAAABcQAAAAAAVAAAAAACVAAAAAACVAAAAAAB + tiles: GwAAAAADGwAAAAACGwAAAAACGwAAAAADGwAAAAABGwAAAAAAGwAAAAABcQAAAAAAVAAAAAACcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABVAAAAAACVAAAAAADVAAAAAACGwAAAAACGwAAAAABGwAAAAACGwAAAAAAGwAAAAADGwAAAAABGwAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAACVAAAAAAAVAAAAAACVAAAAAADVAAAAAABGwAAAAADGwAAAAABGwAAAAADGwAAAAAAGwAAAAAAGwAAAAACGwAAAAACcQAAAAAAVAAAAAACcQAAAAAAcQAAAAAAVAAAAAABVAAAAAAAVAAAAAAAVAAAAAADVAAAAAADcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABcQAAAAAAVAAAAAAAVAAAAAAAVAAAAAABVAAAAAADVAAAAAADcQAAAAAAcQAAAAAAVAAAAAACcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAVAAAAAABcQAAAAAAVAAAAAADVAAAAAAAVAAAAAAAVAAAAAACVAAAAAABcQAAAAAAcQAAAAAAVAAAAAABcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABcQAAAAAAVAAAAAACcQAAAAAAcQAAAAAAVAAAAAADVAAAAAADVAAAAAADVAAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAACcQAAAAAAcQAAAAAAVAAAAAACVAAAAAADVAAAAAACVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAADVAAAAAACVAAAAAADcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABcQAAAAAAAwAAAAAAVAAAAAACAwAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAVAAAAAADVAAAAAABVAAAAAABcQAAAAAAVAAAAAAAAwAAAAAAVAAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABVAAAAAACcQAAAAAAcQAAAAAAAwAAAAAAVAAAAAAAAwAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAAwAAAAAAVAAAAAADAwAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAACVAAAAAACVAAAAAAAcQAAAAAAVAAAAAADAwAAAAAAVAAAAAADcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAAAVAAAAAAAVAAAAAACVAAAAAACVAAAAAAAVAAAAAABAwAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAABVAAAAAACVAAAAAAAVAAAAAAAcQAAAAAAVAAAAAACVAAAAAAAVAAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAABVAAAAAABVAAAAAAAcQAAAAAAVAAAAAABVAAAAAABVAAAAAADcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAcQAAAAAAcQAAAAAAVAAAAAADVAAAAAAAVAAAAAABcQAAAAAAVAAAAAACVAAAAAACVAAAAAAB version: 6 -4,-2: ind: -4,-2 - tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAcQAAAAAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAcQAAAAAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAcQAAAAAAcQAAAAAA + tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAcQAAAAAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAcQAAAAAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAcQAAAAAAcQAAAAAA version: 6 -4,-1: ind: -4,-1 @@ -2190,18 +2190,14 @@ entities: 1346: -41,-26 1347: -42,-26 1348: -42,-27 - 1354: -47,-28 1355: -46,-28 1356: -46,-27 1357: -46,-27 - 1358: -47,-26 1359: -46,-26 1360: -45,-26 1361: -45,-27 1362: -45,-27 1363: -46,-28 - 1364: -47,-27 - 1365: -47,-26 1366: -46,-27 1367: -46,-27 1368: -44,-27 @@ -4464,7 +4460,6 @@ entities: 1286: -34,-18 1297: -38,-24 1298: -37,-24 - 1351: -47,-26 1383: -40,-33 1384: -39,-33 1386: -40,-30 @@ -8332,7 +8327,6 @@ entities: 1280: -32,-13 1281: -31,-20 1282: -30,-20 - 1375: -50,-27 1551: -32,-40 1552: -32,-39 1553: -32,-38 @@ -8345,6 +8339,7 @@ entities: 7034: 33,-50 7035: 33,-51 7036: 33,-52 + 7553: -48,-27 - node: color: '#FFFFFFFF' id: WarnLineE @@ -8726,9 +8721,6 @@ entities: 1170: -40,-6 1265: -35,15 1266: -33,15 - 1372: -49,-28 - 1373: -49,-27 - 1374: -49,-26 1432: -35,-29 1667: -25,-24 1668: -25,-23 @@ -8817,6 +8809,9 @@ entities: 7167: 12,-46 7322: 24,-59 7548: 5,-70 + 7550: -47,-28 + 7551: -47,-27 + 7552: -47,-26 - node: color: '#FFFFFFFF' id: WarnLineW @@ -9273,7 +9268,8 @@ entities: 2,2: 0: 29119 2,3: - 0: 28279 + 0: 28211 + 1: 68 2,-1: 0: 65535 3,0: @@ -9580,7 +9576,8 @@ entities: 3,7: 2: 61936 4,4: - 0: 3003 + 0: 2491 + 1: 512 4,5: 0: 65535 4,6: @@ -9845,7 +9842,7 @@ entities: 0: 61542 -9,4: 0: 53471 - 3: 32 + 1: 32 -13,4: 2: 252 -12,7: @@ -10342,7 +10339,7 @@ entities: 0: 30255 6,-5: 0: 1655 - 4: 256 + 3: 256 6,-8: 0: 61166 6,-9: @@ -10370,12 +10367,12 @@ entities: 5,7: 0: 65520 5,5: - 5: 61152 + 4: 61152 0: 4 5,8: 0: 46079 6,5: - 5: 30576 + 4: 30576 6,6: 0: 32624 6,7: @@ -10583,7 +10580,7 @@ entities: 0: 64783 1,12: 0: 8669 - 6: 1024 + 5: 1024 1: 2048 2,9: 0: 4368 @@ -10703,14 +10700,16 @@ entities: 12,-7: 2: 4974 -4,9: - 0: 65291 + 0: 65289 + 1: 2 -5,9: 0: 60941 -4,10: 0: 32783 2: 28672 -5,10: - 0: 14 + 0: 6 + 1: 8 2: 61440 -4,11: 2: 30583 @@ -10735,7 +10734,8 @@ entities: -2,12: 0: 37751 -8,9: - 0: 61166 + 0: 61038 + 1: 128 -9,9: 0: 61198 -8,10: @@ -10761,8 +10761,8 @@ entities: 0: 29055 -6,11: 0: 7 - 7: 16 - 4: 32 + 6: 16 + 3: 32 2: 63488 -6,12: 2: 7 @@ -11013,10 +11013,10 @@ entities: 10,-12: 0: 4144 2: 204 - 8: 16384 + 7: 16384 10,-11: 0: 61457 - 8: 78 + 7: 78 10,-10: 0: 47615 10,-13: @@ -11024,7 +11024,7 @@ entities: 11,-12: 2: 35775 11,-11: - 8: 1 + 7: 1 0: 61440 2: 200 11,-10: @@ -11122,11 +11122,11 @@ entities: 3,-17: 0: 30583 4,-16: - 9: 1911 + 8: 1911 4,-15: - 10: 1911 + 9: 1911 4,-14: - 8: 1911 + 7: 1911 0,-20: 2: 255 0: 61440 @@ -11231,11 +11231,11 @@ entities: 0: 4096 2: 19711 9,-16: - 8: 1911 + 7: 1911 9,-15: - 11: 1911 + 10: 1911 9,-14: - 8: 1911 + 7: 1911 10,-16: 2: 64989 10,-15: @@ -11270,11 +11270,11 @@ entities: 2: 65534 6,-18: 2: 4369 - 8: 52416 + 7: 52416 7,-19: 2: 65527 7,-18: - 8: 4368 + 7: 4368 2: 16392 8,-19: 2: 61696 @@ -11368,21 +11368,6 @@ entities: - 0 - 0 - 0 - - volume: 2500 - temperature: 293.14975 - moles: - - 21.824879 - - 82.10312 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - volume: 2500 temperature: 293.15 moles: @@ -14185,6 +14170,12 @@ entities: rot: -1.5707963267948966 rad pos: 45.5,-14.5 parent: 2 + - uid: 350 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -43.5,-26.5 + parent: 2 - proto: AirlockExternalGlassCargoLocked entities: - uid: 233 @@ -14312,6 +14303,23 @@ entities: linkedPorts: 248: - DoorStatus: DoorBolt +- proto: AirlockExternalGlassSalvageLocked + entities: + - uid: 1929 + components: + - type: Transform + pos: -49.5,-18.5 + parent: 2 + - uid: 23938 + components: + - type: Transform + pos: -49.5,-19.5 + parent: 2 + - uid: 23940 + components: + - type: Transform + pos: -49.5,-20.5 + parent: 2 - proto: AirlockExternalGlassShuttleArrivals entities: - uid: 250 @@ -14354,12 +14362,6 @@ entities: parent: 2 - proto: AirlockExternalGlassShuttleEscape entities: - - uid: 256 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -49.5,-26.5 - parent: 2 - uid: 257 components: - type: Transform @@ -14372,6 +14374,12 @@ entities: rot: 3.141592653589793 rad pos: -29.5,42.5 parent: 2 + - uid: 23943 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -47.5,-26.5 + parent: 2 - proto: AirlockExternalGlassShuttleLocked entities: - uid: 259 @@ -14416,13 +14424,6 @@ entities: rot: -1.5707963267948966 rad pos: -51.5,-20.5 parent: 2 -- proto: AirlockExternalLocked - entities: - - uid: 263 - components: - - type: Transform - pos: -47.5,-26.5 - parent: 2 - proto: AirlockFreezerLocked entities: - uid: 264 @@ -14951,11 +14952,6 @@ entities: - type: Transform pos: -35.5,-22.5 parent: 2 - - uid: 350 - components: - - type: Transform - pos: -43.5,-26.5 - parent: 2 - uid: 351 components: - type: Transform @@ -15133,7 +15129,7 @@ entities: pos: 34.5,-35.5 parent: 2 - type: Door - secondsUntilStateChange: -53230.88 + secondsUntilStateChange: -53943.504 state: Opening - uid: 383 components: @@ -16999,6 +16995,11 @@ entities: parent: 2 - proto: AtmosDeviceFanTiny entities: + - uid: 263 + components: + - type: Transform + pos: -47.5,-26.5 + parent: 2 - uid: 690 components: - type: Transform @@ -17011,11 +17012,6 @@ entities: rot: -1.5707963267948966 rad pos: -45.5,0.5 parent: 2 - - uid: 692 - components: - - type: Transform - pos: -49.5,-26.5 - parent: 2 - uid: 693 components: - type: Transform @@ -17128,6 +17124,21 @@ entities: - type: Transform pos: -39.5,-18.5 parent: 2 + - uid: 23939 + components: + - type: Transform + pos: -51.5,-20.5 + parent: 2 + - uid: 23941 + components: + - type: Transform + pos: -51.5,-18.5 + parent: 2 + - uid: 23942 + components: + - type: Transform + pos: -51.5,-19.5 + parent: 2 - proto: AtmosFixBlockerMarker entities: - uid: 713 @@ -17732,6 +17743,13 @@ entities: - type: Transform pos: -30.5,-56.5 parent: 2 +- proto: BaseComputer + entities: + - uid: 23911 + components: + - type: Transform + pos: -11.5,-55.5 + parent: 2 - proto: BaseGasCondenser entities: - uid: 830 @@ -18774,6 +18792,13 @@ entities: - type: Transform pos: 19.5,-29.5 parent: 2 +- proto: BiomassReclaimer + entities: + - uid: 23936 + components: + - type: Transform + pos: 20.5,-11.5 + parent: 2 - proto: BlastDoor entities: - uid: 998 @@ -19380,6 +19405,15 @@ entities: - type: Transform pos: 17.490627,16.619688 parent: 2 + - uid: 23923 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: BookBase entities: - uid: 1053 @@ -19843,6 +19877,17 @@ entities: - type: Transform pos: 7.35902,-29.546413 parent: 2 +- proto: BoxBeanbag + entities: + - uid: 23931 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: BoxBodyBag entities: - uid: 1117 @@ -20273,6 +20318,24 @@ entities: - type: Transform pos: -14.615689,-55.254997 parent: 2 + - uid: 18457 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23907 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: BoxMesonScanners entities: - uid: 1195 @@ -20369,6 +20432,24 @@ entities: - type: Transform pos: -36.880898,30.710796 parent: 2 + - uid: 16951 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23903 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: BoxZiptie entities: - uid: 1210 @@ -20507,6 +20588,24 @@ entities: - type: Transform pos: 34.599365,-27.40573 parent: 2 + - uid: 18041 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23905 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: CableApcExtension entities: - uid: 1231 @@ -23999,16 +24098,6 @@ entities: - type: Transform pos: -47.5,-26.5 parent: 2 - - uid: 1929 - components: - - type: Transform - pos: -48.5,-26.5 - parent: 2 - - uid: 1930 - components: - - type: Transform - pos: -49.5,-26.5 - parent: 2 - uid: 1931 components: - type: Transform @@ -44081,11 +44170,6 @@ entities: - type: Transform pos: 34.5,-47.5 parent: 2 - - uid: 5949 - components: - - type: Transform - pos: 35.5,-46.5 - parent: 2 - uid: 5950 components: - type: Transform @@ -59122,11 +59206,6 @@ entities: - type: Transform pos: -19.5,5.5 parent: 2 - - uid: 8684 - components: - - type: Transform - pos: -48.5,-25.5 - parent: 2 - uid: 8685 components: - type: Transform @@ -59217,6 +59296,11 @@ entities: - type: Transform pos: 35.5,-36.5 parent: 2 + - uid: 23913 + components: + - type: Transform + pos: -46.5,-25.5 + parent: 2 - proto: ClosetFireFilled entities: - uid: 8703 @@ -59267,11 +59351,6 @@ entities: - 0 - 0 - 0 - - uid: 8709 - components: - - type: Transform - pos: -48.5,-27.5 - parent: 2 - uid: 8710 components: - type: Transform @@ -59337,24 +59416,17 @@ entities: - type: Transform pos: -25.5,-52.5 parent: 2 -- proto: ClosetL3Filled - entities: - - uid: 8723 + - uid: 23934 components: - type: Transform - pos: 34.5,-29.5 + pos: -46.5,-27.5 parent: 2 -- proto: ClosetL3JanitorFilled +- proto: ClosetL3Filled entities: - - uid: 8724 - components: - - type: Transform - pos: 10.5,12.5 - parent: 2 - - uid: 8725 + - uid: 8723 components: - type: Transform - pos: 10.5,13.5 + pos: 34.5,-29.5 parent: 2 - proto: ClosetL3ScienceFilled entities: @@ -59730,6 +59802,13 @@ entities: linearDamping: 0 canCollide: False - type: InsideEntityStorage +- proto: ClothingBackpackDuffelSurgeryFilled + entities: + - uid: 23914 + components: + - type: Transform + pos: -28.5,38.5 + parent: 2 - proto: ClothingBackpackERTClown entities: - uid: 10531 @@ -59800,6 +59879,26 @@ entities: - type: Transform pos: 14.117703,27.649174 parent: 2 +- proto: ClothingBeltJanitorFilled + entities: + - uid: 15850 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23910 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingBeltMedicalFilled entities: - uid: 8775 @@ -59985,6 +60084,26 @@ entities: - type: Transform pos: -34.37776,-28.519873 parent: 2 +- proto: ClothingHandsGlovesJanitor + entities: + - uid: 8684 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 22225 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingHandsGlovesLatex entities: - uid: 8808 @@ -60045,6 +60164,39 @@ entities: - type: Transform pos: -11.279213,-24.423569 parent: 2 +- proto: ClothingHeadHatFlatcapBartenderIdris + entities: + - uid: 23928 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingHeadHatFlatcapBartenderNanotrasen + entities: + - uid: 23924 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingHeadHatFlatcapBartenderOrion + entities: + - uid: 23922 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingHeadHatHoodBioCmo entities: - uid: 8824 @@ -60403,6 +60555,17 @@ entities: - type: Transform pos: 36.29247,30.486513 parent: 2 +- proto: ClothingOuterApronBar + entities: + - uid: 23929 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingOuterArmorBulletproof entities: - uid: 8864 @@ -60561,6 +60724,17 @@ entities: - type: Transform pos: 25.514149,-62.429245 parent: 2 +- proto: ClothingOuterWinterBar + entities: + - uid: 23927 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingOuterWinterClown entities: - uid: 10551 @@ -60579,6 +60753,26 @@ entities: - type: Transform pos: -8.484784,-22.480118 parent: 2 +- proto: ClothingOuterWinterJani + entities: + - uid: 8724 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 22236 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingOuterWinterMime entities: - uid: 10522 @@ -60688,6 +60882,77 @@ entities: linearDamping: 0 canCollide: False - type: InsideEntityStorage +- proto: ClothingUniformJumpskirtBartender + entities: + - uid: 23920 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpskirtJanimaid + entities: + - uid: 8966 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23897 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpskirtJanimaidmini + entities: + - uid: 9026 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23898 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpskirtJanitor + entities: + - uid: 9237 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23899 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingUniformJumpskirtMime entities: - uid: 10506 @@ -60715,6 +60980,61 @@ entities: - type: Physics canCollide: False - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitBartender + entities: + - uid: 23917 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitBartenderIdris + entities: + - uid: 23925 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitBartenderNt + entities: + - uid: 23921 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitBartenderOrion + entities: + - uid: 23919 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitBartenderPurple + entities: + - uid: 23916 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingUniformJumpsuitCentcomAgent entities: - uid: 22312 @@ -60748,6 +61068,97 @@ entities: linearDamping: 0 canCollide: False - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitJacketMonkey + entities: + - uid: 23926 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitJanitor + entities: + - uid: 15522 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23900 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitJanitorIdris + entities: + - uid: 23901 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23904 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitJanitorNt + entities: + - uid: 8725 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23896 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage +- proto: ClothingUniformJumpsuitJanitorOrion + entities: + - uid: 8709 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 22226 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ClothingUniformJumpsuitMime entities: - uid: 10502 @@ -61193,11 +61604,6 @@ entities: - type: Transform pos: -13.5,-55.5 parent: 2 - - uid: 8966 - components: - - type: Transform - pos: -11.5,-55.5 - parent: 2 - uid: 8967 components: - type: Transform @@ -61553,11 +61959,6 @@ entities: - type: Transform pos: -2.5,85.5 parent: 2 - - uid: 9026 - components: - - type: Transform - pos: -12.5,-55.5 - parent: 2 - uid: 9027 components: - type: Transform @@ -61687,6 +62088,11 @@ entities: - type: Transform pos: 11.5,-53.5 parent: 2 + - uid: 23912 + components: + - type: Transform + pos: -12.5,-55.5 + parent: 2 - proto: ComputerRadar entities: - uid: 9048 @@ -62633,6 +63039,8 @@ entities: - Impassable - LowImpassable layer: + - TableLayer + - LowImpassable - BulletImpassable - Opaque density: 50 @@ -62640,10 +63048,36 @@ entities: restitution: 0 friction: 0.4 - type: EntityStorage - open: True - removedMasks: 20 - - type: PlaceableSurface - isPlaceable: True + air: + volume: 200 + immutable: False + temperature: 293.14673 + moles: + - 1.7459903 + - 6.568249 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - type: ContainerContainer + containers: + entity_storage: !type:Container + showEnts: False + occludes: True + ents: + - 9173 + - 9172 + - 9171 + paper_label: !type:ContainerSlot + showEnts: False + occludes: True + ent: null - proto: CrateEmergencyRadiation entities: - uid: 9174 @@ -63196,11 +63630,6 @@ entities: - type: Transform pos: -19.5,-35.5 parent: 2 - - uid: 9237 - components: - - type: Transform - pos: -45.5,-27.5 - parent: 2 - proto: CrateTrashCartFilled entities: - uid: 9238 @@ -107181,11 +107610,6 @@ entities: rot: -1.5707963267948966 rad pos: -21.5,8.5 parent: 2 - - uid: 15522 - components: - - type: Transform - pos: -46.5,-27.5 - parent: 2 - uid: 15523 components: - type: Transform @@ -107852,15 +108276,23 @@ entities: - uid: 9171 components: - type: Transform - pos: -34.5,17.5 - parent: 2 + parent: 9170 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: IngotSilver entities: - uid: 9172 components: - type: Transform - pos: -34.5,17.5 - parent: 2 + parent: 9170 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: IntercomAll entities: - uid: 15637 @@ -109080,6 +109512,26 @@ entities: - type: Transform pos: 10.483806,54.125267 parent: 2 +- proto: LightReplacer + entities: + - uid: 16950 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23906 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: LightReplacerEmpty entities: - uid: 15836 @@ -109131,6 +109583,57 @@ entities: - type: Transform pos: 34.5,-41.5 parent: 2 +- proto: LockerBartenderFilled + entities: + - uid: 23915 + components: + - type: Transform + pos: 17.5,18.5 + parent: 2 + - type: EntityStorage + air: + volume: 200 + immutable: False + temperature: 293.14673 + moles: + - 1.7459903 + - 6.568249 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - type: ContainerContainer + containers: + entity_storage: !type:Container + showEnts: False + occludes: True + ents: + - 23916 + - 23917 + - 23918 + - 23919 + - 23920 + - 23921 + - 23922 + - 23923 + - 23924 + - 23925 + - 23926 + - 23927 + - 23928 + - 23929 + - 23930 + - 23931 + paper_label: !type:ContainerSlot + showEnts: False + occludes: True + ent: null - proto: LockerBooze entities: - uid: 8887 @@ -109174,13 +109677,6 @@ entities: showEnts: False occludes: True ent: null -- proto: LockerBoozeFilled - entities: - - uid: 15850 - components: - - type: Transform - pos: 17.5,18.5 - parent: 2 - proto: LockerBotanistFilled entities: - uid: 15851 @@ -109465,6 +109961,24 @@ entities: - type: Transform pos: -16.5,40.5 parent: 2 + - type: EntityStorage + air: + volume: 200 + immutable: False + temperature: 293.14673 + moles: + - 1.7459903 + - 6.568249 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 - uid: 15872 components: - type: Transform @@ -109717,6 +110231,108 @@ entities: showEnts: False occludes: True ent: null +- proto: LockerJanitor + entities: + - uid: 1930 + components: + - type: Transform + pos: 10.5,12.5 + parent: 2 + - type: EntityStorage + air: + volume: 200 + immutable: False + temperature: 293.14673 + moles: + - 1.7459903 + - 6.568249 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - type: ContainerContainer + containers: + entity_storage: !type:Container + showEnts: False + occludes: True + ents: + - 5949 + - 8684 + - 8709 + - 8724 + - 8725 + - 8966 + - 9026 + - 9237 + - 15522 + - 15850 + - 15988 + - 16950 + - 16951 + - 17090 + - 18041 + - 18457 + paper_label: !type:ContainerSlot + showEnts: False + occludes: True + ent: null + - uid: 19985 + components: + - type: Transform + pos: 10.5,13.5 + parent: 2 + - type: EntityStorage + air: + volume: 200 + immutable: False + temperature: 293.14673 + moles: + - 1.7459903 + - 6.568249 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - type: ContainerContainer + containers: + entity_storage: !type:Container + showEnts: False + occludes: True + ents: + - 22225 + - 22226 + - 22236 + - 23896 + - 23897 + - 23898 + - 23899 + - 23900 + - 23901 + - 23902 + - 23903 + - 23904 + - 23905 + - 23906 + - 23907 + - 23908 + - 23909 + - 23910 + paper_label: !type:ContainerSlot + showEnts: False + occludes: True + ent: null - proto: LockerMedicalFilled entities: - uid: 15896 @@ -109741,8 +110357,24 @@ entities: - type: Transform pos: -28.5,37.5 parent: 2 - - type: Lock - locked: False + - type: EntityStorage + air: + volume: 200 + immutable: False + temperature: 293.14673 + moles: + - 1.7459903 + - 6.568249 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 - uid: 15900 components: - type: Transform @@ -110015,6 +110647,24 @@ entities: - type: Transform pos: -14.5,36.5 parent: 2 + - type: EntityStorage + air: + volume: 200 + immutable: False + temperature: 293.14673 + moles: + - 1.7459903 + - 6.568249 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 - proto: LockerWeldingSuppliesFilled entities: - uid: 15922 @@ -110446,11 +111096,6 @@ entities: - type: Transform pos: -21.5,-42.5 parent: 2 - - uid: 15988 - components: - - type: Transform - pos: -46.5,-25.5 - parent: 2 - uid: 15989 components: - type: Transform @@ -111010,6 +111655,24 @@ entities: - type: Transform pos: -10.547948,-40.502083 parent: 2 + - uid: 17090 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23908 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: Morgue entities: - uid: 16080 @@ -111642,11 +112305,11 @@ entities: content: >- [color=#002159]█▀▀▀▀▀▀▀▀▀▀▀▀▀▀█▄ - █   ▀██   █▄     █           █ + █   ▀██   █▄     █           █ █       ▀   █▀█▄█   ▄       █ [head=1]Nanotrasen[/head] - █           █     ▀█   ██▄   █ + █           █     ▀█   ██▄   █ ▀█▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ [head=1]Technologies[/head][/color] @@ -111891,7 +112554,7 @@ entities: █       ▀   █▀█▄█   ▄       █ [head=1]Nanotrasen[/head] - █           █     ▀█   ██▄   █ + █           █     ▀█   ██▄   █ ▀█▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ [head=1]Technologies[/head][/color] @@ -112561,6 +113224,17 @@ entities: - type: Transform pos: 43.132454,4.7062783 parent: 2 +- proto: PlushieMothBartender + entities: + - uid: 23918 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: PlushieNuke entities: - uid: 16338 @@ -112582,6 +113256,26 @@ entities: - type: Transform pos: -33.4985,36.450657 parent: 2 +- proto: PlushieSlips + entities: + - uid: 5949 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage + - uid: 23909 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: PlushieSnake entities: - uid: 16341 @@ -116855,6 +117549,17 @@ entities: - 18327 - proto: PoweredSmallLight entities: + - uid: 256 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -45.5,-27.5 + parent: 2 + - uid: 692 + components: + - type: Transform + pos: -45.5,-25.5 + parent: 2 - uid: 8813 components: - type: Transform @@ -116969,17 +117674,6 @@ entities: - type: Transform pos: -39.5,-25.5 parent: 2 - - uid: 16950 - components: - - type: Transform - pos: -48.5,-25.5 - parent: 2 - - uid: 16951 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -48.5,-27.5 - parent: 2 - uid: 16952 components: - type: Transform @@ -117845,11 +118539,6 @@ entities: rot: 1.5707963267948966 rad pos: -41.5,-25.5 parent: 2 - - uid: 17090 - components: - - type: Transform - pos: -46.5,-25.5 - parent: 2 - uid: 17091 components: - type: Transform @@ -123216,11 +123905,11 @@ entities: parent: 2 - proto: SalvageMagnet entities: - - uid: 18041 + - uid: 23935 components: - type: Transform rot: -1.5707963267948966 rad - pos: -46.5,-19.5 + pos: -48.5,-15.5 parent: 2 - proto: SalvageMaterialCrateSpawner entities: @@ -127480,12 +128169,6 @@ entities: parent: 2 - proto: SignEscapePods entities: - - uid: 18457 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -47.5,-27.5 - parent: 2 - uid: 18458 components: - type: Transform @@ -127508,6 +128191,12 @@ entities: rot: 1.5707963267948966 rad pos: -27.5,37.5 parent: 2 + - uid: 23933 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -43.5,-27.5 + parent: 2 - proto: SignFire entities: - uid: 18462 @@ -137208,8 +137897,12 @@ entities: - uid: 9173 components: - type: Transform - pos: -34.5,17.5 - parent: 2 + parent: 9170 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ToolboxMechanicalFilled entities: - uid: 15877 @@ -137335,6 +138028,15 @@ entities: - type: Transform pos: 19.382366,12.697111 parent: 2 + - uid: 23930 + components: + - type: Transform + parent: 23915 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ToyFigurineCaptain entities: - uid: 19943 @@ -137400,11 +138102,29 @@ entities: parent: 2 - proto: ToyFigurineJanitor entities: + - uid: 15988 + components: + - type: Transform + parent: 1930 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - uid: 19951 components: - type: Transform pos: 7.476756,13.849148 parent: 2 + - uid: 23902 + components: + - type: Transform + parent: 19985 + - type: Physics + angularDamping: 0 + linearDamping: 0 + canCollide: False + - type: InsideEntityStorage - proto: ToyFigurineLawyer entities: - uid: 19952 @@ -137870,12 +138590,6 @@ entities: - Middle: Off - proto: UnfinishedMachineFrame entities: - - uid: 19985 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 20.5,-11.5 - parent: 2 - uid: 19986 components: - type: Transform @@ -138684,6 +139398,11 @@ entities: rot: 1.5707963267948966 rad pos: -31.5,43.5 parent: 2 + - uid: 23937 + components: + - type: Transform + pos: -49.5,-28.5 + parent: 2 - proto: WallReinforced entities: - uid: 8905 @@ -151490,22 +152209,6 @@ entities: - type: Transform pos: -47.5,-27.5 parent: 2 - - uid: 22225 - components: - - type: Transform - pos: -49.5,-25.5 - parent: 2 - - uid: 22226 - components: - - type: Transform - pos: -49.5,-27.5 - parent: 2 - - uid: 22236 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -49.5,-28.5 - parent: 2 - uid: 22248 components: - type: Transform @@ -156648,7 +157351,7 @@ entities: links: - 19976 - type: Door - secondsUntilStateChange: -189523.19 + secondsUntilStateChange: -190235.81 state: Opening - uid: 23356 components: diff --git a/Resources/Migrations/deltaMigrations.yml b/Resources/Migrations/deltaMigrations.yml deleted file mode 100644 index 5081d04dc5..0000000000 --- a/Resources/Migrations/deltaMigrations.yml +++ /dev/null @@ -1,101 +0,0 @@ -# 2023-09-29 -PosterContrabandSMSyndie: PosterContrabandSafetyMothSyndie -PosterLegitSMPoisoning: PosterLegitSafetyMothPoisoning -PosterLegitSMBoH: PosterLegitSafetyMothBoH -PosterLegitSMHardhats: PosterLegitSafetyMothHardhat -PosterLegitSMFires: PosterLegitSafetyMothFires -PosterLegitSMPiping: PosterLegitSafetyMothPiping -PosterLegitSMMeth: PosterLegitSafetyMothMeth -PosterLegitSMEpi: PosterLegitSafetyMothEpi -PosterLegitSMPills: PosterLegitSafetyMothPills -PosterLegitSMAnomalies: PosterLegitSafetyMothDelam -PosterLegitSMGlimmer: PosterLegitSafetyMothGlimmer -EngineeringTechFab: Autolathe -EngineeringTechFabCircuitboard: AutolatheMachineCircuitboard -ScienceTechFab: Protolathe -ScienceTechFabCircuitboard: ProtolatheMachineCircuitboard -ServiceTechFab: Autolathe -ServiceTechFabCircuitboard: AutolatheMachineCircuitboard - -# 2023-10-05 -FoodMothTomatoSauce: null -LockerEpistemicsFilled: LockerScienceFilled -LockerMystagogueFilled: LockerResearchDirectorFilled -LockerEpistemics: LockerScientist -LockerMystagogue: LockerResearchDirector -HyperlinkBookAlerts: BookRandom -HyperlinkBookAtmos: BookAtmosDistro -HyperlinkBookBartending: BookBartendersManual -HyperlinkBookBotany: BookLeafLoversSecret -HyperlinkBookChemistry: BookChemicalCompendium -HyperlinkBookCooking: BookChefGaming -HyperlinkBookGlimmer: BookScientistsGuidebook -HyperlinkBookHacking: BookEngineersHandbook -HyperlinkBookMedical: BookMedicalReferenceBook -HyperlinkBookPower: BookEngineersHandbook -HyperlinkBookProcedure: BookRandom -HyperlinkBookShuttle: BookRandom -HyperlinkBookSpaceLaw: BookSecurity -HyperlinkBookSupernanny: BookHowToSurvive -SpawnPointCataloguer: SpawnPointLibrarian -SpawnPointCyborg: SpawnPointBorg -SpawnPointMedicalCyborg: null -SpawnPointEpistemologist: SpawnPointScientist -SpawnPointMystagogue: SpawnPointResearchDirector -SpawnPointSalvageTechnician: SpawnPointSalvageSpecialist -SpawnPointValet: SpawnPointServiceWorker -VendingMachineEpiDrobe: VendingMachineSciDrobe -PlushieMoffRandom: PlushieMothRandom -PlushieMoffbar: PlushieMothBartender -PlushieMoffsician: PlushieMothMusician -PlushieMoff: PlushieMoth -ArachneWeb: SpiderWeb -PowerCellBluespace: PowerCellHigh -CrateMedicalDefib: CrateMedical -WeaponShotgunEnforcerNonLethal: WeaponShotgunEnforcerRubber - -# 2023-10-06 -FoodMealTaco: FoodMealSoftTaco -FoodTinBeansOpen: FoodTinBeans -FoodBreadMoldy: FoodBreadMoldySlice -FoodMeatPatty: FoodMeatMeatball -ClothingHeadHoodMystic: ClothingHeadHoodMysta - -# 2023-11-07 -VendingMachineMailDrobe: VendingMachineCourierDrobe - -#Delta V temporary changes. Remove When items are added. -ComputerShipyard: ComputerBroken -ShipyardComputerCircuitboard: null -SpawnMobGolemCult: null -ShogiBoard: CheckerBoard - -# 2023-11-21 -AirlockBrigLocked: AirlockSecurityLawyerLocked -AirlockBrigGlassLocked: AirlockSecurityLawyerGlassLocked -WindoorSecureBrigLocked: WindoorSecureSecurityLawyerLocked - -#Delta V Optional: Remove "#" for specific maps. -#AsteroidRock: AsteroidAltRock -#AsteroidRockMining: AsteroidAltRockMining - -# 2023-12-16 -PlushieLizardMirrored: PlushieLizard - -# 2024-1-22 -#Use these lights because they are better -PoweredlightExterior: PoweredLightBlueInterior -ExteriorLightTube: BlueLightTube - -# 2024-01-26 -SalvagePartsSpawnerSubSpace: SalvagePartsSpawnerMid - -# 2024-02-08 -SpawnVehicleAntagVehicle: null - -# 2024-02-26 -SpaceTickSpawnerNPC: SpaceTickSpawner - -# 2024-03-07 -LockableButtonBrig: LockableButtonSecurity -SignDirectionalICU: SignDirectionalIcu diff --git a/Resources/Migrations/eeMigration.yml b/Resources/Migrations/eeMigration.yml index 8d95da53bc..195c1f8765 100644 --- a/Resources/Migrations/eeMigration.yml +++ b/Resources/Migrations/eeMigration.yml @@ -1,7 +1,119 @@ +# 2023-09-29 +PosterContrabandSMSyndie: PosterContrabandSafetyMothSyndie +PosterLegitSMPoisoning: PosterLegitSafetyMothPoisoning +PosterLegitSMBoH: PosterLegitSafetyMothBoH +PosterLegitSMHardhats: PosterLegitSafetyMothHardhat +PosterLegitSMFires: PosterLegitSafetyMothFires +PosterLegitSMPiping: PosterLegitSafetyMothPiping +PosterLegitSMMeth: PosterLegitSafetyMothMeth +PosterLegitSMEpi: PosterLegitSafetyMothEpi +PosterLegitSMPills: PosterLegitSafetyMothPills +PosterLegitSMAnomalies: PosterLegitSafetyMothDelam +PosterLegitSMGlimmer: PosterLegitSafetyMothGlimmer +EngineeringTechFab: Autolathe +EngineeringTechFabCircuitboard: AutolatheMachineCircuitboard +ScienceTechFab: Protolathe +ScienceTechFabCircuitboard: ProtolatheMachineCircuitboard +ServiceTechFab: Autolathe +ServiceTechFabCircuitboard: AutolatheMachineCircuitboard + +# 2023-10-05 +FoodMothTomatoSauce: null +LockerEpistemicsFilled: LockerScienceFilled +LockerMystagogueFilled: LockerResearchDirectorFilled +LockerEpistemics: LockerScientist +LockerMystagogue: LockerResearchDirector +HyperlinkBookAlerts: BookRandom +HyperlinkBookAtmos: BookAtmosDistro +HyperlinkBookBartending: BookBartendersManual +HyperlinkBookBotany: BookLeafLoversSecret +HyperlinkBookChemistry: BookChemicalCompendium +HyperlinkBookCooking: BookChefGaming +HyperlinkBookGlimmer: BookScientistsGuidebook +HyperlinkBookHacking: BookEngineersHandbook +HyperlinkBookMedical: BookMedicalReferenceBook +HyperlinkBookPower: BookEngineersHandbook +HyperlinkBookProcedure: BookRandom +HyperlinkBookShuttle: BookRandom +HyperlinkBookSpaceLaw: BookSecurity +HyperlinkBookSupernanny: BookHowToSurvive +SpawnPointCataloguer: SpawnPointLibrarian +SpawnPointCyborg: SpawnPointBorg +SpawnPointMedicalCyborg: null +SpawnPointEpistemologist: SpawnPointScientist +SpawnPointMystagogue: SpawnPointResearchDirector +SpawnPointSalvageTechnician: SpawnPointSalvageSpecialist +SpawnPointValet: SpawnPointServiceWorker +VendingMachineEpiDrobe: VendingMachineSciDrobe +PlushieMoffRandom: PlushieMothRandom +PlushieMoffbar: PlushieMothBartender +PlushieMoffsician: PlushieMothMusician +PlushieMoff: PlushieMoth +ArachneWeb: SpiderWeb +PowerCellBluespace: PowerCellHigh +CrateMedicalDefib: CrateMedical +WeaponShotgunEnforcerNonLethal: WeaponShotgunEnforcerRubber + +# 2023-10-06 +FoodMealTaco: FoodMealSoftTaco +FoodTinBeansOpen: FoodTinBeans +FoodBreadMoldy: FoodBreadMoldySlice +FoodMeatPatty: FoodMeatMeatball +ClothingHeadHoodMystic: ClothingHeadHoodMysta + +# 2023-11-07 +VendingMachineMailDrobe: VendingMachineCourierDrobe + +#Delta V temporary changes. Remove When items are added. # TODO: EE remove when Rebased +ComputerShipyard: ComputerBroken +ShipyardComputerCircuitboard: null +SpawnMobGolemCult: null +ShogiBoard: CheckerBoard + +# 2023-11-21 +AirlockBrigLocked: AirlockSecurityLawyerLocked +AirlockBrigGlassLocked: AirlockSecurityLawyerGlassLocked +WindoorSecureBrigLocked: WindoorSecureSecurityLawyerLocked + +#Delta V Optional: Remove "#" for specific maps. +#AsteroidRock: AsteroidAltRock +#AsteroidRockMining: AsteroidAltRockMining # These two rocks change between the two variants of + # Wizden Rocks, they're the same rock but with two different textures + # both are ugly, but you may have a preference. + +# 2023-12-16 +PlushieLizardMirrored: PlushieLizard + +# 2024-1-22 +#Use these lights because they are better +PoweredlightExterior: PoweredLightBlueInterior +ExteriorLightTube: BlueLightTube + +# 2024-01-26 +SalvagePartsSpawnerSubSpace: SalvagePartsSpawnerMid + +# 2024-02-08 +SpawnVehicleAntagVehicle: null + +# 2024-02-26 +SpaceTickSpawnerNPC: SpaceTickSpawner + +# 2024-03-07 +LockableButtonBrig: LockableButtonSecurity +SignDirectionalICU: SignDirectionalIcu + +# 2024-03-08 +ClothingBackpackSatchelBrigmedicDeltaVFilled: ClothingBackpackSatchelBrigmedicFilled +ClothingBackpackDuffelBrigmedicDeltaVFilled: ClothingBackpackDuffelBrigmedicFilled +ClothingBackpackBrigmedicDeltaVFilled: ClothingBackpackBrigmedicFilled + # 2024-06-08 CrateFunPlushie: CrateFunToyBox CrateFunLizardPlushieBulk: CrateFunToyBox +# 2024-08-22 - Frontier Mail - Add more to these when they come up as mapped. Part of the Frontier Mail port, blame Tortuga. +MailPAI: MailNFPAI + # 2024-08-27 Oracle: OracleSpawner -SophicScribe: SophicScribeSpawner \ No newline at end of file +SophicScribe: SophicScribeSpawner diff --git a/Resources/Migrations/eeMigrations.yml b/Resources/Migrations/eeMigrations.yml deleted file mode 100644 index 682c3c412b..0000000000 --- a/Resources/Migrations/eeMigrations.yml +++ /dev/null @@ -1,4 +0,0 @@ -# 2024-03-08 -ClothingBackpackSatchelBrigmedicDeltaVFilled: ClothingBackpackSatchelBrigmedicFilled -ClothingBackpackDuffelBrigmedicDeltaVFilled: ClothingBackpackDuffelBrigmedicFilled -ClothingBackpackBrigmedicDeltaVFilled: ClothingBackpackBrigmedicFilled diff --git a/Resources/Migrations/frontierMigrations.yml b/Resources/Migrations/frontierMigrations.yml deleted file mode 100644 index e8d607494e..0000000000 --- a/Resources/Migrations/frontierMigrations.yml +++ /dev/null @@ -1,2 +0,0 @@ -# 2024-08-22 - Frontier Mail - Add more to these when they come up as mapped. Part of the Frontier Mail port, blame Tortuga. -MailPAI: MailNFPAI diff --git a/Resources/Prototypes/Alerts/alerts.yml b/Resources/Prototypes/Alerts/alerts.yml index e32eea3cc9..dffebf4b1d 100644 --- a/Resources/Prototypes/Alerts/alerts.yml +++ b/Resources/Prototypes/Alerts/alerts.yml @@ -31,7 +31,7 @@ - type: entity id: AlertSpriteView - categories: [ hideSpawnMenu ] + categories: [ HideSpawnMenu ] components: - type: Sprite layers: diff --git a/Resources/Prototypes/Alerts/revenant.yml b/Resources/Prototypes/Alerts/revenant.yml index a56b898351..9db5228483 100644 --- a/Resources/Prototypes/Alerts/revenant.yml +++ b/Resources/Prototypes/Alerts/revenant.yml @@ -16,7 +16,7 @@ - type: entity id: AlertEssenceSpriteView - categories: [ hideSpawnMenu ] + categories: [ HideSpawnMenu ] components: - type: Sprite sprite: /Textures/Interface/Alerts/essence_counter.rsi diff --git a/Resources/Prototypes/Catalog/Fills/Crates/materials.yml b/Resources/Prototypes/Catalog/Fills/Crates/materials.yml index 885bc92a07..0300830e3b 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/materials.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/materials.yml @@ -131,7 +131,7 @@ - type: entity id: CrateMaterialUranium name: uranium crate - parent: CrateGenericSteel + parent: CrateUranium components: - type: StorageFill contents: diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/service.yml b/Resources/Prototypes/Catalog/Fills/Lockers/service.yml index 83bbdb435f..ba386a83ac 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/service.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/service.yml @@ -20,6 +20,28 @@ - id: LunchboxServiceFilledRandom # Delta-V Lunchboxes! prob: 0.3 +- type: entity + id: LockerBartenderFilled + suffix: Filled + parent: LockerBartender + components: + - type: StorageFill + contents: + - id: DrinkShaker + - id: ClothingEyesHudBeer + - id: HandLabeler + amount: 1 + - id: DrinkBottleBeer + prob: 0.5 + - id: DrinkBottleBeer + prob: 0.5 + - id: DrinkBottleBeer + prob: 0.5 + - id: RagItem + amount: 2 + - id: LunchboxServiceFilledRandom # Delta-V Lunchboxes! + prob: 0.3 + #- type: entity # id: LockerFormalFilled # suffix: Filled diff --git a/Resources/Prototypes/DeltaV/Traits/altvision.yml b/Resources/Prototypes/DeltaV/Traits/altvision.yml index 54fec7df8b..31a67ad350 100644 --- a/Resources/Prototypes/DeltaV/Traits/altvision.yml +++ b/Resources/Prototypes/DeltaV/Traits/altvision.yml @@ -12,8 +12,10 @@ inverted: true traits: - DogVision - components: - - type: UltraVision + functions: + - !type:TraitAddComponent + components: + - type: UltraVision - type: trait id: DogVision @@ -29,5 +31,7 @@ inverted: true traits: - UltraVision - components: - - type: DogVision + functions: + - !type:TraitAddComponent + components: + - type: DogVision diff --git a/Resources/Prototypes/DeltaV/Traits/neutral.yml b/Resources/Prototypes/DeltaV/Traits/neutral.yml index 469fa5b34b..f8c4119f04 100644 --- a/Resources/Prototypes/DeltaV/Traits/neutral.yml +++ b/Resources/Prototypes/DeltaV/Traits/neutral.yml @@ -5,5 +5,7 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: ScottishAccent + functions: + - !type:TraitAddComponent + components: + - type: ScottishAccent diff --git a/Resources/Prototypes/Entities/Effects/puddle.yml b/Resources/Prototypes/Entities/Effects/puddle.yml index 6a29a8af45..7f6125e73d 100644 --- a/Resources/Prototypes/Entities/Effects/puddle.yml +++ b/Resources/Prototypes/Entities/Effects/puddle.yml @@ -166,3 +166,42 @@ solution: puddle - type: BadDrink - type: IgnoresFingerprints + - type: PuddleFootPrints + +- type: entity + name: Footstep + id: Footstep + save: false + description: Trace of liquid + components: + - type: Clickable + - type: FootstepModifier + footstepSoundCollection: + collection: FootstepWater + params: + volume: 3 + - type: Transform + noRot: false + - type: Sprite + drawdepth: FloorObjects + color: "#FFFFFF80" + - type: Physics + bodyType: Static + - type: Fixtures + fixtures: + slipFixture: + shape: + !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" + mask: + - ItemMask + layer: + - SlipLayer + hard: false + - type: SolutionContainerManager + solutions: + step: { maxVol: 2 } + - type: FootPrint + - type: Puddle + solution: step + - type: Appearance diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index 420e7ed50d..f19e76ecf5 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -825,13 +825,6 @@ id: MobMonkeyPunpun description: A prominent representative of monkeys with unlimited access to alcohol. components: - - type: GhostRole - prob: 1 - makeSentient: true - allowSpeech: true - allowMovement: true - name: ghost-role-information-punpun-name - description: ghost-role-information-punpun-description - type: GhostTakeoverAvailable - type: Butcherable butcheringType: Spike @@ -859,6 +852,7 @@ - TauCetiBasic - Monkey - Kobold + - type: Punpun - type: entity name: Tropico diff --git a/Resources/Prototypes/Entities/Mobs/Player/familiars.yml b/Resources/Prototypes/Entities/Mobs/Player/familiars.yml index 0804ba8258..95c87fcb63 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/familiars.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/familiars.yml @@ -28,7 +28,7 @@ - type: MobThresholds thresholds: 0: Alive - 100: Dead + 50: Dead - type: Damageable damageContainer: CorporealSpirit damageModifierSet: CorporealSpirit @@ -61,12 +61,11 @@ attackMemoryLength: 10 retaliateFriendlies: true - type: PsionicFamiliar + - type: Dispellable - type: DamageOnDispel damage: types: Heat: 100 - - type: RandomMetadata - nameSegments: [names_golem] - type: entity name: Remilia @@ -130,6 +129,10 @@ damage: types: Piercing: 5 + - type: MobThresholds + thresholds: + 0: Alive + 30: Dead - type: entity name: Cerberus @@ -239,3 +242,5 @@ - Opaque layer: - MobLayer + - type: RandomMetadata + nameSegments: [names_golem] diff --git a/Resources/Prototypes/Entities/Mobs/Species/arachne.yml b/Resources/Prototypes/Entities/Mobs/Species/arachne.yml index 24ebafd91d..ddbdc57e0a 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/arachne.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/arachne.yml @@ -135,6 +135,9 @@ fireStackAlternateState: 3 - type: Spider - type: IgnoreSpiderWeb + - type: FootPrints + leftBarePrint: "footprint-left-bare-spider" + rightBarePrint: "footprint-right-bare-spider" - type: entity save: false diff --git a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml index d576101e65..f512e71d32 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml @@ -127,6 +127,11 @@ sprite: "Effects/creampie.rsi" state: "creampie_arachnid" visible: false + - type: Spider + - type: IgnoreSpiderWeb + - type: FootPrints + leftBarePrint: "footprint-left-bare-spider" + rightBarePrint: "footprint-right-bare-spider" - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/diona.yml b/Resources/Prototypes/Entities/Mobs/Species/diona.yml index 113151ad08..07d621b139 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/diona.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/diona.yml @@ -120,6 +120,9 @@ whitelist: types: - Shard + - type: FootPrints + leftBarePrint: "footprint-left-bare-diona" + rightBarePrint: "footprint-right-bare-diona" - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml b/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml index 069ecb3eaf..7f31504035 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml @@ -65,6 +65,11 @@ - SolCommon - type: LightweightDrunk boozeStrengthMultiplier: 0.5 + - type: Stamina + critThreshold: 115 + - type: FootPrints + leftBarePrint: "footprint-left-bare-dwarf" + rightBarePrint: "footprint-right-bare-dwarf" - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/harpy.yml b/Resources/Prototypes/Entities/Mobs/Species/harpy.yml index 1d0d60b2da..4ad6ea03cd 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/harpy.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/harpy.yml @@ -127,6 +127,9 @@ - Shard - Landmine - Mousetrap + - type: FootPrints + leftBarePrint: "footprint-left-bare-lizard" + rightBarePrint: "footprint-right-bare-lizard" # I was about to complain about this, then I remembered birbs have dinosaur feet. So this is valid. - type: entity save: false diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml index 013789cd2b..ee2886602d 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml @@ -28,6 +28,7 @@ understands: - TauCetiBasic - SolCommon + - type: FootPrints - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/moth.yml b/Resources/Prototypes/Entities/Mobs/Species/moth.yml index fef380d1d5..5f68422226 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/moth.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/moth.yml @@ -122,6 +122,7 @@ sprite: "Effects/creampie.rsi" state: "creampie_moth" visible: false + - type: FootPrints - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml index b27b4c6029..ee5d628565 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml @@ -66,6 +66,9 @@ understands: - TauCetiBasic - Draconic + - type: FootPrints + leftBarePrint: "footprint-left-bare-lizard" + rightBarePrint: "footprint-right-bare-lizard" - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml b/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml index 28ea5b030f..2d34c87cfb 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/skeleton.yml @@ -9,7 +9,7 @@ components: - type: HumanoidAppearance species: Skeleton - - type: Carriable # Carrying system from nyanotrasen. + - type: Carriable # Carrying system from nyanotrasen. - type: Icon sprite: Mobs/Species/Skeleton/parts.rsi state: full @@ -102,6 +102,7 @@ probability: 0.5 - type: FireVisuals alternateState: Standing + - type: FootPrints - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/slime.yml b/Resources/Prototypes/Entities/Mobs/Species/slime.yml index 7faade46f8..e890916625 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/slime.yml @@ -117,6 +117,9 @@ understands: - TauCetiBasic - Bubblish + - type: FootPrints + leftBarePrint: "footprint-left-bare-slime" + rightBarePrint: "footprint-right-bare-slime" - type: entity parent: MobHumanDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/vox.yml b/Resources/Prototypes/Entities/Mobs/Species/vox.yml index ec8035563b..58e2b3b646 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/vox.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/vox.yml @@ -102,6 +102,9 @@ sprite: "Effects/creampie.rsi" state: "creampie_vox" # Not default visible: false + - type: FootPrints + leftBarePrint: "footprint-left-bare-lizard" + rightBarePrint: "footprint-right-bare-lizard" - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml b/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml index 2aecd13288..d7cba59eb1 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml @@ -3,8 +3,7 @@ id: BaseFlatpack name: base flatpack description: A flatpack used for constructing something. - categories: - - hideSpawnMenu + categories: [ HideSpawnMenu ] components: - type: Item size: Large diff --git a/Resources/Prototypes/Entities/Objects/Devices/instrumentFlatpacks.yml b/Resources/Prototypes/Entities/Objects/Devices/instrumentFlatpacks.yml index feb0e2ab5f..f6057d1d32 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/instrumentFlatpacks.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/instrumentFlatpacks.yml @@ -3,8 +3,7 @@ id: InstrumentFlatpack name: instrument flatpack description: A flatpack used for constructing something. - categories: - - hideSpawnMenu + categories: [ HideSpawnMenu ] components: - type: Item size: Normal diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml index 7d342eed82..614af2a488 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/base_instruments.yml @@ -29,7 +29,7 @@ components: - type: Instrument - type: ActivatableUI - allowSpectator: false # otherwise they can play client-side music + blockSpectators: true # otherwise they can play client-side music inHandsOnly: false singleUser: true requireHands: true diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index d3db29b420..c72f7a2e91 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -159,6 +159,16 @@ backgroundPatchMargin: 16.0, 16.0, 16.0, 16.0 contentMargin: 32.0, 16.0, 32.0, 0.0 +- type: entity + name: note + description: A piece of white paper. + id: PaperWrittenPunpunNote + parent: PaperCaptainsThoughts + suffix: Punpun Note + components: + - type: Paper + content: I, Punpun, invoke my right to have all of my clones on the NT family vacation to the meat packaging plant one out of every 15 shifts. + - type: entity name: cargo invoice parent: Paper diff --git a/Resources/Prototypes/Entities/Objects/Specific/Mail/Items/paper.yml b/Resources/Prototypes/Entities/Objects/Specific/Mail/Items/paper.yml index b21ca40717..56c6123edd 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Mail/Items/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mail/Items/paper.yml @@ -101,7 +101,7 @@ - type: entity id: PaperMailNFVagueThreat8 - categories: [ HideSpawnMenu ] + categories: [ HideSpawnMenu ] suffix: "vague mail threat 8, formatted" parent: Paper components: @@ -267,7 +267,7 @@ - type: entity id: PaperMailNTSoapAd2 - categories: [ HideSpawnMenu ] + categories: [ HideSpawnMenu ] suffix: "soap ad 2" #DeltaV - Edited to not be addressed to Frontier Citizens, localized parent: Paper components: @@ -312,7 +312,7 @@ - type: entity id: PaperMailNFPaperPusherAd categories: [ HideSpawnMenu ] - suffix: "paper pusher" + suffix: "paper pusher" parent: Paper components: - type: Paper @@ -336,7 +336,7 @@ components: - type: Paper content: |2 - + [head=1]HÖGANÄS[/head] [italic](There is a black and white picture of a pet bed on the first page.)[/italic] @@ -435,7 +435,7 @@ stampedName: Chief Friendship Officer - stampedColor: '#333333FF' stampedName: Cuts-With-Scalpel -# stampType: Signature #DeltaV - Not compatible with our signatures code stuff apparently. +# stampType: Signature #DeltaV - Not compatible with our signatures code stuff apparently. content: |2 [head=1]Note of Adoption[/head] diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml index 0021b05321..df1a56866b 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml @@ -775,7 +775,7 @@ energy: 1.6 color: "#b89f25" - type: AccessReader - access: [["Orders"]] # DeltaV - see Resources/Prototypes/DeltaV/Access/cargo.yml + access: [["Cargo"]] - type: DeviceNetwork deviceNetId: Wireless receiveFrequencyId: BasicDevice diff --git a/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml b/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml index b4f05cf68a..e83cbfe873 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml @@ -83,8 +83,7 @@ - type: entity id: FlatpackerNoBoardEffect - categories: - - hideSpawnMenu + categories: [ HideSpawnMenu ] components: - type: Sprite sprite: Structures/Machines/autolathe.rsi diff --git a/Resources/Prototypes/Entities/categories.yml b/Resources/Prototypes/Entities/categories.yml new file mode 100644 index 0000000000..2fb56818f9 --- /dev/null +++ b/Resources/Prototypes/Entities/categories.yml @@ -0,0 +1,4 @@ +- type: entityCategory + id: Actions + name: entity-category-name-actions + hideSpawnMenu: true diff --git a/Resources/Prototypes/Language/Species-Specific/diona.yml b/Resources/Prototypes/Language/Species-Specific/diona.yml index 76b62163ff..57c928dc46 100644 --- a/Resources/Prototypes/Language/Species-Specific/diona.yml +++ b/Resources/Prototypes/Language/Species-Specific/diona.yml @@ -2,6 +2,7 @@ # TODO: Replace this with a much better language. - type: language id: RootSpeak + isVisibleLanguage: true speech: color: "#ce5e14dd" fontId: Noganas @@ -14,4 +15,4 @@ - zt - kr - st - - sh \ No newline at end of file + - sh diff --git a/Resources/Prototypes/Language/Species-Specific/harpy.yml b/Resources/Prototypes/Language/Species-Specific/harpy.yml index 143b089bd1..531b92e325 100644 --- a/Resources/Prototypes/Language/Species-Specific/harpy.yml +++ b/Resources/Prototypes/Language/Species-Specific/harpy.yml @@ -1,5 +1,6 @@ - type: language id: ValyrianStandard + isVisibleLanguage: true speech: fontId: Cambria color: "#008ecc" diff --git a/Resources/Prototypes/Language/Species-Specific/marish.yml b/Resources/Prototypes/Language/Species-Specific/marish.yml index 872d67373d..20b42a80d1 100644 --- a/Resources/Prototypes/Language/Species-Specific/marish.yml +++ b/Resources/Prototypes/Language/Species-Specific/marish.yml @@ -1,6 +1,7 @@ # Spoken by shadowkins. - type: language id: Marish + isVisibleLanguage: true speech: color: "#be3cc5" fontId: Lymphatic @@ -17,4 +18,4 @@ - maaAr - aarrr - wrurrl - - mmar \ No newline at end of file + - mmar diff --git a/Resources/Prototypes/Language/Species-Specific/moth.yml b/Resources/Prototypes/Language/Species-Specific/moth.yml index ed0a6009c5..e44b3bdd7c 100644 --- a/Resources/Prototypes/Language/Species-Specific/moth.yml +++ b/Resources/Prototypes/Language/Species-Specific/moth.yml @@ -2,6 +2,7 @@ # TODO: Replace this with a much better language. - type: language id: Moffic + isVisibleLanguage: true speech: color: "#c7df2edd" fontId: Copperplate @@ -66,4 +67,4 @@ - uhr - kön - we - - hön \ No newline at end of file + - hön diff --git a/Resources/Prototypes/Language/Species-Specific/nekomimetic.yml b/Resources/Prototypes/Language/Species-Specific/nekomimetic.yml index 3610e5fa50..a9dae1650d 100644 --- a/Resources/Prototypes/Language/Species-Specific/nekomimetic.yml +++ b/Resources/Prototypes/Language/Species-Specific/nekomimetic.yml @@ -2,6 +2,7 @@ # TODO: Replace this with a much better language. - type: language id: Nekomimetic + isVisibleLanguage: true speech: color: "#df57aaee" fontId: Manga @@ -57,4 +58,4 @@ - puru - ira - heto - - etto \ No newline at end of file + - etto diff --git a/Resources/Prototypes/Language/Species-Specific/reptilian.yml b/Resources/Prototypes/Language/Species-Specific/reptilian.yml index 6f9a10efa6..b5ba3f6dda 100644 --- a/Resources/Prototypes/Language/Species-Specific/reptilian.yml +++ b/Resources/Prototypes/Language/Species-Specific/reptilian.yml @@ -1,6 +1,7 @@ # Spoken by Unathi. - type: language id: Draconic + isVisibleLanguage: true speech: color: "#2aca2add" obfuscation: diff --git a/Resources/Prototypes/Language/Species-Specific/slimeperson.yml b/Resources/Prototypes/Language/Species-Specific/slimeperson.yml index a3c1f91a17..a4d8fc1345 100644 --- a/Resources/Prototypes/Language/Species-Specific/slimeperson.yml +++ b/Resources/Prototypes/Language/Species-Specific/slimeperson.yml @@ -2,6 +2,7 @@ # TODO: Replace this with a much better language. - type: language id: Bubblish + isVisibleLanguage: true speech: color: "#00a3e2dd" fontId: RubikBubbles @@ -14,4 +15,4 @@ - plop - pop - bop - - boop \ No newline at end of file + - boop diff --git a/Resources/Prototypes/Language/Species-Specific/vulpkanin.yml b/Resources/Prototypes/Language/Species-Specific/vulpkanin.yml index 17a48493a4..2b53f79a55 100644 --- a/Resources/Prototypes/Language/Species-Specific/vulpkanin.yml +++ b/Resources/Prototypes/Language/Species-Specific/vulpkanin.yml @@ -2,6 +2,7 @@ # TODO: Replace this with a much better language. - type: language id: Canilunzt + isVisibleLanguage: true speech: color: "#d69b3dcc" obfuscation: @@ -65,4 +66,4 @@ - einech - cresthz - azunein - - ghzth \ No newline at end of file + - ghzth diff --git a/Resources/Prototypes/Language/Standard/elyran.yml b/Resources/Prototypes/Language/Standard/elyran.yml index c2c90e7b6f..b97a0698f2 100644 --- a/Resources/Prototypes/Language/Standard/elyran.yml +++ b/Resources/Prototypes/Language/Standard/elyran.yml @@ -1,5 +1,6 @@ - type: language id: Elyran + isVisibleLanguage: true speech: color: "#8282fbaa" obfuscation: @@ -83,4 +84,4 @@ - an' - e' - a' - - em' \ No newline at end of file + - em' diff --git a/Resources/Prototypes/Language/Standard/freespeak.yml b/Resources/Prototypes/Language/Standard/freespeak.yml index 831c2a67ff..9fe252e5b2 100644 --- a/Resources/Prototypes/Language/Standard/freespeak.yml +++ b/Resources/Prototypes/Language/Standard/freespeak.yml @@ -1,5 +1,6 @@ - type: language id: Freespeak + isVisibleLanguage: true speech: color: "#597d35" obfuscation: diff --git a/Resources/Prototypes/Language/Standard/solcommon.yml b/Resources/Prototypes/Language/Standard/solcommon.yml index 88c5470154..4bd1563f74 100644 --- a/Resources/Prototypes/Language/Standard/solcommon.yml +++ b/Resources/Prototypes/Language/Standard/solcommon.yml @@ -1,5 +1,6 @@ - type: language id: SolCommon + isVisibleLanguage: true speech: color: "#8282fbaa" obfuscation: @@ -255,4 +256,4 @@ - zo - zu - zun - - zuo \ No newline at end of file + - zuo diff --git a/Resources/Prototypes/Language/Standard/taucetibasic.yml b/Resources/Prototypes/Language/Standard/taucetibasic.yml index 96426f6c24..f21834f04e 100644 --- a/Resources/Prototypes/Language/Standard/taucetibasic.yml +++ b/Resources/Prototypes/Language/Standard/taucetibasic.yml @@ -253,4 +253,4 @@ - zem - zo - zoj - - zon \ No newline at end of file + - zon diff --git a/Resources/Prototypes/Language/Standard/tradeband.yml b/Resources/Prototypes/Language/Standard/tradeband.yml index 96415dc5a6..53613b46b2 100644 --- a/Resources/Prototypes/Language/Standard/tradeband.yml +++ b/Resources/Prototypes/Language/Standard/tradeband.yml @@ -1,5 +1,6 @@ - type: language id: Tradeband + isVisibleLanguage: true speech: color: "#597d35" obfuscation: diff --git a/Resources/Prototypes/Language/genericlanguages.yml b/Resources/Prototypes/Language/genericlanguages.yml index 8d172cdae9..90cb874ee6 100644 --- a/Resources/Prototypes/Language/genericlanguages.yml +++ b/Resources/Prototypes/Language/genericlanguages.yml @@ -12,6 +12,7 @@ # TODO: Replace this with much better languages. Yes, robots can have languages. - type: language id: RobotTalk + isVisibleLanguage: true speech: fontId: Monospace obfuscation: diff --git a/Resources/Prototypes/Store/categories.yml b/Resources/Prototypes/Store/categories.yml index 1b377902e4..489145813e 100644 --- a/Resources/Prototypes/Store/categories.yml +++ b/Resources/Prototypes/Store/categories.yml @@ -104,6 +104,11 @@ name: store-category-disruption priority: 12 +- type: storeCategory + id: UplinkSales + name: Sales + priority: 10 + #revenant - type: storeCategory id: RevenantAbilities diff --git a/Resources/Prototypes/Traits/disabilities.yml b/Resources/Prototypes/Traits/disabilities.yml index 5e5028035f..efa7739101 100644 --- a/Resources/Prototypes/Traits/disabilities.yml +++ b/Resources/Prototypes/Traits/disabilities.yml @@ -8,8 +8,10 @@ jobs: - Borg - MedicalBorg - components: - - type: PermanentBlindness + functions: + - !type:TraitAddComponent + components: + - type: PermanentBlindness - type: trait id: Nearsighted @@ -21,9 +23,11 @@ jobs: - Borg - MedicalBorg - components: - - type: PermanentBlindness - blindness: 4 + functions: + - !type:TraitAddComponent + components: + - type: PermanentBlindness + blindness: 4 - type: trait id: Narcolepsy @@ -39,29 +43,35 @@ inverted: true species: - IPC - components: - - type: Narcolepsy - timeBetweenIncidents: 300, 600 - durationOfIncident: 10, 30 + functions: + - !type:TraitAddComponent + components: + - type: Narcolepsy + timeBetweenIncidents: 300, 600 + durationOfIncident: 10, 30 - type: trait id: Pacifist category: Mental points: 6 - components: - - type: Pacified + functions: + - !type:TraitAddComponent + components: + - type: Pacified - type: trait id: Paracusia category: Auditory points: 2 - components: - - type: Paracusia - minTimeBetweenIncidents: 0.1 - maxTimeBetweenIncidents: 300 - maxSoundDistance: 7 - sounds: - collection: Paracusia + functions: + - !type:TraitAddComponent + components: + - type: Paracusia + minTimeBetweenIncidents: 0.1 + maxTimeBetweenIncidents: 300 + maxSoundDistance: 7 + sounds: + collection: Paracusia - type: trait id: Muted @@ -73,8 +83,10 @@ jobs: - Borg - MedicalBorg - components: - - type: Muted + functions: + - !type:TraitAddComponent + components: + - type: Muted - type: trait id: Uncloneable @@ -86,8 +98,10 @@ jobs: - Borg - MedicalBorg - components: - - type: Uncloneable + functions: + - !type:TraitAddComponent + components: + - type: Uncloneable - type: trait id: FrontalLisp @@ -104,8 +118,10 @@ - IPC - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: FrontalLisp + functions: + - !type:TraitAddComponent + components: + - type: FrontalLisp - type: trait id: Snoring @@ -120,8 +136,10 @@ inverted: true species: - IPC - components: - - type: Snoring + functions: + - !type:TraitAddComponent + components: + - type: Snoring - type: trait id: Sluggish @@ -137,14 +155,16 @@ inverted: true species: - Diona - components: - - type: TraitSpeedModifier - sprintModifier: 0.85 - walkModifier: 0.85 - - type: ClimbDelayModifier - climbDelayMultiplier: 1.35 - - type: LayingDownModifier - layingDownCooldownMultiplier: 1.2 + functions: + - !type:TraitAddComponent + components: + - type: TraitSpeedModifier + sprintModifier: 0.85 + walkModifier: 0.85 + - type: ClimbDelayModifier + climbDelayMultiplier: 1.35 + - type: LayingDownModifier + layingDownCooldownMultiplier: 1.2 - type: trait id: SnailPaced @@ -160,14 +180,16 @@ inverted: true species: - Diona - components: - - type: TraitSpeedModifier - sprintModifier: 0.7 - walkModifier: 0.7 - - type: ClimbDelayModifier - climbDelayMultiplier: 1.66 - - type: LayingDownModifier - layingDownCooldownMultiplier: 1.6 + functions: + - !type:TraitAddComponent + components: + - type: TraitSpeedModifier + sprintModifier: 0.7 + walkModifier: 0.7 + - type: ClimbDelayModifier + climbDelayMultiplier: 1.66 + - type: LayingDownModifier + layingDownCooldownMultiplier: 1.6 - type: trait id: BloodDeficiency @@ -183,9 +205,11 @@ inverted: true species: - IPC - components: - - type: BloodDeficiency # by default, start taking bloodloss damage at around ~21.4 minutes, - bloodLossPercentage: 0.0002333333 # then become crit ~10 minutes + functions: + - !type:TraitAddComponent + components: + - type: BloodDeficiency # By default, start taking bloodloss damage at around ~21.4 minutes, + bloodLossPercentage: 0.0002333333 # then become crit ~10 minutes - type: trait id: Hemophilia @@ -201,12 +225,14 @@ inverted: true species: - IPC - components: - - type: Hemophilia - bleedReductionModifier: 0.5 - damageModifiers: - coefficients: - Blunt: 1.1 + functions: + - !type:TraitAddComponent + components: + - type: Hemophilia + bleedReductionModifier: 0.5 + damageModifiers: + coefficients: + Blunt: 1.1 - type: trait id: Photophobia @@ -218,11 +244,13 @@ species: - Vulpkanin # This trait functions exactly as-is for the Vulpkanin trait. - Shadowkin - components: - - type: Flashable - eyeDamageChance: 0.3 - eyeDamage: 1 - durationMultiplier: 1.5 + functions: + - !type:TraitAddComponent + components: + - type: Flashable + eyeDamageChance: 0.3 + eyeDamage: 1 + durationMultiplier: 1.5 - type: trait id: Clumsy @@ -238,11 +266,13 @@ departments: - Command # Because I know for a fact people will play Captain and grief with their inability to fight back. - Security # Because I know for a fact people will play Security and grief with their inability to use guns. - components: - - type: Clumsy - clumsyDamage: - types: - Blunt: 5 - Piercing: 4 - groups: - Burn: 3 + functions: + - !type:TraitAddComponent + components: + - type: Clumsy + clumsyDamage: + types: + Blunt: 5 + Piercing: 4 + groups: + Burn: 3 diff --git a/Resources/Prototypes/Traits/inconveniences.yml b/Resources/Prototypes/Traits/inconveniences.yml index 2c0df79264..57d166d3e3 100644 --- a/Resources/Prototypes/Traits/inconveniences.yml +++ b/Resources/Prototypes/Traits/inconveniences.yml @@ -17,9 +17,11 @@ species: - Dwarf - IPC - components: - - type: LightweightDrunk - boozeStrengthMultiplier: 2 + functions: + - !type:TraitAddComponent + components: + - type: LightweightDrunk + boozeStrengthMultiplier: 2 - type: trait id: Stutter @@ -32,12 +34,14 @@ - MedicalBorg - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: StutteringAccent - matchRandomProb: 0.1 - fourRandomProb: 0 - threeRandomProb: 0 - cutRandomProb: 0 + functions: + - !type:TraitAddComponent + components: + - type: StutteringAccent + matchRandomProb: 0.1 + fourRandomProb: 0 + threeRandomProb: 0 + cutRandomProb: 0 - type: trait id: ForeignerLight @@ -48,10 +52,12 @@ inverted: true traits: - Foreigner - components: - - type: ForeignerTrait - cantUnderstand: false # Allows to understand - baseTranslator: TranslatorForeigner + functions: + - !type:TraitAddComponent + components: + - type: ForeignerTrait + cantUnderstand: false + baseTranslator: TranslatorForeigner - type: trait id: Foreigner @@ -62,6 +68,8 @@ inverted: true traits: - ForeignerLight - components: - - type: ForeignerTrait - baseTranslator: TranslatorForeigner + functions: + - !type:TraitAddComponent + components: + - type: ForeignerTrait + baseTranslator: TranslatorForeigner diff --git a/Resources/Prototypes/Traits/languages.yml b/Resources/Prototypes/Traits/languages.yml index 06b4890c11..a8bdeff468 100644 --- a/Resources/Prototypes/Traits/languages.yml +++ b/Resources/Prototypes/Traits/languages.yml @@ -5,10 +5,12 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsLanguagesBasic - languagesSpoken: - - Sign - languagesUnderstood: - - Sign + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - Sign + languagesUnderstood: + - Sign - type: trait id: SolCommon @@ -21,10 +23,12 @@ inverted: true species: - Human - languagesSpoken: - - SolCommon - languagesUnderstood: - - SolCommon + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - SolCommon + languagesUnderstood: + - SolCommon - type: trait id: Tradeband @@ -37,10 +41,12 @@ inverted: true species: - Harpy - languagesSpoken: - - Tradeband - languagesUnderstood: - - Tradeband + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - Tradeband + languagesUnderstood: + - Tradeband - type: trait id: Freespeak @@ -49,10 +55,12 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsLanguagesBasic - languagesSpoken: - - Freespeak - languagesUnderstood: - - Freespeak + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - Freespeak + languagesUnderstood: + - Freespeak - type: trait id: Elyran @@ -61,10 +69,12 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsLanguagesBasic - languagesSpoken: - - Elyran - languagesUnderstood: - - Elyran + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - Elyran + languagesUnderstood: + - Elyran - type: trait id: ValyrianStandard @@ -73,10 +83,12 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsLanguagesBasic - languagesSpoken: - - ValyrianStandard - languagesUnderstood: - - ValyrianStandard + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - ValyrianStandard + languagesUnderstood: + - ValyrianStandard - type: trait id: Azaziba @@ -88,7 +100,9 @@ - Reptilian - !type:CharacterItemGroupRequirement group: TraitsLanguagesBasic - languagesSpoken: - - Azaziba - languagesUnderstood: - - Azaziba \ No newline at end of file + functions: + - !type:TraitModifyLanguages + languagesSpoken: + - Azaziba + languagesUnderstood: + - Azaziba diff --git a/Resources/Prototypes/Traits/mental.yml b/Resources/Prototypes/Traits/mental.yml index 70fbfd24b7..5b4fc56bf0 100644 --- a/Resources/Prototypes/Traits/mental.yml +++ b/Resources/Prototypes/Traits/mental.yml @@ -32,9 +32,11 @@ inverted: true traits: - LowPotential - components: - - type: PotentiaModifier - potentiaMultiplier: 1.25 + functions: + - !type:TraitReplaceComponent + components: + - type: PotentiaModifier + potentiaMultiplier: 1.25 - type: trait id: LowPotential @@ -70,9 +72,11 @@ inverted: true traits: - HighPotential - components: - - type: PotentiaModifier - potentiaMultiplier: 0.75 + functions: + - !type:TraitReplaceComponent + components: + - type: PotentiaModifier + potentiaMultiplier: 0.75 - type: trait id: LowAmplification @@ -110,8 +114,10 @@ traits: - HighAmplification - PowerOverwhelming - psionicPowers: - - LowAmplification + functions: + - !type:TraitAddPsionics + psionicPowers: + - LowAmplification - type: trait id: HighAmplification @@ -149,8 +155,10 @@ traits: - LowAmplification - PowerOverwhelming - psionicPowers: - - HighAmplification + functions: + - !type:TraitAddPsionics + psionicPowers: + - HighAmplification - type: trait id: PowerOverwhelming @@ -188,8 +196,10 @@ traits: - LowAmplification - HighAmplification - psionicPowers: - - PowerOverwhelming + functions: + - !type:TraitAddPsionics + psionicPowers: + - PowerOverwhelming - type: trait id: LowDampening @@ -226,8 +236,10 @@ inverted: true traits: - HighDampening - psionicPowers: - - LowDampening + functions: + - !type:TraitAddPsionics + psionicPowers: + - LowDampening - type: trait id: HighDampening @@ -264,5 +276,7 @@ inverted: true traits: - LowDampening - psionicPowers: - - HighDampening + functions: + - !type:TraitAddPsionics + psionicPowers: + - HighDampening diff --git a/Resources/Prototypes/Traits/neutral.yml b/Resources/Prototypes/Traits/neutral.yml index 3b63c930e8..8ea7006c0c 100644 --- a/Resources/Prototypes/Traits/neutral.yml +++ b/Resources/Prototypes/Traits/neutral.yml @@ -4,8 +4,10 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: PirateAccent + functions: + - !type:TraitAddComponent + components: + - type: PirateAccent - type: trait id: Accentless @@ -19,13 +21,15 @@ - MedicalBorg - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: Accentless - removes: - - type: LizardAccent - - type: MothAccent - - type: ReplacementAccent - accent: dwarf + functions: + - !type:TraitAddComponent + components: + - type: Accentless + removes: + - type: LizardAccent + - type: MothAccent + - type: ReplacementAccent + accent: dwarf - type: trait id: Southern @@ -33,8 +37,10 @@ requirements: - !type:CharacterItemGroupRequirement group: TraitsAccents - components: - - type: SouthernAccent + functions: + - !type:TraitAddComponent + components: + - type: SouthernAccent - type: trait id: NormalVision @@ -44,9 +50,11 @@ species: - Harpy - Vulpkanin - componentRemovals: - - UltraVision - - DogVision + functions: + - !type:TraitRemoveComponent + components: + - type: UltraVision + - type: DogVision - type: trait id: Saturnine @@ -62,8 +70,10 @@ inverted: true traits: - Sanguine - moodEffects: - - TraitSaturnine + functions: + - !type:TraitAddMoodlets + moodEffects: + - TraitSaturnine - type: trait id: Sanguine @@ -79,8 +89,10 @@ inverted: true traits: - Saturnine - moodEffects: - - TraitSanguine + functions: + - !type:TraitAddMoodlets + moodEffects: + - TraitSanguine - type: trait id: AddictionNicotine @@ -96,13 +108,17 @@ inverted: true species: - IPC - moodEffects: - - NicotineWithdrawal + functions: + - !type:TraitAddMoodlets + moodEffects: + - NicotineWithdrawal - type: trait id: Liar category: Mental - components: - - type: ReplacementAccent - replacementChance: 0.15 - accent: liar + functions: + - !type:TraitAddComponent + components: + - type: ReplacementAccent + replacementChance: 0.15 + accent: liar diff --git a/Resources/Prototypes/Traits/physical.yml b/Resources/Prototypes/Traits/physical.yml index 0d4b6f6f1b..4ff9aaf88e 100644 --- a/Resources/Prototypes/Traits/physical.yml +++ b/Resources/Prototypes/Traits/physical.yml @@ -16,9 +16,11 @@ inverted: true traits: - WillToDie - components: - - type: DeadModifier - deadThresholdModifier: 10 + functions: + - !type:TraitReplaceComponent + components: + - type: DeadModifier + deadThresholdModifier: 10 - type: trait id: WillToDie @@ -38,9 +40,11 @@ inverted: true traits: - WillToLive - components: - - type: DeadModifier - deadThresholdModifier: -15 + functions: + - !type:TraitReplaceComponent + components: + - type: DeadModifier + deadThresholdModifier: -15 - type: trait id: Tenacity @@ -60,9 +64,11 @@ inverted: true traits: - GlassJaw - components: - - type: CritModifier - critThresholdModifier: 5 + functions: + - !type:TraitReplaceComponent + components: + - type: CritModifier + critThresholdModifier: 5 - type: trait id: GlassJaw @@ -82,9 +88,11 @@ inverted: true traits: - Tenacity - components: - - type: CritModifier - critThresholdModifier: -10 + functions: + - !type:TraitReplaceComponent + components: + - type: CritModifier + critThresholdModifier: -10 - type: trait id: Vigor @@ -105,9 +113,11 @@ species: - Oni - IPC - components: - - type: StaminaCritModifier - critThresholdModifier: 10 + functions: + - !type:TraitReplaceComponent + components: + - type: StaminaCritModifier + critThresholdModifier: 10 - type: trait id: Lethargy @@ -127,9 +137,11 @@ inverted: true species: - Felinid - components: - - type: StaminaCritModifier - critThresholdModifier: -15 + functions: + - !type:TraitReplaceComponent + components: + - type: StaminaCritModifier + critThresholdModifier: -15 - type: trait id: HighAdrenaline @@ -149,10 +161,12 @@ inverted: true traits: - AdrenalDysfunction - components: - - type: Adrenaline - rangeModifier: 0.4 - inverse: true + functions: + - !type:TraitReplaceComponent + components: + - type: Adrenaline + rangeModifier: 0.4 + inverse: true - type: trait id: AdrenalDysfunction @@ -172,9 +186,11 @@ inverted: true traits: - HighAdrenaline - components: - - type: Adrenaline - rangeModifier: 0.8 + functions: + - !type:TraitReplaceComponent + components: + - type: Adrenaline + rangeModifier: 0.8 - type: trait id: Masochism @@ -190,10 +206,12 @@ inverted: true traits: - LowPainTolerance - components: - - type: PainTolerance - rangeModifier: 0.4 - inverse: true + functions: + - !type:TraitReplaceComponent + components: + - type: PainTolerance + rangeModifier: 0.4 + inverse: true - type: trait id: LowPainTolerance @@ -209,9 +227,11 @@ inverted: true traits: - Masochism - components: - - type: PainTolerance - rangeModifier: 0.6 + functions: + - !type:TraitReplaceComponent + components: + - type: PainTolerance + rangeModifier: 0.6 - type: trait id: MartialArtist @@ -224,13 +244,15 @@ - Borg - MedicalBorg - Boxer - components: - - type: Boxer - modifiers: - coefficients: - Blunt: 1.5 - Slash: 1.5 - Piercing: 1.5 + functions: + - !type:TraitReplaceComponent + components: + - type: Boxer + modifiers: + coefficients: + Blunt: 1.5 + Slash: 1.5 + Piercing: 1.5 - type: trait id: Small @@ -245,13 +267,15 @@ max: 150 - !type:CharacterWidthRequirement max: 32 - components: - - type: PseudoItem - storedOffset: 0,17 - shape: - - 0,0,1,4 - - 0,2,3,4 - - 4,0,5,4 + functions: + - !type:TraitAddComponent + components: + - type: PseudoItem + storedOffset: 0,17 + shape: + - 0,0,1,4 + - 0,2,3,4 + - 4,0,5,4 - type: trait id: TemperatureTolerance @@ -262,9 +286,11 @@ inverted: true species: - Vulpkanin # This trait functions exactly as-is for the Vulpkanin trait. - components: - - type: TemperatureProtection - coefficient: 0.1 # Enough resistance to walk into the chef's freezer, or tolerate daytime temperatures on Glacier without a jacket. + functions: + - !type:TraitReplaceComponent + components: + - type: TemperatureProtection + coefficient: 0.1 # Enough resistance to walk into the chef's freezer, or tolerate daytime temperatures on Glacier without a jacket. # These traits largely exist to demonstrate more of the "Component Removals" functionality. This way contributors # can get used to seeing that they can "Remove and Replace" a pre-existing component. @@ -283,17 +309,17 @@ inverted: true traits: - Claws - componentRemovals: - - MeleeWeapon # Remove the original innate melee attack, so that it can be replaced with a new one. - components: - - type: MeleeWeapon - soundHit: - collection: AlienClaw - animation: WeaponArcClaw - damage: - types: - Piercing: 5 # No, this isn't "OP", this is literally the worst brute damage type in the game. - # Same deal as Slash, except that a majority of all armor provides Piercing resistance. + functions: + - !type:TraitReplaceComponent + components: + - type: MeleeWeapon + soundHit: + collection: AlienClaw + animation: WeaponArcClaw + damage: + types: + Piercing: 5 # No, this isn't "OP", this is literally the worst brute damage type in the game. + # Same deal as Slash, except that a majority of all armor provides Piercing resistance. - type: trait id: Claws @@ -311,18 +337,18 @@ inverted: true traits: - Talons - componentRemovals: - - MeleeWeapon # Remove the original innate melee attack, so that it can be replaced with a new one. - components: - - type: MeleeWeapon - soundHit: - collection: AlienClaw - angle: 30 - animation: WeaponArcClaw - damage: - types: - Slash: 5 # Trade stamina damage on hit for a very minor amount of extra bleed. - # Blunt also deals bleed damage, so this is more of a sidegrade. + functions: + - !type:TraitReplaceComponent + components: + - type: MeleeWeapon + soundHit: + collection: AlienClaw + angle: 30 + animation: WeaponArcClaw + damage: + types: + Slash: 5 # Trade stamina damage on hit for a very minor amount of extra bleed. + # Blunt also deals bleed damage, so this is more of a sidegrade. - type: trait id: NaturalWeaponRemoval @@ -340,17 +366,17 @@ traits: - Talons - Claws - componentRemovals: - - MeleeWeapon # Remove the original innate melee attack, so that it can be replaced with a new one. - components: - - type: MeleeWeapon - soundHit: - collection: Punch - angle: 30 - animation: WeaponArcFist - damage: - types: - Blunt: 5 + functions: + - !type:TraitReplaceComponent + components: + - type: MeleeWeapon + soundHit: + collection: Punch + angle: 30 + animation: WeaponArcFist + damage: + types: + Blunt: 5 - type: trait id: StrikingCalluses @@ -378,17 +404,17 @@ - !type:CharacterJobRequirement jobs: - Boxer - componentRemovals: - - MeleeWeapon - components: - - type: MeleeWeapon - soundHit: - collection: Punch - angle: 30 - animation: WeaponArcFist - damage: - types: - Blunt: 6 + functions: + - !type:TraitReplaceComponent + components: + - type: MeleeWeapon + soundHit: + collection: Punch + angle: 30 + animation: WeaponArcFist + damage: + types: + Blunt: 6 - type: trait id: Spinarette @@ -406,12 +432,14 @@ - Arachne - Shadowkin - IPC - components: - - type: Sericulture - action: ActionSericulture - productionLength: 2 - entityProduced: MaterialWebSilk1 - hungerCost: 4 + functions: + - !type:TraitAddComponent + components: + - type: Sericulture + action: ActionSericulture + productionLength: 2 + entityProduced: MaterialWebSilk1 + hungerCost: 4 - type: trait id: BionicArm @@ -422,10 +450,12 @@ inverted: true jobs: - Prisoner # Bionics should be "Confiscated" from long term prisoners. - components: - - type: Prying - speedModifier: 1 - pryPowered: true + functions: + - !type:TraitAddComponent + components: + - type: Prying + speedModifier: 1 + pryPowered: true - type: trait id: PlateletFactories @@ -440,21 +470,21 @@ inverted: true species: - IPC - componentRemovals: - - PassiveDamage - components: - - type: PassiveDamage - allowedStates: - - Alive - - Critical - damageCap: 200 - damage: - groups: - Brute: -0.07 - Burn: -0.07 - Airloss: -0.07 - Toxin: -0.07 - Genetic: -0.07 + functions: # TODO: Code Platelet factories as an actual obtainable implant, and replace this with TraitAddImplant + - !type:TraitReplaceComponent + components: + - type: PassiveDamage + allowedStates: + - Alive + - Critical + damageCap: 200 + damage: + groups: + Brute: -0.07 + Burn: -0.07 + Airloss: -0.07 + Toxin: -0.07 + Genetic: -0.07 - type: trait id: DermalArmor @@ -468,11 +498,11 @@ - !type:CharacterSpeciesRequirement species: - Human - componentRemovals: - - Damageable - components: - - type: Damageable - damageModifierSet: DermalArmor + functions: + - !type:TraitReplaceComponent + components: + - type: Damageable + damageModifierSet: DermalArmor - type: trait id: CyberEyes @@ -489,12 +519,15 @@ - Photophobia - Blindness - Nearsighted - componentRemovals: - - Flashable - components: - - type: FlashImmunity - - type: EyeProtection - - type: CyberEyes + functions: + - !type:TraitRemoveComponent + components: + - type: Flashable + - !type:TraitAddComponent + components: + - type: FlashImmunity + - type: EyeProtection + - type: CyberEyes - type: trait id: CyberEyesSecurity @@ -515,10 +548,12 @@ inverted: true traits: - CyberEyesOmni - components: - - type: ShowJobIcons - - type: ShowMindShieldIcons - - type: ShowCriminalRecordIcons + functions: + - !type:TraitAddComponent + components: + - type: ShowJobIcons + - type: ShowMindShieldIcons + - type: ShowCriminalRecordIcons - type: trait id: CyberEyesMedical @@ -537,13 +572,15 @@ traits: - CyberEyesDiagnostic - CyberEyesOmni - components: - - type: ShowHealthBars - damageContainers: - - Biological - - type: ShowHealthIcons - damageContainers: - - Biological + functions: + - !type:TraitAddComponent + components: + - type: ShowHealthBars + damageContainers: + - Biological + - type: ShowHealthIcons + damageContainers: + - Biological - type: trait id: CyberEyesDiagnostic @@ -562,11 +599,13 @@ traits: - CyberEyesMedical - CyberEyesOmni - components: - - type: ShowHealthBars - damageContainers: - - Inorganic - - Silicon + functions: + - !type:TraitAddComponent + components: + - type: ShowHealthBars + damageContainers: + - Inorganic + - Silicon - type: trait id: CyberEyesOmni @@ -589,18 +628,20 @@ - CyberEyesMedical - CyberEyesDiagnostic - CyberEyesSecurity - components: - - type: ShowJobIcons - - type: ShowMindShieldIcons - - type: ShowCriminalRecordIcons - - type: ShowHealthIcons - damageContainers: - - Biological - - type: ShowHealthBars - damageContainers: - - Biological - - Inorganic - - Silicon + functions: + - !type:TraitAddComponent + components: + - type: ShowJobIcons + - type: ShowMindShieldIcons + - type: ShowCriminalRecordIcons + - type: ShowHealthIcons + damageContainers: + - Biological + - type: ShowHealthBars + damageContainers: + - Biological + - Inorganic + - Silicon - type: trait id: Mk3LoyaltyImplant diff --git a/Resources/Prototypes/Traits/skills.yml b/Resources/Prototypes/Traits/skills.yml index fb0c6d4fc9..2306d254ed 100644 --- a/Resources/Prototypes/Traits/skills.yml +++ b/Resources/Prototypes/Traits/skills.yml @@ -2,8 +2,10 @@ id: CPRTraining category: Mental points: -4 - components: - - type: CPRTraining + functions: + - !type:TraitAddComponent + components: + - type: CPRTraining requirements: - !type:CharacterJobRequirement inverted: true @@ -19,19 +21,21 @@ id: SelfAware category: Mental points: -4 - components: - - type: SelfAware - analyzableTypes: - - Blunt - - Slash - - Piercing - - Heat - - Shock - - Cold - - Caustic - detectableGroups: - - Airloss - - Toxin + functions: + - !type:TraitAddComponent + components: + - type: SelfAware + analyzableTypes: + - Blunt + - Slash + - Piercing + - Heat + - Shock + - Cold + - Caustic + detectableGroups: + - Airloss + - Toxin - type: trait id: HeavyweightDrunk @@ -53,9 +57,11 @@ species: - Dwarf - IPC - components: - - type: LightweightDrunk - boozeStrengthMultiplier: 0.5 + functions: + - !type:TraitReplaceComponent + components: + - type: LightweightDrunk + boozeStrengthMultiplier: 0.5 - type: trait id: LiquorLifeline @@ -77,21 +83,25 @@ species: - Dwarf - IPC - components: - - type: LiquorLifeline - - type: LightweightDrunk - boozeStrengthMultiplier: 0.5 + functions: + - !type:TraitReplaceComponent + components: + - type: LiquorLifeline + - type: LightweightDrunk + boozeStrengthMultiplier: 0.5 - type: trait id: Thieving category: Physical points: -8 - components: - - type: Thieving - ignoreStripHidden: true - stealth: Subtle - stripTimeReduction: 0 - stripTimeMultiplier: 0.667 + functions: + - !type:TraitReplaceComponent + components: + - type: Thieving + ignoreStripHidden: true + stealth: Subtle + stripTimeReduction: 0 + stripTimeMultiplier: 0.667 requirements: - !type:CharacterSpeciesRequirement inverted: true @@ -102,10 +112,12 @@ id: Voracious category: Physical points: -2 - components: - - type: ConsumeDelayModifier - foodDelayMultiplier: 0.5 - drinkDelayMultiplier: 0.5 + functions: + - !type:TraitReplaceComponent + components: + - type: ConsumeDelayModifier + foodDelayMultiplier: 0.5 + drinkDelayMultiplier: 0.5 requirements: - !type:CharacterSpeciesRequirement inverted: true @@ -127,21 +139,25 @@ inverted: true species: - Diona - components: - - type: ClimbDelayModifier - climbDelayMultiplier: 0.35 - - type: LayingDownModifier - layingDownCooldownMultiplier: 0.5 - downedSpeedMultiplierMultiplier: 1.65 + functions: + - !type:TraitReplaceComponent + components: + - type: ClimbDelayModifier + climbDelayMultiplier: 0.35 + - type: LayingDownModifier + layingDownCooldownMultiplier: 0.5 + downedSpeedMultiplierMultiplier: 1.65 - type: trait id: LightStep category: Auditory points: -2 - components: - - type: FootstepVolumeModifier - sprintVolumeModifier: -10 - walkVolumeModifier: -10 + functions: + - !type:TraitReplaceComponent + components: + - type: FootstepVolumeModifier + sprintVolumeModifier: -10 + walkVolumeModifier: -10 requirements: - !type:CharacterSpeciesRequirement inverted: true @@ -157,16 +173,20 @@ inverted: true species: - Harpy - components: - - type: Singer - proto: NormalSinger + functions: + - !type:TraitAddComponent + components: + - type: Singer + proto: NormalSinger - type: trait id: LatentPsychic category: Mental points: -4 - components: - - type: Psionic + functions: + - !type:TraitAddComponent + components: + - type: Psionic requirements: - !type:CharacterJobRequirement inverted: true @@ -201,9 +221,11 @@ id: PsionicInsulation category: Mental points: -10 #Buy a significant disability to get this. - components: - - type: PsionicInsulation - - type: Mindbroken + functions: + - !type:TraitAddComponent + components: + - type: PsionicInsulation + - type: Mindbroken requirements: - !type:CharacterJobRequirement inverted: true @@ -238,8 +260,10 @@ id: NaturalTelepath category: Mental points: -2 - psionicPowers: - - TelepathyPower + functions: + - !type:TraitAddPsionics + psionicPowers: + - TelepathyPower requirements: - !type:CharacterJobRequirement inverted: true @@ -275,14 +299,16 @@ id: TrapAvoider category: Physical points: -3 - components: - - type: StepTriggerImmune - whitelist: - types: - - Shard - - Landmine - - Mousetrap - - SlipEntity + functions: + - !type:TraitAddComponent + components: + - type: StepTriggerImmune + whitelist: + types: + - Shard + - Landmine + - Mousetrap + - SlipEntity requirements: - !type:CharacterSpeciesRequirement inverted: true @@ -294,8 +320,10 @@ id: AnomalousPositronics category: Mental points: -4 - componentRemovals: - - PsionicInsulation + functions: + - !type:TraitRemoveComponent + components: + - type: PsionicInsulation requirements: - !type:CharacterSpeciesRequirement species: @@ -305,5 +333,7 @@ id: AnimalFriend category: Mental points: -4 - addFactions: - - AnimalFriend + functions: + - !type:TraitModifyFactions + addFactions: + - AnimalFriend diff --git a/Resources/Prototypes/Traits/species.yml b/Resources/Prototypes/Traits/species.yml index 17be3489fe..a3e29b3728 100644 --- a/Resources/Prototypes/Traits/species.yml +++ b/Resources/Prototypes/Traits/species.yml @@ -2,13 +2,15 @@ id: Swashbuckler category: Physical points: -2 - components: - - type: OniDamageModifier - modifiers: - coefficients: - Blunt: 1.2 - Slash: 1.35 - Piercing: 1.2 + functions: + - !type:TraitReplaceComponent + components: + - type: OniDamageModifier + modifiers: + coefficients: + Blunt: 1.2 + Slash: 1.35 + Piercing: 1.2 requirements: - !type:CharacterSpeciesRequirement species: @@ -23,13 +25,15 @@ id: Spearmaster category: Physical points: -2 - components: - - type: OniDamageModifier - modifiers: - coefficients: - Blunt: 1.2 - Slash: 1.2 - Piercing: 1.35 + functions: + - !type:TraitReplaceComponent + components: + - type: OniDamageModifier + modifiers: + coefficients: + Blunt: 1.2 + Slash: 1.2 + Piercing: 1.35 requirements: - !type:CharacterSpeciesRequirement species: @@ -44,13 +48,15 @@ id: WeaponsGeneralist category: Physical points: -2 - components: - - type: OniDamageModifier - modifiers: - coefficients: - Blunt: 1.25 - Slash: 1.25 - Piercing: 1.25 + functions: + - !type:TraitReplaceComponent + components: + - type: OniDamageModifier + modifiers: + coefficients: + Blunt: 1.25 + Slash: 1.25 + Piercing: 1.25 requirements: - !type:CharacterSpeciesRequirement species: @@ -65,12 +71,12 @@ id: ShadowkinBlackeye category: Mental points: 4 - componentRemovals: - - Shadowkin - components: - - type: Shadowkin - blackeyeSpawn: true + functions: + - !type:TraitReplaceComponent + components: + - type: Shadowkin + blackeyeSpawn: true requirements: - !type:CharacterSpeciesRequirement species: - - Shadowkin \ No newline at end of file + - Shadowkin diff --git a/Resources/Prototypes/_White/Store/categories.yml b/Resources/Prototypes/_White/Store/categories.yml deleted file mode 100644 index cb9cfbc88f..0000000000 --- a/Resources/Prototypes/_White/Store/categories.yml +++ /dev/null @@ -1,4 +0,0 @@ -- type: storeCategory - id: UplinkSales - name: Sales - priority: 10 diff --git a/Resources/Textures/Effects/footprints.rsi/dragging-1.png b/Resources/Textures/Effects/footprints.rsi/dragging-1.png new file mode 100644 index 0000000000..74d2aeb074 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/dragging-1.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/dragging-2.png b/Resources/Textures/Effects/footprints.rsi/dragging-2.png new file mode 100644 index 0000000000..cc45f4f8ae Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/dragging-2.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/dragging-3.png b/Resources/Textures/Effects/footprints.rsi/dragging-3.png new file mode 100644 index 0000000000..d0f7274dd3 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/dragging-3.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/dragging-4.png b/Resources/Textures/Effects/footprints.rsi/dragging-4.png new file mode 100644 index 0000000000..5eb34b5d57 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/dragging-4.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/dragging-5.png b/Resources/Textures/Effects/footprints.rsi/dragging-5.png new file mode 100644 index 0000000000..6b1b34d145 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/dragging-5.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/dragging-test.png b/Resources/Textures/Effects/footprints.rsi/dragging-test.png new file mode 100644 index 0000000000..b8c9ba50a7 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/dragging-test.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-diona.png b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-diona.png new file mode 100644 index 0000000000..fa40e0f297 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-diona.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-dwarf.png b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-dwarf.png new file mode 100644 index 0000000000..43b88aa164 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-dwarf.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-human.png b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-human.png new file mode 100644 index 0000000000..f7ab3257c5 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-human.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-lizard.png b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-lizard.png new file mode 100644 index 0000000000..e53ba99227 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-lizard.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-slime.png b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-slime.png new file mode 100644 index 0000000000..87561cb161 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-slime.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-spider.png b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-spider.png new file mode 100644 index 0000000000..4939e72c4b Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-left-bare-spider.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-diona.png b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-diona.png new file mode 100644 index 0000000000..21f3a11774 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-diona.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-dwarf.png b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-dwarf.png new file mode 100644 index 0000000000..e493ddbdf6 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-dwarf.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-human.png b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-human.png new file mode 100644 index 0000000000..4de70b5c1e Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-human.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-lizard.png b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-lizard.png new file mode 100644 index 0000000000..e53ba99227 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-lizard.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-slime.png b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-slime.png new file mode 100644 index 0000000000..c10fe24f0b Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-slime.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-spider.png b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-spider.png new file mode 100644 index 0000000000..e9f3a88776 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-right-bare-spider.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-shoes.png b/Resources/Textures/Effects/footprints.rsi/footprint-shoes.png new file mode 100644 index 0000000000..6cf329a9b6 Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-shoes.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/footprint-suit.png b/Resources/Textures/Effects/footprints.rsi/footprint-suit.png new file mode 100644 index 0000000000..6bc32d343c Binary files /dev/null and b/Resources/Textures/Effects/footprints.rsi/footprint-suit.png differ diff --git a/Resources/Textures/Effects/footprints.rsi/meta.json b/Resources/Textures/Effects/footprints.rsi/meta.json new file mode 100644 index 0000000000..0ce2e096ac --- /dev/null +++ b/Resources/Textures/Effects/footprints.rsi/meta.json @@ -0,0 +1,71 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "IMPERIAL SPACE", + "states": [ + { + "name": "footprint-left-bare-diona" + }, + { + "name": "footprint-left-bare-dwarf" + }, + { + "name": "footprint-left-bare-human" + }, + { + "name": "footprint-left-bare-lizard" + }, + { + "name": "footprint-left-bare-slime" + }, + { + "name": "footprint-left-bare-spider" + }, + { + "name": "footprint-right-bare-diona" + }, + { + "name": "footprint-right-bare-dwarf" + }, + { + "name": "footprint-right-bare-human" + }, + { + "name": "footprint-right-bare-lizard" + }, + { + "name": "footprint-right-bare-slime" + }, + { + "name": "footprint-right-bare-spider" + }, + { + "name": "footprint-shoes" + }, + { + "name": "footprint-suit" + }, + { + "name": "dragging-1" + }, + { + "name": "dragging-2" + }, + { + "name": "dragging-3" + }, + { + "name": "dragging-4" + }, + { + "name": "dragging-5" + }, + { + "name": "dragging-test" + } + ] +} diff --git a/Resources/Textures/Interface/Misc/health_analyzer_out_of_range.png b/Resources/Textures/Interface/Misc/health_analyzer_out_of_range.png new file mode 100644 index 0000000000..8a76b0e83f Binary files /dev/null and b/Resources/Textures/Interface/Misc/health_analyzer_out_of_range.png differ diff --git a/RobustToolbox b/RobustToolbox index ec794ce4e4..a9aea7027f 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit ec794ce4e4693069d3b3ebf7a88ead5ff2f860e0 +Subproject commit a9aea7027f1840c83bcaf1c973caf099745f9eed diff --git a/SpaceStation14.sln.DotSettings b/SpaceStation14.sln.DotSettings index 15424a68ec..156e5d2701 100644 --- a/SpaceStation14.sln.DotSettings +++ b/SpaceStation14.sln.DotSettings @@ -655,6 +655,7 @@ public sealed partial class $CLASS$ : Shared$CLASS$ { True True True + True True True True