From d7eb3bfb4492c86d505ffe013fc62a7db7a89eec Mon Sep 17 00:00:00 2001 From: c4llv07e <38111072+c4llv07e@users.noreply.github.com> Date: Mon, 14 Aug 2023 12:06:21 +0000 Subject: [PATCH 01/32] Pipe painter (now with airlock painter) (#19031) * Add a pipe painting function to the airlock painter Signed-off-by: c4llv07e * Rename engineer painter to omnipainter Signed-off-by: c4llv07e * review changes Signed-off-by: c4llv07e * fix migration duplicate Signed-off-by: c4llv07e --------- Signed-off-by: c4llv07e --- .../AirlockPainter/AirlockPainterSystem.cs | 54 ------ .../UI/AirlockPainterBoundUserInterface.cs | 53 ----- .../UI/AirlockPainterWindow.xaml | 14 -- .../UI/AirlockPainterWindow.xaml.cs | 39 ---- .../SprayPainter/SprayPainterSystem.cs | 53 +++++ .../UI/SprayPainterBoundUserInterface.cs | 69 +++++++ .../SprayPainter/UI/SprayPainterWindow.xaml | 34 ++++ .../UI/SprayPainterWindow.xaml.cs | 96 +++++++++ .../AirlockPainter/AirlockPainterComponent.cs | 19 -- .../AirlockPainter/AirlockPainterSystem.cs | 118 ------------ .../SprayPainter/SprayPainterComponent.cs | 28 +++ .../SprayPainter/SprayPainterSystem.cs | 182 ++++++++++++++++++ .../AirlockPainter/AirlockPainterEvents.cs | 51 ----- .../Components/PaintableAirlockComponent.cs | 12 -- .../Prototypes/AirlockGroupPrototype.cs | 20 -- .../SharedAirlockPainterSystem.cs | 30 --- .../Components/PaintableAirlockComponent.cs | 11 ++ .../Prototypes/AirlockGroupPrototype.cs | 19 ++ .../SprayPainter/SharedDevicePainterSystem.cs | 29 +++ .../SprayPainter/SprayPainterEvents.cs | 69 +++++++ .../en-US/airlock-painter/airlock-painter.ftl | 3 - .../engineer-painter/engineer-painter.ftl | 14 ++ Resources/Maps/aspid.yml | 2 +- Resources/Maps/fland.yml | 2 +- Resources/Maps/kettle.yml | 2 +- .../Catalog/Fills/Lockers/engineer.yml | 2 +- .../VendingMachines/Inventories/youtool.yml | 2 +- .../Entities/Clothing/Belt/belts.yml | 4 +- .../Markers/Spawners/Random/maintenance.yml | 2 +- .../Objects/Tools/airlock_painter.yml | 21 -- .../Entities/Objects/Tools/spray_painter.yml | 30 +++ .../Entities/Structures/Machines/lathe.yml | 2 +- Resources/Prototypes/Recipes/Lathes/tools.yml | 4 +- .../meta.json | 2 +- .../spray_painter.png} | Bin Resources/migration.yml | 3 + 36 files changed, 649 insertions(+), 446 deletions(-) delete mode 100644 Content.Client/AirlockPainter/AirlockPainterSystem.cs delete mode 100644 Content.Client/AirlockPainter/UI/AirlockPainterBoundUserInterface.cs delete mode 100644 Content.Client/AirlockPainter/UI/AirlockPainterWindow.xaml delete mode 100644 Content.Client/AirlockPainter/UI/AirlockPainterWindow.xaml.cs create mode 100644 Content.Client/SprayPainter/SprayPainterSystem.cs create mode 100644 Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs create mode 100644 Content.Client/SprayPainter/UI/SprayPainterWindow.xaml create mode 100644 Content.Client/SprayPainter/UI/SprayPainterWindow.xaml.cs delete mode 100644 Content.Server/AirlockPainter/AirlockPainterComponent.cs delete mode 100644 Content.Server/AirlockPainter/AirlockPainterSystem.cs create mode 100644 Content.Server/SprayPainter/SprayPainterComponent.cs create mode 100644 Content.Server/SprayPainter/SprayPainterSystem.cs delete mode 100644 Content.Shared/AirlockPainter/AirlockPainterEvents.cs delete mode 100644 Content.Shared/AirlockPainter/Components/PaintableAirlockComponent.cs delete mode 100644 Content.Shared/AirlockPainter/Prototypes/AirlockGroupPrototype.cs delete mode 100644 Content.Shared/AirlockPainter/SharedAirlockPainterSystem.cs create mode 100644 Content.Shared/SprayPainter/Components/PaintableAirlockComponent.cs create mode 100644 Content.Shared/SprayPainter/Prototypes/AirlockGroupPrototype.cs create mode 100644 Content.Shared/SprayPainter/SharedDevicePainterSystem.cs create mode 100644 Content.Shared/SprayPainter/SprayPainterEvents.cs delete mode 100644 Resources/Locale/en-US/airlock-painter/airlock-painter.ftl create mode 100644 Resources/Locale/en-US/engineer-painter/engineer-painter.ftl delete mode 100644 Resources/Prototypes/Entities/Objects/Tools/airlock_painter.yml create mode 100644 Resources/Prototypes/Entities/Objects/Tools/spray_painter.yml rename Resources/Textures/Objects/Tools/{airlock_painter.rsi => spray_painter.rsi}/meta.json (87%) rename Resources/Textures/Objects/Tools/{airlock_painter.rsi/airlock_painter.png => spray_painter.rsi/spray_painter.png} (100%) diff --git a/Content.Client/AirlockPainter/AirlockPainterSystem.cs b/Content.Client/AirlockPainter/AirlockPainterSystem.cs deleted file mode 100644 index b0ee4a970da4b9..00000000000000 --- a/Content.Client/AirlockPainter/AirlockPainterSystem.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Content.Shared.AirlockPainter; -using Robust.Client.Graphics; -using Robust.Client.ResourceManagement; -using Robust.Shared.Utility; -using System.Linq; -using Robust.Shared.Serialization.TypeSerializers.Implementations; - -namespace Content.Client.AirlockPainter -{ - public sealed class AirlockPainterSystem : SharedAirlockPainterSystem - { - [Dependency] private readonly IResourceCache _resourceCache = default!; - - public List Entries { get; private set; } = new(); - - public override void Initialize() - { - base.Initialize(); - - foreach (string style in Styles) - { - string? iconPath = Groups - .FindAll(x => x.StylePaths.ContainsKey(style))? - .MaxBy(x => x.IconPriority)?.StylePaths[style]; - if (iconPath == null) - { - Entries.Add(new AirlockPainterEntry(style, null)); - continue; - } - - RSIResource doorRsi = _resourceCache.GetResource(SpriteSpecifierSerializer.TextureRoot / new ResPath(iconPath)); - if (!doorRsi.RSI.TryGetState("closed", out var icon)) - { - Entries.Add(new AirlockPainterEntry(style, null)); - continue; - } - - Entries.Add(new AirlockPainterEntry(style, icon.Frame0)); - } - } - } - - public sealed class AirlockPainterEntry - { - public string Name; - public Texture? Icon; - - public AirlockPainterEntry(string name, Texture? icon) - { - Name = name; - Icon = icon; - } - } -} diff --git a/Content.Client/AirlockPainter/UI/AirlockPainterBoundUserInterface.cs b/Content.Client/AirlockPainter/UI/AirlockPainterBoundUserInterface.cs deleted file mode 100644 index 019718c7b55edf..00000000000000 --- a/Content.Client/AirlockPainter/UI/AirlockPainterBoundUserInterface.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Content.Shared.AirlockPainter; -using Robust.Client.GameObjects; -using Robust.Client.UserInterface.Controls; - -namespace Content.Client.AirlockPainter.UI -{ - public sealed class AirlockPainterBoundUserInterface : BoundUserInterface - { - [ViewVariables] - private AirlockPainterWindow? _window; - - [ViewVariables] - private AirlockPainterSystem? _painter; - - public AirlockPainterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) - { - } - - protected override void Open() - { - base.Open(); - - _window = new AirlockPainterWindow(); - - _painter = EntMan.System(); - - _window.OpenCentered(); - _window.OnClose += Close; - _window.OnSpritePicked = OnSpritePicked; - } - - protected override void UpdateState(BoundUserInterfaceState state) - { - base.UpdateState(state); - - if (_window == null) - return; - - if (_painter == null) - return; - - if (state is not AirlockPainterBoundUserInterfaceState stateCast) - return; - - _window.Populate(_painter.Entries, stateCast.SelectedStyle); - } - - private void OnSpritePicked(ItemList.ItemListSelectedEventArgs args) - { - SendMessage(new AirlockPainterSpritePickedMessage(args.ItemIndex)); - } - } -} diff --git a/Content.Client/AirlockPainter/UI/AirlockPainterWindow.xaml b/Content.Client/AirlockPainter/UI/AirlockPainterWindow.xaml deleted file mode 100644 index 564eccb38fcc5d..00000000000000 --- a/Content.Client/AirlockPainter/UI/AirlockPainterWindow.xaml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - diff --git a/Content.Client/AirlockPainter/UI/AirlockPainterWindow.xaml.cs b/Content.Client/AirlockPainter/UI/AirlockPainterWindow.xaml.cs deleted file mode 100644 index 403b83e9e57cab..00000000000000 --- a/Content.Client/AirlockPainter/UI/AirlockPainterWindow.xaml.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Robust.Client.AutoGenerated; -using Robust.Client.UserInterface.Controls; -using Robust.Client.UserInterface.CustomControls; -using Robust.Client.UserInterface.XAML; - -namespace Content.Client.AirlockPainter.UI -{ - [GenerateTypedNameReferences] - public sealed partial class AirlockPainterWindow : DefaultWindow - { - public Action? OnSpritePicked; - - private List CurrentEntries = new List(); - - public AirlockPainterWindow() - { - RobustXamlLoader.Load(this); - } - - public void Populate(List entries, int selected) - { - // Only clear if the entries change. Otherwise the list would "jump" after selecting an item - if (!CurrentEntries.Equals(entries)) - { - CurrentEntries = entries; - SpriteList.Clear(); - foreach (var entry in entries) - { - SpriteList.AddItem(entry.Name, entry.Icon); - } - } - - // Disable event so we don't send a new event for pre-selected entry and end up in a loop - SpriteList.OnItemSelected -= OnSpritePicked; - SpriteList[selected].Selected = true; - SpriteList.OnItemSelected += OnSpritePicked; - } - } -} diff --git a/Content.Client/SprayPainter/SprayPainterSystem.cs b/Content.Client/SprayPainter/SprayPainterSystem.cs new file mode 100644 index 00000000000000..b625f4a667f3c3 --- /dev/null +++ b/Content.Client/SprayPainter/SprayPainterSystem.cs @@ -0,0 +1,53 @@ +using Content.Shared.SprayPainter; +using Robust.Client.Graphics; +using Robust.Client.ResourceManagement; +using Robust.Shared.Serialization.TypeSerializers.Implementations; +using Robust.Shared.Utility; +using System.Linq; + +namespace Content.Client.SprayPainter; + +public sealed class SprayPainterSystem : SharedSprayPainterSystem +{ + [Dependency] private readonly IResourceCache _resourceCache = default!; + + public List Entries { get; private set; } = new(); + + public override void Initialize() + { + base.Initialize(); + + foreach (string style in Styles) + { + string? iconPath = Groups + .FindAll(x => x.StylePaths.ContainsKey(style))? + .MaxBy(x => x.IconPriority)?.StylePaths[style]; + if (iconPath == null) + { + Entries.Add(new SprayPainterEntry(style, null)); + continue; + } + + RSIResource doorRsi = _resourceCache.GetResource(SpriteSpecifierSerializer.TextureRoot / new ResPath(iconPath)); + if (!doorRsi.RSI.TryGetState("closed", out var icon)) + { + Entries.Add(new SprayPainterEntry(style, null)); + continue; + } + + Entries.Add(new SprayPainterEntry(style, icon.Frame0)); + } + } +} + +public sealed class SprayPainterEntry +{ + public string Name; + public Texture? Icon; + + public SprayPainterEntry(string name, Texture? icon) + { + Name = name; + Icon = icon; + } +} diff --git a/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs b/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs new file mode 100644 index 00000000000000..d5c57a601f0005 --- /dev/null +++ b/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs @@ -0,0 +1,69 @@ +using Content.Shared.SprayPainter; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface.Controls; + +namespace Content.Client.SprayPainter.UI; + +public sealed class SprayPainterBoundUserInterface : BoundUserInterface +{ + [ViewVariables] + private SprayPainterWindow? _window; + + [ViewVariables] + private SprayPainterSystem? _painter; + + public SprayPainterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + } + + protected override void Open() + { + base.Open(); + + _window = new SprayPainterWindow(); + + _painter = EntMan.System(); + + _window.OpenCentered(); + _window.OnClose += Close; + _window.OnSpritePicked = OnSpritePicked; + _window.OnColorPicked = OnColorPicked; + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + _window?.Dispose(); + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + + if (_window == null) + return; + + if (_painter == null) + return; + + if (state is not SprayPainterBoundUserInterfaceState stateCast) + return; + + _window.Populate(_painter.Entries, + stateCast.SelectedStyle, + stateCast.SelectedColorKey, + stateCast.Palette); + } + + private void OnSpritePicked(ItemList.ItemListSelectedEventArgs args) + { + SendMessage(new SprayPainterSpritePickedMessage(args.ItemIndex)); + } + + private void OnColorPicked(ItemList.ItemListSelectedEventArgs args) + { + var key = _window?.IndexToColorKey(args.ItemIndex); + SendMessage(new SprayPainterColorPickedMessage(key)); + } +} diff --git a/Content.Client/SprayPainter/UI/SprayPainterWindow.xaml b/Content.Client/SprayPainter/UI/SprayPainterWindow.xaml new file mode 100644 index 00000000000000..13e500c46c8cfb --- /dev/null +++ b/Content.Client/SprayPainter/UI/SprayPainterWindow.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/Content.Client/SprayPainter/UI/SprayPainterWindow.xaml.cs b/Content.Client/SprayPainter/UI/SprayPainterWindow.xaml.cs new file mode 100644 index 00000000000000..e799775bc628a9 --- /dev/null +++ b/Content.Client/SprayPainter/UI/SprayPainterWindow.xaml.cs @@ -0,0 +1,96 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Utility; + +namespace Content.Client.SprayPainter.UI; + +[GenerateTypedNameReferences] +public sealed partial class SprayPainterWindow : DefaultWindow +{ + [Dependency] private readonly IEntitySystemManager _sysMan = default!; + private readonly SpriteSystem _spriteSystem; + + public Action? OnSpritePicked; + public Action? OnColorPicked; + public Dictionary ItemColorIndex = new(); + + private Dictionary currentPalette = new(); + private const string colorLocKeyPrefix = "pipe-painter-color-"; + private List CurrentEntries = new List(); + + private readonly SpriteSpecifier _colorEntryIconTexture = new SpriteSpecifier.Rsi( + new ResPath("Structures/Piping/Atmospherics/pipe.rsi"), + "pipeStraight"); + + public SprayPainterWindow() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + _spriteSystem = _sysMan.GetEntitySystem(); + } + + private static string GetColorLocString(string? colorKey) + { + if (string.IsNullOrEmpty(colorKey)) + return Loc.GetString("pipe-painter-no-color-selected"); + var locKey = colorLocKeyPrefix + colorKey; + + if (!Loc.TryGetString(locKey, out var locString)) + locString = colorKey; + + return locString; + } + + public string? IndexToColorKey(int index) + { + return (string?) ColorList[index].Metadata; + } + + public void Populate(List entries, int selectedStyle, string? selectedColorKey, Dictionary palette) + { + // Only clear if the entries change. Otherwise the list would "jump" after selecting an item + if (!CurrentEntries.Equals(entries)) + { + CurrentEntries = entries; + SpriteList.Clear(); + foreach (var entry in entries) + { + SpriteList.AddItem(entry.Name, entry.Icon); + } + } + + if (!currentPalette.Equals(palette)) + { + currentPalette = palette; + ItemColorIndex.Clear(); + ColorList.Clear(); + + foreach (var color in palette) + { + var locString = GetColorLocString(color.Key); + var item = ColorList.AddItem(locString, _spriteSystem.Frame0(_colorEntryIconTexture)); + item.IconModulate = color.Value; + item.Metadata = color.Key; + + ItemColorIndex.Add(color.Key, ColorList.IndexOf(item)); + } + } + + // Disable event so we don't send a new event for pre-selectedStyle entry and end up in a loop + + if (selectedColorKey != null) + { + var index = ItemColorIndex[selectedColorKey]; + ColorList.OnItemSelected -= OnColorPicked; + ColorList[index].Selected = true; + ColorList.OnItemSelected += OnColorPicked; + } + + SpriteList.OnItemSelected -= OnSpritePicked; + SpriteList[selectedStyle].Selected = true; + SpriteList.OnItemSelected += OnSpritePicked; + } +} diff --git a/Content.Server/AirlockPainter/AirlockPainterComponent.cs b/Content.Server/AirlockPainter/AirlockPainterComponent.cs deleted file mode 100644 index cd88795c1203f2..00000000000000 --- a/Content.Server/AirlockPainter/AirlockPainterComponent.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Robust.Shared.Audio; - -namespace Content.Server.AirlockPainter -{ - [RegisterComponent] - public sealed class AirlockPainterComponent : Component - { - [DataField("spraySound")] - public SoundSpecifier SpraySound = new SoundPathSpecifier("/Audio/Effects/spray2.ogg"); - - [DataField("sprayTime")] - public float SprayTime = 3.0f; - - [DataField("isSpraying")] - public bool IsSpraying = false; - - public int Index = default!; - } -} diff --git a/Content.Server/AirlockPainter/AirlockPainterSystem.cs b/Content.Server/AirlockPainter/AirlockPainterSystem.cs deleted file mode 100644 index 85723fc14e9c54..00000000000000 --- a/Content.Server/AirlockPainter/AirlockPainterSystem.cs +++ /dev/null @@ -1,118 +0,0 @@ -using Content.Server.Administration.Logs; -using Content.Server.Popups; -using Content.Server.UserInterface; -using Content.Shared.AirlockPainter; -using Content.Shared.AirlockPainter.Prototypes; -using Content.Shared.DoAfter; -using Content.Shared.Database; -using Content.Shared.Doors.Components; -using Content.Shared.Interaction; -using JetBrains.Annotations; -using Robust.Server.GameObjects; - -namespace Content.Server.AirlockPainter -{ - /// - /// A system for painting airlocks using airlock painter - /// - [UsedImplicitly] - public sealed class AirlockPainterSystem : SharedAirlockPainterSystem - { - [Dependency] private readonly IAdminLogManager _adminLogger = default!; - [Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!; - [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; - [Dependency] private readonly PopupSystem _popupSystem = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(AfterInteractOn); - SubscribeLocalEvent(OnActivate); - SubscribeLocalEvent(OnSpritePicked); - SubscribeLocalEvent(OnDoAfter); - } - - private void OnDoAfter(EntityUid uid, AirlockPainterComponent component, AirlockPainterDoAfterEvent args) - { - component.IsSpraying = false; - - if (args.Handled || args.Cancelled) - return; - - if (args.Args.Target != null) - { - _audio.PlayPvs(component.SpraySound, uid); - _appearance.SetData(args.Args.Target.Value, DoorVisuals.BaseRSI, args.Sprite); - _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.Args.User):user} painted {ToPrettyString(args.Args.Target.Value):target}"); - } - - args.Handled = true; - } - - private void OnActivate(EntityUid uid, AirlockPainterComponent component, ActivateInWorldEvent args) - { - if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor)) - return; - DirtyUI(uid, component); - - if (_userInterfaceSystem.TryGetUi(uid, AirlockPainterUiKey.Key, out var bui)) - _userInterfaceSystem.OpenUi(bui, actor.PlayerSession); - args.Handled = true; - } - - private void AfterInteractOn(EntityUid uid, AirlockPainterComponent component, AfterInteractEvent args) - { - if (component.IsSpraying || args.Target is not { Valid: true } target || !args.CanReach) - return; - - if (!EntityManager.TryGetComponent(target, out var airlock)) - return; - - if (!_prototypeManager.TryIndex(airlock.Group, out var grp)) - { - Log.Error("Group not defined: %s", airlock.Group); - return; - } - - string style = Styles[component.Index]; - if (!grp.StylePaths.TryGetValue(style, out var sprite)) - { - string msg = Loc.GetString("airlock-painter-style-not-available"); - _popupSystem.PopupEntity(msg, args.User, args.User); - return; - } - component.IsSpraying = true; - - var doAfterEventArgs = new DoAfterArgs(args.User, component.SprayTime, new AirlockPainterDoAfterEvent(sprite), uid, target: target, used: uid) - { - BreakOnTargetMove = true, - BreakOnUserMove = true, - BreakOnDamage = true, - NeedHand = true, - }; - _doAfterSystem.TryStartDoAfter(doAfterEventArgs); - - // Log attempt - _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} is painting {ToPrettyString(uid):target} to '{style}' at {Transform(uid).Coordinates:targetlocation}"); - } - - private void OnSpritePicked(EntityUid uid, AirlockPainterComponent component, AirlockPainterSpritePickedMessage args) - { - component.Index = args.Index; - DirtyUI(uid, component); - } - - private void DirtyUI(EntityUid uid, - AirlockPainterComponent? component = null) - { - if (!Resolve(uid, ref component)) - return; - - _userInterfaceSystem.TrySetUiState(uid, AirlockPainterUiKey.Key, - new AirlockPainterBoundUserInterfaceState(component.Index)); - } - } -} diff --git a/Content.Server/SprayPainter/SprayPainterComponent.cs b/Content.Server/SprayPainter/SprayPainterComponent.cs new file mode 100644 index 00000000000000..c67b793891b85e --- /dev/null +++ b/Content.Server/SprayPainter/SprayPainterComponent.cs @@ -0,0 +1,28 @@ +using Robust.Shared.Audio; + +namespace Content.Server.SprayPainter; + +[RegisterComponent] +public sealed class SprayPainterComponent : Component +{ + [DataField("spraySound")] + public SoundSpecifier SpraySound = new SoundPathSpecifier("/Audio/Effects/spray2.ogg"); + + [DataField("airlockSprayTime")] + public float AirlockSprayTime = 3.0f; + + [DataField("pipeSprayTime")] + public float PipeSprayTime = 1.0f; + + [DataField("isSpraying")] + public bool IsSpraying = false; + + [ViewVariables(VVAccess.ReadWrite)] + public string? PickedColor; + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("colorPalette")] + public Dictionary ColorPalette = new(); + + public int Index = default!; +} diff --git a/Content.Server/SprayPainter/SprayPainterSystem.cs b/Content.Server/SprayPainter/SprayPainterSystem.cs new file mode 100644 index 00000000000000..7fe6ecfb372a48 --- /dev/null +++ b/Content.Server/SprayPainter/SprayPainterSystem.cs @@ -0,0 +1,182 @@ +using System.Linq; +using Content.Server.Administration.Logs; +using Content.Server.Atmos.Piping.Components; +using Content.Server.Atmos.Piping.EntitySystems; +using Content.Server.Popups; +using Content.Shared.Database; +using Content.Shared.DoAfter; +using Content.Shared.Doors.Components; +using Content.Shared.SprayPainter.Prototypes; +using Content.Shared.SprayPainter; +using Content.Shared.Interaction; +using JetBrains.Annotations; +using Robust.Server.GameObjects; + +namespace Content.Server.SprayPainter; + +/// +/// A system for painting airlocks and pipes using enginner painter +/// +[UsedImplicitly] +public sealed class SprayPainterSystem : SharedSprayPainterSystem +{ + [Dependency] private readonly IAdminLogManager _adminLogger = default!; + [Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly AtmosPipeColorSystem _pipeColorSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(AfterInteractOn); + SubscribeLocalEvent(OnActivate); + SubscribeLocalEvent(OnSpritePicked); + SubscribeLocalEvent(OnColorPicked); + SubscribeLocalEvent(OnDoAfter); + } + + private void OnInit(EntityUid uid, SprayPainterComponent component, ComponentInit args) + { + if (component.ColorPalette.Count == 0) + return; + + SetColor(uid, component, component.ColorPalette.First().Key); + } + + private void OnDoAfter(EntityUid uid, SprayPainterComponent component, SprayPainterDoAfterEvent args) + { + component.IsSpraying = false; + + if (args.Handled || args.Cancelled) + return; + + if (args.Args.Target == null) + return; + + EntityUid target = (EntityUid) args.Args.Target; + + _audio.PlayPvs(component.SpraySound, uid); + + if (TryComp(target, out var atmosPipeColorComp)) + { + _pipeColorSystem.SetColor(target, atmosPipeColorComp, args.Color ?? Color.White); + } else { // Target is an airlock + if (args.Sprite != null) + { + _appearance.SetData(target, DoorVisuals.BaseRSI, args.Sprite); + _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.Args.User):user} painted {ToPrettyString(args.Args.Target.Value):target}"); + } + } + + args.Handled = true; + } + + private void OnActivate(EntityUid uid, SprayPainterComponent component, ActivateInWorldEvent args) + { + if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor)) + return; + DirtyUI(uid, component); + + _userInterfaceSystem.TryOpen(uid, SprayPainterUiKey.Key, actor.PlayerSession); + args.Handled = true; + } + + private void AfterInteractOn(EntityUid uid, SprayPainterComponent component, AfterInteractEvent args) + { + if (component.IsSpraying || args.Target is not { Valid: true } target || !args.CanReach) + return; + + if (EntityManager.TryGetComponent(target, out var airlock)) + { + if (!_prototypeManager.TryIndex(airlock.Group, out var grp)) + { + Log.Error("Group not defined: %s", airlock.Group); + return; + } + + string style = Styles[component.Index]; + if (!grp.StylePaths.TryGetValue(style, out var sprite)) + { + string msg = Loc.GetString("spray-painter-style-not-available"); + _popupSystem.PopupEntity(msg, args.User, args.User); + return; + } + component.IsSpraying = true; + + var doAfterEventArgs = new DoAfterArgs(args.User, component.AirlockSprayTime, new SprayPainterDoAfterEvent(sprite, null), uid, target: target, used: uid) + { + BreakOnTargetMove = true, + BreakOnUserMove = true, + BreakOnDamage = true, + NeedHand = true, + }; + _doAfterSystem.TryStartDoAfter(doAfterEventArgs); + + // Log attempt + _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} is painting {ToPrettyString(uid):target} to '{style}' at {Transform(uid).Coordinates:targetlocation}"); + } else { // Painting pipes + if(component.PickedColor is null) + return; + + if (!EntityManager.HasComponent(target)) + return; + + if(!component.ColorPalette.TryGetValue(component.PickedColor, out var color)) + return; + + var doAfterEventArgs = new DoAfterArgs(args.User, component.PipeSprayTime, new SprayPainterDoAfterEvent(null, color), uid, target, uid) + { + BreakOnTargetMove = true, + BreakOnUserMove = true, + BreakOnDamage = true, + CancelDuplicate = true, + DuplicateCondition = DuplicateConditions.SameTarget, + NeedHand = true, + }; + + _doAfterSystem.TryStartDoAfter(doAfterEventArgs); + } + } + + private void OnColorPicked(EntityUid uid, SprayPainterComponent component, SprayPainterColorPickedMessage args) + { + SetColor(uid, component, args.Key); + } + + private void OnSpritePicked(EntityUid uid, SprayPainterComponent component, SprayPainterSpritePickedMessage args) + { + component.Index = args.Index; + DirtyUI(uid, component); + } + + private void SetColor(EntityUid uid, SprayPainterComponent component, string? paletteKey) + { + if (paletteKey == null) + return; + + if (!component.ColorPalette.ContainsKey(paletteKey) || paletteKey == component.PickedColor) + return; + + component.PickedColor = paletteKey; + DirtyUI(uid, component); + } + + private void DirtyUI(EntityUid uid, SprayPainterComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + _userInterfaceSystem.TrySetUiState( + uid, + SprayPainterUiKey.Key, + new SprayPainterBoundUserInterfaceState( + component.Index, + component.PickedColor, + component.ColorPalette)); + } +} diff --git a/Content.Shared/AirlockPainter/AirlockPainterEvents.cs b/Content.Shared/AirlockPainter/AirlockPainterEvents.cs deleted file mode 100644 index d2223313bcd347..00000000000000 --- a/Content.Shared/AirlockPainter/AirlockPainterEvents.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Content.Shared.DoAfter; -using Robust.Shared.Serialization; - -namespace Content.Shared.AirlockPainter -{ - [Serializable, NetSerializable] - public enum AirlockPainterUiKey - { - Key, - } - - [Serializable, NetSerializable] - public sealed class AirlockPainterSpritePickedMessage : BoundUserInterfaceMessage - { - public int Index { get; } - - public AirlockPainterSpritePickedMessage(int index) - { - Index = index; - } - } - - [Serializable, NetSerializable] - public sealed class AirlockPainterBoundUserInterfaceState : BoundUserInterfaceState - { - public int SelectedStyle { get; } - - public AirlockPainterBoundUserInterfaceState(int selectedStyle) - { - SelectedStyle = selectedStyle; - } - } - - [Serializable, NetSerializable] - public sealed class AirlockPainterDoAfterEvent : DoAfterEvent - { - [DataField("sprite", required: true)] - public readonly string Sprite = default!; - - private AirlockPainterDoAfterEvent() - { - } - - public AirlockPainterDoAfterEvent(string sprite) - { - Sprite = sprite; - } - - public override DoAfterEvent Clone() => this; - } -} diff --git a/Content.Shared/AirlockPainter/Components/PaintableAirlockComponent.cs b/Content.Shared/AirlockPainter/Components/PaintableAirlockComponent.cs deleted file mode 100644 index 0453a0d08177e6..00000000000000 --- a/Content.Shared/AirlockPainter/Components/PaintableAirlockComponent.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Content.Shared.AirlockPainter.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; - -namespace Content.Server.AirlockPainter -{ - [RegisterComponent] - public sealed class PaintableAirlockComponent : Component - { - [DataField("group", customTypeSerializer:typeof(PrototypeIdSerializer))] - public string Group = default!; - } -} diff --git a/Content.Shared/AirlockPainter/Prototypes/AirlockGroupPrototype.cs b/Content.Shared/AirlockPainter/Prototypes/AirlockGroupPrototype.cs deleted file mode 100644 index a7d8a15f2a4048..00000000000000 --- a/Content.Shared/AirlockPainter/Prototypes/AirlockGroupPrototype.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Robust.Shared.Prototypes; - -namespace Content.Shared.AirlockPainter.Prototypes -{ - [Prototype("AirlockGroup")] - public sealed class AirlockGroupPrototype : IPrototype - { - [IdDataField] - public string ID { get; } = default!; - - [DataField("stylePaths")] - public Dictionary StylePaths = default!; - - // The priority determines, which sprite is used when showing - // the icon for a style in the airlock painter UI. The highest priority - // gets shown. - [DataField("iconPriority")] - public int IconPriority = 0; - } -} diff --git a/Content.Shared/AirlockPainter/SharedAirlockPainterSystem.cs b/Content.Shared/AirlockPainter/SharedAirlockPainterSystem.cs deleted file mode 100644 index 0cb8c6e5c080d0..00000000000000 --- a/Content.Shared/AirlockPainter/SharedAirlockPainterSystem.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Linq; -using Content.Shared.AirlockPainter.Prototypes; -using Robust.Shared.Prototypes; - -namespace Content.Shared.AirlockPainter -{ - public abstract class SharedAirlockPainterSystem : EntitySystem - { - [Dependency] protected readonly IPrototypeManager _prototypeManager = default!; - - public List Styles { get; private set; } = new(); - public List Groups { get; private set; } = new(); - - public override void Initialize() - { - base.Initialize(); - - SortedSet styles = new(); - foreach (AirlockGroupPrototype grp in _prototypeManager.EnumeratePrototypes()) - { - Groups.Add(grp); - foreach (string style in grp.StylePaths.Keys) - { - styles.Add(style); - } - } - Styles = styles.ToList(); - } - } -} diff --git a/Content.Shared/SprayPainter/Components/PaintableAirlockComponent.cs b/Content.Shared/SprayPainter/Components/PaintableAirlockComponent.cs new file mode 100644 index 00000000000000..78707a40909308 --- /dev/null +++ b/Content.Shared/SprayPainter/Components/PaintableAirlockComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.SprayPainter.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Server.SprayPainter; + +[RegisterComponent] +public sealed class PaintableAirlockComponent : Component +{ + [DataField("group", customTypeSerializer:typeof(PrototypeIdSerializer))] + public string Group = default!; +} diff --git a/Content.Shared/SprayPainter/Prototypes/AirlockGroupPrototype.cs b/Content.Shared/SprayPainter/Prototypes/AirlockGroupPrototype.cs new file mode 100644 index 00000000000000..81691ae83fd9f2 --- /dev/null +++ b/Content.Shared/SprayPainter/Prototypes/AirlockGroupPrototype.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.SprayPainter.Prototypes; + +[Prototype("AirlockGroup")] +public sealed class AirlockGroupPrototype : IPrototype +{ + [IdDataField] + public string ID { get; } = default!; + + [DataField("stylePaths")] + public Dictionary StylePaths = default!; + + // The priority determines, which sprite is used when showing + // the icon for a style in the SprayPainter UI. The highest priority + // gets shown. + [DataField("iconPriority")] + public int IconPriority = 0; +} diff --git a/Content.Shared/SprayPainter/SharedDevicePainterSystem.cs b/Content.Shared/SprayPainter/SharedDevicePainterSystem.cs new file mode 100644 index 00000000000000..ff43b119f63f19 --- /dev/null +++ b/Content.Shared/SprayPainter/SharedDevicePainterSystem.cs @@ -0,0 +1,29 @@ +using System.Linq; +using Content.Shared.SprayPainter.Prototypes; +using Robust.Shared.Prototypes; + +namespace Content.Shared.SprayPainter; + +public abstract class SharedSprayPainterSystem : EntitySystem +{ + [Dependency] protected readonly IPrototypeManager _prototypeManager = default!; + + public List Styles { get; private set; } = new(); + public List Groups { get; private set; } = new(); + + public override void Initialize() + { + base.Initialize(); + + SortedSet styles = new(); + foreach (AirlockGroupPrototype grp in _prototypeManager.EnumeratePrototypes()) + { + Groups.Add(grp); + foreach (string style in grp.StylePaths.Keys) + { + styles.Add(style); + } + } + Styles = styles.ToList(); + } +} diff --git a/Content.Shared/SprayPainter/SprayPainterEvents.cs b/Content.Shared/SprayPainter/SprayPainterEvents.cs new file mode 100644 index 00000000000000..3c2c9b95aec3ab --- /dev/null +++ b/Content.Shared/SprayPainter/SprayPainterEvents.cs @@ -0,0 +1,69 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared.SprayPainter; + +[Serializable, NetSerializable] +public enum SprayPainterUiKey +{ + Key, +} + +[Serializable, NetSerializable] +public sealed class SprayPainterSpritePickedMessage : BoundUserInterfaceMessage +{ + public int Index { get; } + + public SprayPainterSpritePickedMessage(int index) + { + Index = index; + } +} + +[Serializable, NetSerializable] +public sealed class SprayPainterColorPickedMessage : BoundUserInterfaceMessage +{ + public string? Key { get; } + + public SprayPainterColorPickedMessage(string? key) + { + Key = key; + } +} + +[Serializable, NetSerializable] +public sealed class SprayPainterBoundUserInterfaceState : BoundUserInterfaceState +{ + public int SelectedStyle { get; } + public string? SelectedColorKey { get; } + public Dictionary Palette { get; } + + public SprayPainterBoundUserInterfaceState(int selectedStyle, string? selectedColorKey, Dictionary palette) + { + SelectedStyle = selectedStyle; + SelectedColorKey = selectedColorKey; + Palette = palette; + } +} + +[Serializable, NetSerializable] +public sealed class SprayPainterDoAfterEvent : DoAfterEvent +{ + [DataField("sprite")] + public readonly string? Sprite = null; + + [DataField("color")] + public readonly Color? Color = null; + + private SprayPainterDoAfterEvent() + { + } + + public SprayPainterDoAfterEvent(string? sprite, Color? color) + { + Sprite = sprite; + Color = color; + } + + public override DoAfterEvent Clone() => this; +} diff --git a/Resources/Locale/en-US/airlock-painter/airlock-painter.ftl b/Resources/Locale/en-US/airlock-painter/airlock-painter.ftl deleted file mode 100644 index 3fe65668682be3..00000000000000 --- a/Resources/Locale/en-US/airlock-painter/airlock-painter.ftl +++ /dev/null @@ -1,3 +0,0 @@ -airlock-painter-style-not-available = Cannot apply the selected style to this type of airlock -airlock-painter-window-title = Airlock painter -airlock-painter-selected-style = Selected style diff --git a/Resources/Locale/en-US/engineer-painter/engineer-painter.ftl b/Resources/Locale/en-US/engineer-painter/engineer-painter.ftl new file mode 100644 index 00000000000000..d3d3ccc4448867 --- /dev/null +++ b/Resources/Locale/en-US/engineer-painter/engineer-painter.ftl @@ -0,0 +1,14 @@ +spray-painter-window-title = Spray painter + +spray-painter-style-not-available = Cannot apply the selected style to this type of airlock +spray-painter-selected-style = Selected style: + +spray-painter-selected-color = Selected color: +spray-painter-color-red = red +spray-painter-color-yellow = yellow +spray-painter-color-brown = brown +spray-painter-color-green = green +spray-painter-color-cyan = cyan +spray-painter-color-blue = blue +spray-painter-color-white = white +spray-painter-color-black = black diff --git a/Resources/Maps/aspid.yml b/Resources/Maps/aspid.yml index ec55ab072b47fa..42a5ddcccc203a 100644 --- a/Resources/Maps/aspid.yml +++ b/Resources/Maps/aspid.yml @@ -11893,7 +11893,7 @@ entities: - pos: -14.5,29.5 parent: 1 type: Transform -- proto: AirlockPainter +- proto: SprayPainter entities: - uid: 9885 components: diff --git a/Resources/Maps/fland.yml b/Resources/Maps/fland.yml index 7e85a3bcd6dcb3..bb9de6bfb3d135 100644 --- a/Resources/Maps/fland.yml +++ b/Resources/Maps/fland.yml @@ -19872,7 +19872,7 @@ entities: - pos: 1.5,49.5 parent: 13329 type: Transform -- proto: AirlockPainter +- proto: SprayPainter entities: - uid: 29081 components: diff --git a/Resources/Maps/kettle.yml b/Resources/Maps/kettle.yml index 3706dcf1fa52cd..b9acd22947c09f 100644 --- a/Resources/Maps/kettle.yml +++ b/Resources/Maps/kettle.yml @@ -13912,7 +13912,7 @@ entities: - pos: -55.5,-29.5 parent: 82 type: Transform -- proto: AirlockPainter +- proto: SprayPainter entities: - uid: 11279 components: diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml b/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml index da73c329786951..468692fd62b372 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml @@ -37,7 +37,7 @@ prob: 0.3 - id: CableApcStack prob: 0.3 - - id: AirlockPainter + - id: SprayPainter prob: 0.7 - type: entity diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/youtool.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/youtool.yml index ec639f873b43e5..2231c714ff9324 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/youtool.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/youtool.yml @@ -12,7 +12,7 @@ GasAnalyzer: 3 FlashlightLantern: 5 ClothingHandsGlovesColorYellowBudget: 3 - AirlockPainter: 3 + SprayPainter: 3 # Some engineer forgot to take the multitool out the youtool when working on it, happens. contrabandInventory: Multitool: 1 diff --git a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml index 84470d9e105942..fa1a5e951faa12 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml @@ -30,7 +30,7 @@ - Multitool - AppraisalTool components: - - AirlockPainter + - SprayPainter - NetworkConfigurator - RCD - RCDAmmo @@ -103,7 +103,7 @@ - Multitool - AppraisalTool components: - - AirlockPainter + - SprayPainter - NetworkConfigurator - RCD - RCDAmmo diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml index 3b805dda202294..9ff97ad0402ada 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml @@ -161,7 +161,7 @@ - NetworkConfigurator - trayScanner - GasAnalyzer - - AirlockPainter + - SprayPainter - AppraisalTool - Flare - HandheldGPSBasic diff --git a/Resources/Prototypes/Entities/Objects/Tools/airlock_painter.yml b/Resources/Prototypes/Entities/Objects/Tools/airlock_painter.yml deleted file mode 100644 index 8e387db3402f03..00000000000000 --- a/Resources/Prototypes/Entities/Objects/Tools/airlock_painter.yml +++ /dev/null @@ -1,21 +0,0 @@ -- type: entity - parent: BaseItem - id: AirlockPainter - name: airlock painter - description: An airlock painter for painting airlocks. - components: - - type: Sprite - sprite: Objects/Tools/airlock_painter.rsi - state: airlock_painter - - type: Item - sprite: Objects/Tools/airlock_painter.rsi - - type: UserInterface - interfaces: - - key: enum.AirlockPainterUiKey.Key - type: AirlockPainterBoundUserInterface - - type: AirlockPainter - whitelist: - tags: - - PaintableAirlock - - type: StaticPrice - price: 40 diff --git a/Resources/Prototypes/Entities/Objects/Tools/spray_painter.yml b/Resources/Prototypes/Entities/Objects/Tools/spray_painter.yml new file mode 100644 index 00000000000000..0ff3c652709fd4 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Tools/spray_painter.yml @@ -0,0 +1,30 @@ +- type: entity + parent: BaseItem + id: SprayPainter + name: Spray painter + description: A spray painter for painting airlocks and pipes. + components: + - type: Sprite + sprite: Objects/Tools/spray_painter.rsi + state: spray_painter + - type: Item + sprite: Objects/Tools/spray_painter.rsi + - type: UserInterface + interfaces: + - key: enum.SprayPainterUiKey.Key + type: SprayPainterBoundUserInterface + - type: SprayPainter + whitelist: + tags: + - PaintableAirlock + colorPalette: + red: '#FF1212FF' + yellow: '#B3A234FF' + brown: '#947507FF' + green: '#3AB334FF' + cyan: '#03FCD3FF' + blue: '#0335FCFF' + white: '#FFFFFFFF' + black: '#333333FF' + - type: StaticPrice + price: 40 diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 5252f9e429d142..49efcb37119124 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -88,7 +88,7 @@ - Crowbar - Multitool - NetworkConfigurator - - AirlockPainter + - SprayPainter - FlashlightLantern - CableStack - CableMVStack diff --git a/Resources/Prototypes/Recipes/Lathes/tools.yml b/Resources/Prototypes/Recipes/Lathes/tools.yml index 6ae6aaadeaecd5..df38db13d746d0 100644 --- a/Resources/Prototypes/Recipes/Lathes/tools.yml +++ b/Resources/Prototypes/Recipes/Lathes/tools.yml @@ -143,8 +143,8 @@ Glass: 300 - type: latheRecipe - id: AirlockPainter - result: AirlockPainter + id: SprayPainter + result: SprayPainter completetime: 2 materials: Steel: 300 diff --git a/Resources/Textures/Objects/Tools/airlock_painter.rsi/meta.json b/Resources/Textures/Objects/Tools/spray_painter.rsi/meta.json similarity index 87% rename from Resources/Textures/Objects/Tools/airlock_painter.rsi/meta.json rename to Resources/Textures/Objects/Tools/spray_painter.rsi/meta.json index 6312e9b2610451..056ba0a8563e6e 100644 --- a/Resources/Textures/Objects/Tools/airlock_painter.rsi/meta.json +++ b/Resources/Textures/Objects/Tools/spray_painter.rsi/meta.json @@ -7,7 +7,7 @@ }, "states" : [ { - "name" : "airlock_painter" + "name" : "spray_painter" } ], "version" : 1 diff --git a/Resources/Textures/Objects/Tools/airlock_painter.rsi/airlock_painter.png b/Resources/Textures/Objects/Tools/spray_painter.rsi/spray_painter.png similarity index 100% rename from Resources/Textures/Objects/Tools/airlock_painter.rsi/airlock_painter.png rename to Resources/Textures/Objects/Tools/spray_painter.rsi/spray_painter.png diff --git a/Resources/migration.yml b/Resources/migration.yml index 9fae5aead96059..9234ce54974f9f 100644 --- a/Resources/migration.yml +++ b/Resources/migration.yml @@ -78,3 +78,6 @@ WindowTintedDirectional: WindowFrostedDirectional # 2023-08-10 SyringeSpaceacillin: null + +# 2023-08-13 +AirlockPainter: SprayPainter From e85834d57b819ea749f658ccbcb82cf439b26350 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 14 Aug 2023 08:07:26 -0400 Subject: [PATCH 02/32] Automatic changelog update --- Resources/Changelog/Changelog.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 4d70605b7f143a..b4ba13ab1de581 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: crazybrain - changes: - - {message: QM is now officially supervised by the Captain., type: Tweak} - - {message: The Cargo department is no longer supervised by the HoP., type: Tweak} - id: 4077 - time: '2023-06-24T05:32:15.0000000+00:00' - author: EmoGarbage404 changes: - {message: 'Added Artifexium, a chemical that can activate artifacts when sprayed @@ -3017,3 +3011,10 @@ Entries: on glass airlocks, type: Fix} id: 4576 time: '2023-08-14T06:42:02.0000000+00:00' +- author: kseandi + changes: + - {message: 'The new airlock painters are so accurate that you can use them to paint + pipes. Because of this, Nanotrasen decided to rename them to "Spray painters".', + type: Tweak} + id: 4577 + time: '2023-08-14T12:06:21.0000000+00:00' From 6bbf05229f5f4a9ab3b52f9676170b246fb32612 Mon Sep 17 00:00:00 2001 From: Interrobang01 <113810873+Interrobang01@users.noreply.github.com> Date: Mon, 14 Aug 2023 06:56:06 -0700 Subject: [PATCH 03/32] Fixed cargo's gas canister purchase prices (#19093) --- .../Catalog/Cargo/cargo_atmospherics.yml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_atmospherics.yml b/Resources/Prototypes/Catalog/Cargo/cargo_atmospherics.yml index 4a352e77c3c29d..a4f6bdd90b5d6a 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_atmospherics.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_atmospherics.yml @@ -4,7 +4,7 @@ sprite: Structures/Storage/canister.rsi state: grey product: AirCanister - cost: 2700 + cost: 1100 category: Atmospherics group: market @@ -14,7 +14,7 @@ sprite: Structures/Storage/canister.rsi state: blue product: OxygenCanister - cost: 2300 + cost: 1100 category: Atmospherics group: market @@ -24,7 +24,7 @@ sprite: Structures/Storage/canister.rsi state: red product: NitrogenCanister - cost: 3200 + cost: 1100 category: Atmospherics group: market @@ -34,7 +34,17 @@ sprite: Structures/Storage/canister.rsi state: black product: CarbonDioxideCanister - cost: 2600 + cost: 2200 # Until someone fixes it co2 can be used to oneshot people so it's more expensive + category: Atmospherics + group: market + +- type: cargoProduct + id: AtmosphericsStorage + icon: + sprite: Structures/Storage/canister.rsi + state: yellow + product: StorageCanister + cost: 1010 # No gases in it so it's cheaper category: Atmospherics group: market From d71472cb031c6a833b6e9c1c1715d4cb2a32cb90 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 14 Aug 2023 09:57:10 -0400 Subject: [PATCH 04/32] Automatic changelog update --- Resources/Changelog/Changelog.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index b4ba13ab1de581..297781967f495c 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: EmoGarbage404 - changes: - - {message: 'Added Artifexium, a chemical that can activate artifacts when sprayed - on their surface. Get it by grinding artifact fragments.', type: Add} - id: 4078 - time: '2023-06-24T12:00:42.0000000+00:00' - author: Nimfar11 changes: - {message: Adds Amanita fly agaric seeds to the Vendomat of seeds after EMAG., @@ -3018,3 +3012,9 @@ Entries: type: Tweak} id: 4577 time: '2023-08-14T12:06:21.0000000+00:00' +- author: Interrobang01 + changes: + - {message: Centcom will now sell Cargo gas canisters at a vastly reduced (and consistent!) + price after realizing the station has infinite gasses anyway., type: Tweak} + id: 4578 + time: '2023-08-14T13:56:07.0000000+00:00' From 912aba5e8c7b6b4844ceec07e39740af1c4d5917 Mon Sep 17 00:00:00 2001 From: Kara Date: Mon, 14 Aug 2023 08:59:14 -0700 Subject: [PATCH 05/32] Fix some non-norot sprites (#19130) --- .../Entities/Structures/Doors/SecretDoor/secret_door.yml | 1 + Resources/Prototypes/Entities/Structures/Walls/asteroid.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml b/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml index 2cc6ae0467a069..5aafd1544b10b5 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml @@ -8,6 +8,7 @@ components: - type: Sprite sprite: Structures/Doors/secret_door.rsi + noRot: true layers: - state: closed map: ["enum.DoorVisualLayers.Base"] diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index 6c262afee46351..8d19f41e518040 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -16,6 +16,7 @@ mode: NoSprite - type: SmoothEdge - type: Sprite + noRot: true sprite: Structures/Walls/rock.rsi layers: - state: rock_asteroid From 9ccad0470c764e3fb9400bcc289e220e422716a9 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 14 Aug 2023 12:00:18 -0400 Subject: [PATCH 06/32] Automatic changelog update --- Resources/Changelog/Changelog.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 297781967f495c..34aa0888d7c490 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: Nimfar11 - changes: - - {message: Adds Amanita fly agaric seeds to the Vendomat of seeds after EMAG., - type: Add} - id: 4079 - time: '2023-06-24T12:03:09.0000000+00:00' - author: Lank changes: - {message: Chemist PDA's can now analyze patient health., type: Tweak} @@ -3018,3 +3012,9 @@ Entries: price after realizing the station has infinite gasses anyway., type: Tweak} id: 4578 time: '2023-08-14T13:56:07.0000000+00:00' +- author: mirrorcult + changes: + - {message: Asteroid rocks and secret doors should look less weird in certain scenarios, + type: Fix} + id: 4579 + time: '2023-08-14T15:59:14.0000000+00:00' From ac2ac4b9e554b807c9d8322f261ff0a97eecf6e4 Mon Sep 17 00:00:00 2001 From: LightVillet Date: Mon, 14 Aug 2023 19:04:21 +0300 Subject: [PATCH 07/32] Fix recipes for translations (#19133) Co-authored-by: LightVillet --- Resources/Prototypes/Recipes/Lathes/medical.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/Resources/Prototypes/Recipes/Lathes/medical.yml b/Resources/Prototypes/Recipes/Lathes/medical.yml index 66ab4d889920d2..bb83a0a52eefde 100644 --- a/Resources/Prototypes/Recipes/Lathes/medical.yml +++ b/Resources/Prototypes/Recipes/Lathes/medical.yml @@ -193,7 +193,6 @@ - type: latheRecipe id: HandLabeler result: HandLabeler - name: hand labeler completetime: 2 materials: Plastic: 100 From 56685798738bc598a69234717b99dda244b1d26d Mon Sep 17 00:00:00 2001 From: Kara Date: Mon, 14 Aug 2023 09:04:41 -0700 Subject: [PATCH 08/32] Add cooldown to bike horn implant (#19128) --- Content.Server/Explosion/EntitySystems/TriggerSystem.cs | 2 +- Resources/Prototypes/Actions/types.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs index 57ece48b3bedea..5c0fdea7b6220c 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs @@ -196,7 +196,7 @@ private void OnActivate(EntityUid uid, TriggerOnActivateComponent component, Act private void OnImplantTrigger(EntityUid uid, TriggerImplantActionComponent component, ActivateImplantEvent args) { - Trigger(uid); + args.Handled = Trigger(uid); } private void OnStepTriggered(EntityUid uid, TriggerOnStepTriggerComponent component, ref StepTriggeredEvent args) diff --git a/Resources/Prototypes/Actions/types.yml b/Resources/Prototypes/Actions/types.yml index 95bd224231257d..2bf3b9b98a97b8 100644 --- a/Resources/Prototypes/Actions/types.yml +++ b/Resources/Prototypes/Actions/types.yml @@ -181,3 +181,4 @@ description: action-desc-honk icon: { sprite: Objects/Fun/bikehorn.rsi, state: icon } event: !type:ActivateImplantEvent + useDelay: 1 From 73386af66fccaf32e59dc4428799cbf19f681668 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 14 Aug 2023 12:05:50 -0400 Subject: [PATCH 09/32] Automatic changelog update --- Resources/Changelog/Changelog.yml | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 34aa0888d7c490..3eba7d3fbb8f82 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,15 +1,4 @@ Entries: -- author: Lank - changes: - - {message: Chemist PDA's can now analyze patient health., type: Tweak} - id: 4080 - time: '2023-06-24T12:11:48.0000000+00:00' -- author: '0x6273' - changes: - - {message: 'Hotplates no longer use itemslots, which means you can see and interact - with the beaker while it''s being heated.', type: Tweak} - id: 4081 - time: '2023-06-24T18:09:24.0000000+00:00' - author: Alekshhh changes: - {message: Changed cap gun ammo to look less like real bullets, type: Tweak} @@ -3018,3 +3007,13 @@ Entries: type: Fix} id: 4579 time: '2023-08-14T15:59:14.0000000+00:00' +- author: LightVillet + changes: + - {message: Fixed hand labeler recipe's name, type: Fix} + id: 4580 + time: '2023-08-14T16:04:22.0000000+00:00' +- author: mirrorcult + changes: + - {message: 'Bike horn implant now has a short cooldown, sorry', type: Fix} + id: 4581 + time: '2023-08-14T16:04:42.0000000+00:00' From 7a702221ef2e409913856088b469d4adc7ad1f3e Mon Sep 17 00:00:00 2001 From: Errant <35878406+Errant-4@users.noreply.github.com> Date: Mon, 14 Aug 2023 16:10:15 +0000 Subject: [PATCH 10/32] fix attack stamina cost check (#18872) Co-authored-by: Errant <35878406+errant@users.noreply.github.com> --- Content.Shared/Damage/Systems/StaminaSystem.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Shared/Damage/Systems/StaminaSystem.cs b/Content.Shared/Damage/Systems/StaminaSystem.cs index 44474623a5bfc9..31abbf039cf642 100644 --- a/Content.Shared/Damage/Systems/StaminaSystem.cs +++ b/Content.Shared/Damage/Systems/StaminaSystem.cs @@ -249,8 +249,9 @@ private void SetStaminaAlert(EntityUid uid, StaminaComponent? component = null) /// public bool TryTakeStamina(EntityUid uid, float value, StaminaComponent? component = null, EntityUid? source = null, EntityUid? with = null) { + // Something that has no Stamina component automatically passes stamina checks if (!Resolve(uid, ref component, false)) - return false; + return true; var oldStam = component.StaminaDamage; From da62b05f4be36724f5b8db7c8b8443dfb7f9d7c2 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 14 Aug 2023 12:11:30 -0400 Subject: [PATCH 11/32] Automatic changelog update --- Resources/Changelog/Changelog.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 3eba7d3fbb8f82..b6773ed264c44b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: Alekshhh - changes: - - {message: Changed cap gun ammo to look less like real bullets, type: Tweak} - id: 4082 - time: '2023-06-24T19:56:42.0000000+00:00' - author: Equivocateur changes: - {message: As part of a bounty program - whatever insulated gloves we could find @@ -3017,3 +3012,10 @@ Entries: - {message: 'Bike horn implant now has a short cooldown, sorry', type: Fix} id: 4581 time: '2023-08-14T16:04:42.0000000+00:00' +- author: Errant + changes: + - {message: 'Admin ghosts, robots, and other soulless monsters that never tire can + now perform wide melee attacks again. Most notably this fixes the borg mining + drill.', type: Fix} + id: 4582 + time: '2023-08-14T16:10:16.0000000+00:00' From 5ce47fbb033eef86bbcdcac80eb67cd2185bea98 Mon Sep 17 00:00:00 2001 From: mhamster <81412348+mhamsterr@users.noreply.github.com> Date: Tue, 15 Aug 2023 02:45:55 +0700 Subject: [PATCH 12/32] Add ability to burn papers +Flammable tweaks. (#18955) --- .../Atmos/Components/FlammableComponent.cs | 21 ++++++++++++ .../Atmos/EntitySystems/FlammableSystem.cs | 34 +++++++++++++++---- .../Entities/Objects/Misc/paper.yml | 26 ++++++++++++++ 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/Content.Server/Atmos/Components/FlammableComponent.cs b/Content.Server/Atmos/Components/FlammableComponent.cs index c959d5d4176898..badd494cc39695 100644 --- a/Content.Server/Atmos/Components/FlammableComponent.cs +++ b/Content.Server/Atmos/Components/FlammableComponent.cs @@ -35,5 +35,26 @@ public sealed class FlammableComponent : Component /// [DataField("flammableCollisionShape")] public IPhysShape FlammableCollisionShape = new PhysShapeCircle(0.35f); + + /// + /// Should the component be set on fire by interactions with isHot entities + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField("alwaysCombustible")] + public bool AlwaysCombustible = false; + + /// + /// Can the component anyhow lose its FireStacks? + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField("canExtinguish")] + public bool CanExtinguish = true; + + /// + /// How many firestacks should be applied to component when being set on fire? + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField("firestacksOnIgnite")] + public float FirestacksOnIgnite = 2.0f; } } diff --git a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs index 47f283c075b314..4c36807a356396 100644 --- a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs +++ b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs @@ -148,15 +148,30 @@ private void OnCollide(EntityUid uid, FlammableComponent flammable, ref StartCol { if (otherFlammable.OnFire) { - var fireSplit = (flammable.FireStacks + otherFlammable.FireStacks) / 2; - flammable.FireStacks = fireSplit; - otherFlammable.FireStacks = fireSplit; + if (flammable.CanExtinguish) + { + var fireSplit = (flammable.FireStacks + otherFlammable.FireStacks) / 2; + flammable.FireStacks = fireSplit; + otherFlammable.FireStacks = fireSplit; + } + else + { + otherFlammable.FireStacks = flammable.FireStacks / 2; + } } else { - flammable.FireStacks /= 2; - otherFlammable.FireStacks += flammable.FireStacks; - Ignite(otherUid, uid, otherFlammable); + if (!flammable.CanExtinguish) + { + otherFlammable.FireStacks += flammable.FireStacks / 2; + Ignite(otherUid, uid, otherFlammable); + } + else + { + flammable.FireStacks /= 2; + otherFlammable.FireStacks += flammable.FireStacks; + Ignite(otherUid, uid, otherFlammable); + } } } else if (otherFlammable.OnFire) @@ -215,7 +230,7 @@ public void Extinguish(EntityUid uid, FlammableComponent? flammable = null) if (!Resolve(uid, ref flammable)) return; - if (!flammable.OnFire) + if (!flammable.OnFire || !flammable.CanExtinguish) return; _adminLogger.Add(LogType.Flammable, $"{ToPrettyString(flammable.Owner):entity} stopped being on fire damage"); @@ -233,6 +248,11 @@ public void Ignite(EntityUid uid, EntityUid ignitionSource, FlammableComponent? if (!Resolve(uid, ref flammable)) return; + if (flammable.AlwaysCombustible) + { + flammable.FireStacks = Math.Max(flammable.FirestacksOnIgnite, flammable.FireStacks); + } + if (flammable.FireStacks > 0 && !flammable.OnFire) { if (ignitionSourceUser != null) diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index d1fc0bb8e8f18a..9050353d9d13cb 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -30,6 +30,32 @@ - Trash - type: Appearance - type: PaperVisuals + - type: Flammable + fireSpread: true + canResistFire: false + alwaysCombustible: true + canExtinguish: false # Mwahaha! Let the world burn because of one piece of paper! + damage: + types: + Heat: 1 + - type: FireVisuals + sprite: Effects/fire.rsi + normalState: fire + - type: Damageable + damageModifierSet: Wood + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 15 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Ash: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity name: office paper From 40e12866064546dc109ed39df50cd5626063c33b Mon Sep 17 00:00:00 2001 From: Repo <47093363+Titian3@users.noreply.github.com> Date: Tue, 15 Aug 2023 07:50:33 +1200 Subject: [PATCH 13/32] Fix to allow no severity on messages and watchlists (#19125) --- Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs b/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs index 6a921cf6a10e39..77dde4688d2b42 100644 --- a/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs +++ b/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs @@ -239,7 +239,7 @@ private void UpdateSubmitButton() return; } - SubmitButton.Disabled = NoteSeverity == null; + SubmitButton.Disabled = (NoteType != NoteType.Watchlist && NoteType != NoteType.Message) && NoteSeverity == null; } private void ResetSubmitButton() From 979aa8c1008ee2e54ac10608efbb42cbba279045 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 14 Aug 2023 15:51:37 -0400 Subject: [PATCH 14/32] Automatic changelog update --- Resources/Changelog/Changelog.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index b6773ed264c44b..5b1fbcec24a324 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: Equivocateur - changes: - - {message: As part of a bounty program - whatever insulated gloves we could find - on Origin we have handed over to cargo., type: Remove} - id: 4083 - time: '2023-06-24T19:57:56.0000000+00:00' - author: Alekshhh changes: - {message: 'Changed bluespace and cryostasis beakers to not be weird when thrown, @@ -3019,3 +3013,8 @@ Entries: drill.', type: Fix} id: 4582 time: '2023-08-14T16:10:16.0000000+00:00' +- author: Titian3 + changes: + - {message: Fixed Admin watchlists and messages., type: Fix} + id: 4583 + time: '2023-08-14T19:50:33.0000000+00:00' From 5cd1d464ecb3bf6ee7a936313232ed84225c815e Mon Sep 17 00:00:00 2001 From: MilenVolf Date: Mon, 14 Aug 2023 23:36:59 +0300 Subject: [PATCH 15/32] Locale fix --- .../doors/secretdoor/secret_door.ftl | 8 +- Resources/Locale/ru-RU/weapons/ranged/gun.ftl | 2 +- Resources/Prototypes/Datasets/Names/clown.yml | 104 +++++++++--------- 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/doors/secretdoor/secret_door.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/doors/secretdoor/secret_door.ftl index 9b383a59fa2f99..c987e72f0c4f8e 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/doors/secretdoor/secret_door.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/doors/secretdoor/secret_door.ftl @@ -1,9 +1,9 @@ -ent-BaseSecretDoor = { ent-BaseSecretDoor } - .desc = { ent-BaseSecretDoor.desc } +ent-BaseSecretDoor = { ent-WallSolid } + .desc = { ent-WallSolid.desc } .suffix = Потайная дверь ent-BaseSecretDoorAssembly = каркас потайной двери .desc = Она открывается, закрывается и, возможно, раздавит вас. .suffix = { "" } -ent-SolidSecretDoor = { ent-BaseSecretDoor } - .desc = { ent-BaseSecretDoor.desc } +ent-SolidSecretDoor = { ent-WallSolid } + .desc = { ent-WallSolid.desc } .suffix = { "" } diff --git a/Resources/Locale/ru-RU/weapons/ranged/gun.ftl b/Resources/Locale/ru-RU/weapons/ranged/gun.ftl index e3b389c467426a..eb91a4cc7fdf89 100644 --- a/Resources/Locale/ru-RU/weapons/ranged/gun.ftl +++ b/Resources/Locale/ru-RU/weapons/ranged/gun.ftl @@ -21,7 +21,7 @@ gun-cartridge-unspent = Он [color=lime]не израсходован[/color]. # BatteryAmmoProvider gun-battery-examine = Заряда хватит на [color={ $color }]{ $count }[/color] выстрелов. # CartridgeAmmoProvider -gun-chamber-bolt-ammo = Отсутствует затвор +gun-chamber-bolt-ammo = Затвор не закрыт gun-chamber-bolt = Затвор [color={ $color }]{ $bolt }[/color]. gun-chamber-bolt-closed = Затвор закрыт gun-chamber-bolt-opened = Затвор открыт diff --git a/Resources/Prototypes/Datasets/Names/clown.yml b/Resources/Prototypes/Datasets/Names/clown.yml index 701cae82dbe12b..ae1c6367005e15 100644 --- a/Resources/Prototypes/Datasets/Names/clown.yml +++ b/Resources/Prototypes/Datasets/Names/clown.yml @@ -1,55 +1,55 @@ - type: dataset id: names_clown values: - - Gigglesworth - - Honkel the III - - Goose McSunny - - Toodles Sharperton - - Dinky Doodle - - Honkerbelle - - Bo Bo Sassy - - Baby Cakes - - Ladybug Honks - - Ziggy Yoyo - - Razzle Dazzle - - Buster Frown - - Pepinpop - - Silly Willy - - Jo Jo Bobo Bo - - Pocket - - Patches - - Checkers - - Freckle - - Honker - - Bonker - - Skiddle - - Sprinkledinkle - - Ronnie Pace - - Miss Stockings - - Slippy Joe - - Redshirt McBeat - - Flop O'Honker - - Speckles - - Bubble - - Button - - Sparkle - - Giggles - - Jingle - - Candy - - Shiggy Diggintons - - Hingle McCringleberry - - Pagliacci - - Coco - - Blinko - - Shaggy Two Dope - - Aunt Scootaloo - - Bozo - - Doink - - Mr. Noodle - - Yucko - - Buggy - - Chuckles - - Yorick - - Cutter - - Sweet Tooth - - Pogo + - Хихикостоящий + - Хонкель III + - Гусь МакСанни + - Тудлс Шарпертон + - Изящный Болван + - Хонкербелль + - Бо Бо Дерзкий + - Детские Торты + - Хонк Божьей Коровки + - Зигги Йойо + - Раззл Дазл + - Бастер Хмурый + - Пепинпоп + - Глупый Вилли + - Джо Джо Бобо Бо + - Карман + - Заплаткин + - Чекер + - Веснушка + - Хонкер + - Бонкер + - Скидл + - Спринклдинкл + - Ронни Пейс + - Мисс Чулки + - Скользкий Джо + - Краснорубаший МакУдар + - Флоп О'Хонкер + - Крапинкин + - Пузырёк + - Пуговица + - Блеск + - Хихинкин + - Звон + - Конфетка + - Шигги Диггинтонс + - Хингл МакКринглберри + - Пальяччи + - Коко + - Блинко + - Два Лохматых Дурня + - Тётя Скуталу + - Бозо + - Доинк + - Мистер Лапша + - Юкко + - Багги + - Чаклз + - Йорик + - Резак + - Сладкий Зубок + - Пого From 50dcc14f9c4e77beafaa93bd1d4bd665772d6419 Mon Sep 17 00:00:00 2001 From: MilenVolf Date: Mon, 14 Aug 2023 23:40:33 +0300 Subject: [PATCH 16/32] Update english locale files --- .../prototypes/entities/objects/tools/spray_painter.ftl | 3 +++ .../prototypes/entities/objects/tools/spray_painter.ftl | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/tools/spray_painter.ftl create mode 100644 Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/tools/spray_painter.ftl diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/tools/spray_painter.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/tools/spray_painter.ftl new file mode 100644 index 00000000000000..769d1f97c18da2 --- /dev/null +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/objects/tools/spray_painter.ftl @@ -0,0 +1,3 @@ +ent-SprayPainter = Spray painter + .desc = A spray painter for painting airlocks and pipes. + .suffix = { "" } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/tools/spray_painter.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/tools/spray_painter.ftl new file mode 100644 index 00000000000000..769d1f97c18da2 --- /dev/null +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/tools/spray_painter.ftl @@ -0,0 +1,3 @@ +ent-SprayPainter = Spray painter + .desc = A spray painter for painting airlocks and pipes. + .suffix = { "" } From e5a62e69ac6eda4fce11b534c2999352cc9eefa3 Mon Sep 17 00:00:00 2001 From: MilenVolf Date: Mon, 14 Aug 2023 23:41:14 +0300 Subject: [PATCH 17/32] Update russian locale files --- .../ru-RU/engineer-painter/engineer-painter.ftl | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Resources/Locale/ru-RU/engineer-painter/engineer-painter.ftl diff --git a/Resources/Locale/ru-RU/engineer-painter/engineer-painter.ftl b/Resources/Locale/ru-RU/engineer-painter/engineer-painter.ftl new file mode 100644 index 00000000000000..915e6325e771fb --- /dev/null +++ b/Resources/Locale/ru-RU/engineer-painter/engineer-painter.ftl @@ -0,0 +1,12 @@ +spray-painter-window-title = Spray painter +spray-painter-style-not-available = Cannot apply the selected style to this type of airlock +spray-painter-selected-style = Selected style: +spray-painter-selected-color = Selected color: +spray-painter-color-red = red +spray-painter-color-yellow = yellow +spray-painter-color-brown = brown +spray-painter-color-green = green +spray-painter-color-cyan = cyan +spray-painter-color-blue = blue +spray-painter-color-white = white +spray-painter-color-black = black From bee2768494179e6a78dc33ac25182cfd6c940c60 Mon Sep 17 00:00:00 2001 From: crazybrain23 <44417085+crazybrain23@users.noreply.github.com> Date: Mon, 14 Aug 2023 22:00:08 +0100 Subject: [PATCH 18/32] add binary to observer (#19141) --- Resources/Prototypes/Entities/Mobs/Player/observer.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Mobs/Player/observer.yml b/Resources/Prototypes/Entities/Mobs/Player/observer.yml index a39c6e38e7434c..30e71f22bd6300 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/observer.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/observer.yml @@ -34,6 +34,7 @@ - type: IntrinsicRadioReceiver - type: ActiveRadio channels: + - Binary - Common - Command - CentCom From ee5974ece109a2cea935c765c4821f9f414dfaf4 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 14 Aug 2023 17:01:12 -0400 Subject: [PATCH 19/32] Automatic changelog update --- Resources/Changelog/Changelog.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 5b1fbcec24a324..94569660b08243 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,10 +1,4 @@ Entries: -- author: Alekshhh - changes: - - {message: 'Changed bluespace and cryostasis beakers to not be weird when thrown, - and cryostasis contents can now be spilled when thrown.', type: Tweak} - id: 4084 - time: '2023-06-24T20:01:04.0000000+00:00' - author: deltanedas changes: - {message: Emergency crowbar and regular crowbar now do the same damage. Please @@ -3018,3 +3012,8 @@ Entries: - {message: Fixed Admin watchlists and messages., type: Fix} id: 4583 time: '2023-08-14T19:50:33.0000000+00:00' +- author: crazybrain + changes: + - {message: Observers can now hear the binary radio., type: Tweak} + id: 4584 + time: '2023-08-14T21:00:08.0000000+00:00' From 024d2f3f986afdacd36ebc0b5b90255bdabe3545 Mon Sep 17 00:00:00 2001 From: crazybrain23 <44417085+crazybrain23@users.noreply.github.com> Date: Mon, 14 Aug 2023 22:01:56 +0100 Subject: [PATCH 20/32] Singularity Stability Tweaks (fixed) (#19135) * Singulo drain * PA levels --------- Co-authored-by: liltenhead --- .../EntitySystems/ParticleAcceleratorSystem.Emitter.cs | 4 ++-- .../Singularity/EntitySystems/SingularitySystem.cs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Emitter.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Emitter.cs index 1dfcb4241c95e8..dbe55bb6e5c19a 100644 --- a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Emitter.cs +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Emitter.cs @@ -47,8 +47,8 @@ private void FireEmitter(EntityUid uid, ParticleAcceleratorPowerState strength, { ParticleAcceleratorPowerState.Standby => 0, ParticleAcceleratorPowerState.Level0 => 1, - ParticleAcceleratorPowerState.Level1 => 3, - ParticleAcceleratorPowerState.Level2 => 6, + ParticleAcceleratorPowerState.Level1 => 2, + ParticleAcceleratorPowerState.Level2 => 3, ParticleAcceleratorPowerState.Level3 => 10, _ => 0, } * 10; diff --git a/Content.Server/Singularity/EntitySystems/SingularitySystem.cs b/Content.Server/Singularity/EntitySystems/SingularitySystem.cs index e4416b21e12114..37e26b9cc0302c 100644 --- a/Content.Server/Singularity/EntitySystems/SingularitySystem.cs +++ b/Content.Server/Singularity/EntitySystems/SingularitySystem.cs @@ -130,9 +130,9 @@ public void SetEnergy(EntityUid uid, float value, SingularityComponent? singular singularity.Energy = value; SetLevel(uid, value switch { - >= 1500 => 6, - >= 1000 => 5, - >= 600 => 4, + >= 2400 => 6, + >= 1600 => 5, + >= 900 => 4, >= 300 => 3, >= 200 => 2, > 0 => 1, @@ -312,8 +312,8 @@ public void UpdateEnergyDrain(EntityUid uid, SingularityComponent comp, Singular { 6 => 20, 5 => 15, - 4 => 10, - 3 => 6, + 4 => 12, + 3 => 8, 2 => 2, 1 => 1, _ => 0 From f6f03514876e673582106a7ea9a22cda1d849a7f Mon Sep 17 00:00:00 2001 From: Kara Date: Mon, 14 Aug 2023 14:02:28 -0700 Subject: [PATCH 21/32] Fix monkeys not getting rotated on crit/death (#19132) --- Resources/Prototypes/Entities/Mobs/NPCs/animals.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 1cba1ecd2f06d6..1047aa230e9e9a 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -796,6 +796,9 @@ speciesId: monkey - type: InventorySlots - type: Cuffable + - type: RotationVisuals + defaultRotation: 90 + horizontalRotation: 90 - type: Fixtures fixtures: fix1: @@ -1411,6 +1414,9 @@ speciesId: monkey - type: InventorySlots - type: Cuffable + - type: RotationVisuals + defaultRotation: 90 + horizontalRotation: 90 - type: Fixtures fixtures: fix1: From ec02907446a74b3401f72eee21f1ceef71d71eea Mon Sep 17 00:00:00 2001 From: Kara Date: Mon, 14 Aug 2023 14:03:20 -0700 Subject: [PATCH 22/32] Various bar-related fixes (#19126) * Various bar-related fixes * smartfwidge * gumbo --- .../Chemistry/UI/ReagentDispenserWindow.xaml | 4 ++-- .../Catalog/ReagentDispensers/beverage.yml | 6 ------ .../Structures/Machines/vending_machines.yml | 16 ++++------------ .../VendingMachines/condiments.rsi/meta.json | 3 --- .../condiments.rsi/normal-unshaded.png | Bin 817 -> 0 bytes .../VendingMachines/smartfridge.rsi/meta.json | 2 +- .../smartfridge.rsi/off-real.png | Bin 2003 -> 0 bytes .../VendingMachines/smartfridge.rsi/off.png | Bin 2278 -> 2003 bytes .../VendingMachines/smartfridge.rsi/on.png | Bin 0 -> 2278 bytes 9 files changed, 7 insertions(+), 24 deletions(-) delete mode 100644 Resources/Textures/Structures/Machines/VendingMachines/condiments.rsi/normal-unshaded.png delete mode 100644 Resources/Textures/Structures/Machines/VendingMachines/smartfridge.rsi/off-real.png create mode 100644 Resources/Textures/Structures/Machines/VendingMachines/smartfridge.rsi/on.png diff --git a/Content.Client/Chemistry/UI/ReagentDispenserWindow.xaml b/Content.Client/Chemistry/UI/ReagentDispenserWindow.xaml index 9cec0962039b83..d01454eb7a7a9b 100644 --- a/Content.Client/Chemistry/UI/ReagentDispenserWindow.xaml +++ b/Content.Client/Chemistry/UI/ReagentDispenserWindow.xaml @@ -1,8 +1,8 @@  + SetSize="620 450" + MinSize="620 450">