From 960cc806cc4cdcabcbe9f08f0bb3e54aa2513c4a Mon Sep 17 00:00:00 2001 From: Winkarst <74284083+Winkarst-cpu@users.noreply.github.com> Date: Sun, 14 Jul 2024 13:24:26 +0300 Subject: [PATCH 001/134] Update AccessLevelControl.xaml.cs to use ISawmill (#29987) * Update AccessLevelControl.xaml.cs to use ISawmill * Update * Silly me * Update --- Content.Client/Access/UI/AccessLevelControl.xaml.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml.cs b/Content.Client/Access/UI/AccessLevelControl.xaml.cs index 34db80b7af9..9f09eceec06 100644 --- a/Content.Client/Access/UI/AccessLevelControl.xaml.cs +++ b/Content.Client/Access/UI/AccessLevelControl.xaml.cs @@ -12,11 +12,17 @@ namespace Content.Client.Access.UI; [GenerateTypedNameReferences] public sealed partial class AccessLevelControl : GridContainer { + [Dependency] private readonly ILogManager _logManager = default!; + + private ISawmill _sawmill = default!; + public readonly Dictionary, Button> ButtonsList = new(); public AccessLevelControl() { RobustXamlLoader.Load(this); + + _sawmill = _logManager.GetSawmill("accesslevelcontrol"); } public void Populate(List> accessLevels, IPrototypeManager prototypeManager) @@ -25,7 +31,7 @@ public void Populate(List> accessLevels, IPrototyp { if (!prototypeManager.TryIndex(access, out var accessLevel)) { - Logger.Error($"Unable to find accesslevel for {access}"); + _sawmill.Error($"Unable to find accesslevel for {access}"); continue; } From 011250f35ed90d285cb37e50949c0e086718a0e7 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sun, 14 Jul 2024 12:25:18 +0200 Subject: [PATCH 002/134] Fix AGhostCommand naming (#29945) --- .../Administration/Commands/{AGhost.cs => AGhostCommand.cs} | 3 +-- Resources/Locale/en-US/administration/commands/aghost.ftl | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) rename Content.Server/Administration/Commands/{AGhost.cs => AGhostCommand.cs} (97%) diff --git a/Content.Server/Administration/Commands/AGhost.cs b/Content.Server/Administration/Commands/AGhostCommand.cs similarity index 97% rename from Content.Server/Administration/Commands/AGhost.cs rename to Content.Server/Administration/Commands/AGhostCommand.cs index 935114e7a68..b24dbbc018c 100644 --- a/Content.Server/Administration/Commands/AGhost.cs +++ b/Content.Server/Administration/Commands/AGhostCommand.cs @@ -12,13 +12,12 @@ namespace Content.Server.Administration.Commands; [AdminCommand(AdminFlags.Admin)] -public sealed class AGhost : LocalizedCommands +public sealed class AGhostCommand : LocalizedCommands { [Dependency] private readonly IEntityManager _entities = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; public override string Command => "aghost"; - public override string Description => LocalizationManager.GetString("aghost-description"); public override string Help => "aghost"; public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) diff --git a/Resources/Locale/en-US/administration/commands/aghost.ftl b/Resources/Locale/en-US/administration/commands/aghost.ftl index 4de0639981e..30cd893dc8f 100644 --- a/Resources/Locale/en-US/administration/commands/aghost.ftl +++ b/Resources/Locale/en-US/administration/commands/aghost.ftl @@ -1,3 +1,3 @@ -aghost-description = Makes you an admin ghost. +cmd-aghost-desc = Makes you or others an admin ghost. aghost-no-mind-self = You can't ghost here! aghost-no-mind-other = They can't ghost here! From 919b3ac9e64a18990bd8dbf21eceae782e2b3f77 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sun, 14 Jul 2024 12:25:57 +0200 Subject: [PATCH 003/134] Change wristwatch meta description (#30036) --- Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml index 7fbb4aecf61..6359f659b57 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml @@ -2,7 +2,7 @@ id: Wristwatch parent: BaseItem name: wristwatch - description: A cheap watch for telling time. How much did you waste playing Space Station 14? + description: A cheap watch for telling time. How much did you waste working on this shift? components: - type: Sprite sprite: Objects/Devices/wristwatch.rsi From 4f479b6c85aec0b775062ece959b34f21171f211 Mon Sep 17 00:00:00 2001 From: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Date: Sun, 14 Jul 2024 12:26:34 +0200 Subject: [PATCH 004/134] Fix RGB toys color when worn/in-hand (#30023) rgbeeeeeeee --- .../Prototypes/Entities/Objects/Fun/toys.yml | 22 ++++++++++++++++++ .../Textures/Objects/Fun/toys.rsi/meta.json | 8 +++++++ .../toys.rsi/rainbowcarpplush-inhand-left.png | Bin 0 -> 15498 bytes .../rainbowcarpplush-inhand-right.png | Bin 0 -> 15496 bytes 4 files changed, 30 insertions(+) create mode 100644 Resources/Textures/Objects/Fun/toys.rsi/rainbowcarpplush-inhand-left.png create mode 100644 Resources/Textures/Objects/Fun/toys.rsi/rainbowcarpplush-inhand-right.png diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index 310f92e60c3..33a322cb25e 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -184,6 +184,19 @@ energy: 2 - type: RgbLightController layers: [ 0 ] + - type: Item + inhandVisuals: + left: + - state: bee-inhand-left + shader: unshaded + right: + - state: bee-inhand-right + shader: unshaded + - type: Clothing + clothingVisuals: + head: + - state: bee-equipped-HELMET + shader: unshaded - type: entity parent: BasePlushie @@ -543,6 +556,15 @@ energy: 2 - type: RgbLightController layers: [ 0 ] + - type: Item + heldPrefix: rainbowcarpplush + inhandVisuals: + left: + - state: rainbowcarpplush-inhand-left + shader: unshaded + right: + - state: rainbowcarpplush-inhand-right + shader: unshaded - type: entity parent: PlushieCarp diff --git a/Resources/Textures/Objects/Fun/toys.rsi/meta.json b/Resources/Textures/Objects/Fun/toys.rsi/meta.json index fc92a479367..fa118695c20 100644 --- a/Resources/Textures/Objects/Fun/toys.rsi/meta.json +++ b/Resources/Textures/Objects/Fun/toys.rsi/meta.json @@ -53,6 +53,14 @@ { "name": "rainbowcarpplush" }, + { + "name": "rainbowcarpplush-inhand-left", + "directions": 4 + }, + { + "name": "rainbowcarpplush-inhand-right", + "directions": 4 + }, { "name": "narplush" }, diff --git a/Resources/Textures/Objects/Fun/toys.rsi/rainbowcarpplush-inhand-left.png b/Resources/Textures/Objects/Fun/toys.rsi/rainbowcarpplush-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..8f28f41fd8513829dc0f926f9bd0fa46f67c05c4 GIT binary patch literal 15498 zcmeI3XHXkS7RSeHT)WHOZtd2s?{2rY>U3J1k!F+-$dUjfFxVExfK6~>B#mH+av{Zsto5kBM&o zz3;ES2!ebc6{(2@zah-uH;q9#Ytz6o@bj%TGRcl0-~FBWYlKXn`7Z)&<6+c0y#kAHiB8`m9wh?jJ z(ee81bbXM4AFTFOx)dOQnV@l=%WSgP6)qLu9ajNtrW)n*+!8un#SdjV$c-#1e%RQ%J?Us)w)k1(wogFe+j-5mnuR zHx)mPrmYGTbvm6wr$k8EQc+P*P!NiVQL$J66asseg~nY1i~V;`kk4^6gk5hVtu#ql zcuZVeM>%K}pU-sUeX8bVwt73V*sIt9il_^>q9P%N*5_oR6~xVe{tCqqgwS4EhOz-h`BPf;edXO+c# zM#u{bbFV61%LLM5pq%zrO0>31b-t^k5gME()M8956<~6KNE(lU#TW#ZWE)JZz%VF? zM_DU|mNJmWta@U|Ko}Vu15(zG0rrmpr|~}&1=d1w40?r;vYByOO`7pk0<~IFm1uP( zr1Y*TMHpqGY+zVm`bxCEYRJpI(iBk^JB?fPM3hDiDug6yP!NPptP2PT5Xdo|P5>}U z1c72gE-(b>3;`0UL@W#NK-6ks_d209l-|MYma5Q(KN%WwuM@hnjRYqhZh|z-=>KdN z^@OR@RU~N#>oW^lw_x?U&$2ioqh{^r1{3K%ldQPSPB1%8#s9qJyoZ?gjADG;J6D10 znbS# z)Z}pMe?PLq>C^mYDlnu?aZnSkXHHBZm8EWsUb(Gp~}&dD(K(2JCmMT@UZ~CQ&8`R zO3fsDH^N_RRL|%y4h)CmI)Q1h+8i!cM6iIv1=C=)Ib5uWU;&2dA8hl>>vEZ}g#G+1p87b_xI zz~O>vu-Y6hRz$FX!v)h|wK-g@h+qMS3#P$pbGTR$!2%8!OoP?taIqqS1spDz2CL2C zVnqZCI9xCdR-41ciU<~PxL_KrHiwH95iH=XafWrmT zV6{11tcYL%hYO~`YIC?)5y1iu7fgfI{vs~l>Z^Z*1>E;@f{T3>%igX4mjZeE$XG3c zWH&>QoIwauQ3-w@AczA)kcTMsFW+o7Ta`526 zptRfVp!D~fj}q}q9_WkQiwz%u~;mT zNTgD!OeO}m0GP14h{|p2?-4iZP%_{SXh`wqX`cW zkBEq9-@bihWMouSREG{7I(F>XsZ%GdRvR51-MMq;n3$L@UAn}^#>U0P#mC2Y?b@|l zw{8gu35kh`Nl8h`$;sWjckj`oN6(%;d-dwoyLa!DloTAtbvm71uQwPB1VI>$#?;i* zw6rvmB>VK~lb)V#GMUU~v&CYeC<@Ta$jAT?z?5m4b~qeh;^3mA%jL?-$^yjt_U+rR zUq1k6z<>b&S58jOz<~pEb8`m`8U$Dk88T$((4l#GdBcVc8$Nvah!G<|3Pz0@1^AC1 zJsNNxJ9g~2apT61A3tHj1dxbHlO|1`JbB8LDO0CT1=y!gpFU&8jF~fM&YCrA_Uzen z=FFKpckaA-^XAW=zhJ?Fg$oxhTC`~K;>AmrECCr`wrtt*<;z#BSg~^D%2lgYtzNyl zprByQnl)?Ju3fio-TL+GH*DBYSXj7mK79Ddkt0Ws z9zAyK*zx1XPnAmsE?vHS`O1|m zSFc{ZcJ12r>(_7GxN-C5&0Du_-M)SM&Ye4V@7}$4@813U_a8iX@bKZoM~@zrm6bhy z{P@X}Cr_U~efI3x^XJcBym$eY=*yQcU%h(u`t|EKZ{ECp`?jK@;@!J<@87@w@ZrP9 zj~_pM`czq2nb6yK5A1bZ{a@`I!c>nT>Dh{ z?|V%n2Ki0MdX#0lzR*7k)%%40_>XOQzrIm9Lw|hH_ouI%jUqC}KOF6!x-!H$uw|R# z>S0?>rY>_nf!qxgNKiY(&M9%%l-Ah6oZ6lpsPBun)10yswmX3uL9{L1PQsK*vZ7=%g>nRopKRG77E$J4ae~T#8JuCHm5R)Ak?~nE zMpIU*Nn;kb)cI-MI0#@TSwiHt+Z+t;4iO4>*}>0lY) zC#%%YX{A}3vC>rx>Fcg?V2~4o!8dlL^R?S69hzao(*c4~q?LLy#!M%P#*qx2<}#7t z>0l`hDqB5ES;~@AE)v&M<=ja(RfQYZ<8||tf;U52uvR?GMG`FSGSak7=dH5XF9=0p zVVlE6SECLw}M zYDthH$YL>RuFOOw_8d>oBv{H$o;F(?OYT%=?EL7;b#9=ho~gX zS3^Zo45-gcsBS^^dd{+VvRC=mFC8|@b0#?n7ejJ8E?E3!%lQs5-xDu&mh-05$l$|u6xT0TEtD)#GqYPmxV2ekm^MR;-`)1qIsm5uDxCvrKprFryf zIR-9N#@$O@;qHpAN#AybyDPeud3JD6EVs)&6Rpq;d2uJN_gIJrFA1bBP^D6+v}ncV ziXO3)o3thBDX@PTt||kSr9KrqDs@b%$`R@)b@ZkR`giWhq_-8kEP(eE)c2xNKFPj~ z@HZP}EBc!Q!{LNMU>dx(fQuIqED&(PGl*Hj^Z2u~<@4Qmj@h zMNvI__DoGpwb^WTyWQb%&@>I`_3G6NEFY|wW!bc}G_ZE?p`+XF&dkgN#CrGc-KS3< z0Hi9f=&)hKh7TV;V#J7%BS(Tnj2=B2@E<#N zEFe5?+_>@M$7g3}Pna+PZ{EE5^XD&EuwdcBg^Ly~TD*8MNcYmEOP4KMmYbWqeEISfD^{#rxpLL2 zRjXI8UbALRUS8hXwQJX{Tep7w`VAX4Y}~kU)223T%hs)1w{6?Def#zu zJ9ZQl6ztr&bJwn2yLa#2vu96XVd37rd-v_zw}1cs0|yQqJb3WXp+kocA3k#A$kC%m zj~zQ!R8(~Q`0*1bPMkb>^3&d2uy4LDNzs{*v^h1LrEJk!~%MZ`|P{{vh2vnK!m literal 0 HcmV?d00001 From 07535e8ecfbbba14f2845629306af192d11ffce9 Mon Sep 17 00:00:00 2001 From: Winkarst <74284083+Winkarst-cpu@users.noreply.github.com> Date: Sun, 14 Jul 2024 13:26:56 +0300 Subject: [PATCH 005/134] Clumsy proof grappling gun (#29904) Make grappling gun clumsy proof --- .../Entities/Objects/Weapons/Guns/Launchers/launchers.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index 19a0cf30e86..0ecad70a64e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -251,6 +251,7 @@ - type: Gun soundGunshot: /Audio/Weapons/Guns/Gunshots/harpoon.ogg fireRate: 0.5 + clumsyProof: true - type: BasicEntityAmmoProvider proto: GrapplingHook capacity: 1 From f90538cca79340378fdbf5ad44decba2d4a46f68 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 14 Jul 2024 10:28:02 +0000 Subject: [PATCH 006/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 0a41c2e2e9c..d06bda3324f 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,19 +1,4 @@ Entries: -- author: Weax - changes: - - message: The CLF3 reaction now requires heating first before you can engulf chemistry - in fiery death. - type: Tweak - id: 6417 - time: '2024-04-22T08:44:14.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27187 -- author: Potato1234_x - changes: - - message: Added Psicodine, Mannitol, Lipolicide and Happiness. - type: Add - id: 6418 - time: '2024-04-22T08:45:39.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27134 - author: Terraspark4941 changes: - message: Updated the engineering section of the guidebook! @@ -3813,3 +3798,17 @@ id: 6916 time: '2024-07-14T02:59:45.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29979 +- author: SlamBamActionman + changes: + - message: RGBee and Rainbow Carp plushies now cycle color when held/worn. + type: Fix + id: 6917 + time: '2024-07-14T10:26:34.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30023 +- author: Winkarst-cpu + changes: + - message: Now grappling gun is clumsy proof. + type: Tweak + id: 6918 + time: '2024-07-14T10:26:56.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29904 From 7d9653fff7f7c415e317c3fab03a2162da7983bf Mon Sep 17 00:00:00 2001 From: osjarw <62134478+osjarw@users.noreply.github.com> Date: Sun, 14 Jul 2024 13:28:46 +0300 Subject: [PATCH 007/134] Fix HTN/NPC better plan selection (#30017) * recording commit * Remove debugging/recording content --- Content.Server/NPC/HTN/HTNPlanJob.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/NPC/HTN/HTNPlanJob.cs b/Content.Server/NPC/HTN/HTNPlanJob.cs index d6d10ad311f..8158303524a 100644 --- a/Content.Server/NPC/HTN/HTNPlanJob.cs +++ b/Content.Server/NPC/HTN/HTNPlanJob.cs @@ -160,9 +160,9 @@ private bool TryFindSatisfiedMethod(HTNCompoundTask compoundId, Queue t { var compound = _protoManager.Index(compoundId.Task); - for (var i = mtrIndex; i < compound.Branches.Count; i++) + for (; mtrIndex < compound.Branches.Count; mtrIndex++) { - var branch = compound.Branches[i]; + var branch = compound.Branches[mtrIndex]; var isValid = true; foreach (var con in branch.Preconditions) From 1c74ffb8e475d619e188864194333ca8890509e4 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Sun, 14 Jul 2024 16:58:48 +0300 Subject: [PATCH 008/134] Ambient music rules refactor (#29921) * refactor * dutypo --- .../Audio/ContentAudioSystem.AmbientMusic.cs | 1 + Content.Shared/Audio/AmbientMusicPrototype.cs | 1 + Content.Shared/Random/Rules/AlwaysTrue.cs | 12 + Content.Shared/Random/Rules/GridInRange.cs | 39 +++ Content.Shared/Random/Rules/InSpace.cs | 18 ++ Content.Shared/Random/Rules/NearbyAccess.cs | 77 ++++++ .../Random/Rules/NearbyComponents.cs | 71 +++++ Content.Shared/Random/Rules/NearbyEntities.cs | 58 ++++ .../Random/Rules/NearbyTilesPercent.cs | 79 ++++++ Content.Shared/Random/Rules/OnMapGrid.cs | 19 ++ Content.Shared/Random/Rules/RulesSystem.cs | 39 +++ Content.Shared/Random/RulesPrototype.cs | 141 ---------- Content.Shared/Random/RulesSystem.cs | 247 ------------------ 13 files changed, 414 insertions(+), 388 deletions(-) create mode 100644 Content.Shared/Random/Rules/AlwaysTrue.cs create mode 100644 Content.Shared/Random/Rules/GridInRange.cs create mode 100644 Content.Shared/Random/Rules/InSpace.cs create mode 100644 Content.Shared/Random/Rules/NearbyAccess.cs create mode 100644 Content.Shared/Random/Rules/NearbyComponents.cs create mode 100644 Content.Shared/Random/Rules/NearbyEntities.cs create mode 100644 Content.Shared/Random/Rules/NearbyTilesPercent.cs create mode 100644 Content.Shared/Random/Rules/OnMapGrid.cs create mode 100644 Content.Shared/Random/Rules/RulesSystem.cs delete mode 100644 Content.Shared/Random/RulesPrototype.cs delete mode 100644 Content.Shared/Random/RulesSystem.cs diff --git a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs index 84b787a4ec9..d60c978ccf5 100644 --- a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs +++ b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs @@ -4,6 +4,7 @@ using Content.Shared.CCVar; using Content.Shared.GameTicking; using Content.Shared.Random; +using Content.Shared.Random.Rules; using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Client.ResourceManagement; diff --git a/Content.Shared/Audio/AmbientMusicPrototype.cs b/Content.Shared/Audio/AmbientMusicPrototype.cs index 54f70f57280..219c41527d1 100644 --- a/Content.Shared/Audio/AmbientMusicPrototype.cs +++ b/Content.Shared/Audio/AmbientMusicPrototype.cs @@ -1,4 +1,5 @@ using Content.Shared.Random; +using Content.Shared.Random.Rules; using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; diff --git a/Content.Shared/Random/Rules/AlwaysTrue.cs b/Content.Shared/Random/Rules/AlwaysTrue.cs new file mode 100644 index 00000000000..98b81fae793 --- /dev/null +++ b/Content.Shared/Random/Rules/AlwaysTrue.cs @@ -0,0 +1,12 @@ +namespace Content.Shared.Random.Rules; + +/// +/// Always returns true. Used for fallbacks. +/// +public sealed partial class AlwaysTrueRule : RulesRule +{ + public override bool Check(EntityManager entManager, EntityUid uid) + { + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/GridInRange.cs b/Content.Shared/Random/Rules/GridInRange.cs new file mode 100644 index 00000000000..8cbbef1cdc2 --- /dev/null +++ b/Content.Shared/Random/Rules/GridInRange.cs @@ -0,0 +1,39 @@ +using System.Numerics; +using Robust.Shared.Map; + +namespace Content.Shared.Random.Rules; + +/// +/// Returns true if on a grid or in range of one. +/// +public sealed partial class GridInRangeRule : RulesRule +{ + [DataField] + public float Range = 10f; + + public override bool Check(EntityManager entManager, EntityUid uid) + { + if (!entManager.TryGetComponent(uid, out TransformComponent? xform)) + { + return false; + } + + if (xform.GridUid != null) + { + return !Inverted; + } + + var transform = entManager.System(); + var mapManager = IoCManager.Resolve(); + + var worldPos = transform.GetWorldPosition(xform); + var gridRange = new Vector2(Range, Range); + + foreach (var _ in mapManager.FindGridsIntersecting(xform.MapID, new Box2(worldPos - gridRange, worldPos + gridRange))) + { + return !Inverted; + } + + return false; + } +} diff --git a/Content.Shared/Random/Rules/InSpace.cs b/Content.Shared/Random/Rules/InSpace.cs new file mode 100644 index 00000000000..8163e1f6be9 --- /dev/null +++ b/Content.Shared/Random/Rules/InSpace.cs @@ -0,0 +1,18 @@ +namespace Content.Shared.Random.Rules; + +/// +/// Returns true if the attached entity is in space. +/// +public sealed partial class InSpaceRule : RulesRule +{ + public override bool Check(EntityManager entManager, EntityUid uid) + { + if (!entManager.TryGetComponent(uid, out TransformComponent? xform) || + xform.GridUid != null) + { + return Inverted; + } + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/NearbyAccess.cs b/Content.Shared/Random/Rules/NearbyAccess.cs new file mode 100644 index 00000000000..2a8ad077c6e --- /dev/null +++ b/Content.Shared/Random/Rules/NearbyAccess.cs @@ -0,0 +1,77 @@ +using Content.Shared.Access; +using Content.Shared.Access.Components; +using Content.Shared.Access.Systems; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Random.Rules; + +/// +/// Checks for an entity nearby with the specified access. +/// +public sealed partial class NearbyAccessRule : RulesRule +{ + // This exists because of door electronics contained inside doors. + /// + /// Does the access entity need to be anchored. + /// + [DataField] + public bool Anchored = true; + + /// + /// Count of entities that need to be nearby. + /// + [DataField] + public int Count = 1; + + [DataField(required: true)] + public List> Access = new(); + + [DataField] + public float Range = 10f; + + public override bool Check(EntityManager entManager, EntityUid uid) + { + var xformQuery = entManager.GetEntityQuery(); + + if (!xformQuery.TryGetComponent(uid, out var xform) || + xform.MapUid == null) + { + return false; + } + + var transform = entManager.System(); + var lookup = entManager.System(); + var reader = entManager.System(); + + var found = false; + var worldPos = transform.GetWorldPosition(xform, xformQuery); + var count = 0; + + // TODO: Update this when we get the callback version + var entities = new HashSet>(); + lookup.GetEntitiesInRange(xform.MapID, worldPos, Range, entities); + foreach (var comp in entities) + { + if (!reader.AreAccessTagsAllowed(Access, comp) || + Anchored && + (!xformQuery.TryGetComponent(comp, out var compXform) || + !compXform.Anchored)) + { + continue; + } + + count++; + + if (count < Count) + continue; + + found = true; + break; + } + + if (!found) + return Inverted; + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/NearbyComponents.cs b/Content.Shared/Random/Rules/NearbyComponents.cs new file mode 100644 index 00000000000..13108e88d6c --- /dev/null +++ b/Content.Shared/Random/Rules/NearbyComponents.cs @@ -0,0 +1,71 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Random.Rules; + +public sealed partial class NearbyComponentsRule : RulesRule +{ + /// + /// Does the entity need to be anchored. + /// + [DataField] + public bool Anchored; + + [DataField] + public int Count; + + [DataField(required: true)] + public ComponentRegistry Components = default!; + + [DataField] + public float Range = 10f; + + public override bool Check(EntityManager entManager, EntityUid uid) + { + var inRange = new HashSet>(); + var xformQuery = entManager.GetEntityQuery(); + + if (!xformQuery.TryGetComponent(uid, out var xform) || + xform.MapUid == null) + { + return false; + } + + var transform = entManager.System(); + var lookup = entManager.System(); + + var found = false; + var worldPos = transform.GetWorldPosition(xform); + var count = 0; + + foreach (var compType in Components.Values) + { + inRange.Clear(); + lookup.GetEntitiesInRange(compType.Component.GetType(), xform.MapID, worldPos, Range, inRange); + foreach (var comp in inRange) + { + if (Anchored && + (!xformQuery.TryGetComponent(comp, out var compXform) || + !compXform.Anchored)) + { + continue; + } + + count++; + + if (count < Count) + continue; + + found = true; + break; + } + + if (found) + break; + } + + if (!found) + return Inverted; + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/NearbyEntities.cs b/Content.Shared/Random/Rules/NearbyEntities.cs new file mode 100644 index 00000000000..0754750bc47 --- /dev/null +++ b/Content.Shared/Random/Rules/NearbyEntities.cs @@ -0,0 +1,58 @@ +using Content.Shared.Whitelist; + +namespace Content.Shared.Random.Rules; + +/// +/// Checks for entities matching the whitelist in range. +/// This is more expensive than so prefer that! +/// +public sealed partial class NearbyEntitiesRule : RulesRule +{ + /// + /// How many of the entity need to be nearby. + /// + [DataField] + public int Count = 1; + + [DataField(required: true)] + public EntityWhitelist Whitelist = new(); + + [DataField] + public float Range = 10f; + + public override bool Check(EntityManager entManager, EntityUid uid) + { + if (!entManager.TryGetComponent(uid, out TransformComponent? xform) || + xform.MapUid == null) + { + return false; + } + + var transform = entManager.System(); + var lookup = entManager.System(); + var whitelistSystem = entManager.System(); + + var found = false; + var worldPos = transform.GetWorldPosition(xform); + var count = 0; + + foreach (var ent in lookup.GetEntitiesInRange(xform.MapID, worldPos, Range)) + { + if (whitelistSystem.IsWhitelistFail(Whitelist, ent)) + continue; + + count++; + + if (count < Count) + continue; + + found = true; + break; + } + + if (!found) + return Inverted; + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/NearbyTilesPercent.cs b/Content.Shared/Random/Rules/NearbyTilesPercent.cs new file mode 100644 index 00000000000..465ac8dc5c6 --- /dev/null +++ b/Content.Shared/Random/Rules/NearbyTilesPercent.cs @@ -0,0 +1,79 @@ +using Content.Shared.Maps; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Physics.Components; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Random.Rules; + +public sealed partial class NearbyTilesPercentRule : RulesRule +{ + /// + /// If there are anchored entities on the tile do we ignore the tile. + /// + [DataField] + public bool IgnoreAnchored; + + [DataField(required: true)] + public float Percent; + + [DataField(required: true)] + public List> Tiles = new(); + + [DataField] + public float Range = 10f; + + public override bool Check(EntityManager entManager, EntityUid uid) + { + if (!entManager.TryGetComponent(uid, out TransformComponent? xform) || + !entManager.TryGetComponent(xform.GridUid, out var grid)) + { + return false; + } + + var transform = entManager.System(); + var tileDef = IoCManager.Resolve(); + + var physicsQuery = entManager.GetEntityQuery(); + var tileCount = 0; + var matchingTileCount = 0; + + foreach (var tile in grid.GetTilesIntersecting(new Circle(transform.GetWorldPosition(xform), + Range))) + { + // Only consider collidable anchored (for reasons some subfloor stuff has physics but non-collidable) + if (IgnoreAnchored) + { + var gridEnum = grid.GetAnchoredEntitiesEnumerator(tile.GridIndices); + var found = false; + + while (gridEnum.MoveNext(out var ancUid)) + { + if (!physicsQuery.TryGetComponent(ancUid, out var physics) || + !physics.CanCollide) + { + continue; + } + + found = true; + break; + } + + if (found) + continue; + } + + tileCount++; + + if (!Tiles.Contains(tileDef[tile.Tile.TypeId].ID)) + continue; + + matchingTileCount++; + } + + if (tileCount == 0 || matchingTileCount / (float) tileCount < Percent) + return Inverted; + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/OnMapGrid.cs b/Content.Shared/Random/Rules/OnMapGrid.cs new file mode 100644 index 00000000000..bea841872eb --- /dev/null +++ b/Content.Shared/Random/Rules/OnMapGrid.cs @@ -0,0 +1,19 @@ +namespace Content.Shared.Random.Rules; + +/// +/// Returns true if griduid and mapuid match (AKA on 'planet'). +/// +public sealed partial class OnMapGridRule : RulesRule +{ + public override bool Check(EntityManager entManager, EntityUid uid) + { + if (!entManager.TryGetComponent(uid, out TransformComponent? xform) || + xform.GridUid != xform.MapUid || + xform.MapUid == null) + { + return Inverted; + } + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/RulesSystem.cs b/Content.Shared/Random/Rules/RulesSystem.cs new file mode 100644 index 00000000000..1957beab510 --- /dev/null +++ b/Content.Shared/Random/Rules/RulesSystem.cs @@ -0,0 +1,39 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Random.Rules; + +/// +/// Rules-based item selection. Can be used for any sort of conditional selection +/// Every single condition needs to be true for this to be selected. +/// e.g. "choose maintenance audio if 90% of tiles nearby are maintenance tiles" +/// +[Prototype("rules")] +public sealed partial class RulesPrototype : IPrototype +{ + [IdDataField] public string ID { get; } = string.Empty; + + [DataField("rules", required: true)] + public List Rules = new(); +} + +[ImplicitDataDefinitionForInheritors] +public abstract partial class RulesRule +{ + [DataField] + public bool Inverted; + public abstract bool Check(EntityManager entManager, EntityUid uid); +} + +public sealed class RulesSystem : EntitySystem +{ + public bool IsTrue(EntityUid uid, RulesPrototype rules) + { + foreach (var rule in rules.Rules) + { + if (!rule.Check(EntityManager, uid)) + return false; + } + + return true; + } +} diff --git a/Content.Shared/Random/RulesPrototype.cs b/Content.Shared/Random/RulesPrototype.cs deleted file mode 100644 index 20961af8e72..00000000000 --- a/Content.Shared/Random/RulesPrototype.cs +++ /dev/null @@ -1,141 +0,0 @@ -using Content.Shared.Access; -using Content.Shared.Maps; -using Content.Shared.Whitelist; -using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; - -namespace Content.Shared.Random; - -/// -/// Rules-based item selection. Can be used for any sort of conditional selection -/// Every single condition needs to be true for this to be selected. -/// e.g. "choose maintenance audio if 90% of tiles nearby are maintenance tiles" -/// -[Prototype("rules")] -public sealed partial class RulesPrototype : IPrototype -{ - [IdDataField] public string ID { get; } = string.Empty; - - [DataField("rules", required: true)] - public List Rules = new(); -} - -[ImplicitDataDefinitionForInheritors] -public abstract partial class RulesRule -{ - -} - -/// -/// Returns true if the attached entity is in space. -/// -public sealed partial class InSpaceRule : RulesRule -{ - -} - -/// -/// Checks for entities matching the whitelist in range. -/// This is more expensive than so prefer that! -/// -public sealed partial class NearbyEntitiesRule : RulesRule -{ - /// - /// How many of the entity need to be nearby. - /// - [DataField("count")] - public int Count = 1; - - [DataField("whitelist", required: true)] - public EntityWhitelist Whitelist = new(); - - [DataField("range")] - public float Range = 10f; -} - -public sealed partial class NearbyTilesPercentRule : RulesRule -{ - /// - /// If there are anchored entities on the tile do we ignore the tile. - /// - [DataField("ignoreAnchored")] public bool IgnoreAnchored; - - [DataField("percent", required: true)] - public float Percent; - - [DataField("tiles", required: true, customTypeSerializer:typeof(PrototypeIdListSerializer))] - public List Tiles = new(); - - [DataField("range")] - public float Range = 10f; -} - -/// -/// Always returns true. Used for fallbacks. -/// -public sealed partial class AlwaysTrueRule : RulesRule -{ - -} - -/// -/// Returns true if on a grid or in range of one. -/// -public sealed partial class GridInRangeRule : RulesRule -{ - [DataField("range")] - public float Range = 10f; - - [DataField("inverted")] - public bool Inverted = false; -} - -/// -/// Returns true if griduid and mapuid match (AKA on 'planet'). -/// -public sealed partial class OnMapGridRule : RulesRule -{ - -} - -/// -/// Checks for an entity nearby with the specified access. -/// -public sealed partial class NearbyAccessRule : RulesRule -{ - // This exists because of doorelectronics contained inside doors. - /// - /// Does the access entity need to be anchored. - /// - [DataField("anchored")] - public bool Anchored = true; - - /// - /// Count of entities that need to be nearby. - /// - [DataField("count")] - public int Count = 1; - - [DataField("access", required: true)] - public List> Access = new(); - - [DataField("range")] - public float Range = 10f; -} - -public sealed partial class NearbyComponentsRule : RulesRule -{ - /// - /// Does the entity need to be anchored. - /// - [DataField("anchored")] - public bool Anchored; - - [DataField("count")] public int Count; - - [DataField("components", required: true)] - public ComponentRegistry Components = default!; - - [DataField("range")] - public float Range = 10f; -} diff --git a/Content.Shared/Random/RulesSystem.cs b/Content.Shared/Random/RulesSystem.cs deleted file mode 100644 index 58d67c268e3..00000000000 --- a/Content.Shared/Random/RulesSystem.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System.Numerics; -using Content.Shared.Access.Components; -using Content.Shared.Access.Systems; -using Content.Shared.Whitelist; -using Robust.Shared.Map; -using Robust.Shared.Map.Components; -using Robust.Shared.Physics.Components; - -namespace Content.Shared.Random; - -public sealed class RulesSystem : EntitySystem -{ - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly ITileDefinitionManager _tileDef = default!; - [Dependency] private readonly AccessReaderSystem _reader = default!; - [Dependency] private readonly EntityLookupSystem _lookup = default!; - [Dependency] private readonly SharedTransformSystem _transform = default!; - [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; - public bool IsTrue(EntityUid uid, RulesPrototype rules) - { - var inRange = new HashSet>(); - foreach (var rule in rules.Rules) - { - switch (rule) - { - case AlwaysTrueRule: - break; - case GridInRangeRule griddy: - { - if (!TryComp(uid, out TransformComponent? xform)) - { - return false; - } - - if (xform.GridUid != null) - { - return !griddy.Inverted; - } - - var worldPos = _transform.GetWorldPosition(xform); - var gridRange = new Vector2(griddy.Range, griddy.Range); - - foreach (var _ in _mapManager.FindGridsIntersecting( - xform.MapID, - new Box2(worldPos - gridRange, worldPos + gridRange))) - { - return !griddy.Inverted; - } - - break; - } - case InSpaceRule: - { - if (!TryComp(uid, out TransformComponent? xform) || - xform.GridUid != null) - { - return false; - } - - break; - } - case NearbyAccessRule access: - { - var xformQuery = GetEntityQuery(); - - if (!xformQuery.TryGetComponent(uid, out var xform) || - xform.MapUid == null) - { - return false; - } - - var found = false; - var worldPos = _transform.GetWorldPosition(xform, xformQuery); - var count = 0; - - // TODO: Update this when we get the callback version - var entities = new HashSet>(); - _lookup.GetEntitiesInRange(xform.MapID, worldPos, access.Range, entities); - foreach (var comp in entities) - { - if (!_reader.AreAccessTagsAllowed(access.Access, comp) || - access.Anchored && - (!xformQuery.TryGetComponent(comp, out var compXform) || - !compXform.Anchored)) - { - continue; - } - - count++; - - if (count < access.Count) - continue; - - found = true; - break; - } - - if (!found) - return false; - - break; - } - case NearbyComponentsRule nearbyComps: - { - var xformQuery = GetEntityQuery(); - - if (!xformQuery.TryGetComponent(uid, out var xform) || - xform.MapUid == null) - { - return false; - } - - var found = false; - var worldPos = _transform.GetWorldPosition(xform); - var count = 0; - - foreach (var compType in nearbyComps.Components.Values) - { - inRange.Clear(); - _lookup.GetEntitiesInRange(compType.Component.GetType(), xform.MapID, worldPos, nearbyComps.Range, inRange); - foreach (var comp in inRange) - { - if (nearbyComps.Anchored && - (!xformQuery.TryGetComponent(comp, out var compXform) || - !compXform.Anchored)) - { - continue; - } - - count++; - - if (count < nearbyComps.Count) - continue; - - found = true; - break; - } - - if (found) - break; - } - - if (!found) - return false; - - break; - } - case NearbyEntitiesRule entity: - { - if (!TryComp(uid, out TransformComponent? xform) || - xform.MapUid == null) - { - return false; - } - - var found = false; - var worldPos = _transform.GetWorldPosition(xform); - var count = 0; - - foreach (var ent in _lookup.GetEntitiesInRange(xform.MapID, worldPos, entity.Range)) - { - if (_whitelistSystem.IsWhitelistFail(entity.Whitelist, ent)) - continue; - - count++; - - if (count < entity.Count) - continue; - - found = true; - break; - } - - if (!found) - return false; - - break; - } - case NearbyTilesPercentRule tiles: - { - if (!TryComp(uid, out TransformComponent? xform) || - !TryComp(xform.GridUid, out var grid)) - { - return false; - } - - var physicsQuery = GetEntityQuery(); - var tileCount = 0; - var matchingTileCount = 0; - - foreach (var tile in grid.GetTilesIntersecting(new Circle(_transform.GetWorldPosition(xform), - tiles.Range))) - { - // Only consider collidable anchored (for reasons some subfloor stuff has physics but non-collidable) - if (tiles.IgnoreAnchored) - { - var gridEnum = grid.GetAnchoredEntitiesEnumerator(tile.GridIndices); - var found = false; - - while (gridEnum.MoveNext(out var ancUid)) - { - if (!physicsQuery.TryGetComponent(ancUid, out var physics) || - !physics.CanCollide) - { - continue; - } - - found = true; - break; - } - - if (found) - continue; - } - - tileCount++; - - if (!tiles.Tiles.Contains(_tileDef[tile.Tile.TypeId].ID)) - continue; - - matchingTileCount++; - } - - if (tileCount == 0 || matchingTileCount / (float) tileCount < tiles.Percent) - return false; - - break; - } - case OnMapGridRule: - { - if (!TryComp(uid, out TransformComponent? xform) || - xform.GridUid != xform.MapUid || - xform.MapUid == null) - { - return false; - } - - break; - } - default: - throw new NotImplementedException(); - } - } - - return true; - } -} From a0052c5b0996dd88a4ed2d4fd5c8c15a030e8e93 Mon Sep 17 00:00:00 2001 From: themias <89101928+themias@users.noreply.github.com> Date: Sun, 14 Jul 2024 10:08:39 -0400 Subject: [PATCH 009/134] Prevent virtual item storage and popups (#30020) * Prevent virtual item storage and popups * fix typo * add comment --- Content.Shared/Interaction/SmartEquipSystem.cs | 11 ++++++----- .../Inventory/VirtualItem/SharedVirtualItemSystem.cs | 8 ++++++++ .../Prototypes/Entities/Virtual/virtual_item.yml | 1 + 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Content.Shared/Interaction/SmartEquipSystem.cs b/Content.Shared/Interaction/SmartEquipSystem.cs index bba294db28d..4feb0445f8f 100644 --- a/Content.Shared/Interaction/SmartEquipSystem.cs +++ b/Content.Shared/Interaction/SmartEquipSystem.cs @@ -62,21 +62,22 @@ private void HandleSmartEquip(ICommonSession? session, string equipmentSlot) if (playerSession.AttachedEntity is not { Valid: true } uid || !Exists(uid)) return; - if (!_actionBlocker.CanInteract(uid, null)) - return; - // early out if we don't have any hands or a valid inventory slot if (!TryComp(uid, out var hands) || hands.ActiveHand == null) return; + var handItem = hands.ActiveHand.HeldEntity; + + // can the user interact, and is the item interactable? e.g. virtual items + if (!_actionBlocker.CanInteract(uid, handItem)) + return; + if (!TryComp(uid, out var inventory) || !_inventory.HasSlot(uid, equipmentSlot, inventory)) { _popup.PopupClient(Loc.GetString("smart-equip-missing-equipment-slot", ("slotName", equipmentSlot)), uid, uid); return; } - var handItem = hands.ActiveHand.HeldEntity; - // early out if we have an item and cant drop it at all if (handItem != null && !_hands.CanDropHeld(uid, hands.ActiveHand)) { diff --git a/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs b/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs index cd0863ec88d..8b9c052c8d5 100644 --- a/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs +++ b/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs @@ -2,6 +2,7 @@ using Content.Shared.Hands; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; +using Content.Shared.Interaction.Events; using Content.Shared.Inventory.Events; using Content.Shared.Item; using Content.Shared.Popups; @@ -43,6 +44,7 @@ public override void Initialize() SubscribeLocalEvent(OnBeingUnequippedAttempt); SubscribeLocalEvent(OnBeforeRangedInteract); + SubscribeLocalEvent(OnGettingInteractedWithAttemptEvent); } /// @@ -72,6 +74,12 @@ private void OnBeforeRangedInteract(Entity ent, ref Before args.Handled = true; } + private void OnGettingInteractedWithAttemptEvent(Entity ent, ref GettingInteractedWithAttemptEvent args) + { + // No interactions with a virtual item, please. + args.Cancelled = true; + } + #region Hands /// diff --git a/Resources/Prototypes/Entities/Virtual/virtual_item.yml b/Resources/Prototypes/Entities/Virtual/virtual_item.yml index ed742435501..088de6a6da5 100644 --- a/Resources/Prototypes/Entities/Virtual/virtual_item.yml +++ b/Resources/Prototypes/Entities/Virtual/virtual_item.yml @@ -5,4 +5,5 @@ noSpawn: true components: - type: Item + size: Ginormous # no storage insertion visuals - type: VirtualItem From b6115b672aa6a67e693c8ac21ada4083f5eb0871 Mon Sep 17 00:00:00 2001 From: CookieMasterT <124045269+CookieMasterT@users.noreply.github.com> Date: Sun, 14 Jul 2024 16:09:41 +0200 Subject: [PATCH 010/134] Add petting cyborgs (#30037) added petting borgs, adjusted interactions --- .../interaction-popup-component.ftl | 14 ++++++ .../Mobs/Cyborgs/base_borg_chassis.yml | 1 + .../Entities/Mobs/Cyborgs/borg_chassis.yml | 45 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl index 55be1fb3b97..10773d6de84 100644 --- a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl +++ b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl @@ -60,12 +60,26 @@ petting-success-honkbot = You pet {THE($target)} on {POSS-ADJ($target)} slippery petting-success-mimebot = You pet {THE($target)} on {POSS-ADJ($target)} cold metal head. petting-success-cleanbot = You pet {THE($target)} on {POSS-ADJ($target)} damp metal head. petting-success-medibot = You pet {THE($target)} on {POSS-ADJ($target)} sterile metal head. +petting-success-generic-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} metal head. +petting-success-salvage-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} dirty metal head. +petting-success-engineer-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} reflective metal head. +petting-success-janitor-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} damp metal head. +petting-success-medical-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} sterile metal head. +petting-success-service-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} dapper looking metal head. +petting-success-syndicate-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} menacing metal head. petting-success-recycler = You pet {THE($target)} on {POSS-ADJ($target)} mildly threatening steel exterior. petting-failure-honkbot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BASIC($target, "honk", "honks")} in refusal! petting-failure-cleanbot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy mopping! petting-failure-mimebot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy miming! petting-failure-medibot = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} syringe nearly stabs your hand! +petting-failure-generic-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy stating laws! +petting-failure-salvage-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy drilling! +petting-failure-engineer-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy repairing! +petting-failure-janitor-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy cleaning! +petting-failure-medical-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy saving lives! +petting-failure-service-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy serving others! +petting-failure-syndicate-cyborg = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} treacherous affiliation makes you reconsider. ## Rattling fences diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index 6656a7aadbf..2618207b7a9 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -150,6 +150,7 @@ - type: Lock locked: true breakOnEmag: false + unlockOnClick: false - type: ActivatableUIRequiresLock - type: LockedWiresPanel - type: Damageable diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml index 075ac534c62..3a17869dc8f 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml @@ -29,6 +29,11 @@ node: cyborg - type: Speech speechVerb: Robotic + - type: InteractionPopup + interactSuccessString: petting-success-generic-cyborg + interactFailureString: petting-failure-generic-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisMining @@ -85,6 +90,11 @@ access: [["Cargo"], ["Salvage"], ["Command"], ["Research"]] - type: Inventory templateId: borgTall + - type: InteractionPopup + interactSuccessString: petting-success-salvage-cyborg + interactFailureString: petting-failure-salvage-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisEngineer @@ -133,6 +143,11 @@ access: [["Engineering"], ["Command"], ["Research"]] - type: Inventory templateId: borgShort + - type: InteractionPopup + interactSuccessString: petting-success-engineer-cyborg + interactFailureString: petting-failure-engineer-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisJanitor @@ -189,6 +204,11 @@ access: [["Service"], ["Command"], ["Research"]] - type: Inventory templateId: borgShort + - type: InteractionPopup + interactSuccessString: petting-success-janitor-cyborg + interactFailureString: petting-failure-janitor-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisMedical @@ -248,6 +268,11 @@ - type: FootstepModifier footstepSoundCollection: collection: FootstepHoverBorg + - type: InteractionPopup + interactSuccessString: petting-success-medical-cyborg + interactFailureString: petting-failure-medical-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisService @@ -296,6 +321,11 @@ access: [["Service"], ["Command"], ["Research"]] - type: Inventory templateId: borgTall + - type: InteractionPopup + interactSuccessString: petting-success-service-cyborg + interactFailureString: petting-failure-service-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisSyndicateAssault @@ -325,6 +355,11 @@ noMindState: synd_sec - type: Construction node: syndicateassault + - type: InteractionPopup + interactSuccessString: petting-success-syndicate-cyborg + interactFailureString: petting-failure-syndicate-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisSyndicateMedical @@ -357,6 +392,11 @@ - type: ShowHealthBars damageContainers: - Biological + - type: InteractionPopup + interactSuccessString: petting-success-syndicate-cyborg + interactFailureString: petting-failure-syndicate-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisSyndicateSaboteur @@ -390,3 +430,8 @@ damageContainers: - Inorganic - Silicon + - type: InteractionPopup + interactSuccessString: petting-success-syndicate-cyborg + interactFailureString: petting-failure-syndicate-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg From f6d827f5d98c772b38c8fdc960be2f0a4026c6bf Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 14 Jul 2024 14:10:48 +0000 Subject: [PATCH 011/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d06bda3324f..f0ef8806add 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Terraspark4941 - changes: - - message: Updated the engineering section of the guidebook! - type: Tweak - id: 6419 - time: '2024-04-22T08:58:54.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/26851 - author: eclips_e changes: - message: Slimepeople can now morph into a "geras"--a smaller slime form that can @@ -3812,3 +3805,12 @@ id: 6918 time: '2024-07-14T10:26:56.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29904 +- author: HahayesSiH + changes: + - message: It is now possible to pet cyborgs. + type: Add + - message: Clicking on cyborgs and opening the strip menu no longer unlocks them. + type: Tweak + id: 6919 + time: '2024-07-14T14:09:41.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30037 From 35cd013e88091311fb2c179aa8523f9d68f78bc1 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Sun, 14 Jul 2024 15:11:40 +0000 Subject: [PATCH 012/134] make ninja shoes magboots (#28586) Co-authored-by: deltanedas <@deltanedas:kde.org> --- Resources/Prototypes/Entities/Clothing/Shoes/specific.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml b/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml index 4ae752345a7..80d5eab249b 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml @@ -121,6 +121,7 @@ - type: Clothing sprite: Clothing/Shoes/Specific/spaceninja.rsi - type: NoSlip + - type: Magboots # always have gravity because le suction cups - type: ClothingSpeedModifier # ninja are masters of sneaking around relatively quickly, won't break cloak walkModifier: 1.1 From 3b85b1e43e16a8d183fca4438e8d0eabb57900dc Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sun, 14 Jul 2024 17:12:25 +0200 Subject: [PATCH 013/134] make scarves eatable again (#29959) --- .../Prototypes/Entities/Clothing/Neck/base_clothingneck.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml index d2fffb81537..d7f04f49bc3 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml @@ -38,3 +38,4 @@ - type: Tag tags: - Scarf + - ClothMade From 17c23f11c5c798814c2d948af02f958e6384a779 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 14 Jul 2024 15:13:31 +0000 Subject: [PATCH 014/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 37 ++++++++++++------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index f0ef8806add..0b965b19702 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,27 +1,4 @@ Entries: -- author: eclips_e - changes: - - message: Slimepeople can now morph into a "geras"--a smaller slime form that can - pass under grilles, at the cost of dropping all of their inventory. They can - also be picked up with two hands and placed into duffelbags. - type: Add - - message: Slimepeople now have an internal 2x2 storage that they (and anyone around - them) can access. It is not dropped when morphing into a geras! - type: Add - - message: Slimepeople now have slightly increased regeneration and a slightly meatier - punch, but slower attacks. - type: Add - id: 6420 - time: '2024-04-22T10:03:03.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/23425 -- author: FungiFellow - changes: - - message: Syndi-Cats are now 6TC, Insulated, Available to Syndies, Can Move in - Space, Open Doors, and Hit Harder - type: Tweak - id: 6421 - time: '2024-04-22T12:18:28.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27222 - author: Tayrtahn changes: - message: Ghosts can no longer trigger artifacts by examining them. @@ -3814,3 +3791,17 @@ id: 6919 time: '2024-07-14T14:09:41.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30037 +- author: deltanedas + changes: + - message: Fixed ninja shoes not working as magboots. + type: Fix + id: 6920 + time: '2024-07-14T15:11:40.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28586 +- author: lzk228 + changes: + - message: Scarves are eatable again. + type: Fix + id: 6921 + time: '2024-07-14T15:12:25.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29959 From b7d3964c5672bc3fe0ee683ad168cb3f8d74b335 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 15 Jul 2024 00:07:48 +0200 Subject: [PATCH 015/134] Fix AccessLevelControl breaking (#30045) #29987 did an oopsie This broke the ID computer, station records, and maybe some others too. --- Content.Client/Access/UI/AccessLevelControl.xaml.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml.cs b/Content.Client/Access/UI/AccessLevelControl.xaml.cs index 9f09eceec06..12487b2e5ce 100644 --- a/Content.Client/Access/UI/AccessLevelControl.xaml.cs +++ b/Content.Client/Access/UI/AccessLevelControl.xaml.cs @@ -21,6 +21,7 @@ public sealed partial class AccessLevelControl : GridContainer public AccessLevelControl() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); _sawmill = _logManager.GetSawmill("accesslevelcontrol"); } From eb3b2ae01a1fcefa82f1e05e969c990e60e75b82 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 15 Jul 2024 16:32:12 +0200 Subject: [PATCH 016/134] Update host key for changelog RSS (#30068) --- Tools/actions_changelog_rss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/actions_changelog_rss.py b/Tools/actions_changelog_rss.py index 01ca7852ccb..5c696f5b01a 100755 --- a/Tools/actions_changelog_rss.py +++ b/Tools/actions_changelog_rss.py @@ -35,7 +35,7 @@ RSS_FILE = "changelog.xml" XSL_FILE = "stylesheet.xsl" HOST_KEYS = [ - "AAAAC3NzaC1lZDI1NTE5AAAAIEE8EhnPjb3nIaAPTXAJHbjrwdGGxHoM0f1imCK0SygD" + "AAAAC3NzaC1lZDI1NTE5AAAAIOBpGO/Qc6X0YWuw7z+/WS/65+aewWI29oAyx+jJpCmh" ] # RSS feed parameters, change these From c0593fb32808de845d26f851d7c7b02953039039 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 15 Jul 2024 16:55:05 +0200 Subject: [PATCH 017/134] Fix invalid UI hover/click sounds breaking client (#30067) fixes #29561 --- Content.Client/Audio/AudioUIController.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Content.Client/Audio/AudioUIController.cs b/Content.Client/Audio/AudioUIController.cs index ef903672fd0..16e1edd2523 100644 --- a/Content.Client/Audio/AudioUIController.cs +++ b/Content.Client/Audio/AudioUIController.cs @@ -54,7 +54,7 @@ private void SetClickSound(string value) { if (!string.IsNullOrEmpty(value)) { - var resource = _cache.GetResource(value); + var resource = GetSoundOrFallback(value, CCVars.UIClickSound.DefaultValue); var source = _audioManager.CreateAudioSource(resource); @@ -77,7 +77,7 @@ private void SetHoverSound(string value) { if (!string.IsNullOrEmpty(value)) { - var hoverResource = _cache.GetResource(value); + var hoverResource = GetSoundOrFallback(value, CCVars.UIHoverSound.DefaultValue); var hoverSource = _audioManager.CreateAudioSource(hoverResource); @@ -95,4 +95,12 @@ private void SetHoverSound(string value) UIManager.SetHoverSound(null); } } + + private AudioResource GetSoundOrFallback(string path, string fallback) + { + if (!_cache.TryGetResource(path, out AudioResource? resource)) + return _cache.GetResource(fallback); + + return resource; + } } From b35539db4a800559926a6e998b7f38e5cfc9365e Mon Sep 17 00:00:00 2001 From: Simon <63975668+Simyon264@users.noreply.github.com> Date: Mon, 15 Jul 2024 21:14:37 +0200 Subject: [PATCH 018/134] Fix some markup related obsolete warnings in research and anomaly related systems (#30072) Fix some Markup related obsolete warnings in Research and Anomaly related systems --- .../UI/DiskConsoleBoundUserInterface.cs | 1 - .../UI/ResearchClientBoundUserInterface.cs | 1 - .../UI/ResearchConsoleBoundUserInterface.cs | 1 - .../Research/UI/ResearchConsoleMenu.xaml.cs | 4 +- .../Research/UI/TechnologyCardControl.xaml.cs | 2 +- .../Anomaly/AnomalySystem.Scanner.cs | 40 +++++++++---------- 6 files changed, 23 insertions(+), 26 deletions(-) diff --git a/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs b/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs index da008ca04c9..c14a8c5bd05 100644 --- a/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs +++ b/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Research; using Content.Shared.Research.Components; -using Robust.Client.GameObjects; namespace Content.Client.Research.UI { diff --git a/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs b/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs index 07dd35a0056..a0a2b58e889 100644 --- a/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs +++ b/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs @@ -1,5 +1,4 @@ using Content.Shared.Research.Components; -using Robust.Client.GameObjects; namespace Content.Client.Research.UI { diff --git a/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs b/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs index f29e66baaeb..2a9782045b8 100644 --- a/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs +++ b/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Research.Components; using JetBrains.Annotations; -using Robust.Client.GameObjects; namespace Content.Client.Research.UI; diff --git a/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs b/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs index b364b833124..77ebe6740c5 100644 --- a/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs +++ b/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs @@ -81,7 +81,7 @@ public void UpdatePanels(ResearchConsoleBoundInterfaceState state) public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state) { var amountMsg = new FormattedMessage(); - amountMsg.AddMarkup(Loc.GetString("research-console-menu-research-points-text", + amountMsg.AddMarkupOrThrow(Loc.GetString("research-console-menu-research-points-text", ("points", state.Points))); ResearchAmountLabel.SetMessage(amountMsg); @@ -98,7 +98,7 @@ public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state) } var msg = new FormattedMessage(); - msg.AddMarkup(Loc.GetString("research-console-menu-main-discipline", + msg.AddMarkupOrThrow(Loc.GetString("research-console-menu-main-discipline", ("name", disciplineText), ("color", disciplineColor))); MainDisciplineLabel.SetMessage(msg); diff --git a/Content.Client/Research/UI/TechnologyCardControl.xaml.cs b/Content.Client/Research/UI/TechnologyCardControl.xaml.cs index f547457203e..292ed0ebe0b 100644 --- a/Content.Client/Research/UI/TechnologyCardControl.xaml.cs +++ b/Content.Client/Research/UI/TechnologyCardControl.xaml.cs @@ -23,7 +23,7 @@ public TechnologyCardControl(TechnologyPrototype technology, IPrototypeManager p DisciplineTexture.Texture = spriteSys.Frame0(discipline.Icon); TechnologyNameLabel.Text = Loc.GetString(technology.Name); var message = new FormattedMessage(); - message.AddMarkup(Loc.GetString("research-console-tier-discipline-info", + message.AddMarkupOrThrow(Loc.GetString("research-console-tier-discipline-info", ("tier", technology.Tier), ("color", discipline.Color), ("discipline", Loc.GetString(discipline.Name)))); TierLabel.SetMessage(message); UnlocksLabel.SetMessage(description); diff --git a/Content.Server/Anomaly/AnomalySystem.Scanner.cs b/Content.Server/Anomaly/AnomalySystem.Scanner.cs index 39c0d08b55e..65d79de60c6 100644 --- a/Content.Server/Anomaly/AnomalySystem.Scanner.cs +++ b/Content.Server/Anomaly/AnomalySystem.Scanner.cs @@ -141,7 +141,7 @@ public FormattedMessage GetScannerMessage(AnomalyScannerComponent component) var msg = new FormattedMessage(); if (component.ScannedAnomaly is not { } anomaly || !TryComp(anomaly, out var anomalyComp)) { - msg.AddMarkup(Loc.GetString("anomaly-scanner-no-anomaly")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-no-anomaly")); return msg; } @@ -149,14 +149,14 @@ public FormattedMessage GetScannerMessage(AnomalyScannerComponent component) //Severity if (secret != null && secret.Secret.Contains(AnomalySecretData.Severity)) - msg.AddMarkup(Loc.GetString("anomaly-scanner-severity-percentage-unknown")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-severity-percentage-unknown")); else - msg.AddMarkup(Loc.GetString("anomaly-scanner-severity-percentage", ("percent", anomalyComp.Severity.ToString("P")))); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-severity-percentage", ("percent", anomalyComp.Severity.ToString("P")))); msg.PushNewline(); //Stability if (secret != null && secret.Secret.Contains(AnomalySecretData.Stability)) - msg.AddMarkup(Loc.GetString("anomaly-scanner-stability-unknown")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-stability-unknown")); else { string stateLoc; @@ -166,54 +166,54 @@ public FormattedMessage GetScannerMessage(AnomalyScannerComponent component) stateLoc = Loc.GetString("anomaly-scanner-stability-high"); else stateLoc = Loc.GetString("anomaly-scanner-stability-medium"); - msg.AddMarkup(stateLoc); + msg.AddMarkupOrThrow(stateLoc); } msg.PushNewline(); //Point output if (secret != null && secret.Secret.Contains(AnomalySecretData.OutputPoint)) - msg.AddMarkup(Loc.GetString("anomaly-scanner-point-output-unknown")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-point-output-unknown")); else - msg.AddMarkup(Loc.GetString("anomaly-scanner-point-output", ("point", GetAnomalyPointValue(anomaly, anomalyComp)))); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-point-output", ("point", GetAnomalyPointValue(anomaly, anomalyComp)))); msg.PushNewline(); msg.PushNewline(); //Particles title - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-readout")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-readout")); msg.PushNewline(); //Danger if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleDanger)) - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-danger-unknown")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-danger-unknown")); else - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-danger", ("type", GetParticleLocale(anomalyComp.SeverityParticleType)))); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-danger", ("type", GetParticleLocale(anomalyComp.SeverityParticleType)))); msg.PushNewline(); //Unstable if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleUnstable)) - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-unstable-unknown")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-unstable-unknown")); else - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-unstable", ("type", GetParticleLocale(anomalyComp.DestabilizingParticleType)))); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-unstable", ("type", GetParticleLocale(anomalyComp.DestabilizingParticleType)))); msg.PushNewline(); //Containment if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleContainment)) - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-containment-unknown")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-containment-unknown")); else - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-containment", ("type", GetParticleLocale(anomalyComp.WeakeningParticleType)))); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-containment", ("type", GetParticleLocale(anomalyComp.WeakeningParticleType)))); msg.PushNewline(); //Transformation if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleTransformation)) - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-transformation-unknown")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-transformation-unknown")); else - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-transformation", ("type", GetParticleLocale(anomalyComp.TransformationParticleType)))); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-transformation", ("type", GetParticleLocale(anomalyComp.TransformationParticleType)))); //Behavior msg.PushNewline(); msg.PushNewline(); - msg.AddMarkup(Loc.GetString("anomaly-behavior-title")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-behavior-title")); msg.PushNewline(); if (secret != null && secret.Secret.Contains(AnomalySecretData.Behavior)) @@ -224,14 +224,14 @@ public FormattedMessage GetScannerMessage(AnomalyScannerComponent component) { var behavior = _prototype.Index(anomalyComp.CurrentBehavior.Value); - msg.AddMarkup("- " + Loc.GetString(behavior.Description)); + msg.AddMarkupOrThrow("- " + Loc.GetString(behavior.Description)); msg.PushNewline(); var mod = Math.Floor((behavior.EarnPointModifier) * 100); - msg.AddMarkup("- " + Loc.GetString("anomaly-behavior-point", ("mod", mod))); + msg.AddMarkupOrThrow("- " + Loc.GetString("anomaly-behavior-point", ("mod", mod))); } else { - msg.AddMarkup(Loc.GetString("anomaly-behavior-balanced")); + msg.AddMarkupOrThrow(Loc.GetString("anomaly-behavior-balanced")); } } From 33a303236c010fd3a5bd41ad449ae7447ae817f2 Mon Sep 17 00:00:00 2001 From: Winkarst <74284083+Winkarst-cpu@users.noreply.github.com> Date: Mon, 15 Jul 2024 22:18:33 +0300 Subject: [PATCH 019/134] Make addgamerule command process only valid game rules (#29912) * addgamerule command processes only valid rules * Update * English moment --- Content.Server/GameTicking/GameTicker.GameRule.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Content.Server/GameTicking/GameTicker.GameRule.cs b/Content.Server/GameTicking/GameTicker.GameRule.cs index 2a33d01bd09..c10f3023471 100644 --- a/Content.Server/GameTicking/GameTicker.GameRule.cs +++ b/Content.Server/GameTicking/GameTicker.GameRule.cs @@ -324,6 +324,13 @@ private void AddGameRuleCommand(IConsoleShell shell, string argstr, string[] arg foreach (var rule in args) { + if (!_prototypeManager.HasIndex(rule)) + { + shell.WriteError($"Invalid game rule {rule} was skipped."); + + continue; + } + if (shell.Player != null) { _adminLogger.Add(LogType.EventStarted, $"{shell.Player} tried to add game rule [{rule}] via command"); From 09a05955d7d409cac1b4be93b5c26bb52c010408 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 15 Jul 2024 19:19:40 +0000 Subject: [PATCH 020/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 0b965b19702..b709a84f1fe 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Tayrtahn - changes: - - message: Ghosts can no longer trigger artifacts by examining them. - type: Fix - id: 6422 - time: '2024-04-22T22:46:22.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27249 - author: Tyzemol changes: - message: Slimes no longer absorb all items used on them @@ -3805,3 +3798,10 @@ id: 6921 time: '2024-07-14T15:12:25.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29959 +- author: Winkarst-cpu + changes: + - message: Now addgamerule command processes only valid game rules. + type: Fix + id: 6922 + time: '2024-07-15T19:18:33.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29912 From 911a94dba95e0b0ef4ae1fffc8a8c16853f49942 Mon Sep 17 00:00:00 2001 From: Simon <63975668+Simyon264@users.noreply.github.com> Date: Tue, 16 Jul 2024 03:04:31 +0200 Subject: [PATCH 021/134] Add missing command description to replay_toggleui (#30071) --- Resources/Locale/en-US/replays/replays.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Resources/Locale/en-US/replays/replays.ftl b/Resources/Locale/en-US/replays/replays.ftl index 7a7e551b3e9..4722f4c56b9 100644 --- a/Resources/Locale/en-US/replays/replays.ftl +++ b/Resources/Locale/en-US/replays/replays.ftl @@ -41,3 +41,5 @@ replay-verb-spectate = Spectate cmd-replay-spectate-help = replay_spectate [optional entity] cmd-replay-spectate-desc = Attaches or detaches the local player to a given entity uid. cmd-replay-spectate-hint = Optional EntityUid + +cmd-replay-toggleui-desc = Toggles the replay control UI. From 927cf7799fc45ef5726e995020de1af6b710ea29 Mon Sep 17 00:00:00 2001 From: Cojoke <83733158+Cojoke-dot@users.noreply.github.com> Date: Tue, 16 Jul 2024 02:17:18 -0500 Subject: [PATCH 022/134] Remove uses of AllObjectives (#30077) Remove the uses of AllObjectives --- Content.Server/CharacterInfo/CharacterInfoSystem.cs | 2 +- Content.Server/Dragon/DragonSystem.cs | 4 ++-- Content.Server/Objectives/Commands/ListObjectivesCommand.cs | 2 +- .../Objectives/Systems/HelpProgressConditionSystem.cs | 4 ++-- .../Objectives/Systems/ObjectiveBlacklistRequirementSystem.cs | 2 +- Content.Shared/Mind/SharedMindSystem.cs | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Content.Server/CharacterInfo/CharacterInfoSystem.cs b/Content.Server/CharacterInfo/CharacterInfoSystem.cs index df8718a022e..cb2216b5e3b 100644 --- a/Content.Server/CharacterInfo/CharacterInfoSystem.cs +++ b/Content.Server/CharacterInfo/CharacterInfoSystem.cs @@ -36,7 +36,7 @@ private void OnRequestCharacterInfoEvent(RequestCharacterInfoEvent msg, EntitySe if (_minds.TryGetMind(entity, out var mindId, out var mind)) { // Get objectives - foreach (var objective in mind.AllObjectives) + foreach (var objective in mind.Objectives) { var info = _objectives.GetInfo(objective, mindId, mind); if (info == null) diff --git a/Content.Server/Dragon/DragonSystem.cs b/Content.Server/Dragon/DragonSystem.cs index 96ca8d3614a..e626edeb269 100644 --- a/Content.Server/Dragon/DragonSystem.cs +++ b/Content.Server/Dragon/DragonSystem.cs @@ -225,7 +225,7 @@ public void DeleteRifts(EntityUid uid, bool resetRole, DragonComponent? comp = n return; var mind = Comp(mindContainer.Mind.Value); - foreach (var objId in mind.AllObjectives) + foreach (var objId in mind.Objectives) { if (_objQuery.TryGetComponent(objId, out var obj)) { @@ -247,7 +247,7 @@ public void RiftCharged(EntityUid uid, DragonComponent? comp = null) return; var mind = Comp(mindContainer.Mind.Value); - foreach (var objId in mind.AllObjectives) + foreach (var objId in mind.Objectives) { if (_objQuery.TryGetComponent(objId, out var obj)) { diff --git a/Content.Server/Objectives/Commands/ListObjectivesCommand.cs b/Content.Server/Objectives/Commands/ListObjectivesCommand.cs index 97fc943269a..88dcdcedf65 100644 --- a/Content.Server/Objectives/Commands/ListObjectivesCommand.cs +++ b/Content.Server/Objectives/Commands/ListObjectivesCommand.cs @@ -33,7 +33,7 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) } shell.WriteLine($"Objectives for player {player.UserId}:"); - var objectives = mind.AllObjectives.ToList(); + var objectives = mind.Objectives.ToList(); if (objectives.Count == 0) { shell.WriteLine("None."); diff --git a/Content.Server/Objectives/Systems/HelpProgressConditionSystem.cs b/Content.Server/Objectives/Systems/HelpProgressConditionSystem.cs index e4455c03813..e0a56149b3e 100644 --- a/Content.Server/Objectives/Systems/HelpProgressConditionSystem.cs +++ b/Content.Server/Objectives/Systems/HelpProgressConditionSystem.cs @@ -59,7 +59,7 @@ private void OnTraitorAssigned(EntityUid uid, RandomTraitorProgressComponent com if (!TryComp(traitor, out var mind)) continue; - foreach (var objective in mind.AllObjectives) + foreach (var objective in mind.Objectives) { if (HasComp(objective)) removeList.Add(traitor); @@ -88,7 +88,7 @@ private float GetProgress(EntityUid target) if (TryComp(target, out var mind)) { - foreach (var objective in mind.AllObjectives) + foreach (var objective in mind.Objectives) { // this has the potential to loop forever, anything setting target has to check that there is no HelpProgressCondition. var info = _objectives.GetInfo(objective, target, mind); diff --git a/Content.Server/Objectives/Systems/ObjectiveBlacklistRequirementSystem.cs b/Content.Server/Objectives/Systems/ObjectiveBlacklistRequirementSystem.cs index 8fe7e7e2031..0671c6b67e4 100644 --- a/Content.Server/Objectives/Systems/ObjectiveBlacklistRequirementSystem.cs +++ b/Content.Server/Objectives/Systems/ObjectiveBlacklistRequirementSystem.cs @@ -23,7 +23,7 @@ private void OnCheck(EntityUid uid, ObjectiveBlacklistRequirementComponent comp, if (args.Cancelled) return; - foreach (var objective in args.Mind.AllObjectives) + foreach (var objective in args.Mind.Objectives) { if (_whitelistSystem.IsBlacklistPass(comp.Blacklist, objective)) { diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index bf1065c1b1d..ba365daf15c 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -370,7 +370,7 @@ public bool TryGetObjectiveComp(EntityUid mindId, [NotNullWhen(true)] out T? if (Resolve(mindId, ref mind)) { var query = GetEntityQuery(); - foreach (var uid in mind.AllObjectives) + foreach (var uid in mind.Objectives) { if (query.TryGetComponent(uid, out objective)) { From 2e3d2db97edffc726e8f09418e3827a88d102b1a Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Tue, 16 Jul 2024 10:27:37 -0400 Subject: [PATCH 023/134] Revert "Change wristwatch meta description" (#30070) Revert "Change wristwatch meta description (#30036)" This reverts commit 919b3ac9e64a18990bd8dbf21eceae782e2b3f77. --- Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml index 6359f659b57..7fbb4aecf61 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml @@ -2,7 +2,7 @@ id: Wristwatch parent: BaseItem name: wristwatch - description: A cheap watch for telling time. How much did you waste working on this shift? + description: A cheap watch for telling time. How much did you waste playing Space Station 14? components: - type: Sprite sprite: Objects/Devices/wristwatch.rsi From db3f304f4b5d6ec94b2ba997ca9680886e8bcd11 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Tue, 16 Jul 2024 07:29:31 -0700 Subject: [PATCH 024/134] Replace EntityPrototype.NoSpawn with EntityPrototype.HideSpawnMenu (#30082) NoSpawn Co-authored-by: plykiya --- Content.Server/Holiday/Christmas/RandomGiftSystem.cs | 2 +- .../Clothing/EntitySystems/SharedChameleonClothingSystem.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/Holiday/Christmas/RandomGiftSystem.cs b/Content.Server/Holiday/Christmas/RandomGiftSystem.cs index ee542572d7e..4603f45ed81 100644 --- a/Content.Server/Holiday/Christmas/RandomGiftSystem.cs +++ b/Content.Server/Holiday/Christmas/RandomGiftSystem.cs @@ -95,7 +95,7 @@ private void BuildIndex() foreach (var proto in _prototype.EnumeratePrototypes()) { - if (proto.Abstract || proto.NoSpawn || proto.Components.ContainsKey(mapGridCompName) || !proto.Components.ContainsKey(physicsCompName)) + if (proto.Abstract || proto.HideSpawnMenu || proto.Components.ContainsKey(mapGridCompName) || !proto.Components.ContainsKey(physicsCompName)) continue; _possibleGiftsUnsafe.Add(proto.ID); diff --git a/Content.Shared/Clothing/EntitySystems/SharedChameleonClothingSystem.cs b/Content.Shared/Clothing/EntitySystems/SharedChameleonClothingSystem.cs index fced03bfabf..f5df04037ee 100644 --- a/Content.Shared/Clothing/EntitySystems/SharedChameleonClothingSystem.cs +++ b/Content.Shared/Clothing/EntitySystems/SharedChameleonClothingSystem.cs @@ -78,7 +78,7 @@ protected virtual void UpdateSprite(EntityUid uid, EntityPrototype proto) { } public bool IsValidTarget(EntityPrototype proto, SlotFlags chameleonSlot = SlotFlags.NONE) { // check if entity is valid - if (proto.Abstract || proto.NoSpawn) + if (proto.Abstract || proto.HideSpawnMenu) return false; // check if it is marked as valid chameleon target From 93e4bfcfb3bf1aec9483361a5b7304fe9cfca67d Mon Sep 17 00:00:00 2001 From: Jezithyr Date: Tue, 16 Jul 2024 15:50:17 -0700 Subject: [PATCH 025/134] Remove Geras from Slimes to address combat balance (#29731) Removed Geras Removed Geras --- Resources/Prototypes/Entities/Mobs/Species/slime.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Mobs/Species/slime.yml b/Resources/Prototypes/Entities/Mobs/Species/slime.yml index caa3690e5d2..6d5c8697f46 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/slime.yml @@ -53,7 +53,6 @@ - type: Damageable damageContainer: Biological damageModifierSet: Slime - - type: Geras - type: PassiveDamage # Around 8 damage a minute healed allowedStates: - Alive From 21d48ca5c485a1cc0a8f5008acbac8249adc2fff Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 16 Jul 2024 22:51:25 +0000 Subject: [PATCH 026/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index b709a84f1fe..c7c2a9731b1 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Tyzemol - changes: - - message: Slimes no longer absorb all items used on them - type: Fix - id: 6423 - time: '2024-04-23T08:48:26.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27260 - author: Rainbeon changes: - message: Suit sensor vitals now function again. @@ -3805,3 +3798,10 @@ id: 6922 time: '2024-07-15T19:18:33.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29912 +- author: Jezithyr + changes: + - message: Removed the Geras ability from Slimes + type: Remove + id: 6923 + time: '2024-07-16T22:50:17.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29731 From 8db252e7dc0c5b9386e7ca79b72adf279ec316e7 Mon Sep 17 00:00:00 2001 From: K-Dynamic <20566341+K-Dynamic@users.noreply.github.com> Date: Wed, 17 Jul 2024 11:26:02 +1200 Subject: [PATCH 027/134] Nerf & standardised slip times (#27879) * standardised slip times * puddle and gib soap * banana peels * cleaned yaml by shifting to component * error slip * error slip intersect * intersect ratio return * error and omega soap changes * SlipocalypseClusterSoap 2 tc cost --- Content.Shared/Slippery/SlipperyComponent.cs | 4 ++-- Resources/Prototypes/Catalog/uplink_catalog.yml | 2 +- Resources/Prototypes/Entities/Effects/puddle.yml | 1 - .../Entities/Objects/Consumable/Food/produce.yml | 4 ---- .../Prototypes/Entities/Objects/Devices/pda.yml | 4 +--- .../Objects/Fun/Instruments/instruments_misc.yml | 2 -- .../Prototypes/Entities/Objects/Fun/error.yml | 7 ++++--- .../Entities/Objects/Misc/spider_web.yml | 2 -- .../Entities/Objects/Specific/Janitorial/soap.yml | 15 ++++++--------- Resources/Prototypes/Entities/Tiles/bananium.yml | 2 -- Resources/Prototypes/Reagents/cleaning.yml | 2 -- 11 files changed, 14 insertions(+), 31 deletions(-) diff --git a/Content.Shared/Slippery/SlipperyComponent.cs b/Content.Shared/Slippery/SlipperyComponent.cs index b80a9b57e4d..154ca6c51a4 100644 --- a/Content.Shared/Slippery/SlipperyComponent.cs +++ b/Content.Shared/Slippery/SlipperyComponent.cs @@ -25,14 +25,14 @@ public sealed partial class SlipperyComponent : Component /// [DataField, AutoNetworkedField] [Access(Other = AccessPermissions.ReadWrite)] - public float ParalyzeTime = 3f; + public float ParalyzeTime = 1.5f; /// /// The entity's speed will be multiplied by this to slip it forwards. /// [DataField, AutoNetworkedField] [Access(Other = AccessPermissions.ReadWrite)] - public float LaunchForwardsMultiplier = 1f; + public float LaunchForwardsMultiplier = 1.5f; /// /// If this is true, any slipping entity loses its friction until diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 9bd10c8ef0a..c9dc048cd38 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -784,7 +784,7 @@ description: uplink-slipocalypse-clustersoap-desc productEntity: SlipocalypseClusterSoap cost: - Telecrystal: 3 + Telecrystal: 2 categories: - UplinkDisruption diff --git a/Resources/Prototypes/Entities/Effects/puddle.yml b/Resources/Prototypes/Entities/Effects/puddle.yml index fecf9f19a47..62bb923a61b 100644 --- a/Resources/Prototypes/Entities/Effects/puddle.yml +++ b/Resources/Prototypes/Entities/Effects/puddle.yml @@ -113,7 +113,6 @@ components: - type: Clickable - type: Slippery - launchForwardsMultiplier: 2.0 - type: Transform noRot: true anchored: true diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index a74e3450e94..b2375a2dbf9 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -311,7 +311,6 @@ sprite: Objects/Specific/Hydroponics/banana.rsi heldPrefix: peel - type: Slippery - launchForwardsMultiplier: 1.5 - type: StepTrigger intersectRatio: 0.2 - type: CollisionWake @@ -388,7 +387,6 @@ path: /Audio/Effects/slip.ogg params: volume: -100 - launchForwardsMultiplier: 1.6 - type: entity name: bananium peel @@ -402,8 +400,6 @@ sprite: Objects/Materials/materials.rsi heldPrefix: peel - type: Slippery - paralyzeTime: 4 - launchForwardsMultiplier: 2 - type: entity name: carrot diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index bf0b7190b5b..04b023248e8 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -257,9 +257,7 @@ borderColor: "#C18199" - type: Icon state: pda-clown - - type: Slippery - paralyzeTime: 4 - launchForwardsMultiplier: 1.5 + - type: Slippery # secretly made of bananium - type: StepTrigger - type: CollisionWake enabled: false diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml index 8cb3d88ede2..243a816a478 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml @@ -162,8 +162,6 @@ sound: path: /Audio/Items/bikehorn.ogg - type: Slippery - paralyzeTime: 4 - launchForwardsMultiplier: 1.5 - type: StepTrigger - type: CollisionWake enabled: false diff --git a/Resources/Prototypes/Entities/Objects/Fun/error.yml b/Resources/Prototypes/Entities/Objects/Fun/error.yml index 8f3fc211378..e4b9af61e0a 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/error.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/error.yml @@ -16,7 +16,8 @@ - ReagentId: Nutriment Quantity: 5 - type: Slippery - launchForwardsMultiplier: 5 + paralyzeTime: 3 + launchForwardsMultiplier: 3 - type: StepTrigger intersectRatio: 0.2 - type: CollisionWake @@ -28,14 +29,14 @@ slips: shape: !type:PhysShapeAabb - bounds: "-0.2,-0.2,0.2,0.2" + bounds: "-0.4,-0.3,0.4,0.3" hard: false layer: - SlipLayer fix1: shape: !type:PhysShapeAabb - bounds: "-0.2,-0.2,0.2,0.2" + bounds: "-0.4,-0.3,0.4,0.3" density: 30 mask: - ItemMask diff --git a/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml b/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml index 9561fa3538f..02feda953f8 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/spider_web.yml @@ -108,8 +108,6 @@ - type: Transform anchored: true - type: Slippery - paralyzeTime: 2 - launchForwardsMultiplier: 1.5 - type: StepTrigger intersectRatio: 0.2 - type: Physics diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml index 5678de6bafc..efb93a88680 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml @@ -21,8 +21,6 @@ sprite: Objects/Specific/Janitorial/soap.rsi storedRotation: -90 - type: Slippery - paralyzeTime: 2 - launchForwardsMultiplier: 1.5 - type: StepTrigger intersectRatio: 0.2 - type: CollisionWake @@ -129,8 +127,8 @@ - type: SolutionContainerVisuals fillBaseName: syndie- - type: Slippery - paralyzeTime: 5 - launchForwardsMultiplier: 2.5 + paralyzeTime: 3 + launchForwardsMultiplier: 3 - type: Item heldPrefix: syndie - type: FlavorProfile @@ -154,8 +152,8 @@ layers: - state: syndie-soaplet - type: Slippery - paralyzeTime: 5 - launchForwardsMultiplier: 2.5 + paralyzeTime: 1.5 # these things are tiny + launchForwardsMultiplier: 1.5 - type: StepTrigger intersectRatio: 0.04 - type: Item @@ -196,7 +194,6 @@ - type: SolutionContainerVisuals fillBaseName: gibs- - type: Slippery - paralyzeTime: 2 - type: StepTrigger - type: Item heldPrefix: gibs @@ -221,8 +218,8 @@ - type: SolutionContainerVisuals fillBaseName: omega- - type: Slippery - paralyzeTime: 7 - launchForwardsMultiplier: 3 + paralyzeTime: 5.0 + launchForwardsMultiplier: 3.0 - type: Item heldPrefix: omega - type: SolutionContainerManager diff --git a/Resources/Prototypes/Entities/Tiles/bananium.yml b/Resources/Prototypes/Entities/Tiles/bananium.yml index c9a6ec28441..fa8cfdd001a 100644 --- a/Resources/Prototypes/Entities/Tiles/bananium.yml +++ b/Resources/Prototypes/Entities/Tiles/bananium.yml @@ -44,8 +44,6 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - type: Slippery - paralyzeTime: 2 - launchForwardsMultiplier: 1.5 - type: StepTrigger intersectRatio: 0.2 - type: Physics diff --git a/Resources/Prototypes/Reagents/cleaning.yml b/Resources/Prototypes/Reagents/cleaning.yml index da02fc666d8..a6b53be6883 100644 --- a/Resources/Prototypes/Reagents/cleaning.yml +++ b/Resources/Prototypes/Reagents/cleaning.yml @@ -77,8 +77,6 @@ meltingPoint: 18.2 tileReactions: - !type:SpillTileReaction - paralyzeTime: 3 - launchForwardsMultiplier: 2 requiredSlipSpeed: 1 superSlippery: true From 8d99961a00ebabb5f8e4cb82fd2fc6873acc748f Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 16 Jul 2024 23:27:09 +0000 Subject: [PATCH 028/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index c7c2a9731b1..e0f8aef124b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Rainbeon - changes: - - message: Suit sensor vitals now function again. - type: Fix - id: 6424 - time: '2024-04-23T08:57:09.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27259 - author: Ghagliiarghii changes: - message: Security can now find replacements for their trusty Combat Knife in the @@ -3805,3 +3798,11 @@ id: 6923 time: '2024-07-16T22:50:17.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29731 +- author: K-Dynamic + changes: + - message: nerfed paraylze timer of all slippable objects (including soaps, water + puddles, and clown-related items) + type: Tweak + id: 6924 + time: '2024-07-16T23:26:02.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/27879 From 13bec7a0e98e4ce850efced1fddb9d9ac4e5b1d5 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Wed, 17 Jul 2024 00:35:18 -0400 Subject: [PATCH 029/134] Sign Resprite (#29806) * Redone signage * Signs * ok this thing now * alright ig? * big data * cryo sign * new sign --- .../Structures/Wallmounts/Signs/signs.yml | 190 +-- .../ServerInfo/Guidebook/Service/Chef.xml | 1 - .../Structures/Wallmounts/signs.rsi/ai.png | Bin 400 -> 406 bytes .../Wallmounts/signs.rsi/ai_upload.png | Bin 0 -> 513 bytes .../Wallmounts/signs.rsi/anomaly.png | Bin 399 -> 515 bytes .../Wallmounts/signs.rsi/anomaly2.png | Bin 454 -> 0 bytes .../Wallmounts/signs.rsi/arcade.png | Bin 3131 -> 3126 bytes .../Wallmounts/signs.rsi/armory.png | Bin 391 -> 423 bytes .../Structures/Wallmounts/signs.rsi/ass.png | Bin 385 -> 519 bytes .../Wallmounts/signs.rsi/atmominsky.png | Bin 626 -> 0 bytes .../Structures/Wallmounts/signs.rsi/atmos.png | Bin 486 -> 466 bytes .../Structures/Wallmounts/signs.rsi/bar.png | Bin 388 -> 398 bytes .../Wallmounts/signs.rsi/barbershop.png | Bin 444 -> 481 bytes .../Wallmounts/signs.rsi/biblio.png | Bin 339 -> 397 bytes .../Wallmounts/signs.rsi/bridge.png | Bin 484 -> 475 bytes .../Structures/Wallmounts/signs.rsi/cans.png | Bin 0 -> 445 bytes .../Structures/Wallmounts/signs.rsi/cargo.png | Bin 352 -> 445 bytes .../Wallmounts/signs.rsi/cargo_dock.png | Bin 407 -> 476 bytes .../Wallmounts/signs.rsi/chapel.png | Bin 354 -> 533 bytes .../Structures/Wallmounts/signs.rsi/chem.png | Bin 431 -> 461 bytes .../Wallmounts/signs.rsi/chemistry1.png | Bin 450 -> 0 bytes .../Wallmounts/signs.rsi/chemistry2.png | Bin 401 -> 0 bytes .../Wallmounts/signs.rsi/cloning.png | Bin 418 -> 446 bytes .../Wallmounts/signs.rsi/commander.png | Bin 370 -> 434 bytes .../Wallmounts/signs.rsi/conference_room.png | Bin 356 -> 406 bytes .../Structures/Wallmounts/signs.rsi/court.png | Bin 431 -> 0 bytes .../Structures/Wallmounts/signs.rsi/cryo.png | Bin 0 -> 3065 bytes .../Structures/Wallmounts/signs.rsi/data.png | Bin 0 -> 408 bytes .../Wallmounts/signs.rsi/deathsposal.png | Bin 461 -> 470 bytes .../Structures/Wallmounts/signs.rsi/dock.png | Bin 432 -> 477 bytes .../Structures/Wallmounts/signs.rsi/doors.png | Bin 467 -> 480 bytes .../Wallmounts/signs.rsi/drama1.png | Bin 0 -> 627 bytes .../Wallmounts/signs.rsi/drama2.png | Bin 0 -> 588 bytes .../Wallmounts/signs.rsi/drama3.png | Bin 0 -> 578 bytes .../Wallmounts/signs.rsi/drones.png | Bin 405 -> 0 bytes .../Structures/Wallmounts/signs.rsi/eng.png | Bin 432 -> 418 bytes .../Wallmounts/signs.rsi/engine.png | Bin 471 -> 446 bytes .../Structures/Wallmounts/signs.rsi/eva.png | Bin 387 -> 517 bytes .../Wallmounts/signs.rsi/examroom.png | Bin 494 -> 490 bytes .../Structures/Wallmounts/signs.rsi/gravi.png | Bin 458 -> 423 bytes .../Structures/Wallmounts/signs.rsi/hydro.png | Bin 0 -> 479 bytes .../Wallmounts/signs.rsi/hydro1.png | Bin 428 -> 0 bytes .../Wallmounts/signs.rsi/hydro2.png | Bin 421 -> 0 bytes .../Wallmounts/signs.rsi/hydro3.png | Bin 448 -> 0 bytes .../Wallmounts/signs.rsi/interrogation.png | Bin 395 -> 441 bytes .../Wallmounts/signs.rsi/janitor.png | Bin 552 -> 434 bytes .../Wallmounts/signs.rsi/kitchen.png | Bin 0 -> 486 bytes .../Wallmounts/signs.rsi/laundromat.png | Bin 397 -> 467 bytes .../Structures/Wallmounts/signs.rsi/law.png | Bin 367 -> 396 bytes .../Structures/Wallmounts/signs.rsi/mail.png | Bin 346 -> 418 bytes .../Structures/Wallmounts/signs.rsi/mats.png | Bin 0 -> 391 bytes .../Wallmounts/signs.rsi/medbay.png | Bin 313 -> 533 bytes .../Structures/Wallmounts/signs.rsi/meta.json | 1372 +++-------------- .../Wallmounts/signs.rsi/miner_dock.png | Bin 462 -> 0 bytes .../Wallmounts/signs.rsi/morgue.png | Bin 341 -> 535 bytes .../Structures/Wallmounts/signs.rsi/news.png | Bin 3095 -> 3096 bytes .../Wallmounts/signs.rsi/prison.png | Bin 320 -> 373 bytes .../Wallmounts/signs.rsi/psychology.png | Bin 582 -> 576 bytes .../Wallmounts/signs.rsi/reception.png | Bin 3103 -> 3069 bytes .../Wallmounts/signs.rsi/restroom.png | Bin 0 -> 515 bytes .../Structures/Wallmounts/signs.rsi/rnd.png | Bin 390 -> 448 bytes .../Structures/Wallmounts/signs.rsi/robo.png | Bin 413 -> 481 bytes .../Wallmounts/signs.rsi/salvage.png | Bin 3109 -> 3061 bytes .../Structures/Wallmounts/signs.rsi/sci.png | Bin 473 -> 570 bytes .../Wallmounts/signs.rsi/science1.png | Bin 516 -> 0 bytes .../Wallmounts/signs.rsi/science2.png | Bin 422 -> 0 bytes .../Wallmounts/signs.rsi/security.png | Bin 473 -> 426 bytes .../Wallmounts/signs.rsi/shield.png | Bin 402 -> 0 bytes .../Structures/Wallmounts/signs.rsi/space.png | Bin 515 -> 527 bytes .../Wallmounts/signs.rsi/surgery.png | Bin 428 -> 430 bytes .../Wallmounts/signs.rsi/telecoms.png | Bin 466 -> 431 bytes .../Wallmounts/signs.rsi/toxins.png | Bin 424 -> 541 bytes .../Wallmounts/signs.rsi/toxins2.png | Bin 433 -> 0 bytes .../Structures/Wallmounts/signs.rsi/vault.png | Bin 0 -> 458 bytes .../Wallmounts/signs.rsi/virology.png | Bin 468 -> 519 bytes .../Wallmounts/signs.rsi/xenoarch.png | Bin 0 -> 449 bytes .../Wallmounts/signs.rsi/xenobio.png | Bin 609 -> 490 bytes .../Wallmounts/signs.rsi/xenobio2.png | Bin 569 -> 0 bytes .../Wallmounts/signs.rsi/xenolab.png | Bin 408 -> 0 bytes .../Wallmounts/signs.rsi/zomlab.png | Bin 6115 -> 958 bytes Resources/Textures/Template/signs.png | Bin 0 -> 1013 bytes Resources/migration.yml | 16 + 82 files changed, 279 insertions(+), 1300 deletions(-) create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/ai_upload.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/anomaly2.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/atmominsky.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/cans.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/chemistry1.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/chemistry2.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/court.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/cryo.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/data.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/drama1.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/drama2.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/drama3.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/drones.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/hydro.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/hydro1.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/hydro2.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/hydro3.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/kitchen.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/mats.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/miner_dock.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/restroom.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/science1.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/science2.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/shield.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/toxins2.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/vault.png create mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/xenoarch.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/xenobio2.png delete mode 100644 Resources/Textures/Structures/Wallmounts/signs.rsi/xenolab.png create mode 100644 Resources/Textures/Template/signs.png diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/signs.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/signs.yml index 9aac49a6bd7..c6ecb5fd308 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/signs.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/signs.yml @@ -243,6 +243,15 @@ - type: Sprite state: ai +- type: entity + parent: BaseSign + id: SignAiUpload + name: ai upload sign + description: A sign, indicating an AI is present. + components: + - type: Sprite + state: ai_upload + - type: entity parent: BaseSign id: SignArcade @@ -273,11 +282,11 @@ - type: entity parent: BaseSign id: SignAnomaly - name: xenoarchaeology lab sign + name: xenoarcheology lab sign description: A sign indicating the xenoarchaeology lab. components: - type: Sprite - state: anomaly + state: xenoarch - type: entity parent: BaseSign @@ -286,7 +295,7 @@ description: A sign indicating the anomalous research lab. components: - type: Sprite - state: anomaly2 + state: anomaly - type: entity parent: BaseSign @@ -299,21 +308,38 @@ - type: entity parent: BaseSign - id: SignAtmosMinsky - name: atmospherics sign - description: A sign indicating the atmospherics area. + id: SignBar + name: bar sign + description: A sign indicating the bar. components: - type: Sprite - state: atmominsky + state: bar - type: entity parent: BaseSign - id: SignBar - name: bar sign - description: A sign indicating the bar. + id: SignKitchen + name: kitchen sign + description: The heart of the home. And disease. components: - type: Sprite - state: bar + state: kitchen + +- type: entity + parent: BaseSign + id: SignTheater + name: theater sign + description: Would it even be Space Station without drama? + components: + - type: Sprite + layers: + - state: drama1 + map: [ "base" ] + - type: RandomSprite + available: + - base: + drama1: null + drama2: null + drama3: null - type: entity parent: BaseSign @@ -396,24 +422,6 @@ - type: Sprite state: chem -- type: entity - parent: BaseSign - id: SignChemistry1 - name: chemistry sign - description: A sign indicating the chemistry lab. - components: - - type: Sprite - state: chemistry1 - -- type: entity - parent: BaseSign - id: SignChemistry2 - name: chemistry sign - description: A sign indicating the chemistry lab. - components: - - type: Sprite - state: chemistry2 - - type: entity parent: BaseSign id: SignCloning @@ -427,19 +435,20 @@ parent: BaseSign id: SignConference name: conference room sign - description: A sign indicating the conference room. + description: Where work happens. components: - type: Sprite state: conference_room - type: entity parent: BaseSign - id: SignCourt - name: court sign - description: A sign labelling the courtroom. + id: SignCryo + name: cryosleep sign + description: Just like that? You're gonna chicken out? components: - type: Sprite - state: court + state: cryo + - type: entity parent: BaseSign @@ -461,18 +470,27 @@ - type: entity parent: BaseSign - id: SignDrones - name: drones sign - description: A sign indicating drones. + id: SignRestroom + name: restroom sign + description: A sign indicating where you go to... What do you do here again? components: - type: Sprite - state: drones + state: restroom + +- type: entity + parent: BaseSign + id: SignMaterials + name: materials sign + description: An omen to the juicy vault of steel, glass, and plastic that lays before you. + components: + - type: Sprite + state: mats - type: entity parent: BaseSign id: SignEngine - name: engine sign - description: A sign indicating the engine room. + name: power sign + description: Where the powa happens. components: - type: Sprite state: engine @@ -544,7 +562,7 @@ parent: BaseSign id: SignHead name: head sign - description: A sign with a hat on it. + description: An official sign indicating the dwellings of a Nanotrasen-certified head of department. components: - type: Sprite state: commander @@ -556,25 +574,7 @@ description: A sign indicating a hydroponics area. components: - type: Sprite - state: hydro1 - -- type: entity - parent: BaseSign - id: SignHydro2 - name: hydro sign - description: A sign indicating a hydroponics area. - components: - - type: Sprite - state: hydro2 - -- type: entity - parent: BaseSign - id: SignHydro3 - name: hydro sign - description: A sign indicating a hydroponics area. - components: - - type: Sprite - state: hydro3 + state: hydro - type: entity parent: BaseSign @@ -606,8 +606,8 @@ - type: entity parent: BaseSign id: SignLawyer - name: lawyer sign - description: A sign labelling an area where the Lawyers work. + name: law sign + description: A sign indicating the presence of the (typically absent) rule of law. components: - type: Sprite state: law @@ -639,15 +639,6 @@ - type: Sprite state: medbay -- type: entity - parent: BaseSign - id: SignMinerDock - name: miner dock sign - description: A sign indicating the miner dock. - components: - - type: Sprite - state: miner_dock - - type: entity parent: BaseSign id: SignMorgue @@ -740,36 +731,27 @@ - type: entity parent: BaseSign - id: SignScience1 - name: science sign - description: A sign indicating the science area. + id: SignServer + name: server sign + description: Ever heard of Big Data? This is it, chump. The biggest. components: - type: Sprite - state: science1 + state: data - type: entity parent: BaseSign - id: SignScience2 - name: science sign - description: A sign indicating the science area. - components: - - type: Sprite - state: science2 - -- type: entity - parent: BaseSign - id: SignShield - name: shield sign - description: A sign with a shield. + id: SignCans + name: canisters sign + description: A sign indicating the auspicious presence of gas canisters. components: - type: Sprite - state: shield + state: cans - type: entity parent: BaseSign id: SignShipDock - name: docking sign - description: A sign indicating the ship docking area. + name: evac sign + description: A sign indicating the where the evac shuttle will (likely) arrive. components: - type: Sprite state: dock @@ -812,12 +794,12 @@ - type: entity parent: BaseSign - id: SignToxins2 - name: toxins sign - description: A sign indicating the toxin lab. + id: SignVault + name: vault sign + description: A sign indicating the vault. Who knows what secrets lie inside? components: - type: Sprite - state: toxins2 + state: vault - type: entity parent: BaseSign @@ -964,29 +946,11 @@ - type: Sprite state: xenobio -- type: entity - parent: BaseSign - id: SignXenobio2 - name: xenobio sign - description: A sign indicating the xenobiology lab. - components: - - type: Sprite - state: xenobio2 - -- type: entity - parent: BaseSign - id: SignXenolab - name: xenolab sign - description: A sign indicating the xenobiology lab. - components: - - type: Sprite - state: xenolab - - type: entity parent: BaseSign id: SignZomlab name: zombie lab sign - description: A sign indicating the zombie lab. + description: The final remains of a shut-down Nanotrasen research project that aimed to harness the powers of Romerol. I wonder how that went... components: - type: Sprite state: zomlab diff --git a/Resources/ServerInfo/Guidebook/Service/Chef.xml b/Resources/ServerInfo/Guidebook/Service/Chef.xml index e0692b889b4..79eb81468cd 100644 --- a/Resources/ServerInfo/Guidebook/Service/Chef.xml +++ b/Resources/ServerInfo/Guidebook/Service/Chef.xml @@ -54,7 +54,6 @@ Ask Botany for what you need, without a botanist, you may need to grow more plan - ## Gathering Milk: Alt-Click on a Cow with a container in your hand. (Beakers, Buckets, Milk Jugs, ect.) diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/ai.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/ai.png index 6cee540a6b2b727d219e49585e6395cebeaf0f46..e532ec039e84e8d2b1b2fb7892852f9b98749e39 100644 GIT binary patch delta 380 zcmV-?0fYXK1C|4jBYyw^b5ch_0Itp)=>Px$P)S5VR9J;$U>NCu5uYTNvG;#!S@iAf zR;+g6bO4vJ_kS)SaRv@v0g5gE@%aP8w|6hGIs&T$V3zYq$Wd%L419X=2&*GlaA`pH z`Q1f6WLvBpw*_wAw|6fw2p|LHxGfBK7x}<_Lw^h)Ry|Q6KyDNeqmL*D zp!=jEEry{YEry`jkO%>i(f|x}%vyq>2AkNB2m!Lw05(8Q8XzhP(0$S|YYA3Iphp8S zS&^(XfXy;o`UrsmPXk1S0HqGW2Zl~vKr1jbLI4?5q{T3#+I(POU|?XFeMEqvW7ZOs zv_WcUksJc4Hgz8ul;gHAD93GqI|ODaIZ;J&2rw{EH#d-#24EpDU=BbBun-|9WN@~M zh2+&4*tq#9a~Tr&_4O0OyN5T4Zx#Re`~kxO#QG3h^!)hz0jt`<*)c(O1jV*P0j{pu aC;$Lc%#;2PWaqa400006vn?+s3+*ijKpB+p_~B;Eq-anyK=CnAGz+S>l!x77X+BHBVFdFm`$rOv(v~o@) zQ*8uo8&E1Mbi@8|ER5$VSj?us#!Oh(0FkKO`8knHS#9eafjVv{0(EW2jet`Z=t{4E z+XdDsSO$cN_iqRQIu%vAUCmjiA^Ri*ep;|jIk4{ny}LZbWxa-h@-f^dRt7G)j+=0* z0pR=6@xxfFE6xTYnSw}Y{c{6=`y1dKb{FL2busbW>ciRqk#NqjO=|xAS>Dm{1&N}Z UI1{IdNB{r;07*qoM6N<$f`aX^cK`qY diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/ai_upload.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/ai_upload.png new file mode 100644 index 0000000000000000000000000000000000000000..91256aa1df71351761153db05f3f6ef7c1ed1207 GIT binary patch literal 513 zcmV+c0{;DpP)Px$yGcYrR9J=WS36F_KoET(6rn^!Q5vYANWlTp`Ude4taSDne1x1KbQVVlH%Q9? zC|p1VO=Kk^ifBRsV|K^;nGHrlg4bBy-I@2^%-FJlzm6l*Vs|{*{}kc&{!Zg;2meh&zEb$U@ za*DU*Co}}8phT)0o|KD}#E1n@LK~Tl&=;fP#6`}DOk@%Rt{AHTX$kom6Ol`>xB{l$ za}wL&x!@E)iB(ctuU%^g3rM31v$?(&>JR|RA_f4ArVF`%vWPL7F6t{_c1OuSP$7-t z#u*p9Es((EOoc8|hxa`oO$2Px$y-7qtR9J=WSG`WdFc3ZvLs6yvEC?Z$ zy$@h{$==6k=4^SAZkdzEV9#RZ0kTsGAr?p^1Y21+%Q5HVj%26=-_q9S=KFm2-N^y? z>$vC(M(f>aDx&iBf#eDbh}OH)@_Gr2+qBSpG^7Yp0DqF--`$KRM?5~gkRmQa zf8d;4M;fv!1|8|ay`kp?1%%)dn$kd`axkUo2$JARvROwO5|!KU`@`18inIn(8ZgR$ zjhu|dK+-_hspLN!;_4?e6 zCiOk=_WlXS=Ocd-`f!aEs;z5MPW?p!u%2i#f8u3T+{q57{s6xyftv+t68ifPp%REj zF-|yl?D_(SJmN!?0Ut<6na;-~8Sp`6K??RHbSGX`#bX^4QgQclv;eHDYq~_`mVkE1djudBYy!_NklZq}6n(9_WbaamAr}A81Ucm&^BSQTphaz ze9k`_H5vyO%hmDu`+y?LS>mqmVLux+ns{m>DY6_^XWP7V-T@Nlf@PrGmMF6PLY!Nw)&`cW1I_|{)0Q{_XNM&*nx(z+YID{ll6`;RMWddj7sBxQ; zw5kFkrZy0vTD5*5r7|(*G(G~#LG)hV62>swdSe5w@3E`E^*!uc=KT3@`G5f@rCY6j T45emh00000NkvXXu0mjfsm!cw diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/anomaly2.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/anomaly2.png deleted file mode 100644 index 73d94ac95e45de566b4003a5605a00de2f3c55ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 454 zcmV;%0XhDOP)Px$fJsC_R9J=WmN9C>FcgOWmMq;1p`albkdW!nGuTk5x804vB49G9BuFQ4~G&e^1hr3=I13x@iiS%@+p~gSXe0T94Yn z*?e)hUw$J`vrgt*3hbtLwGgAGN%Azq^GDbTAn_wSOrL6F8UZe8A8#*D7L2v$(gIM8 zi%n4(V-73FbwIRNfQ+x53+6Db`EJ_=s@dmh1~>G;r2v-#Zs=8ju5FPK0C3En%+)O@ zHbn_>zBN_>R72pn+_dDn#zp`()d@h&T3wCa0hq(UrNBB`RScQKu#Q&XQfPy;F2hkU zE>AZ>kn%JGm!cAD9e{K#!>(JP1wfhY1hL}J9EFU!J2X6PK{}4FVF#rGn07*qoM6N<$g2_n27ytkO diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/arcade.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/arcade.png index 9f36d43776ffe216cb3fec73d7ba255228a107be..7cb18443529fbb6b7988d25d9e9bc151055e5cf0 100644 GIT binary patch delta 478 zcmV<40U`do7`7OYBe63>3V#8*NklO060@3NC8OR>yOC?qrinQPJgt&TOAvh6%n_b zYRU32P9O?gE%Iycu_2Iv)FP7kbH0T0AwbZ!#QuxGHJfAuxD{vnL?j=8p zk8}4WG%iD_1us{5$z!zzNQBaPn(ZNslTt@jA%*}gSgvv{aZ`97g%sN`2l8KiGFzNS zk59$F*~T~>caW}MD)RyBfx~tKR>!W@fK-HWg0n#d>}1sTV3L1-lGD+zk7ob)0jmA$ UD-)6l>;M1&07*qoM6N<$f*?ZN$N&HU delta 482 zcmV<80UiFf7`qsdBMtxrXF*Lt006O%3;baPu^~kYe*hq3NK#Dz0D2|>0Dy!50Qvv` z0D$NK0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01FZT01FZU(%pXi0000RbVXQn zQ*UN;cVTj607GSLb9r+hQ*?D?X>TA@Z*OeDr{R1600BoyL_t(oh3(ccYlA=(2k^gJ zhkS!Ne^~+<6!b$#>*5y7>e9V|4*3KQg}7&NO>lED!4Hu@G6pPe zPsfY(G)9QV0qgS@wx=VTXtzJWwQMeD$O>KtPhtR0=)<*a1aSmiQ@L8g1aZXGHwJJ* zpXFW41_1Uc3|RpH1aZV_=oujZT~oQGrhlUqK-snfz}2>>b>@4_iGy>@KQc8$Qv;Re{Yk3>d13Cx% Y0`B|4(ES~6X8-^I07*qoM6N<$g4z$qcmMzZ diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/armory.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/armory.png index 671e57aa5cf295495ae5f9c8f377b847a3f772cb..3f237ec04663cd1dce749f3c7705b3232cacfa80 100644 GIT binary patch delta 398 zcmV;90df9^1E&L!BYyw^b5ch_0Itp)=>Px$VM#gMU!!>bNB+(RMf60d;?R29TcIpc5MZif#2DZ^`F+eYZ>_KGE0L;V6J6! zX1rK{BQQ4r9x9km07eEP3qa;i70gMm48$GxK)Un&{9H6?oquEJagn?)uBwEfdBIrG zTrt4d^=M9qFZW`_<5CDQ04*Maq(C{SY5=tO;63&W#)J2_0Z7A1Fs*ZH(^za3ltkg* zV!jEWmR11-W7!OsmMTe=gutcQLhny9XA|13LhZo0tF88-N!m&I7UNJKs77;1d4yI+msvhya?? z0m0a-(n_z%RNIKeIgs0BoP=Z7uS!fYK-zlK2n^nfyWc7RiBfaP>-h01U_0UT0iaE) soPx2Kn6cmaV-iDD@CO+4e*wTdO#Gy)!DZ)300000Ne4wvM6N<$f>`so0ssI2 delta 365 zcmV-z0h0cw1BU~UBYy!-NklAP&|3{(x-WKOMLR2~pR%AYecfX_@U*SjdQ z_RfGzzM7Y3m0_(_2aN&{O=o2z*slQ`_gi@H;hY0A!+Q^7Oc>JwsR1Mq@Rk19oiYkw zIxB+@QtCe%pk{8uR3)1*Re$3wsP6k$0Z2KHF9IMs?zgbkf`~%tNncuRWvDz*56;Y? zZ;a7Q6$elaL_`5d;Hqt3sg^*zkh=M(0Ej5M3hEb_CSCnnK4{Pf7`T^%m5Zlq00000 LNkvXXu0mjfp|hf= diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/ass.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/ass.png index 0dfa8a04f5cd9b305f3aa331f0894bd8c2e3a9ec..9d57ebe7e9a44b6ff917562f4475bd464aa620c3 100644 GIT binary patch delta 494 zcmVPx$!AV3xR9J=WSFvitFc7_#u7N;sGCEtp zqcMRj#aq6>U9;y8{007l>|NV0$X2=(g7Ij`7LREN6#4<_P|lT4r?aIbbZFlaN$2=I zo$gLPfWM9#$vB%YPM0EjTR*Z~cM`cjnZjT+KAZfw-vI!eIDZkW03;tzrkX8VMy-VD zDsRkt{UHuD5k?PiJI|Jp_Hqu~bA!PFG#C~nJfm0nYk=T+0ICwxs z68rVeUE$;b1m-ZL zQywCC&g3x^Z(dyJL&RXO&6K=BhHUAi;-smhlS4zO|HYPc+0yGAC1*?h6@ z6X5mvNgG4EIGZo_AL9+`rgaJ~I776XXd!M*PU@z`+vAH9fPXA9ME4V|&5e`iGs>8O z-z1CdVC5Hq@R$0!ZV;%FYJV2>^gq2`IX*Ms(3V;M(a-x{eYY_x(Qy=yM&P z1polvx1Y$X5@2bZAg@XY&QLe)!8i1LEY~a28^U@IsGtg>8(fW5aEeHqF!cOyh*NM1 ziX!qcdybQaOnMou*2+Zs-^ZnkNH*Y3QS+V_ZfU~|# zmLYO}DYak#i0^OIrPHo2B%X{?k$yUb@)&^#%Q#%Jn6I>MKo$g zoZe%6ya)iiO{_56;}nJIB!zfVe0LpXCxFguA7f5XobzAq_Tm5r4)5m~la@eH0HG0} zF&~&ie;xtbL!Aprkq=P-dZOzzz_8~CJB}fbV_B^T0%#Sb81=wD4LZ@7^}P%-Z#T?b z)`#dVpy_I+ORpW;*$P>C1BV0HF#7T#h}ojd)3S>xItS)Ku#H<2``(iL`n9iSS2c`& zlDRG!pIguipuKr2>)S{2`Fty**9&w1)8H}R12pzI4~DtJ;Z+;}7NHOTT%sC|^Ee(2 z;A0v}L-^WU0G~y5M3xQ^;~DmybI^_kpl8~{sQ1j4gdfE diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/atmos.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/atmos.png index 9441b32827891b83ec11770bb1a94bba35f4739c..ae31db348b28b877966c3e870f97c66aae2efacf 100644 GIT binary patch delta 441 zcmV;q0Y?7j1JVPKBYyw^b5ch_0Itp)=>Px$j7da6R9J=WmoZL-KoEw1jVF-eC0OVI z+=if@g^EMazS5RMP;nNOyk_44v~UxO=M|m>8M3UiFf3b`=$}w5limN@8JGp&uj^ti zxG!*yW%S(gUS5EGf%EMRuuHd__Xha*EAWSbdXPtr{#i3Z>r_%!#B1_N-r_i2r>7(lxFP({rEDQXEqGN8&1NmhtJ z#EmFb6#&e>4S()ENkb9?&>~z5whirF>n4XPyIFvsMx@Ga%!n=OfLzQcaRyu?yUxBC zjiUoBExe{BM>z|&Xb~V))uiUC?8b}6wrK3m3kFECVsgAvdhIlGFz&oy0C!9C6vn?)y+9^bk4!MJWh)1$6eUtm(6v%` z58fkn%?T=jxB=PNm|*hgl?mkp=>T?trr<}ZIyB!BjIH;6`27oT(|^}$>cHXne))-m z*XO5EAETRx89T-{p~0BB-9w<5libqI8V1)L*o6H(_w93`Iz%LKdq7HVk# zpkD#N*DE)1mw&?ArZqquHDA_ss>7jkAZ@FpmKosM*(K$`ltRzxhvPQ@bg5nIka|!5 z+Q>Qt0WS~_x}X|3)}nMnQW6Hd0Fwf>%uve=3<7Mw?Oi){Zjfhza=A&cvvEr6|73t+ z`7J3cfVtz?2AmWECWRS1X<3;8)O|+cWh{$EA z&}97?K=6p(8tuD90Yc9)(~qjqb8wnC^XGrdZ@TFNV)L;JSxBqh00000NkvXXu0mjf DFuK!I diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/bar.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/bar.png index e5fb2ab766ec9d9bc20e1325ca743d06dcb87ad8..8fdc8016af35f04020fb2b985d2e33c5f3615d67 100644 GIT binary patch delta 372 zcmV-)0gL{G1C9fbBYyw^b5ch_0Itp)=>Px$NJ&INR9J=WmoaX_FcgOWR_(yhMqLUA zhy-U~L9vu8aE4qVTee(*yF^O1o&h8dP*|dpAp-*)Xj0=ooBG)U2>$KqIsQM#)_XQ^ z>v}LH!zm8FjMg8tmlhzL;_&mr6-%gWnN)XWPLmrGjd!KXAo)huQ{#$fJh@G@eyEAWJuzyk2&Vn z04jtkTXPnG3?Xj^#~iRc11dy!Cb;HK05SyE9AIvNPu&5o8=x!4E@hbwpqg?aoa%rN zUDp{X^9p5N^=(~nE@mgOn)eO>oHnDb1k26I)U3P!sCNSDFv@xF0Mv?2dG7$WD?BId zt@w2e1Vewf;;&7E-RkeHSX&3$8VH8JF{jYT+tb$cn9F>a$Pn)KN9mqscYOn5ErutI S6ZrxF0000n7dE*9lrr)-Mb#f7OXeBvrmHe z)tfbk_2qiAJ0G7vfD4IA&M1NSw6H=vjRoOCLYZz^X9X8=YCY!CZy^IS+^l(>d-2jD_Nk)(R8b|MPG3)pM?w*bS$ zzH$brvr^ZAsqJBZn<6wJhI1G_qP{W`GD^_Ny#S^X8bBR^>i?Sp}&r0T0U#mClb%cxc~qF07*qo IM6N<$f^({(`~Uy| diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/barbershop.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/barbershop.png index d196072a32b0e63fa87efd8d4abe329dc2e4701d..b01a82717f781ae49f7efa4628cc1d0b824c7884 100644 GIT binary patch delta 455 zcmV;&0XY7=1K|UZB!2;OQb$4nuFf3k0004-NklFfje>$=hzcl$%*%F*ldBkAi#=iJ|H;r4Dl+xg{u0sv?z2!9d)ov%0B_FWiwP?WW? zQ+fVkxx&{yi0h#R)SV}>4`JXLJ5OR?yWS`OB@+nBxlYCajEhkS**VU42B1Pvn(BNq zfGjl%rui`&fI14B&|3pg5Vp>(0c1_dc&7lk+hbmJ#y~Yxynha4X#~f-0>(ufcC7XIluDH-Pg;{viY8ocvk z_Spa?i#jhvVcn7t{ao;{f+F7e!VsO*Eb=?$G7bF+_eAz002ovPDHLkV1gC1-G%@F delta 418 zcmV;T0bTy#1H1!}B!3BTNLh0L01FZT01FZU(%pXi0000RbVXQnQ*UN;cVTj607GSL zb9r+hQ*?D?X>TA@Z*OeDr{R1600BoyL_t(oh3(d{Zo)7S2H-zi2i|~AMMw;Zls*Ik z7Pcy^EbJh4=o56PM0OTds%$Kz;vtBX3`i(U@CF&!(xqpa)_;IVoJ)nc#ThK!cRt&( zk)|oi4C4;?_ki(amPLi}IG&5w zdW#3(cDUKdNzQndIGTkPx$M@d9MR9J;$U>NCu5uc=r6~ljOS#;+Z zcDryoK*fsTKdTr61E(P6mVbZG!0`JOc1K`!0L*d;4PMG^hk_S3K4WzR6D|$Z@HsK& zv5;cOzV`h@shhF8fnn9YgG8w%$pH)u3=B?{jyUD^weM$`v46XPA;YzSVbwm|>L_vm z0|Ns?n3Fw*7|h43_8nx%a3$U>oN0hwV89(fRumAMz-Zj`Rz*!yhsWUL}i&L*U{`m4U!>5}h zRLArJL^}XI@oepD-w(&gd{Pr3*&zU{mXWJxr%FeX6CqWj0M;HDFbB{)1kmFgnTD}p zAwX>NZNRf3&VuOsdj(0uCCcA003&)fs->1 RdN2S0002ovPDHLkV1iYwqFn$0 delta 313 zcmV-90mlA~1JeSKBYy!JNklHz|%z&f;@O zXD3IIZY~Z!gn?vs(syvvsipNNY0?Gz8h@&j39u1BlBHmjAPPd9 zua~!a6ol9w4<;kgHR^UC58wfeW0)%n!ruUJA+2x5Rsa|!Uu!n^fYlMGwqFI<7+^nL zBFR$y5sYFt069dPss&Kz0dfk^c z;6fILPx$l}SWFR9J=WmoZMmFcgM=5UNlsqNoc@ zbjZK~y5E=JA>5!V2Vlqm6D*b0h$>jm@p?4R|7k8MK!wmT*MA0}46eIeWB{3YnuMr}0BI5$Ly!PO18yAq3|>?r_L&q!Y|BL2hTJGk zLc~4;z`kXJKOdovhm;qUsEYtuZUKM~E*gsxK`0^t=v1|CJPCjo)OzD0%S&bZv{Y&s zt%HaUs%rC^v3e4UUqIOxQP#&AfGPu~GS0xzdww@iWjhEU-Un<*`##V%43n8-eAnyB siz>8@e7Sz-k4YC|wEL&}e$D>%0qM}{g%`-a761SM07*qoM6N<$f}h&W761SM delta 459 zcmV;+0W|*G1LOmcBYy#_NklZrE5Ji8YC?{}9jpPDp5NEJtU%-fh!c`8C z0&xP1!Uu3gL4n``Sjri!jI>3h)G2*}G)`eJ!FB?>3s#DF8pQ5s=I!kK0pMo;-R`;^ zR_lD1gL6`-KB!4sl@S_ZqvDfNzZxp$a zV3~8D5PAT9lwq^o{kp%|?%+q67C`3}G>ynXT2=sN$LHaSd=^;D4{Jou^#J04umq5n z6^bOpGH1B9g{e1!A7vnN5C^0Mpxpz^0z}S9sbz8#wJ2Ah*=(+D!L==9q!8K8N(*MIkqi+#CP`zZn_UqO+C^*oTLC33Ks&%i9;+SY~Npa9Zjw>Og%Nr<$p zu$a$u!|ADDv)$EFlTFAhkd~(soq8kXm|7K($>V@fBw?-jA_)-()PPVotqOGAZ5)tt z^BDmQk-~N1P&6_Q2<~t2Sl2~2l$?VCJF!yD!?pG=D(Dt ztj5&=&ii5N9p4Sr&D4inpOZiTEx*~#z5v`)xJ$h>xeovU002ovPDHLkV1j#+ B*vS9@ diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/cans.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/cans.png new file mode 100644 index 0000000000000000000000000000000000000000..53cdbbb5c90e050ba1b4436e71db44fffdf2f450 GIT binary patch literal 445 zcmV;u0Yd(XP)Px$cS%G+R9J=WS20e+Fc2INFCfK9p@0XFCJNkJT;&nhUP+rrr1D#UD2?v{P@JU{ z;R{C*?aAb9pS=zO38sl+JK5RU@x}rEIxc*ZTYbi{s5|SpYAfe6t9&9bhm(L0V=tjq^JOeAHk?=S2xO%| zR*IAHIjIm_atHvE++!~>_R=f;IYcW!Qky;?HS%H;twJ<`tQ5|Si@J*@z%BtWWn9!9 z+kk8W6qKa58S+~RsJ22@3XHu3fa8?|);1())v&gni6jp!0k#KHWH-SoK}zG9>y=JO6{&e_%{6QKT2=A(PF1FE(<2Ar=?CSZdvJMu}$ zHzMgg;DT1oi9#*}nb358h^(|WWLG#(#g7lb-E|1PFuZ*LFRu}&;z3UYLY#aKs;w|+ n``qvRF)>M`ho9j3HT%aW%=??Ofo!l+00000NkvXXu0mjfD(Jv1 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/cargo.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/cargo.png index bf0176ea97ecd8d2a47e095dba2082fae42236d8..0366a82ffa65b5fa94b2e2f5c7fa100be17d4169 100644 GIT binary patch delta 420 zcmV;V0bBmy0=)x}BYyw^b5ch_0Itp)=>Px$cS%G+R9J=WSG{V(Fc7|$%qb$6jDZdw zx_HSe6at2H%iuL$(-&|?`z<^hlD$t6FI_TZD0D2ri1r1pOBIZBO78sA6q*l=k#)ZB zlTNym0RB5}PIdYoU|U2luQZocfbRj`^#KM-H6|~#hR-ir1b->OkUzL?V{(J-Zbyo^ zwf)e>$T|M30)7iUj!~3mBBx0hv@0M91BlWL^7WGCG)gnJ2zCgPFo5waX4&TJC41Ja zyWoDLVCXnUeRad}vERenyFS_ltPqsRpPwE{VU#Tg><~!eDp@b0UBDd`mz*tta%vW& z?R)D2&IziE&VMrDcowtPOeX@kL>Wm+u2)OAS> zD9=c>O+kDfs0;CVpwJqIjw3#RP)Nc63a!b$zj-k!iydgp{sY_9?22#8>jhp_(5?;u O0000wIsxogL$v!7<9{71fF7`jIKV6b00`s6 zcz)PzSn=vyfU@;<0QM{3rnqzfB4Iq|wk#U}06N`XzQ3GL`Say`V#jg<(B)$61@K%4 zMB?)q(Cfe_1HadXu7jx*0N0`94N!Cly$!%;9G3#12Mpr`husE5BCiRxClUw-i^4J4 zU7(w*mXtC>7(XZMB4q<8bM^62E0J&-R9;;W%|Zi7Z3?tEqA{DTVAQs Y1IX`VC+9BnkpKVy07*qoM6N<$f|0b5xBvhE diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/cargo_dock.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/cargo_dock.png index df7ee4cf112dfcf787a8e68e4b007f2cf8eb35e6..4b07e410e29efd308e689ed7baa58261a4b0d6a1 100644 GIT binary patch delta 451 zcmV;!0X+Vf1Kb0UBYyw^b5ch_0Itp)=>Px$mPtfGR9J=WS37QlKoFfosS}|Hxr{{N zB8?l)0EK%BYHk4~+=7~dK7~00O_~%gkWxk#TG-xD7dOsOOqoZlbGyPH_019h08J#9>u+RjM6GkS zH|_VHD}Z7s9rV8ISS(*!0;Zr+Gg<;<`N#W6o&@8$N3d%^2KtyW_bTMt0&Fkt6&Tto z23*H#wHknY7vMPN z7UbYMwq6WanPx*icN=~k4p4mx{yL`E71iWc(*>&r!Zd?0&6>yRI+oN9)2um9ud@XJ zTqYc*0mp6ER-J-M0#p&E8B5UB1SEmKYzpWYF7rrgb36#UV71{AP;SFo2w0h>R#aUi tfe*FlzYzo6>W2vxF`NAdL!V~<_y+nJ*U2Bf#Bcxr delta 381 zcmV-@0fPSA1D6AkBYy#2Nkl%m0hK zU&wIz@&&Ri*VQ#(cq15(*AXm)47q&y0)ubfPO==Zd6GMWq+L8-H3S`iZXh-Qb0D%j zv5qF%0h=eeGk69h;*^6~sH6$c<2<{6O4uzkaPl(c|Nj95pLR1Tn91WWO-8WNU8 zX;vA*EQeVnqil%c7??aMl@UqV5S0%pXcXik;5h-Eriue}bq&bQ1-iNh3~vai8SrNL bC>R9*k|dwl&Ptjw00000NkvXXu0mjfPCc64 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/chapel.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/chapel.png index 635f00ec536f7a9666c491dc4439f7cc9fbc3c86..a862131d76c7f6531e0dc2919cecfc912678e916 100644 GIT binary patch delta 508 zcmVPx$&q+i}^Juvrmap2(aj0ksC$(iX6?Zl63J0DtcfvIt24C*R&H+h_m8 z-T6=wF|QiTBJ#ZFrv#XS29dTciUqN=u>-%f2`sOcCOXFK8fRBGsdf@ZuWuMV0#CO% z1`1?AjWDErc*Fq!c*H?S`?>a6Fc#45`KbqUQjwg`b9-w7R3RMgrk^`+U4V#bHz1&? z18ciLr7G6}kAFBuk?L&Jz43fM#LGoa9nc}9{mj&=qeoW!RPY7MY@3(P$#GsaG(mfxFRqL0|tTVUe% zMrH=OJs&iPKss)c1=AwKeF1=U++1IyI$#q}9-#(6YeQ}+wAIEA$y1rO|Of#Te0(BP`h0dS%_YV&w+aG@mQW=N` yK&3j}8J`8xaS;#XvETJ$B8sq2KZg2i_Ky$f4^UjzPI6lS0000!Q-+@gBQ&L3>*W#Z+M*wU-$E^UU!31Yz?d7xYdI;mFT!H4$q%QDXuS^Ks zE}`J;ZvM;Z*g;ezfH00AI4ftrbU-Fe@)Nl;8keAA>BP~mZ2<_*jJrT^1{C@;U;i!d a)aeS&q;JawR0B2u0000Px$he<`QWLXw%uC+#gdbL7W0e_77mfuC28y(cM72?|U z0F`+mc4#U-3&1s>6M&N7J<3|mhDZX?R2*fk03Zp(%~EqSmWl!R3NpSY8Gy}v7%L){ z2*6}o2nOKN14gD4<7=qAJ#cx=u$sqeRuiT+4+1D_1;KmLybwEbOev@bd|8j-hCTpV znGk@|v_SztDu1A2jRu%zJRP^PgH#Ny?7VY%OE6?( zH=^Pp<^XXjzTZ9|U$25D3DN289mm7dw^On64QQ>AuPs+e4xVMLptZKfe&>(L7$VyJ eQ?6gLe|-R(2 zu1bN|=U!or!iU32vU`8}Ak(?1xT_rc>uw>$Ls^nc=PbOb2!Fs|M)V)Mg)yZ7KP86! z4uOM15>OEUKpcehwjBVHV9q$5iSmd57Ty#;jaVrSRC`Tg2LRrhF97&N;vDx?0P2tk zV6YjTSibP43^t?R1ITnv(wO5fBm8AV(wK{9g*CunGa?Scldpc9&WM9hU zsjBE{DRgMh63aL7Ial}iMi=<&xY7mYi)9y!Gg7s<|q9;s1S)?G8MHAsAV7;1xPzC_e zL@3_^8#!NBb$hzz5Wf>mfQp>2O)(c(OTaVDv*ctzkw7ekFS%8KxXr+~0b|11gqI+< z3LuoBEK(zRo+ZY$4OSD{vKGa0KQ!BevjFc#BtkZ5o+YU2)~i4C79bl`gpY`z9f$$v zPAH?QTa-m=j9*khvpsm3O$TcUc=r>#o%|`seg3koJK)lQj6qmjfnv+wzI?#Iz`*bymm@G70JB^{-Hc+( z85kHCcm>2@OstMz!lsEDJ}1^ZtPY?jz?ue#0qt2PaCYUiGxT*pdzJ}`rRaQ809jE` zIqeKQ1SqkbYzI&i3{3|ZX^GCMab;I*l$5(?bj(m0BYyw^b5ch_0Itp)=>Px$cu7P-R9J=WS3OR{FckhkoFGkyNDN)T zLnSVd1F(3^0W$OkS-3+$51V$HNtpOLR90UFZ+DU+EP*at={3&>+ zfEuL8Sp9S%)ql||1-}iuj?s(oD8P6gxSU@hnob5IT7P`vW%cZT9sqv!^{UF-)!yFs z+bg2opMrH2Q2%zyUSz;hY`<;aS-l6iR?6OMz&87X2yjKfngSt16j^hiYDQ@;YrBvk zfL$WJ|Mkri$uasWFh)Qrg=ji)=FkUeE}@hnZGZD(q8^Lr&HfG3)$E8bz6ZBo0hZ*D P00000NkvXXu0mjfdSbsk delta 393 zcmV;40e1er1EK?vBYy#DNkl}?q+=yeUx9_8>ckX9@(Xli>fWUc)=eEqo%kjx1363LANhVczP=97>%Z%)YQl8B z+&2mEbRTgIZlVPP7EPsG#onU-9^3FLAU39XY zvBr+6(t)2!O@;^wl#sZ&5&(eDFLT%?-7x@w!!&k1adNf+-_ac*EIlHKiSR-NvMQmL9iTn9z5C? z_ZR|*aH3;KE`O93qOJjykmU|&UMUW~3-aKBW5-m>0Zxf+6`;v=+zNoZ7!{z0+dI5` zy!|Rj^j;S_C(dkYF*rAwYWAlAcTe;WW) nVmVSm0vrFFKmRT7)$1Dw6PJ$WJEk500000Px$Y)M2xR9J=Wmpx9yKoEr=2t~*dmX!u7 zC|u+KX?=tE2$nnN3^_v15O-FNU~b@+1Eg>P6*SQ*7Li308a7&-{Yz#Okl;1;Xtg_^ zcV>3Hz+cyeZqOTzx2_y*o*t#XlmOmny!8gRxV{O<&fA7zvwwP%LP!C)bN}w1?3`=; z`XYt6R84U4bG=_b`hyn7GR5_J(HuL8{G3*($HEv>+mI{*NAwNITz4AV(swKy4I zHeZ|^LJM#X2qOT8kjVvv6@X4uh@$|y8BT%FmZ1qkEYmDv01^P~pmj(gknO~wBIkha zz_AGn89)bNlYbjd04Na7089`nDckYjVTfMecS8o?<9&_Q^U}T@pG#H%yx#e9I!RC$ z@t)0N&Bsnw1zE%prsXc?+!kZqwaEbDsb^!`${L`X;U?QTfT+9*zU6>S{P)eIA1^~? zH*6b*Uf(}DwxYtcMBB&{@^@ZLL;EO=)h1K^znLbbSdh@;; zpyxTB1mL<@Oi@E30%lI*VM^9QtD`vHe`W?EN~Xq`6huT+T~h@hA}RZ0B1Y3(I+j$u q1ykOA6+q7qN6p*t@Za)Tv%UeErgobM5?7`G0000v(JayEL4o+TND`K29jta$~~_fd`W(B!h53 z-)*N&sy_}~ILXTVtf6a*MBDD}8i{v$pBx_^E@IszWA;_VTH)$5=H{Y1Vik7||5#}z z{~&A1<823YT}s3KH!`1KT++gDac6^wgO{J81k>hzjs-tBj;WiS7v|!evo=YwvXsp% z&u)>9BHN!|zd9e@Jv>`tZPJ{;505{ygC!md$pf8m2*h7g)Vw*l=?zC$ZaY&Vr>mdKI;Vst0R3#IGynhq delta 330 zcmV-Q0k!^?1LOjbBYy!aNkl^wfOymL>3JWR^VBr}o zJb)F2g^>$TcnCM4FroGoHd=|Oxa__qF-E50x4aqNXBMEtzoXZ*V7=L0Z3q_gNXemm zxZdophtma8<}7j|fw4DKiWoEnkut}AHDd{wF1HwaBjuVtD}Qo@V7lDegs>CP1{zDC z0=G2Q0zRdkBZ!>=BJp(1ofPdJ&}}%=#$-34?>e>TrqC`yU483_P5Xe|14){3U$qy| z#`xXQIpJ?Op>3M21=wuItq7V!U5Bs# cmUrlI17y8!23K}i(*OVf07*qoM6N<$f_B4_)Bpeg diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/court.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/court.png deleted file mode 100644 index fbb8c50593e43a54c2f61f5a8d97fe98bdc090d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 431 zcmV;g0Z{&lP)gv`SZXI&h7d?+=Mz}li!a~{=o{Fl z&J)<#1wu#}NT;QW&!GN?zYOci&F;?KWkAMtasTgTX7^@mNyYYm0p13qqm{_#^8LXJ z0OIZLYtm?SqQwu}HQezY#0>z&JLivuJ=UN2H4`E;0v1p1uDAL7%AAWT!slKy`T5<) zED;AV?6=V z5Z(X~DYXcTHuX^~3z2DH?m6#zGXU54x`j|>{eb%-Djk3kC=I}EJfxu(cplK30=S|a z)61>tTN9Z8=;hH)TZ9;pm%D)u;L^LNx1z~x7YzV$wB+iGiG;Y<%ln%5)hzE%mR9*u Zd;%Sq$86x@y|e%T002ovPDHLkV1gIT!BhYM diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/cryo.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/cryo.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0fc6d71683852e419285e836efa71b6e34a3e1 GIT binary patch literal 3065 zcmVf6Xi@@54ZTQ_E-Enz5K6$1 z03tR-RB%L5k){YTDBysjLy@r}iiH7DvFijGMAUI`6dRUFWUU$Bym{}eS9UO(Z2>7`&z9wUXbV-Il z#&6`Y8GKGQ04S2&F6MJnWNa;Ck|;8QE#r9r;7G||@X{|>%+C|c55>;RS}qbKr-&IQ zTvLXPlM{>K&(BTgi^a?^4mXV>;xX8n8Ce|RasXz}{8imI52H3ZN4bf ze_i~WlJ|C&UW9+{8AKoW!}eExnGFE2re(F+`iE_46#!l90Z_aBhs|Iw0E)7{bq;-T z9=d#9QpDmcXDh4R++0fmpKB>E=%LdZt9g z$j;($`3&Zthxi`{{&gM}5&R^+h%b~yM9Zd3AWW9ETgVfL1(`yIK=_}U_z%PWq}jQa ziQ4!P(3V&Nr6C$XejWfQDiI(Fdt@un?|lo#M+5oIi_w{wo%_#%{(V=tO#a9gB!7-$ zM?^BX5>d|Vn*3S!?g~$*UQipUP zL&zMmg;!4Do9IA%up=Rh?=qPj=x&RGBx1dpI68aT- z2O}^EromdU5o`ssU{5#*j)WJ%$?!5bA1;Eoz?EiTr=n?cd`V|I)p<|3O zju?MT93~aB0<#&j8`F+Cg&D?-VWzQItUA^l>xvDRIYI4MQ`g1<+DyrL=EogS06Xii({|v`U^zjmmKqDIK93(F5q| z^fLNk`gQs{RV`IdRle#b)i%{Ds;|}NsClUI)k@Ub)kf6bsWa4l)YH_rsduU0(?DsM zX@qO!YV6TCtMPOWZH~(v?wpc2hv(eZgf-1HBQ#fN?$aF5oYvCT^3%%Fs?s{6^;Da# z?V+8jy+iwi_M{F~$4y6|vqR^k&SQoO!;_KDsATjprgSxR{dFa}^}2()GkV5)QF?`X z?Rxk03HmJkB>f%wz4}uIItC#I1qQ7Kw+-=zEW;GTU55RJuZ@h2VvIHzbs0S}Rx=JT z&Npr~zH34@aW`3J(qMAU6l2OVO*7qXdf5y%vo}jIt1%lghs_<#1?IcWhb_<+P8LFo z28$a^64R5J!)#@aTGB0pEekEXET35!SjAgyv+B3{Xl-wuZrx~o$A)4PXj5p@WAm%6 znJw40#`fA=@?77!tLJvleQsxN$G6*KchjC~A7a13zSsVPgQJ7Uq0M2^(ZDg$vDWbh zi^d9LZDyT!LOXdmt#&%*^w!zIS?qk+`4<X~g?%562@eae34a)26HyS+zks@6 z$%2*zuOhu7%OdYYnM6sVdZQJi6QY}=U&naIl*dS8tzuWkUW(I*6U24LW8oFzvR(TOpMEs5_rp_~TJ^wNN(wM(bC zZ0;`Z6P^ce2XB(^$}i_nB)KM)Cp}7bP2Qe7nc|*Ok@8f)7E}wKr~0SXrM^xJP1~RL zDLp2=Jp-4Km~m7{5vB?IGPN`FGKaIwvx>8%%bb_(Ts9>N5;bK**^9Ef#WdN^)PTf9 zvR*Qp{o-l7TcBI8wqSIn=gRt3(5j`Y zdRObOE?Pal#&6AmwS={4Ykw%TE-Wv6xh`g1Pmxy9nxe7we(PI{6^cd0H#WFzsN0Cz zDA+i-Y3`<~O&?2mB^OJrODjs>Z{}{k_?699m0x|@lC)*8%%N=0R?Jr6*6Z8cw;d=~ zF3&F?+a9vLa|dHb$&Qyhm+ZVyVOLSNi?B>BD~E ze(8aT1AWbo&CM;EEoH56tE6@EV8X%6-*|u1-NtOIZ>P7H9s-9XhaP{M`0e$>L5F*f zu#U8SXZT%h2eqT56Y5;vIn|ZYCGC#u9zGg)w718lr{jCe@An_mJyvsE<#^c%!il02 zpHAkVoIaIx>gnm^(__6$dheWxJ#(!uyl?Pq(Ao3ne9xWf_v}A;-u3*k3(gmgUSwVD zy5w-FbHIL};|Kd6ItCpEJBJ*Hx-UCj?irppeBz4xmD5+fub#UWaP88_{E^}7QP*$Y zNVp-r$-DXJR{E{yw{vdK+*xxMeYfPE(!GlNn)e%iH2tw%>L5Kn>ODH}V8MesW8ASP zKV|>)e!S=*`C-L`&P4Mg+egPHeJ3wJUif(YN!F8@r^P=j|6Kdbc>FRj6+1Ql zT=e|YubW?}zu5oM?q%DiJqyhfA?sPY& z^JVSI=wtmV^?J~mhocD|pN7`vr~M89Y8iwSfSC_R6Kit-@ce)^1&DjqLoOnxyiYj= zHoBY-jcYCgf|MDsk>>|m)7}Aq-z>C&SWQ7R9teHq_DD9j1}L{jEer*u6(CDuX@8m* zf;j`C&OhK_4P2X>sxH$7_9+j&Y-$R&5Jw**XFK70_e*eFx&-v+Z9Z2 zCm~hFyTG+>o&gd-G#(&J;-59Z+HCLh{rq^@@!SbuF$YR9YY8w1Fc zB{5c;3IMR$RE=vBbq3%gWG7;mlaU0#B2;}DRpTick^ZYs=gT^Jelhy2w&`*{pnQK5 z>I3CDaN6(S`2jgsK+B`hP+12 zBTN##?;L^{&t7t{X;%9xGa+?X!;?cD5nr9vrHu?OsA&i3N>Acuv*GF}IUx{DV#pMh$D7h61#zc!y<)!@{_hc`fVEcW5bKai!VNf6f#&TOi}3c-H>A45U@za z?4r!CbnQ`5^n;HxZq8Z&=R-dz+4Gd}qPgg&ebxsLQ00>{K Aj{pDw literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/deathsposal.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/deathsposal.png index 28975a1b12b7eb516409bfe62fd84cf92e4a0b63..1fa88f63afa4f524eba589a462e26b11a459faf4 100644 GIT binary patch delta 445 zcmV;u0Yd)G1J(nOBYyw^b5ch_0Itp)=>Px$kV!;AR9J=WS21gYKotI3x&{KpbTnJQ zQ6!M1xaAkvHM{f=+#hKEfqU1u7rIH8LJ>!yTO3mf6#4_~5T0DrJL7q^E$uhu<>`Ij zz4z{&5BTdilQ|d5RiTUM`SHGy>q16u&gQthn)W8&@3sI?G=GU`6hP$D*}Qe}weNrh zvGkeIctSsGBF;rG>Dc)x>j?!61!Vzi-+^rz007%Eu=br{1%y!s&ou!6o@*kEvS9@z zX!X{e*=;&Lz`ck z0zT)bfFef3ye+DM#&7k-a#h&ZH~iOZZ+yJJA$i)=<~9Ri1opcvM&pT=^Ui{pW`i1p nlacPhBzt{noQ}SIH2cRVKoGWbYj>5E00000NkvXXu0mjfr|Qy8 delta 436 zcmV;l0ZabY1I+`FBYy#uNklygFqg@6vv2Jch%c9CLx*1b=UpBnVsErfWK}hvX0ey zQw}Ba^l&THIg^Q-izUu4=Gx->-4*~!8AJns#OI4;=j5U9Ab*I`)-jXmj2?v$r=pLB z@VxJQLVz(%2_WkRuq^|j?~Dr&CpkRV1ORxhi8#r}1z=fGiN;9|mKDkX!fn`Q z6z(8OE8+UPF9!e)UQ-TGo0eo009CQU07Riy-3dwnyr9b3YXbyP3fnTYb^!2OPr@Gq zpc{TbF$Z+cet&HMos2&Uz_yI)zzL$X@|wgU`1cmTM*xj!DjbIpdgG%?GHs-JK3 zcZ4+ z%YnvU>T10y?aQnB->kO1zrBJz-U;giVFdQOEhf|1AT9enh*GKzgeEK&hAvFPx$mq|oHR9J=WS37FMKoETiX$^)Tr?fkR zN+AqxLOP!yY2E7vK7nrFK5cx0bRtc_7?lQhR_Pc+AO}#YG2{J6yE_UglGjMukKWsz z&+Y(!9al}A)7iZ4is=3I*~oR%L_Qo(aC0G@P+tjYV;@l7z^)u*$0o!me1+pHL0pFJNa-(Ix(!0Lpj!ydie9;q delta 407 zcmV;I0cif+1F!>-BYy#RNklZq}6n(9-bnj9rLoNWK>d-TQgh(23KZsy|8!1D165``;{2$N%e+*3c@3=8d*lc$v zp8#*KFM}}#oty3MbpP>#rmCHS2T_RQ>TZz4%(O^T)kyckiGM(zNj$8c2j>_GD15I! zwGv%Ic_y{ZC40-6+_!k1Nd!@-FG|J+)(Z4N1z)^B{SB_qROT1VI$)pogzRD|jpt9h{Sl)&xpf=&uBzZPkWLS+sn% zu-*bH=>qL+rPx$nn^@KR9J=WSFuWwFB^XcTz){(+nQdm z3pRorDFb$w@(c%pA8=M1a>?vwHd(RI*Cd-v=DpdOSu((1$ARkQbT;3aB6@v(Ai0iI z+^$<=SW2Ejwd)h9}OnoZq@+M zh(z=RF!IrOGMF3yj!(|mD=FfT`p8D)y8g%%Q1CrRo3JQrZCfn?j9kaD?>X>2M_UA$ z0)Ledo6r^zg|2iziG!aJ;Cl|D&_$M4Qu0N*+Dm}423X|XCnMy^b;KGA$nvUn+AS<9 za%KZvhNhUbXGjjhufsO@mPz0_uVjrOTQCRkfQGps@gx zD^?d;HBgjwd&TP7TNPmH)C9&gU>m{{V1K>MDw=OEYAvz{fScu$P=NFV7U^o|3YM)! z_NuP2nt~(_+BVGc3P~I&3)iXu{sfA$?wt??X%|otiPqG&%ua^hU+Q!=Z~TiZ{%>|L zzCJ%tygZWg0eJ%3%^LT2m(~Pa-=@Mna#*lEm{jj?!s+PON3(x?0|e0A(CR<*X$$}W N002ovPDHLkV1hKG!$kl9 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/drama1.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/drama1.png new file mode 100644 index 0000000000000000000000000000000000000000..af0d276d5c0d73da964edf56eb88e80b2428eedd GIT binary patch literal 627 zcmV-(0*w8MP)Px%ElET{R9J=WS3OSaKoI^wP*4PfkbnaqfoP$kvAj~Q-~+rW2cW>6yHId|R2;xp zh_sO#s?Z{kH~=6;(R(RUyaI}3*0bYrY?B}g_?l$LyYqeXvtt?f=~&Z@M;CbiD#GVG zpR*v~=mPJX`@q(2Zo5C7{hmE6M?M_`|KEHOo&X|0JZU+b-J1Xa%&6to^uG+WN1g?M zm&b`GVqG5Qk#jP;Hz_#Qh&AEd&iw;Q2DXoZodf?67Xbjc90CA({RFAa5Saj-c9J`~ zIadXmQ44=xC;0c2XP{I7&j2SjahONh9pujAu&|Gxryv>$;8ANejZEM&klL*D4DSIc zpwI(a+MLtNAYy_xg$JbVqW{ZVJNE{aS_yr9IH=C%N-D^qQ;=Qk!{%+#g42 z24;l%At&r=@kHdrWdT&)f=)YeDeUzVuQXJ5X(Q5Eqb3Xe*XjXEWok2Y+C?H-^L=!V zM9__qPzTZd?XW;jps}ktBT+KlJeadT=glUe22Dg6xrCgAwFZ#{H7Jj)4!MR;WndXJ zdKXZK(~Otv$OMJw{8v8LQ2jEBL+>i_HT401&dZ`bZ!ADUyM9uz+`kBo1!x(m+P{h)`!WeQ2AlPMXa8F2Kj0Bix0MGb%MV|dtLwl N002ovPDHLkV1m5b9z_5E literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/drama2.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/drama2.png new file mode 100644 index 0000000000000000000000000000000000000000..538374ce404d406c0a81951dc09b15d291f6daeb GIT binary patch literal 588 zcmV-S0<-;zP)Px%21!IgR9J=WS3OU|Fc5tp7&?@y3*`qO!46ZGs*$>N?p!hTCp4R-4&f(w;s<2x z*hr4DFqO_Au~q_>3OaOP2t#nNFV1I+K!Ufl=dzwYUNt&upO6S69&2~GYy618Te zg2aC2>=MZV0O1_M@r#B8U{IhE!Z|Fv3)o!%fN=cCE`Y)cP-*$B4?gR|8rQ)+hJn>7 z!MFke08ypmI{2)Q$#4Nz1ONb61egpLl}MB$@CjE0ST3j9*m60I36()^515)tI6kk9thAWk1OO(w~OR9*~P=Woi|!2;xNCV+o(SPA!5W z@faPQ0e3g^c#O(AusRs^m{D$7J(XKcesOh)w}-FC$Vi~k%6?ExB+`;oygsir0+rqZ z*`V~8R=J2ODXd_x^_!4;3@y8>9VOM4eW3c)Z87;v6QEGf zIZY@D()n2^O~9l`-u$fy(294BA3p_&dtkEy8m;`js{+gJVzbi6e%FVIN@DlvBhXK? ae|!LaZ!HcAeT=sN0000Px${7FPXR9J=WS3OI^P!zpN9UQc{Sf_$e(6Muu(m;2o{)OfTxD=Oc`3vb^$S7`s z7qU1x)J?&ugIJeRD|E1+L%h%XzLJ+TqM&EV`#$HL`|gDR{B>;U23s9?|1QFZYmrkC z(CWbZ&LP0=LG|RTIl$YqC_)f`24{AsL2cH%_rk@x;$e$3~bQIEGx<9LQnjFkWi=Eqi~xQ-I)$TJ1d4W<(IDt+i5}PhybO7P@JsyrA`f7(Pfme44LF5VKXg{{)Fjxzqo6$<$ zEkc$k8iFRHA)+2Xvl>MK@nqfDHMi=hb~v`jr-- zb0ly5MgnxXT_t`z3zRyrngi4u`LQblXVin$TpasdKPFT}_4Fy^U$cLF0B@x-sd=Ud Qi~s-t07*qoM6N<$f{wWXvH$=8 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/drones.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/drones.png deleted file mode 100644 index 3d7e65f7a57fd46dadbdee861e15d71d43057f7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 405 zcmV;G0c!q&<>lg6GEvYYyw+YQ5Rty*)vyHYho#1l#Dv z3UNIYM5-2X-UIH_Z72{|R5!->syh4$J7ru$`yNv7K{fSx@$Kv`7al%OmslT51C{1>$SYpoan zJ^;k`=-eM)eKZKbDLL7CUEbXe_?-P%K5Nz|xTu5#!@|^000000NkvXXu0mjfUV61R diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/eng.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/eng.png index 2d12b080fc7cb40ed8ad81b42f7159274b9008c8..5a70940bd90814ff369ed54aecc486c030d27145 100644 GIT binary patch delta 393 zcmV;40e1ed1EK?vBYyw^b5ch_0Itp)=>Px$TuDShR9J=WmoZMmFcgM=5GSAmk{RFt zc&P%MB~uQOwIgc|ktt^ZqAunDFkmS|xk4GLSGlfVJ3eIx0FjkY>30A1a|;m_9WL&+;S@CkR9@ZA+(drdzh?sgi2B6- z=z&C9-BYy#RNklZvcK%X?($;UsXaqLlT4gKp zvSx3>wKW0jTYpf@BLq>T-WesR@O3U#Td}@oO4?Whj1m>RxjvgO006W30*n$uZA$(0jfu7$rD%?78`G`5kwB0(uCjDG;W_MXmq<002ovPDHLkV1m+) Bz`Xzf diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/engine.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/engine.png index 2c4f14d70771827b0096a605673649f6b68153e1..629680bfea85b70e0e38e41d12c97aa1df7c3312 100644 GIT binary patch delta 421 zcmV;W0b2go1HJ>0BYyw^b5ch_0Itp)=>Px$cu7P-R9J=WmpyKSKoEtWqnscVkw}po zAlo4Fa}_EMLF+PY4nf5Ma*8C#MeqUa!blYM2_iWKnrIC>3$u$YOUY|2GYjvVVOR#> zuWM!t&J*mXGI}Y@UM#>o!T$CJxDNfzn;KYe%n(KZGJm@FH-9I+FU=5_+zCUOhblu5 zC2YLPh+iS42|E&!K3nb+0p@c_8&UCf;T zOxe4d10GGNn-ds46%rUH05Yxe_@Ejm>47Sbja`1S9sv4%;L`)%Pl1oQ6F?9p_a(}qO96xWaI z>%{;-n>B5*)C1fgLUFxPw)LX`r0@6cFfw%hs0!E`u4~xs6YmP>+AfM-M!F%zB_kO- z6+b=zcUKZTyH-2k<5MsdH+2gj$%a#v$7pJE>^whAbRGzQ`&Qhi*}r}O$ZykGbfFR7 P00000NkvXXu0mjfXso;= delta 446 zcmV;v0YU!01J?tPBYy#&Nkl&^D` z8wVe6uY*1YC)b

FM|mscI|dN#J7deGWoAjv0}vMwC`o0Dn@1n0do%9;_^1kf#Oa zyJz-)RselRo)*Zn!m3m(08a}5ZCPkM-#sJG3IMPw6$>EG3KM;!OB_T9pxtZ)Ltr-n zh|&sD)kp#tjvpflTu4=$vE#=k8&?N7h|omm_%Rw?!trA)R|~Ty&k96o#md5DfFy8{ zX9bq4g^9A!Wq;=hboazn0i>$2TrJS(vJ*9Bg66q>V=_RLR-MSG_5gllgrm_;*oTlJ z1XR&+d=AAuiY$PG2+eLMQ3)t|DMA(m3jk=NqzoAK-x*?;;M$r5KppQEngn1Q`4n*W z9w4LCkoqn7rl$bF#h!l-a%9?L-v^|sjY9zDNYZz%*f$xV6n_DTUVtNjC{5XpCj%sb o+jc(-C4r0m$eKUDmfv;PH&+e1E0c-@S^xk507*qoM6N<$g7$&LfdBvi diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/eva.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/eva.png index 2db7d42645646bfbda6aa0634d6129076b12aa60..3e5d2db3c327eb11dd23129738481b66359c3f89 100644 GIT binary patch delta 492 zcmVTBYyw^b5ch_0Itp)=>Px$zez+vR9J=WS21eCFcf_)T?>Wcc67FY zM`Hq6O17N9U9;x~Ie~BBy=#4fZl+5i1dWDl@tB%Gp$Bl6epj|6>nk>NXdi?a$<}-N z`g+m_{yHxDI_Jw(Jr>d1%afMts*l{C&TxA_8BBgU9sr=$iGR=vAo9s{Hkcd$u5a$> zQ4wK`K;O*6z(c(7mG&$zA&Sa4Ub){Y?M4A6BzwdAq+g@yP~KNFZ@QVX-S*}P*{_7)R3EUfcokEQ3U7&5#dlc<$#Pa z$k_tq#1ci-OMgxwryLkXfGDa~=9|`4Zr`Lk>-w_=06#O5Bhmfo-m`&~gvmN;ML=gp z)J9uR6qWMbSpvF)(BNU*Yg>8)Yr$v%qFBE_Z>m1lWwlFj zfGk#aLXO+@L3>x9FIRQ=@F?GA2jlbO9pd#_sSk`vcsd?h0$kS?XfMZiZJ@wd8I4_- il>4o=I{Nj}>>poLtOnrvSizD2000015QSetiWIqlRVf5g?85300;^FML`qeu zjn83JyK-rQIyWwI2n(dzm2(GoPPNO%KPzS?IED49LA%WR7|mz|47zpQ^<9|Fmj{W# z^y59~5j>pDmxr&%Z!~SkGB;Ww-H(D04}D3Rw!`P!gauI46@Su~QSi<^E3;=%)RiO! zAE2l!lv$24%S8|@0N-%4+nzk5sJ90$85^yzSg%~%w4FPr^b85WngKu(#qOCOQzwQD zU=5Ne78$buY-x+S!e+O1rnV}aaV1y4mo=71^c`s0j$L{&z@;X<8i1YuPx$q)9|UR9J=Wm$7ZbFc3w5f=pn`g@F`q zk}C{k0jvy`5{VQEWe)5Pwbpc0Q+v-p*MY_2z`Q z^-UP!%R|=l0$fUWr%YOi7yz)6>xL~)2~tH~dvAb+h#{!hx8jBqc3zHY+HIXB1vOx| zj*0+(y&YmRC1syKMJEH8p?9S~Pys;%0FbI~OBJ<(1gAhyfh1E^JIPc9vXW~gnL4nW z^V)RO9^g>h?|*&NnSwm!uto>@=l49V$GRd=j&Jq{1JsKu2qGirwBK~iIV-uY_QQ`H zL!hn)T{;^;$PoluZo|j<6Q+~#U_jf?FT8GE!f(S%>G}Z{B1WE4bsX&{+qo`qKg(_( z4Zs!9b;eD*S@CShUI6w&Nv4pebO2;KDhm_^9mOC3+e#Tjxa>fA1iLOFR%azN%dIaB zF8!K1;EjOR8q>)*Xd`tg$rQBKPTO_%_>Ng;t8GCZCpiF^XKcBI#zVjfYM}N2Sx;7yb>!}B zwJlhzv0hDpyIu-G;5+7ioaAO5C;3q#st^RegD^_XI*ignoWm$B$oalwQ0D;8>{GJ* z7%D^XFzEsKc7H3+@;J$j8~`2{>x2FD{MiKfp@HudVs0lLAzN*mFGF%UZ!&fm_?j%& zgi2KfWJy(-NwP*8k*3Da=>xy-Wpr@@^O4$7MdPR^0(L0>FCEtvwwU6Dge~+dLP$R00000 LNkvXXu0mjfuWjKb diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/gravi.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/gravi.png index 21eb2e861365f25fd830d1a6ed79432e56bb494f..811d40aa898442b5812200188dfc94181c9d14d3 100644 GIT binary patch delta 398 zcmV;90dfAy1E&L!BYyw^b5ch_0Itp)=>Px$VM# zc&P$COQs$oYe!ZNktt^ZsxIjPU}&TaBql#coO&traF5&$YJo@rC%gZ%)HHB!%n z{P?)5#lG19xa^EW>%a?u=69a)6rAs(^q^%>V!Z delta 433 zcmV;i0Z#s>1Ih!CBYy#rNklj)B4c9T&*{km(vFr@0^@xafp5NrG=8G{vLlb0ih=42sTz8+v zp<)MQiJB%>5XL!>R!1=2q2BJsoeLNM&ZTM$5VaI(b^NtE8Nwwetg0Ytsq);n2gRvN z&oIt`(Gi)(M1R;tF1R!-;|MU`Dc@NRy=>dcI08R+Cx_mr9~c8fEk)lR#wf_q5Vl;Z zCsN%P;6y5b0O_lK-g&r8Wdz`R;CKVL9>*r&R;?JgmK@`qau3K7^>#Oo*+5%0qN2>f zc&FR}D9(#AAN#`H0fZxQ7RXg0bZbl}>ppPCR0+3ic`EEK09hP@IaWayhuF`|`SZW! b4?Xk^O1HJogTRu!00000NkvXXu0mjfxwOf~ diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/hydro.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/hydro.png new file mode 100644 index 0000000000000000000000000000000000000000..f23fa7960de10d47971976cec74d3a8d0b36374b GIT binary patch literal 479 zcmV<50U-W~P)Px$nMp)JR9J=WS36F`FccgR6cn(cVL8A`aE5K7SjrW0245kayIdh>$Q2?vO2ZjI z;s8Js!4@efmSW}Lc>T|=K!Rx!|MKQNd&Uaz*KuMST&=M^RG{YveJmq^)f(IL8{p!4 ze(<3OKHu~tv;;)(+xtuB$8(aP=ACoi%i~5%;?%UjC-a;npcz9>66ajg_lyL5Kr=RZ z#vq!2nzc_AbT|uLz{?f@K#CLq1I-w!hN0%2GUkV%3h=T;)v)os=G|WKs$t{%!3i7# z!30Fff$!~*vkyIxK?KC!$|MBj;2~$gXhc_cz+$O4A~|CLSMc}O4L+U%jK~JL5pU2NQ6?ma$L8eq04c9~gRIu?*L>4x~si^!l;i`C}rJm>+%z)34b-z5xFW V+gU*~Gv5FJ002ovPDHLkV1l>A(Sra0 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/hydro1.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/hydro1.png deleted file mode 100644 index b20654fcd64d131182ac3e9f7bc4a124e5e44d85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 428 zcmV;d0aN~oP)15QSetT7x0TDdomASiE;_+#2ZGOF+0iaSr z+yIdIe6h4P2Y|_RMyFDUd)Y%KU+#Mj;xK^kIj#5V-X{exG2gCTL`jP6+BJgc6@bir z7>1=t@7#9@FeFA;|U_J@KEApHy4l;tG=)aDcq1`vnA4GdSTA&8O`QIgg$B2ZVc zGSGyv5i0|Is&fXK=@w&7Hacg3OlTg6F-M~h!RP?2zkpUkF&-2k%S-D8h&1{TC;=$N zx}#VRG-K0x!72mItyql3dVvkloM>%ZFK27k0*H$XO*-A=;}j=WL!kR&lZ*k9zF@W4 zRsQpfSj}4N=lcuU$D6c2kgfyQ%NdjD%xa$}MM+A%fmG6Fq3_0|_&h1QqtRQlfBgal Wgr_VU2}0li0000*4}gCFZQ z(nest^bjQ}q9pwW0U)hK;5ZE20qhQi_Q3ic0XqZ8@=`ibG#VwT15QSetT7x0TDecanQV4^akj^JaTKBqvPM{m8PaB=Uok$Z1LZu;{RXWBH$N`jU zV6&Rt9a(D!w96nUyj8h#N#npfZQOdH$0&yv_5fNs>c zoHd|A6lEiZ$dVXE**O2#>nZ3H2~&D>i6fvx_)>2G0HV;I6~Jc{PVR(7*|0r;*3J%4 zZx3D~aZ(C=>h}Urer=!XL8V_uVPHMToB$H(C!TsuXN9Y2Spn24r>eJAxU~I>0n~O% z6>qD2={tZJz$KfPx$b4f%&R9J=Wmpx9zFc5{G5eJ~4N=>zO zE|7D$jUwkZ+a*FN*XP&^xTd1rR1~?v(BQ>uJc;cXgal98!to^Uo6-1Zfxj-XHrWAG z%IKN#VgWjUDgX}!%ohMN0}%wU=1&F8tzH?3JMM+p%q1B}GJl(K-1k_3RAWg7jZ(?q z$pTo*IJP2IY!4g&JSLiJQ3vC+sPP8i1qnUCY3?V?{j_Qx8gt6-0S?5E*#fywF?E~l zJdS9TVj(1%s48Stz?z@OG3WI>05|*4a&w=>W}gJ$%T{5pq5xuz8l{r5j|SKSwHtsl z@*A)kT2w;|;D2*BjDajt0c-558rn^WM9+-0RjeLd;?`D$pPMg1k7>yb@>9Qnt!B(r*G6$c0%%h?sM*~H#( z=6?GA8&R&fWyszKmJfiGY&dCAV`1ig=N}UnqJTfZm>K^I0Nw$)rqN&S8O%Wd0000< KMNUMnLSTY$BEIGT delta 369 zcmV-%0gnE;1B(NYBYy!>NklNL^(hY5DJAXfQ-*o58Tcq%dQ@%B1s zV{mYHIG%pKzrf5Q<3xnT^UEN_)7U1=jH+%#0L~gLM&^tHw13)fH#a>&M0o$)WTFWG zm>EO_rBwGXgwR3lw`Yi4m}G#eZs4rB@RAp=7hg2UIy4*ndYg5WKV?Zof-`||t) z{B<0Sb*|Rfg(7;mHFH@7tk&3_UI4Sjbn>cDv68YtzWhJpuH+yX_Pg}g+ zGg4qemPn^rs-nh5xkZDW0-E;_IOe>pXYX1D7w{c8xB!+5fbJhCD`_3j_M_Tdz>Yv! zNo2{V&1jh=a(`5u32Xt>-+E1;Ys1k0!3BiI?-Wp0vR{yB$<06D;R0U-b3tgZ1n6+5 zB7!Pvq$29u=^ml$F8hX81oUD?}s{ zhSn2N+W_-rm|TlIM%$SCe&)r5ikME{!FDzK$2$zQs}Zi$#nrt40000U$B!32COGiWi{{a60|De66lK=n!32;bRa{vGf6951U69E94oEQKA z00(qQO+^Ri3I-Ae0uQ)%Qvd(}9cffpbVF}#ZDnqB0000007G(RVRU6=Aa`kWXdp*P zO;BVmWd{HN0gOpRK~z}7V_+ERfDxC3rF;B;YFTo8=R%zJuz%pPTwdLbL0DXYV$0vY ze89lK!0;cJBUo@*uApv472op;h{2dx9l?Z6lZb>8RpS|-c~~95%*sYp2jDZ0gh5#~u^?`>B=dQh`z5_xX-dd4xkkv*#Smcq717KJj6;<%>jRZ|H7(x^?`>Bp$_u!M21X< zI>NxofXU zDrl${0*nI@1<01RL4(^!OO&BK%LJb7kV{AOsG&*-Fn=>KVXYI8Q$M+70KqiypMima zjg^t%$4~rq0JG2UG|9}NoTb@@yj4Jhi<+L-fz5(&so7x?dhc{2*>>Ukw*K8C30M*H^rW{-2 Ry#N3J00>D%PDHLkV1hwp<^KQx diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/kitchen.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/kitchen.png new file mode 100644 index 0000000000000000000000000000000000000000..322d62d8d2e6d584d30d7ae572accb2eb7545983 GIT binary patch literal 486 zcmV@P)Px$ph-kQR9J=WS20e*Fcf_t7#KpuLODPsm^*fH)cekUU=@=|P3I!>`Vku4q&jOw@5_xDbBIQ7+h-mZ% zF#QRPF^`5#lgim1Y?_$a{it&9i)Yis^d~T`Egq>5SqJP{3I(3BT4#95YM1Or0Xi#5 z)>HQfjRKn9z!l%BfI8%bg3ijQT@h(5hyi&m*sg$1H-66t>^{qO>k*L?7E%Emy}z9*ib`3eaIW53t_sD={>dW<}M~m@L4AM~(m;MDjYP zBZGAUBE%h1pIVNP#sXwN=;H280Fjd)03eAY0APz~B!I|?6hQUN72s?_SKM7dqY$K7 zfh3L;4^STPE`NaHEPCMAZUJRLA~nr<6HsTD-VzbTzRo%?0`kM9+MOJ8F*9TA@Z*OeDr{R16009_DL_t(og=75x|3AY(0>)7X40;Fj&00Z`3yabs z7|C`(->en?cXK>txN!LjS(Y2<>M*$ekjCo>f)41uy^~>OXn!GD4hUb}&rquBPCW;- z-`LGyD5J!1{>eQ!jSW<4xYEu6!~mK(V8@rcL^;5NN0~Mb81N84cL2;HT;eo!fT4^M z!~E@=7#J8B7*>WBqR7$Q0mzoa0J0;7zXQ-6LH8&?b_4?h14e-~d0f zfOF7V*7`(VS!p>37obj++Eof}uqmRk*49om%dVYB$=3ja<$LqPtbo6+=DV9a2(^rk zikAwogU|v`70eglq(CGA#Qdd#x#(Sic+eKqh}`l%6~LLN&fFVjfU)Ul4_nn(%qQ;w zn7lVZROtcHYCQqLCyTua9CbuZ+qs07w1Zw63f zHe>Z?YAt12l>5K)$0UZR;17!VzW_b~E8>Vp*tMzJ P00000NkvXXu0mjf!-lYR delta 340 zcmV-a0jvIu1MdQmB!3BTNLh0L01m_e01m_fl`9S#0003YNklL5?9F@MB4z(`9J!xD5pa;ShD zckbG2>Nx;p8M2RwQBPF|&=QO~VAKIbIRKOcNXhG@Px$TuDShR9J=Wm$7cbFc5}+s?JnV6)_@Z zVCceV3c0LOhrT zxOj6)JR`tw>E-~Blupa_#@ZlDVm<&RkWLhE@)Go&1!{lt3>0}<2fa2MvQLqx2&0ud zfbFgXkp3`HK~!VeKa9HLk^#OU&;n^1_fanZ6Nrs53xI2C1;D8VYyg`YK-JAl@g1NO zpqYH~em)DZTz_vcp9S@EdFjSk1E|5&pkcH^mc(_rm5JInVMze;KOn1J6O1Dgz;;)n z$kSHgaq)SQld!Am>6S^&36qSw;$ZAy%m0hK zU&wIz@&&Ri*VQ#(cq15(*AXm)47q&y0)ubfPO==Zd6GMWq+L8-HB4lgOhqu@4j>o> z$YAp%ccRph5@jSg00uk*60wSJ-!PwKvq+8tU0nmL7H!`!pMODD*MRm8kWn_oa0JY9 z8D&F~9Y9tTz$}6}f?UhVb^y!~*;PT}Q@Nyq!Ik|u=2Y3b~ z!X1I^7;*|Jk~yOQmL7cbAVIC*$bdpq-2u9~24v>~U0nl)Hw4rSc(Z&Ii~<0xBw52O SxfuBX0000Px$K}keGR9J=Wmpg8QKoExiL_R@WM8bu0fNW!7`z%x(g4ShP4nf6P>>!%;0qnvn zQQ#}sg*6s2JNp0JKR9W-*F(H=4Ti|v#owf>LlGB7yUao-Kb-&qk)SSf);?WC&c3_>Y?+(D z1_1#0^4j2ZVh7=0X#^MnMu1-da9xIhjth}#!BH~x^5qTSlbws6e+)d9o4x~)K*R+C zk=*~&)3n?62d4^ITr|l=CQ=g{YL? l_M8`!CPe@6H*r_9QCGiqcA-lz9ku`f002ovPDHLkV1hR8tX%*A literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/medbay.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/medbay.png index c9c6e1362a7f973039ffd199b7a7c4827b7dc6ab..e57571f6821a78822ed0771ed2c4c228a22933ec 100644 GIT binary patch delta 508 zcmVPx$&q+i&v)+V8iT>0x4D!O+kefw7D5X^<`Z_KePG~w z$as#x_u#WFxNxiMjOW__ti`Jq;?hKIdUG-bpgjh@*XemifF^S;TmaA>n;?1tsOCP~ zB8^y8?u_S1BX)4VEkrATx_KB2aN#127yuxR7`Si|#-cOCRTuM&=g9c}cREiahAla^N#R(T_W}S=Rlv6Yy#Ul4ES9VDh7dRm zT|JOz0U!uqAHpBWz-(Fq=vM)&Wk^a22T5V~=A_mYsC9>ot^?mg8nJ`Hlt%2d)39!; z!q9Y7GeA@EaIs*`dDyoWF1znX)>a`!}BGZ1rxD2I~ y7!93X{UwF5fRs{u?{|Kfs1Uu~zhwF}``0H01pc!c)+ho10000!{?0v delta 287 zcmV+)0pR|X1i1o`BYyz^Nkl%l|Kt z-@$PH%0;p)H`LK*hHwnC0D7E`mIK4a0c6(&mn2+`aDlvKx5 zaRAJ)4CiQu8GDy980zT58!0e0x*Sc4;*&40FfcGMFqn($FfcGcLgxIHiwuT3`V2Gn zE@jAYj)wDz1td9Of?yGfL+lU7!+mV1qYoD+1&~}4!h_ZpNfH;E8V)ej(I-0>80zRV lFg(PsX26@}qZnWm004RpTw$E^!8-r|002ovPDHLkV1hb+c!mG~ diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/meta.json b/Resources/Textures/Structures/Wallmounts/signs.rsi/meta.json index 97be2aaa0d0..a13df6f7d66 100644 --- a/Resources/Textures/Structures/Wallmounts/signs.rsi/meta.json +++ b/Resources/Textures/Structures/Wallmounts/signs.rsi/meta.json @@ -5,1490 +5,490 @@ "y": 32 }, "license": "CC-BY-SA-3.0", - "copyright": "Taken from https://github.com/discordia-space/CEV-Eris at commit 4e0bbe682d0a00192d24708fdb7031008aa03f18 and bee station at commit https://github.com/BeeStation/BeeStation-Hornet/commit/13dd5ac712385642574138f6d7b30eea7c2fab9c, except numerical signs which were created by discord: brainfood#7460, states: 'survival' and 'ntmining' from https://github.com/tgstation/tgstation/commit/f743754ec3ef446c8172388431effa73aeddb7ff#diff-b429dd7fccbca60d740d4887c1077a178abf1efffe57e7ae2a0b607c8a9e2202, 'janitor' edited by forgotmyotheraccount on github, 'arcade', 'barbershop', 'direction_exam', 'direction_icu', 'laundromat', 'news', 'reception', and 'salvage' made by rosieposieeee (github)", + "copyright": "Taken from https://github.com/discordia-space/CEV-Eris at commit 4e0bbe682d0a00192d24708fdb7031008aa03f18 and bee station at commit https://github.com/BeeStation/BeeStation-Hornet/commit/13dd5ac712385642574138f6d7b30eea7c2fab9c, Job signs by EmoGarbage404 (github) with inspiration from yogstation and tgstation, 'direction_exam' and 'direction_icu' made by rosieposieeee (github)", "states": [ { - "name": "ai", - "delays": [ - [ - 1 - ] - ] + "name": "ai" }, { - "name": "anomaly", - "delays": [ - [ - 1 - ] - ] + "name": "ai_upload" }, { - "name": "anomaly2" + "name": "vault" }, { - "name": "arcade", - "delays": [ - [ - 1 - ] - ] + "name": "xenoarch" }, { - "name": "armory", - "delays": [ - [ - 1 - ] - ] + "name": "anomaly" }, { - "name": "barbershop", - "delays": [ - [ - 1 - ] - ] + "name": "arcade" }, { - "name": "ass", - "delays": [ - [ - 1 - ] - ] + "name": "armory" }, { - "name": "atmos", - "delays": [ - [ - 1 - ] - ] + "name": "barbershop" }, { - "name": "atmos_air", - "delays": [ - [ - 1 - ] - ] + "name": "ass" }, { - "name": "atmos_co2", - "delays": [ - [ - 1 - ] - ] + "name": "atmos" }, { - "name": "atmos_n2", - "delays": [ - [ - 1 - ] - ] + "name": "atmos_air" }, { - "name": "atmos_n2o", - "delays": [ - [ - 1 - ] - ] + "name": "atmos_co2" }, { - "name": "atmos_o2", - "delays": [ - [ - 1 - ] - ] + "name": "atmos_n2" }, { - "name": "atmos_plasma", - "delays": [ - [ - 1 - ] - ] + "name": "atmos_n2o" }, { - "name": "atmos_tritium", - "delays": [ - [ - 1 - ] - ] + "name": "atmos_o2" }, { - "name": "atmos_waste", - "delays": [ - [ - 1 - ] - ] + "name": "atmos_plasma" }, { - "name": "atmosplaque", - "delays": [ - [ - 1 - ] - ] + "name": "atmos_tritium" }, { - "name": "zumosplaque", - "delays": [ - [ - 1 - ] - ] + "name": "atmos_waste" }, { - "name": "bar", - "delays": [ - [ - 1 - ] - ] + "name": "atmosplaque" }, { - "name": "biblio", - "delays": [ - [ - 1 - ] - ] + "name": "zumosplaque" }, { - "name": "bio", - "delays": [ - [ - 1 - ] - ] + "name": "bar" }, { - "name": "biohazard", - "delays": [ - [ - 1 - ] - ] + "name": "biblio" }, { - "name": "bridge", - "delays": [ - [ - 1 - ] - ] + "name": "bio" }, { - "name": "canisters", - "delays": [ - [ - 1 - ] - ] + "name": "biohazard" }, { - "name": "cargo", - "delays": [ - [ - 1 - ] - ] + "name": "bridge" }, { - "name": "cargo_dock", - "delays": [ - [ - 1 - ] - ] + "name": "canisters" }, { - "name": "chapel", - "delays": [ - [ - 1 - ] - ] + "name": "cargo" }, { - "name": "chem", - "delays": [ - [ - 1 - ] - ] + "name": "cargo_dock" }, { - "name": "chemistry1", - "delays": [ - [ - 1 - ] - ] + "name": "chapel" }, { - "name": "chemistry2", - "delays": [ - [ - 1 - ] - ] + "name": "chem" }, { - "name": "commander", - "delays": [ - [ - 1 - ] - ] + "name": "commander" }, { - "name": "conference_room", - "delays": [ - [ - 1 - ] - ] + "name": "conference_room" }, { - "name": "corrosives", - "delays": [ - [ - 1 - ] - ] + "name": "corrosives" }, { - "name": "court", - "delays": [ - [ - 1 - ] - ] + "name": "cryogenics" }, { - "name": "cryogenics", - "delays": [ - [ - 1 - ] - ] + "name": "danger" }, { - "name": "danger", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "deathsposal", - "delays": [ - [ - 1 - ] - ] + "name": "deathsposal" }, { "name": "direction_bar", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_exam", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_icu", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_janitor", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_food", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_hop", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_library", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_chemistry", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_eng", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_evac", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_supply", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_bridge", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_med", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_sci", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_sec", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_brig", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_chapel", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_hydro", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_dorms", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_cryo", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_gravity", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_salvage", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_solar", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "direction_wash", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] - }, - { - "name": "dock", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "doors", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "drones", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "electrical", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "eng", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "engine", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "eva", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "examroom", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "explosives", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "fire", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "flammable", - "delays": [ - [ - 1 - ] - ] - }, - { - "name": "cloning", - "delays": [ - [ - 1 - ] - ] + "directions": 4 + }, + { + "name": "dock" + }, + { + "name": "doors" + }, + { + "name": "mats" + }, + { + "name": "electrical" + }, + { + "name": "eng" + }, + { + "name": "engine" + }, + { + "name": "eva" + }, + { + "name": "examroom" }, { - "name": "gravi", - "delays": [ - [ - 1 - ] - ] + "name": "explosives" }, { - "name": "hydro1", - "delays": [ - [ - 1 - ] - ] + "name": "fire" }, { - "name": "hydro2", - "delays": [ - [ - 1 - ] - ] + "name": "flammable" }, { - "name": "hydro3", - "delays": [ - [ - 1 - ] - ] + "name": "cloning" }, { - "name": "interrogation", - "delays": [ - [ - 1 - ] - ] + "name": "gravi" }, { - "name": "janitor", - "delays": [ - [ - 1 - ] - ] + "name": "hydro" }, { - "name": "laser", - "delays": [ - [ - 1 - ] - ] + "name": "interrogation" }, { - "name": "laundromat", - "delays": [ - [ - 1 - ] - ] + "name": "janitor" }, { - "name": "law", - "delays": [ - [ - 1 - ] - ] + "name": "laser" }, { - "name": "magnetics", - "delays": [ - [ - 1 - ] - ] + "name": "laundromat" }, { - "name": "mail", - "delays": [ - [ - 1 - ] - ] + "name": "law" }, { - "name": "medbay", - "delays": [ - [ - 1 - ] - ] + "name": "magnetics" }, { - "name": "memetic", - "delays": [ - [ - 1 - ] - ] + "name": "mail" }, { - "name": "miner_dock", - "delays": [ - [ - 1 - ] - ] + "name": "medbay" }, { - "name": "monkey_painting", - "delays": [ - [ - 1 - ] - ] + "name": "memetic" }, { - "name": "morgue", - "delays": [ - [ - 1 - ] - ] + "name": "monkey_painting" }, { - "name": "news", - "delays": [ - [ - 1 - ] - ] + "name": "morgue" }, { - "name": "nosmoking", - "delays": [ - [ - 1 - ] - ] + "name": "news" }, { - "name": "nosmoking2", - "delays": [ - [ - 1 - ] - ] + "name": "kitchen" }, { - "name": "surgery", - "delays": [ - [ - 1 - ] - ] + "name": "drama1" }, { - "name": "optical", - "delays": [ - [ - 1 - ] - ] + "name": "drama2" }, { - "name": "oxidants", - "delays": [ - [ - 1 - ] - ] + "name": "drama3" }, { - "name": "pods", - "delays": [ - [ - 1 - ] - ] + "name": "restroom" }, { - "name": "prison", - "delays": [ - [ - 1 - ] - ] + "name": "nosmoking" }, { - "name": "psychology", - "delays": [ - [ - 1 - ] - ] + "name": "nosmoking2" }, { - "name": "radiation", - "delays": [ - [ - 1 - ] - ] + "name": "surgery" }, { - "name": "reception", - "delays": [ - [ - 1 - ] - ] + "name": "optical" }, { - "name": "rnd", - "delays": [ - [ - 1 - ] - ] + "name": "oxidants" }, { - "name": "robo", - "delays": [ - [ - 1 - ] - ] + "name": "pods" }, { - "name": "salvage", - "delays": [ - [ - 1 - ] - ] + "name": "prison" }, { - "name": "sci", - "delays": [ - [ - 1 - ] - ] + "name": "psychology" }, { - "name": "science1", - "delays": [ - [ - 1 - ] - ] + "name": "radiation" }, { - "name": "science2", - "delays": [ - [ - 1 - ] - ] + "name": "reception" }, { - "name": "secure", - "delays": [ - [ - 1 - ] - ] + "name": "rnd" }, { - "name": "securearea", - "delays": [ - [ - 1 - ] - ] + "name": "robo" }, { - "name": "shield", - "delays": [ - [ - 1 - ] - ] + "name": "salvage" }, { - "name": "shock", - "delays": [ - [ - 1 - ] - ] + "name": "sci" }, { - "name": "something-old1", - "delays": [ - [ - 1 - ] - ] + "name": "secure" }, { - "name": "something-old2", - "delays": [ - [ - 1 - ] - ] + "name": "securearea" }, { - "name": "space", - "delays": [ - [ - 1 - ] - ] + "name": "cans" }, { - "name": "telecoms", - "delays": [ - [ - 1 - ] - ] + "name": "shock" }, { - "name": "toxins2", - "delays": [ - [ - 1 - ] - ] + "name": "something-old1" }, { - "name": "toxins", - "delays": [ - [ - 1 - ] - ] + "name": "something-old2" }, { - "name": "virology", - "delays": [ - [ - 1 - ] - ] + "name": "space" }, { - "name": "xenobio", - "delays": [ - [ - 1 - ] - ] + "name": "telecoms" }, { - "name": "xenobio2", - "delays": [ - [ - 1 - ] - ] + "name": "toxins" }, { - "name": "xenolab", - "delays": [ - [ - 1 - ] - ] + "name": "virology" }, { - "name": "zomlab", - "delays": [ - [ - 1 - ] - ] + "name": "xenobio" }, { - "name": "small_secure_red", - "delays": [ - [ - 1 - ] - ] + "name": "zomlab" }, { - "name": "small_secure", - "delays": [ - [ - 1 - ] - ] + "name": "small_secure_red" }, { - "name": "medium_secure_red", - "delays": [ - [ - 1 - ] - ] + "name": "small_secure" }, { - "name": "medium_blank", - "delays": [ - [ - 1 - ] - ] + "name": "medium_secure_red" }, { - "name": "medium_magnetics", - "delays": [ - [ - 1 - ] - ] + "name": "medium_blank" }, { - "name": "medium_danger", - "delays": [ - [ - 1 - ] - ] + "name": "medium_magnetics" }, { - "name": "medium_explosives", - "delays": [ - [ - 1 - ] - ] + "name": "medium_danger" }, { - "name": "medium_cryogenics", - "delays": [ - [ - 1 - ] - ] + "name": "medium_explosives" }, { - "name": "medium_electrical", - "delays": [ - [ - 1 - ] - ] + "name": "medium_cryogenics" }, { - "name": "medium_biohazard", - "delays": [ - [ - 1 - ] - ] + "name": "medium_electrical" }, { - "name": "medium_radiation", - "delays": [ - [ - 1 - ] - ] + "name": "medium_biohazard" }, { - "name": "medium_flammable", - "delays": [ - [ - 1 - ] - ] + "name": "medium_radiation" }, { - "name": "medium_laser", - "delays": [ - [ - 1 - ] - ] + "name": "medium_flammable" }, { - "name": "medium_secure", - "delays": [ - [ - 1 - ] - ] + "name": "medium_laser" }, { - "name": "goldenplaque", - "delays": [ - [ - 1 - ] - ] + "name": "medium_secure" }, { - "name": "kiddieplaque", - "delays": [ - [ - 1 - ] - ] + "name": "goldenplaque" }, { - "name": "security", - "delays": [ - [ - 1 - ] - ] + "name": "kiddieplaque" }, { - "name": "nanotrasen_sign1", - "delays": [ - [ - 1 - ] - ] + "name": "security" }, { - "name": "nanotrasen_sign2", - "delays": [ - [ - 1 - ] - ] + "name": "data" }, { - "name": "nanotrasen_sign3", - "delays": [ - [ - 1 - ] - ] + "name": "cryo" }, { - "name": "nanotrasen_sign4", - "delays": [ - [ - 1 - ] - ] + "name": "nanotrasen_sign1" }, { - "name": "nanotrasen_sign5", - "delays": [ - [ - 1 - ] - ] + "name": "nanotrasen_sign2" }, { - "name": "atmominsky", - "delays": [ - [ - 1 - ] - ] - }, + "name": "nanotrasen_sign3" + }, { - "name": "one", - "delays": [ - [ - 1 - ] - ] - }, + "name": "nanotrasen_sign4" + }, { - "name": "two", - "delays": [ - [ - 1 - ] - ] - }, + "name": "nanotrasen_sign5" + }, { - "name": "three", - "delays": [ - [ - 1 - ] - ] - }, + "name": "one" + }, { - "name": "four", - "delays": [ - [ - 1 - ] - ] - }, + "name": "two" + }, { - "name": "five", - "delays": [ - [ - 1 - ] - ] - }, + "name": "three" + }, { - "name": "six", - "delays": [ - [ - 1 - ] - ] - }, + "name": "four" + }, { - "name": "seven", - "delays": [ - [ - 1 - ] - ] - }, + "name": "five" + }, { - "name": "eight", - "delays": [ - [ - 1 - ] - ] - }, + "name": "six" + }, + { + "name": "seven" + }, + { + "name": "eight" + }, { - "name": "nine", - "delays": [ - [ - 1 - ] - ] - }, + "name": "nine" + }, { - "name": "zero", - "delays": [ - [ - 1 - ] - ] - }, + "name": "zero" + }, { - "name": "survival", - "delays": [ - [ - 1 - ] - ] - }, + "name": "survival" + }, { - "name": "ntmining", - "delays": [ - [ - 1 - ] - ] + "name": "ntmining" } ] } diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/miner_dock.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/miner_dock.png deleted file mode 100644 index a9444f1ed6c073171a40752b1ecb271846153888..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 462 zcmV;<0WtoGP)V}V><;;-Mn<@Gjzz3EmP=}j)4pzQy;;Gn++X2 z2Kor;B=vF)_T42RL-T{dJ`3rybkZ5P=)dc#%V0d6Zx0FZ^8C~qqxI!@I^W)XzeDRP zC^(VA=62Kyant2Q>k4VH4gy$ChPZziwc2z7n9f*4O76|<5GilqYiCP99BW<4Wdeni z$~glz1k21!NU6L4mXjgUV!aa-`2F$_80Qk0bq9bX%VjOeaO*M77 zlkTt2S8pHA0OsHUAnh2%A5w~tvF%j?JAgS8LeC6mfZpH@y}{r0(1Xegz@B`^loP-q z$MI1B*qPaiyeE<@M^l&3x{@^?XsX0T08=PbcFr9uTu^JAX33yK%}tgusQp0`9&A~08l@Px$(Md!>R9J=WSG#S)Fc5tSGJ!vZffQ~M z76!6_21vtF1E}x@YO;hjNTC5-Y6WKi11^{}DFV2N!WEptK7~AyG$qSGfaC!NKX<%) zyd%#P@YiwWnw-n!{!$L#t7pq+i@;ni_mkNzMx)W-&b8L4cYhxi35x(ZUx+)Wfm9}~ zxmC3e>T&s2y;&r#`C{MBQ<-2@ts8^X=cGuFbhw<`ZxI**0|^#SE>sMA3C3bp%HZkT=$t1DszEK zO#lE=)K(t=vVTH#Cy>hIXdr0}5u^}J-!x8oCJ7?wA`v8D8sjjH1In7`&O->E0W#t; zCPm%+&Ve@qKeZnK)UgeNcFyzPivV!QTUYqf<-0{*0*3{s|4d@gyAWOK?wfEPLJB># zsZ3DjqNxRCF03)h`8vMdl~Qj6Ol2u*WQ9VRqdAP`n0Mqpgyi097&1r%`SlDPTA!@< zizq8pry9_!6cZ{nL77uQY8&Em-xvTMpI)rBtyl5=;sLYiIEGg*>^{Hny4^Id;#LH- z)|gGly^7E&WQBs(+M4@aA0{S=!Mz{BKh6H}4Q`PM!~8Hs82|tP07*qoM6N<$f^cZ% Ay#N3J delta 315 zcmV-B0mS~71l0nNBYy!LNkl%l|Kt z-@$PH%0;p)H`LK*hX<4HKsGSLIhx_*%PR~F43M@0 zj1Oba*t?V@2a}u&V3wJS>!9!rb@Ul#>|M%WsH0Dkc_cdkW--h%nB_2WQk!oiMZrPa zg$xY87#JdL-82w_won>foLUYr)X^t97Z~d3GcY{FuV%oT<)dH}003M@Xv62T2p#|c N002ovPDHLkV1jAjf$IPO diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/news.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/news.png index 575d943c769404a914cfa4e57e3bfdf5668647fe..40b73c7c2d272b8ba2a332c70cc83a9a1ebd7ec6 100644 GIT binary patch delta 448 zcmV;x0YCni7?>E4Be63>3V#8dNklMv7FCj%16(h)|>~RknOV zx@PAO@&)+=_O9g%vY{@OD#VD?EsQCORH+|8hxVu;J~+Tqhx9EzbKv)UJ{uo!>9}fg zE>@eu6w%B6QOkAHL~hUKxV@VWCO;hy08r>eXax}YbT%JM4gjO^gn!I45!c*DCT1=f zk6i-7&i4kBZ-bciwF*!Na2*Q(kfeFVR^d8U=}*$Ubpq@X)WH#wPbW?SQ3PDa!g^@~ zK-m)1e%)tGK$7O#nM=?nN+bZ#uRryH?_>?5tRxMiOe9(?Kpjjsa2RDJG1*21sM$>- zRGY}V=0WEOaFL*`+J7}yI&DLByQwW_OVBF^)IJvxX(U<&gi&VXIPNWA$QdAkI0r6Q zz|Qw7Ip8{00Dy!50Qvv` z0D$NK0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01FZT01FZU(%pXi0000RbVXQn zQ*UN;cVTj607GSLb9r+hQ*?D?X>TA@Z*OeDr{R1600AROL_t(og=75x|3AY(0>)7X z40;Fjf6ZD!kqe8`A{fbbK;Ntt|95jdWw>zp3R#vL=;|=I{*cD&2!amizP*!SWoRK; z4hUb}&rquBJ`5cYzPcZ)qtL}^8UolX!{$(`J7C9`yKwgW?VA`9J^kP`0|Ntt2ahuC z91y;`A8rvo0CNOY9T2{{A1-d7tAp18l^U+Je|LbPj1oNPVLooZv76z-;l(pa1{> diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/prison.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/prison.png index a6fe5ca1f399fc26dd62ecf9ea2c53721ed143e2..cea5bba81a9159ce005092b40175b474d274dcc3 100644 GIT binary patch delta 347 zcmV-h0i^!G0`&rrBYyw^b5ch_0Itp)=>Px$FG)l}R9J=Wmp^WUFcijru5y43nV36e z<^r69HA3b#-4aEN;T*jHbEmBF)PWngL$T!id6r8|OWS-BvY(9oeSG%g0sMEU&|n2N z713Vc5(QLXGhms3ya$XR;-&yc{+xi^;V6h$NE6(X7h02TH-DpvP2KRi+p!!3T;gf; z%2T2O`vUghT_>$a_YcE*w+?l*1O7IAwI9NdZ^0x2O52^a-!1^4Re98Xe{%~U&i=^+ zv?|BcP1H6_=D@E>L$MgGffea$!8`EAbupU11F0}u2ciU&wxhHih1S8?<$j^{S$wwu z_{?qpF#55}cU0GA+YPPC)4m5v+hOWPjHNlr1cV&82csRh9P?XKH&G734AM~iD((jX tu~jXER^{}<*gStsd=UxwK_Gts-~$z+rB9h_#QOjM002ovPDHLkV1oKQq@(}< delta 294 zcmV+>0onfb0>A>0BYy!0Nkl1p=5FCd*Log4KAK(WBL%@w85Zqa$NvTqe zu{)zmrNJ-A19A_UmpGLV1tQ(;Sx$=FG`F0Nnb8b~1Z4bo%t8lt?dfuhz}xHdsK)5S zU3c#16o$VR-3=(xV4y>m zmP3FXz-ezlc*+4Z2T^z}A1xY9Yd zU%vsc*l&@-xND{JCy?Xp%m%Q*eI1H*r?pTi5K#dBWQ+ZlL$PMD-vYSR`(w|ROhZfp z_-U8I@cGjU=zp%>!T=phViaw`p;$YQZ9v=lP)g?xDkcljZ-JkBn`XocFm7*1VSvB3 zxXg&vJb<#+G!-bGH=6a>g5miNKxcEB(fOk+C~J)r#_a(=xWDQ8)<|I{YeKXI{zSIm z^eyOH6jP9rD`6kT2eRJB27fU?2&k!6sQ4-jB$nbBkbjibpB%tKr0C=TsTu`nDnU~T zuH_W~*Ye8s*>S&}8Xr=0A=;?v_d3;oNcb25uD08Z*z5jhy8rwvfU?$X)ExjDb?0`v zz4qJC^J7Y?1Ks1;@x(7VmIY76A1^Lh7H27ZquT9%^W*+|{HeHYTb9LH()li=vevY1 pJ2>`l{veq65VNB{DfDahsz1DeBc7o7_;~;T002ovPDHLkV1oT06Pf@3 delta 557 zcmV+|0@D4!1jYoAB!3BTNLh0L01m_e01m_fl`9S#0005_Nkl*gou>@NKReu4T8+?~4%Zf=5zTLW%()Z*r(Xv`Dyl$W=6m%Ap= zK2WZ?yWI1;_q|*$Yte$Wya1#ps9iBwndw=c9<{xjbC{i253;@mB z*{=?5Zte1~5yBXOo&5vnpjQ{iGj*5OPuBhzZ~XFTY%>C^u5UPvhxg-YU9a29ui0h- zv5jX1u$jZC)BMb?8hIJVaWoo@@@qn&pDP-30nl73nKYufC@DZO8om&v05ab&fFVoH zUbe}U_&_)TWPjLu-8ipHvTM#-!ay*WP(JcX0SuBN1v&~?2ZZ|X(+En17l1a!Od-UC zYlC%&0Q>sL2>^P%0GVTgVaBqK;pZZ)1Rx=(p-KhKO;MVA5&nFC%|K8RMy9}JuE#3{ zNYh{I4SH4tV(v{dca2y1JU}ymBx?dua^vfE?JdV>oIV=+Zif;oyfa2_)e--ry@09^y vjw8AEhbD=Hu$|>Y75r&dc2k{N_*VP}eB5SSzumj100000NkvXXu0mjfm~R7- diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/reception.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/reception.png index b16670d5b5f6bfffcc8dcbd3b1cb2798b2a7557e..3f3e6dfa490179644e10f24b4c621c1101ba025a 100644 GIT binary patch delta 421 zcmV;W0b2f_82uNJBe63>3V#8CNkl$r0^dM;*X9J>k`5^p;jMvg@tA}_p$Bj$1=*IRCrc%i_M0Tcd*7$`BlLj3jtkS_ zcsega5xqV?YPqgV)XCJ`Ej=efI=riD?pO>2P1EC0O)jka(`J9aoJ=P;^q{8 zjVYiYP2$sIcU#ZggB)jO=6>S#swG` zrRW3`Aj#7t*51A+44bBmukh_4?hOU*Z+656HE8i8iwj~Py zfY~H+7C-?x1wVzew|}8A0@Zhacz1J31>?fHSM68py}JO_QMNf?Hi=5f`CW7~Vgqzgcg5 zeeRLHJk{od#v(lKw&-+wt)Ad27#DIjsG)H(3O$(QA8*>}=o;*!*+0Gk5&ytAhM@W` P00000NkvXXu0mjfk4VUn delta 454 zcmV;%0XhEt7oQlABMtxrXF*Lt006O%3;baPu^~kYe*hq3NK#Dz0D2|>0Dy!50Qvv` z0D$NK0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01FZT01FZU(%pXi0000RbVXQn zQ*UN;cVTj607GSLb9r+hQ*?D?X>TA@Z*OeDr{R1600ApWL_t(oh3(d{YQj(y#_@l) z4t;|=odN$IFqzH^2_Nt8wA_Hnbe{MZp9Eo)tGQ|DSYKBM5k~>f zZ?C)zA94X~&*kanRvo~JeE`NCs~*6yC2gtEKch^*o5`g^SLy>EmzX>Y? z6iG8CAOplR?6%s>mJ3Gx!EPS}VYFAP1Tg9km@OB;&($OLfobUK7LkY(`vhUM*H}zM wEcpaZNhyF@k5Yli)%`bx&hjd92GkDt27!L5&;k3efdBvi07*qoM6N<$f{HA-`v3p{ diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/restroom.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/restroom.png new file mode 100644 index 0000000000000000000000000000000000000000..f5903a7d155910ffd43d1ce8f8fa252070a4990d GIT binary patch literal 515 zcmV+e0{s1nP)Px$y-7qtR9J=WSG`WdFcALu-6~ar6t+|>l`=+Er7kF2pCGK=`v!S}zCm_Y`UGqh z3lfSlMq+Em5>-NC13?(jA?Iu-P7?$OzQs;^x$nDkd}jlH9Xn-zjwjQ+Eu!1&OC{HS z8M!?e;pn8_n0&Kd0YI)2p%g&m{lTa)IRJFJJ(@})c6BcupPm^xcOA>fPUlZ6VDI2i zBAU;J5~1(eMt0m^r2q~h;)L7U)fVtoFcz>_riHPo9YMPdMa*Zz&$;i}@I4zr7!`=w%uagu3$S7u;78%ohEmg%P`axRJ@1YuP9Ef_5UkDx4~x+oPu(eo|kI#wYI zO;Gv`P)a!wrMrzxXfyEo@(e&<>F9SF#r0Rs$sdO{19|=i;A6exB!lZ%g^}QUwoxX? zA4ltzur7X2CDg&R;_09~rHm)j+&#Y#`*>qKJw715xspyswMsFSRk7>_VI)0^+m=^H z4kH1g<2cErvdf>zwu&66@eS~vAVx`5(e!k*l>pvY#OUHAGip347%zbcu@8uAzRiyK zxw~MqUZKPx$dPzh$^&Gl5<)DHNC>tvzy&9bqxc*mB=|SiN&oN8=d%O+ zb)EH1%GLHbhROc<&gf&DkgM&{yY#T|7Eb0>S)qI@jS!tbl7IQ_&6Sfm>Hgu#2yt$D z$u@E!1(H0p{x2hdt$DE9Ad3s@cbx%rbG28~0+2ZXmN@`iaLwE6Eu@$}1G<9U211Hy z04Vw_E)e-?1LDU4l02+UDdn8%X9JMA9yzxF0cH`J8qQ<@dh|eZJKBm>ghC2d#dnF7 z0g5)jY1Fp;z<(+OeFsh(Zgc>bb?(#PB~W_><@2|j6M&v}{nShH@MPTeoHGFMz4ekj zgz{D05ov6CZZrUjjtsK6XtZUn1{Y!Er**`@XSLJVr8Bbc17zM_YyG4gBIB)ieZ9tV zKI8H=^z!jMP1wLS_2 RHyr=~002ovPDHLkV1h%G%<=#L delta 364 zcmV-y0h9i~1BL^TBYy!+Nkl%m0h4 z|ITpv!X>gS*EP^%coWEp*AXm)47q&a5`*u?M6w*P*?&HRWS}`-HB4lgj0ODJ@RDJ( z|9q155exxh0L)^~L@$!{QXB%vzGev!r>_H$E!Q>BBg+i39e?nk{w#{+moHpG5u>>S z6dH{gbPe;PD)xY>U`hJ~;wAq9|~29V?Z@`X!ervb7Yu-Sh;JSvbardv@=ZskO_1IY0iRUJS{ zbxaippc@J+^<_L0y%?UHe*#Yjo{3&0mkVSiLRiteef~DMm}jCF3ZJG9@J#fAhXAr; z$Y~FdT@d*OpwbEqq!&U&IY8GykL+BaYoN#QhJcy@ZPx$n@L1LR9J=WSG`WdKnymBp{P>RE(jr& zy$=v&$==6k=5BeCZke0MV9yfe0kTsGAr{C<2)43dbh-NHF6n>--x9^XoIm?MTNi-8 zjtj||F4o6$1*%>j$XG0abg@20*AdL3+34V=Gthl>BngrL27kZ5yXo1BCIbL~ZMc1l-J#kh?Ku zN3o6~KoPQ^ntxqGFo7~}dr!@-A-E0eswTz7+0RY@;kKo3+qqDWpv+sc3pfqfD4I+? z614(YT9<^+Oz>IbeFR)3r1d`VCNNZF8bl2gP1YMO?y&LoOO;baXiqboinib+KWaeI zf=WPBvX9aw1XW;&e>4Fb*a>#V_B-X*z}||Nw@a8$CqW_nM7+I!!r}RFaw}%r&~ygo y)5+kwfQ@au2h$nS_d9<~Y!aiRe}nrq`^OjHz2*-*l-6Vb0000b>!47?Owx_2p%p&yW-qC?+c1A&{dqo+Ke z56BDhfJ_=Q7J-4}6+sO90~s=A@0bn+1KCk+Qa0M5zQvSCkSCI&3=H`17_}KJmaB7@ z0PnN6#u$yt#d3AN|M*0i7eT?5(Kt=-8cE!?IVtl3lXV(IAb(3N9;PpiHa8N7hxrbN z`7T)RLu&?HP$?eq9Hj3|fJ%`i_Npwtz1|79M6$#}84aLYpNI%#iLI>N+u`aYWJFB} z;Bsn`>uV|48K4uo>88EeS$^6ciLYi(B(Pqg#bBouNle8XpEo6*xF4+&m}E>j(q{k zyg-!3*xC&MAWCDlPtjWtr7_C9z;S=95CU)^L^2ob3{XlZuisyH(EKF#LclkAxll&q h)ME4JzvTl4d;wiAot?M?=JWsn002ovPDHLkV1n3Bv3LLg diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/salvage.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/salvage.png index 8c51238f897b6fad6fbeac1dd4f134034ccb4b0d..20b0eb577de574a673c40d2fcce02a7d6b63f42d 100644 GIT binary patch delta 413 zcmV;O0b>5881)yBBe63>3V#84Nkl5dr6opT#&aF^|GFD>9&?O7c07G^L z&%6bU@D|Jr>>bQAuypB=0jXmZA*+3XbZCwEGhAY%1hr>D=3<}EzW5LL>$({W?sqsX zW%Tko?4<addKq;w$}z*6rgF; z?XA>Y^RoaX1kY)k&3}~EF$-MBLXf2Ou*UY!=&y+|hki8vST;w;g&+7D0AeE&d{zG%0)}eH@P{ z-$n0KtQ>(#2y9GqkzB_^d(dO$crGU#YHU|M~{{5E7^wputLr00000NkvXX Hu0mjfi>ADk delta 460 zcmV;-0W<#f7o`}GBMtxrXF*Lt006O%3;baPu^~kYe*hq3NK#Dz0D2|>0Dy!50Qvv` z0D$NK0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01FZT01FZU(%pXi0000RbVXQn zQ*UN;cVTj607GSLb9r+hQ*?D?X>TA@Z*OeDr{R1600A*cL_t(og=75x|3AY(0>)7X z40;Fjf6ZD!kqe8`A{fbbK;Ntt|3%&}WVn3!0$G;p>KZV-5sb&{2!alHeyEVaH*Y6d z4%j@&ok7yBpSlisu)mx^!LbvodUQFeJK(|oa=0A2Be2QQ!~rtOh73>cp2z9{bUCUz z0NID=7U7bknFC+|mOFHH4KU<}rvs4V9hr|ye~#*jaPuU0xEy-ffK8674nVd5n?=~< zs2&1;9<5+tk&A%S$N-z%@G1w8EgG<*m{dSD2T%frM+hK0VDlt*2G4**h9`H=Gsq|# zGHl;4pMik^QW{>qd;vo(O%frj2=)v}WME)mV0d!(Jj3P77Z^MP5>c`z%|Za#$1ob^ zG8mdWfD}L#2MlPV6y^xBY=;7hn&tEWqYfBw2LJ#JV8_sFOmsW|0000Px$^hrcPR9J=Wm$6QRP!xuLjf2LdwTm$( zy7K^(#IW}&x@O=G6VeQzOKo z=?^xUd%lM>58?S@y04s2;d+{90b^oSMC6SMZ83shdLA9TxLm0V^)q;GO4o% zRHk%^xqf&Aglo7%xlHaYcJQE9nU2h+yhPK^>eZZXc)P3D~Qf1kVfoy zxiQsa<<`tyvQ5_efIQ}I=lLE~rnKR$x4`sfs;7nVgMR?zy4Jzii0pytqcXnVp_KyLi zdARZDWktC5^b;z6n(8&x>u?yWyl2*8D;1hK#Eevj-Gme z9suP49Dpe!BSewl6eyN`0R}Hf>|K!PfSejg6Fa8rP~Mb$JO4fZ|NVb}8~!`)+BQt4 zvx5u4$NO6&N8{pTIy*ehKOq?JL>`b3yU|0Vh+dl$!8qcac7GC3BpIGZFO7TdJ9*X! ziX?M!(Otl1yhfZ;#5r{m(V7AsMUo*P;YC`Mh`O~l7)PK;GQ>HBpGE+V5zyBFz)vIV zh!_jd9S0?5lE_9_C-#i)pMofS?3T#2m&xDFg=0WRbCDgtz8YTy9J#v@A!ukS&Y5`u9I z=n$)HX)M}UKtMtOs7PcftFEYbLS-|BaU&9pLoj|qs5$J4P?oZ?nZl|ODX6=y-}yS* qRRpLh*98Fyv1{4$=fCAQ-0%gzXUoBQj%_gj0000Zq}6n(9_R;pCdj%16(h)|?%Y&`*UcW#gqaD(ifbAoQ!DpiOPsaqH$lryADANl#Q zjR{B@+P@HE$M5;Q?{5tJ^|-Nhyu7|0rULo=c(>x**}%j30*}wL(ct^t761-55@!Sm zKASI`6UR}2EDf>VG^py)va~>#RMb}02Fy*mAuH4j*xuUN5E;pded|hb8-Suc0Oev z!PlF{3EoSfs@pRXBt{U~*5G}s2YM_Z2@OVTbRX^U1@|IA5)w=*uw0cVq=tqU0h!$d ztLnA`WI>WDO{RdY;>q{y(_7Jpgfj^_ne-btdMy=TP?;2AN9Z<><)PKk+X6~H=Hp`&0a;+KLV$&aNk>KKy?*+JcMfQ8^`5`v zB(xIP@3!)Ddhn_=q2IfKF^rdmsV^qY_m}l{boHy*fBXO-!#dn{TP!620000U`J9^uJqlANQZhZph?s)^BAaCH_*(d1cRw&{qbUVjG?isF2bL3(o z$uFrL+TWr<^!xe!OZ)+U-L7m8o}OP$u|(eAUadMeHt}@3!~NqXSp0a{1Hj1!F$0j| zo9!-G8~|?b9^|bN;@b2Q#q&H%AUHEVTl$_6fFfQNDVlclem59E74L^>T>vQ#fFurB zy1>QseCJuRegsr2ixhd5tOFpuZ`u)6-CaQZIDp{nEGk1zseUqm6jwc`79c<@LfeM3 z8i49OaM_N&Mk>NQOGp)OGExMjw(d^&80BqZoi6iB8 Qod5s;07*qoM6N<$f)X>lga7~l diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/security.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/security.png index 7e27efa2b3220c9bd937bff71fa8694b5ad11231..2de5d34a5ee47c2512be0faa7c0baf09f092c63c 100644 GIT binary patch delta 400 zcmV;B0dM}<1F8d%B!2;OQb$4nuFf3k0004GNklQt%s z0(%Zxgvf2SV-=;$o+B5aPL+DA6nlf&%4isknejk=q~tZ2;paWuV;kVFqguMyf!m7c zS>aLzbl_^>ZUgcQa8^V_1qk`W2IPVdMZ}Hvz>?>U8`<~$WPbzf`+l-5?^6ZDASCCf z7wVy%?8c4MLp#|bE(dA~9)bH{T?kXChn7>do2`8U?-){$i+X5RJ#P{qp-&0QiBge( zx8rd}Bw~C!yf1~-dm!fVx9tHTU$YNP5rA|h#Jqd4n5{gm~6H!8L7SOnH z>U6#cA(u|M)PIt*(1AOEdj;p*I6GQxIUc~p#(OdX(%&V#e*Xs+*K=C8xe7}0WwT%{ zipFvH4WOOp;MO7_EVa~m4$RXq{NPwya^`6mHldQ{N|8K6%pdZ@IGMZb%lBNXYbyWZuVA4#Fn1Se74dED|dDl3|2EeGS zS&-&{@#X^841Z_{sff87pa~*s?gEe*PeRa~nUau202t9a=VPhqemM))eIWq7tT<}+ zwe>f}iVFZEm5GIhI@wtLxv#T2!+ zkal;qhP p6A95&%X{VCnr*tNq_)00{soO!Dbl$zmudh2002ovPDHLkV1l4Z*4qF8 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/shield.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/shield.png deleted file mode 100644 index bb88d2a770e7e6da59be40ee3d317eea2cd814d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 402 zcmV;D0d4+?P)L*939?4&&cGh2Yn~udBHqB+yfKA|F)I_|3DTu@ zZB)VeLKRizU%+7b|L!=S0Y?3IP5LJ6_J`X&2Jf4%|*j zI$uCQnR@{4xX6ANpe~g$wxRSpU;V8j)cPq>PW0XYadPP_GEUE6e*!yVZuBewI}3HG zj5)VsdhY@Q(P}u{cFh8~$FQx3Z$nZBeEa+00Niv_z{xd`w+@`udWq99g9rmm=L>VM zcL)`l46s@+QJ2aXIEF>$fYqf!LtK|!gr{Q$Sybi-wxiWq0N_AUM9zRtX#*gB{l4mF w4S+aFoaci8*gqh?5@CRI&zy(Px$$w@>(R9J=WSG{V3P!v8bT?2t)I+`uu zC=$q0-0}o=%`SZbU!cB$d)K%Zx`i%mAB9|3Dsp$VhU=TYN0VG+` z*|YfqZ+jvxWs6MVxygFc6d-)h>HSw$jdBip?|Y8+S!o350{lfqi3Fx`U?fy4Kt@1; zBuEMXO#Vj;7y{pOAdLg9_(1}wrxZz6bYoHIGQXn)@OjJ+HAJB+^e#Wtkj4Szhq|+M z(Cz{NvDZ=PGJoQH&tW__tpg(gbTK5N-thu45~BIm0{Fd*_Fpv{H0T7Dby zHa<`7`-dlc0iw!AA!XHc}a$QX|G3H1#jKBQb1WXkYok(R!g#iDNLP* zx^ZO+XwFSQ-vLQhFt)4)gx~6$?XLB2@95X;XncKsK>4!ooe!iDIG>I%n=iCEG(nOT scsA%kdNP{&U{b%o2~S7Ael+{XH`1sDU^f#ERsaA107*qoM6N<$f-foOL;wH) delta 490 zcmV z(7b_rSKSNUq)VYl#y~eSS`i9;06U#X0rh zw>?i80zw#gwg0mG&`3tshk<9@3urvR50D=&N+mE&A}gUr0XhN>A|X-$mH4+7a1O%2 zLz+ZJ@n;F(mU1kX+wxjG^()`41jsn9HwEIUue5HxDUc=+)|;YS+n})u0JYWe)USvO z1FvGaOCA^n@PEUIh+8KGk|$L6I}4DtOypFKWGxp)!F@A%tnYkYlvAbVLU=L4k&j{6;Y{edxlHdrjTG#ec0R`v<(YjkkE&u=k07*qoM6N<$f;{@<;s5{u diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/surgery.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/surgery.png index 254ada76fd4d76c38965d88101b216d133fa576c..f24ba5c1b331d0d183373f349b8d7a87eb245fa7 100644 GIT binary patch delta 405 zcmV;G0c!rN1Fi#*BYyw^b5ch_0Itp)=>Px$Xh}ptR9J=W*D-E`Fcb#hzg12^$bi%# zOY0$0FTfQ%asYO?RAz^MxWf)Ol$(sAoN1i=Dq)FT_g0*rxR11ushbr7N#kjeD4)cQW#l`#b2 zeH`Dd?vX6!gnv2EvU}g-dHY0v9A7FVKqk}Hp1^gi3embG)IG$E0+6Eq_9yEmFEy$H z*eKffZAcxk51w=P{i+Z_%aH`I%dC0p?WS+s7t$rLGx?mMK6d2myqmu9W`2AbdOKi@ zL9&>Svgyc64P%UR?03GHG!g9T$M{~&{__Fi&cFzhmkx(J00000NkvXXu0mjfofEqF delta 403 zcmV;E0c`%R1FQp(BYy#NNkl8b{6#iO@TZc{^`v(Hz)G0U|l=}iHzYeXw9+)8m z9&xSSHzpud&~VmMgf5IqkUIsEGLxzI%Me%r!Rblcmr(|~5>(k{C*ap1qBcguS+DjU zaiuK%I{ZBXLVy2a6zJM?6`@@MkGSyb@J9xQwyDr=!jHQ*fR5W{C7@f^*$LQO$77h> z1404aQC!2~xjRmURuewn6DhgZ)iaVZlWR$t!6RPx$X-PyuR9J=WmoZMmFcgM=5GSAmQW)R> zc&SV|OQswmYe&`|!c)!yL|x1QU}&TaP~ z2G=DHxs0A0x0e@SUE*+e3)~dx=6wfz?%WVg05X4iNH-_FynnkPE`13(cFtMP3-DXI zicJtzJ2^)yIS+uSTGry+c~Jo7qM<5iC83pML$CmB^U%UH&V`r+C`9cvcU8eQ)=Huf zH9EaH9e|R3Af{Z#A#)bM6bLESI2s@XLUD{S>EuR4MpT7Z<75ESoYS0U0iYv@>3mrM zQq8jfr0To@3V%^URPE0tqqqnn*Hk=M$F60s}I)$!~g&Q07*qoM6N<$g7eq8 A%K!iX delta 441 zcmV;q0Y?6>1JVPKBYy#zNklZrE5S&C&UXaqYB^O9*`3;uL2S5}QRCz!O z7YKjAk@AL!l_(-nQ|1L}oFd*6U*VnE@df6*7derI`Q))x#6#C5%sJB7?|&u04Y!z2X00*zy>7lD zIy2D3>-#4*yZzaBfn#Gadm2uFkpET^H{1d+6QM1jN`5X2fny_$ePa>Y0-EH_EC{iP zSj_YqSGx&`EC4`Ol#1L9w?|?ijeTTAS&P+yb_S;7QEiP9RzjkLvGnL9=Bfgurm`+Q zLX>dLCz>%jFn{uaDB;>ObAFQUW=t21K11dl@JQ92$O3Z?_h{8=?5mhT1W1PyS(uJT z*zERdpA{wCaBFPa#!e_AWI!?JYTsvO7z^l2bddn5`4G?&aLG8nih$~6()rCslrz(Q z(Ds4Au>t%vUEtV?NJ!<3$Qs6q1w@vbgjrE4(rP9EXfk_&krk^6SG`>J%~cbf0*I{M jUx7|3{`|N6h8w;C$9BhYDO7v+00000NkvXXu0mjf@*2&$ diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/toxins.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/toxins.png index 6c28bfde0033b911a4a60d8c897cef911abd6c47..cf11ed6155f27279e02623f7c3f3879089a18a8e 100644 GIT binary patch delta 516 zcmV+f0{i`_1DynrBYyw^b5ch_0Itp)=>Px$*GWV{R9J=WS20V&Kp1_BL#5C*i-=H% z4nluG$dbK3pp#QGXS-k0Epsw;>JM;kD1`igK!*+%L|keDqFWvGi1!$#Ar(O6*H;&f z$qDxlPf`)5ssUvyw`>bu>=fF(*nwqR$}y_>lmg1gXY(;!(=W8UrjOZtTq>d!0Wxw? z#J36npj>6$)dRrUF#=}uF~ES)bf33vmqzW?*A~DBPqc#X^I}J7lL##f_|yk1!75xA zNa?u>*9cgWw}0taQYnB^AFu?j=_3jw0LWKJc zA4BD3l%*L4-A<$JCAg-KEX|~Szw^a}7txsg6RKCUf4l>P;QUXv+9CJ=0000wB+v&H(a6d^1v0Lw&*9gFk>c|_k|hwfd3bH0!*nG(ca>;OQ0~m7Cg)G9UW6YobmX8|s0TS=0(+1jEN&o-=00>D%PDHLkV1k_dv}6DP diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/toxins2.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/toxins2.png deleted file mode 100644 index c2c35212d0b5bce15bd13d83f7fac3f65358fb13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 433 zcmV;i0Z#sjP)9C7{yTsj_60h4%-%7b zK4T(^|A5+|yah0p-w*rQAHbylt}9!I-TrVMV({|()a%jva<@O6Z{NQlxd<|k(*&pO zO)tdEHi+Z`>th}SP-G1E+sEEMR)DTS`{WDj4Dk8-0m%j8G(oh8006310ML3aGKM%! zFn@b+8u!{2fN~HmBB)wvb23)7(jY#WaR%s`TFFJHna?tKWng{GTNxlDY6}UhcL=)- zLU#$^u>?QKoDtg&84ZApDDm_hG7~`nmsuDh?+gIVmjlfiP-N`)W`IQILlnFOk_&wp z4XGDFOF$6%eiOb8odCuPTrj|pay$ya6)T;gokO_HSNck( zBvmU7V^+yg0ZcOhs94!*H_Nq;oR?s>xzlN%qxspOd$Y}FS6Bhev))&6n&4#V^XI?i blO}xwSDT$DhFH7M00000NkvXXu0mjfS!KEb diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/vault.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/vault.png new file mode 100644 index 0000000000000000000000000000000000000000..33572ca25b572fe3f99f904a89906766308ad606 GIT binary patch literal 458 zcmV;*0X6=KP)Px$gh@m}R9J=WmqAX0Koo|5jcE*xgmj}TU9j)~-S!6M2!vfZ14rl?%8v91cmuW` zzy%9k*$p8j65^(Adf9N@Yi+LHfSu@r?HI6#|NpG62Mrl zPsZXJmsggyc~#^nvx5{u3P9%O&23{W@Lgl% zh*xHZ#=P^+NCV9|^Vk4WnFB3LP#3Ma_*iA?W6lQP2Ic^YV%NY_8U#R@4#`*>AdMV^ ziG{#-5hj*4L~j791uD$GMW+ow8Hb7W?Z0Z?=m54CW3$S!-R+gVftG0!0D`DrW#-%6 zo)wGT2e^;4ZqBKX(HjvrbJFim^$o1?6`?Zv1HdEx%d50g5Cw)>}4pJxC10LxCfy$yt^^8f$<07*qoM6N<$f|7RA A(f|Me literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/virology.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/virology.png index b83297d037c3c92d58d919e5fd167280daea92c2..232d9a74b553fcb8edbb9d42a46a2940b721df4e 100644 GIT binary patch delta 494 zcmVPx$!AV3xR9J=WSG#S)Fc7^2nLw5c0V&)h zDhy-+t-w+PsPG1!LmQ;<04lkH7YN{jNs}Ugi#S}tDU>tG(@{FfDgq=A5cHwQ_wFkS z;IHGRZ*ZkH=eda9^)t&A6|hp9bDG^lk|bA?TWjHT{9r|}0)LQvoj+VnjyRY%R>W;= zg2eJt6|mdpP^x0^-Pn3j0TdjO%1^+$V66}C;)*ZXknxGfe`AAA&5iZlTh+f6;P_8;~5DCJy5FR5>q7ftsXOP zk^n!`Rqm|AihpQxBP3|O;N~?tzW!hc(B0akz465`0JM4H&+EgW2Qd3-Ru6?CHgB{5 z3R(q@Y(J?AMhkF#z&*p<2>Zay0x+v-_oIZqha}Y^?gLzV#hRzJ&$aCs#2(<c3@)c4_LB1WwJ6LA$|dYl(88R z{SFW#jFF1?g)R(HCZ;Hoe}IvRy$c=StSF5VpNZ6=yd}mt-MxFhJOe!N-|^HIu-NP_ z_Z0YeA2-%$e7V@{E}w5-$W7r@TnUNkanwlSr7cNr3Zy#mB7YEO5vH%B#+YZX%(vv# zb$QPfYywn72?+q0otH>;VxL^J9zhjUEH?#0+&V{Oi-%dnBI2w-S>D_fRskg>l#mFs z$V&xh0@Qh!MNmQ_HwEIs1i2{?^o8A{n9d0Rz^XU5Yb7Ms`>j=?9K%t8Jp+WGFA(&_ zuYH;iR}#(yNPqe^ta@`myJlq&upR08@0|vd`xST{0S#PrkJ~-qX+*2u97;%}Izg%v zTYPq2a?|k%ki4V-5dyB~&$VOkyMTyP&zoyRPBY+h$#hEKp6j?10+cKsOsxCS4A8o4 z&+GlRdm{pX!^zlnJec5cGPT7ya3)aKebo!Px$dr3q=R9J=Wm%mQKFc8K+5JOR=rd<$1DtjIv^5VUZk<8ipB-t{jkHMZL$^&$# z5<)CsO9-~IaFLbTjsFcG_!jGA$M?I-ot*%GT^Hvj`D$~F<*0pq(E2h0@YUv+Tqjs0 zi(uzcNQe)ih0p?!^ZUD-$;}yO=-O^_-Q&}X7UI(MfKB9#GvrkY#@Xar(|$$(8|77s zGHZ}msrMe<0OP1_vJe%3q6ZL^1upv^s-KfYY6Jwho$M!i{)qw8aS8erH)Q!Oa z08ZXNwOy#J0b<>L-T*G5Y}s^;@vC@!yT)=piw5=f{)xl$;pD5>*acEZEax+)-Z!bt r8b~3vb3gOPM1=_U{w>q5*}uL31);w6U&E9Z00000NkvXXu0mjf{$tIP literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/xenobio.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/xenobio.png index 0d9336c01a19f7967bb4e2b70feb77d2b778b4ee..4f99ab19c3da09dae0f756c6b902996445ea472b 100644 GIT binary patch delta 465 zcmV;?0WSXG1nL8jBYyw^b5ch_0Itp)=>Px$q)9|UR9J=Wmp@CxKp4g!#i3GYn?*#Z zLk6KAAOuP}_XA{dO6P3(B-uKrQzt)wb4#K00~9(qSP*fE7m&KuK`&gcm-1dNsGtvo zgnKXd{O)}(e-8NTIyn~ftl_>cqj`F-^eP4Ltl_?W-bSn4GJiJDSO&IZN(dzYH^08R zFgE9Ue0otroR!@m&ippM!NBWlo6hD7OruRc9^0{lKBWMn23{YNXsrzp#C=S$Iojux zGSF zC4%Uv5&$>XHGiuOKn5{^sayj2S}qAyr1yZR&-Z~&sxCjImC#BK_Je?5%H?cZ@fl?XV zD?ea=K+qT1{X!}mcB>Ry#o1;dHtH-$XO)Qv1QJMjx4PQ#Xht)N6Sl~n#*8$+=iJw5 zF7Vm0V|vl)4d}f{e*gSt56Bq0XeT~o6Y7K;>gEnvP2ko7)_RlBOghc7i$}gDUgjZ;>h3l zL|28K#o1cZD4^YH79wO(u7^#M=0#+xU`#<6cqI?3E~V@-r;PX7TC;RZ?eqrJK0U+U z{z2s*>q6l9=>f^FsdhflM&R*&jlKN??Uk%9Mw2Da23lx`h4&szvb$U3bo9?hv;X)5 XTzo~p=G`P)jOX>HZ z5DkELdeo4*AcI}xP!>ZQt`|3SpxiYA`z71mg5StQLlU! zIgoKL@CiJGH<-!%0L+OzUGNdkNJA9?iOP16QVO6ooxkY;G*HTO_jpqg53m zxTv&|zF6&qW#XW8!LVPC%us&v@j){tmr+~pLKz}^W_K|5jJtb&n$3;Rk9RDdAEoyL zsRj1iHLfbP%%>X}EXSq0ffUkHL(vzL&D*Q;cJ%94vwwU6G}j0Z3SOnJ00000NkvXX Hu0mjff|UYh diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/xenolab.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/xenolab.png deleted file mode 100644 index 21eb486835b9418e35103b15dcfbe06efc4a22b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmV;J0cZY+P)9C6vn?+S-N+rlpz-YQDx{EKtd#AM^8OK4}f}r93T^8#tI=Nr>KJP1v)Th@0bpe zE$0u$@5OD0@+~&c#@`S7*#;Q&-*wa1VX<88uQ7OidA5338yCyf{{H<7vTj)BK@?&) zzq3M&`Ua78gR~SZfGR8SFn_Z4=>@P2Zi)+e>%+V&_9Fl`BMt;>27HPHP-O*zC`1s2 zXKgA@odt3dPTr=6N)Ej}gDBK-nbEc^dkHkiNu4SZKw1iX<{zEyRaTI= zi$#J>vDP~w775yI3t2a3G1tS%ISEbk@#7c(w0SHN4WVMLat7EGYi-nSTL91?=B!ZV zyaXx_(%GS$V0!dy##HGAfOEx~@9ui~{P}PBph4gKfS9#W%prRK0000EX>4Tx04R~OkOy}Ge_^C9a{vGV^GQTO zR9J=Wm%nO*P!z_$mJTTa6PHp7>EMaN?85#^PeHtoFXDv&RmP4P zrm@9p2*(W5wla`L09IhYF+*tc2!IN09$~6au=X|p)D+4J3~7kly5?M4SIs;DK$}OI zY_tNvC)4H;wyt{00#2*Xw&hFG2!K|;_BL3ohM4LT0NK?Oe++Qk4;-p70BP$UYkb}V zNS_?aF~bx}CJWM=kf)x~d^A755foc{n~Tg`4X_;97aNdjOkjYTi2>*GO!bBU9D>Bn z`KA+Psp@rq=lk<<)bDD5<;c#Ym1<0@hEuH!K zziUyfHh|3K!uNbQW(eQ&Gx1h4z^`JWmF3N8TvY}NZ^eVh0s7sJ44;%fzrL}1-^t&K zlQ==Y+mXInm1#M$k;I9x?RS2daEQk4Cl!5~{p$x)6WuE0;-PVY00000NkvXXu0mjf D?Hmoa literal 6115 zcmeHKdpwi<`=3ZPDix(tW)jN zaR{BHM}9MEcX4A z#Nbp?v+SYW)<b4OFPZKlZrny5KNk?SXT0aGt3w8>(Nw>_ zXSVo2@Tn2m#_Pvq!UFi45XtZKD<#=sjS25IDK7ZX;@aaXvAyX$U)@D)@ksAO#+7~} z--LGEso~-1b6ZVD>rKxM9A91Aqjp2LYv}LnHiF1B=0SsC9N&{)v2!tU)2a@t-`Ue^ zt{n%ZQIH*ML&f80LL;q2_qfwlJ@?!Om{uddVz9$oEzm4R(^c-7V#H?dIQyEb}j z@$r*^%Q8tTS*rZ;ootIs9XCr)tHsvjn@jX%EwSj0JD4VCN43h{Z`2-`jb{`NG%z|t z&6maREbtB76@-A@GToUmO+&t0o$d@PX%arPP?;OO=ox0uEP)&$#o2hea0^vSLvh_M z%^aC|gDvnd+_HF;#CY=+i%mR|wRSitXRYyBKdf4KN!8fb&EVRKyi~hCsJT^ZTr?b0 z9o^THvYc}=@mg0-kRIhZCA24IDNOre4)0r^6qP zqE3l=Svuk`Q7^bL*V;~ve50kvnZ`MN5V*F>Jt#LOTR%kS1iFVvd!rLlx%+gA*mizV z*?z71BTKN?VX8F)34gDUL*SRQ?Elf&tr2u!RgRL16~;~R%;$L#g?rK;5JubaHRbL{@7R)yO# z9!?<<$z`vbV8K|c6IB=bFWTB_kJYrBu^9W(P4$X;t~wZ6)?Jr$U3)*CBP4WCn&k?R z!s~82;-q>e#L)UYfg|kB!`1ck_kg2Bmmw1*@KV`@r{0X$aTBy^{vGXP7$YxmuFW z>z7itJ)`*~9(Qo=%UG_rp8DwOnL~kTO@GDx^|*fBoj%6wiE7&8uFV#Gv_pR=*~G=f za9-3}7sJiz>r~EqR^)AVebCb@aQb+8JjAKUEtB@0UrR&(wdkfbLh`Z=o z-jLQhvW35Fb?or5l>1SyVZle2pQ`4Y&9}kHnch_@tR*YQzZuMnP?!kwdoBAs8#CU% zGO(ws>bC9<&1Kx?T#S{aO38>M&~LMm&S6ResWaJyw3%h|q3whAu6s@HqjJ`E2ixe_ zSEo;9-|I>q8k#kTzJe6NV!Yy0YtI9^Y(JU=h$uFCbwR!8?hw$5p^Xt0|}i8GX9o@r0e|Izab0#&)MuSo)bAYIZdglL5U0-Ri)(l@ zK^$!;!Ew2LaiwEz$e{-L@pCV0G7^qd61y|pGMAQEU$*$9phq-qQC-?>8RfSl(fdqi z3;BG9kNyhByyu?ThpW^>)nFqsYp{-y<@vDf59+|FRJ6!cvOk8tkILGPx)SD8+Ze%ZSG6u7U2=4cl!P9)CSjTWSAWH z4_$O8X>)_K<=L_v&Vuezlj;-Vxmxz|@GT`6?ZCrS&vJ7It3w~3Y;WL;vZhzT4~GMH zV-F9eZ5v&GF~rDV-Fesr`Gxz?Y6jFcg$KYM-978_Nt(GGiHeO+L!REhl4<2`R;E(G zX>XG0dUhcdemBohv|;e*yEO|{;@dtCbd!V{qet{(G=yK)Q6y7?| z7BbLuhP^pky;Wy%yZ`onSlTjEaZ=EqVcm-^&dL+TcWlh{(K#5|;@ApT2p=xmDBKEM zI46Vt*iUH6UA}2T-}Ei4^53L^*HL}e`rH2QZD`*Yb>v@)PS>Yat0gaYO|FF7k&bLX z{?ZEulaa8kt!a+d)?eSN(AzXGE|cPLk*2)O^=62z{(>l_h!)zP20K#8>s59J9Bp%Z(+F5{9jCDXs9=}g0D>E36C*Ur>WPM`4C;^LZg z7I)zKPwnVQIYvPJ`Nk~bK-QXV@AIN>6(}q==lex{NE37c2|S zoX11QhdT;G_Mw@6o+jJ~&(=S>>vgsQYfqw%)wqPtjW9qatg&e+q055aJ8qO`(vh|! z*oB`8hFteJY4^yhk{)kJfM0!`^y&QA-P~;{5ky^OS+alFBtv!X=&ZC{&Q|r_s3Eym z=CWSCtpTO7Mu&=fe0_)KKIxS=EZ>-0KWEb@OxCrQ>5x8rOiLNwG`T#^eZiB)*|lE% zHO3tgA7RX3PbXs2c@2zP@eAV&k*KQU<%9gkQ(IuJY5W}KiLx?i2c*h|b~@fvXEKA! zF$9=gI%pWp;Xykg7|hf>ng=jKK_P+;2C>5_$g#RcB!bPPAia#K7%I;i3}!os`JlVl z#e*RZWssOib2GSUG#LWmfI`n_9vJ2j#Sz=3n>LbYz}Y63L^U_O(C20ovfc?la9=!^J5^8`8V93 zw7=#)qYPUcgGr1zc_aP59 z2Xq$#Qa-T+JPC)z7!!ylL>v)E_^#v$@&!;YN>Q;GL!-~g(!!9TbRcR0X{SN}GZs)b zWNSVM2)TR@E;o#Vlm>;6TFx{$!t`@l9M}R#BSzZuU%K8MjQITYc@l)NXNC}nnZ_jp zjL%L4KorQFaRk|Y9%2Lo;XxoY!@soDS2_E?l#7W0j7i3LI*I{8b;jfAP{m0`SQOoa z#lnF`MgRcC`IBP-mn9Sde9$ro$`r~5YN45I5Np4Xsr$3OC>WG7g@NWb29LrRd*E=hvHHT7l*0ev=L;SGLk|%2 zZzsRR?{B(()AdUX{F3tT?)pvFFEQ{-%D=no|BWvA_u~#24()(M&|&6}zUlzzAS6$B zvbTYKl70)$9oq{@=J6bS1TdJw66qxa%gs}TgmZ+BRNFa^<>Y70Lfcs)vZ3=X-OgNx&2mdyZ+{qlxx}<} zWkOxU_Mxe>*~x;ZO8JitgcsV$odpsHrz)a4+NuOi*f>CaOj*RNlL>tLv2#^IT)n=9 z-vfOM(8?4)$xJWh&&o<^3B7mxd2*(#dFe?$U9MFwI$QtQ@qPPGMq1UuhsV~#hHd=( zy)`YCx1Xtpop3WSA1hYOQp~vRre?q7RQ&mzevy5_i@938?6_c|Px&uSrBfRA_e|m4479{YZmVNLLoR=pv+r6hE>ns0a#i(?wmliglr@ zmUeCaKpR06EQpH~TnGwoY!#tkLj;A0y98Hls3_gJaNP7hZ*FGhy)>m$um{4+eRtl> zn=^Orc{2kzMq#z0lv1j&T2Zr08;U?S`IS9SN_mlU7Uiq`Kp2SELxoi@Nk!W3cZtJejiJ|cK%L^Q`^D<{}kSbB`pz_?- z!8tKOAXTRs5>55_<(xxDjBey@5wRD{<%_*NOc;}?5(eq^M605Ea3Fi@` z`!dyahJ%m1i8R~uGN)V~T?YVMI6txbta2YQeD@6SCq)PT3`K)!D?&z;3C<%%2i=aH zUs;)>xJt=#+z$Y+Kc{xD|8(HLSEY9^7eRa5-H`!rnmLacQWZe28d7zD#vT7wmIs%v z&D7acmvds|xsMEedF~|T-3GplD3xnklD|9}LpTKV_4FVXjbi@sa})~;?uh{!Rl@cq z+svjFPq6%GB$JMNZLPLlL1%jm?QId9`W?bNfKP*qW@5HCE8d)I6?6F_oh=#t@*GJ{ z8xuLU4K3-T12umC{<&9(p8;Znz)&v$T*Zyfhk9am6QlxwnFm|u9tXtsW(C!6AGN2E z&FruNjjBSUugg1f`;yjW9M5)cqyN`g^q%O&=|6pV3ShnKu3nW02XREZ->Rfr5Zdrz zVFBTeFhb!FB3 Date: Wed, 17 Jul 2024 04:36:25 +0000 Subject: [PATCH 030/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e0f8aef124b..2d6851dcc1c 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Ghagliiarghii - changes: - - message: Security can now find replacements for their trusty Combat Knife in the - SecVend, or craft them with the Sec Lathe. - type: Tweak - id: 6425 - time: '2024-04-23T11:24:58.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27224 - author: Whisper changes: - message: Fire stack limit reduced from 20 to 10. Fire transfers will be less effective, @@ -3806,3 +3798,10 @@ id: 6924 time: '2024-07-16T23:26:02.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/27879 +- author: EmoGarbage404 + changes: + - message: Resprited wall signs. + type: Tweak + id: 6925 + time: '2024-07-17T04:35:19.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29806 From d8ab4982ade982b44f845e6532c291e39eec1203 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Wed, 17 Jul 2024 08:47:50 +0300 Subject: [PATCH 031/134] Character menu issuer localization (#29840) * Update CharacterUIController.cs * TODO Burn this shit * huh? * huh! --------- Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com> --- .../Systems/Character/CharacterUIController.cs | 16 ++++++++++++---- .../CharacterInfo/CharacterInfoSystem.cs | 2 +- Content.Server/Objectives/ObjectivesSystem.cs | 4 ++-- .../Objectives/Components/ObjectiveComponent.cs | 7 +++++-- Resources/Prototypes/Objectives/dragon.yml | 2 +- Resources/Prototypes/Objectives/ninja.yml | 2 +- Resources/Prototypes/Objectives/thief.yml | 2 +- Resources/Prototypes/Objectives/traitor.yml | 2 +- 8 files changed, 24 insertions(+), 13 deletions(-) diff --git a/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs b/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs index 88edb6a4f12..1e4d2f27657 100644 --- a/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs +++ b/Content.Client/UserInterface/Systems/Character/CharacterUIController.cs @@ -1,11 +1,13 @@ using System.Linq; using Content.Client.CharacterInfo; using Content.Client.Gameplay; +using Content.Client.Stylesheets; using Content.Client.UserInterface.Controls; using Content.Client.UserInterface.Systems.Character.Controls; using Content.Client.UserInterface.Systems.Character.Windows; using Content.Client.UserInterface.Systems.Objectives.Controls; using Content.Shared.Input; +using Content.Shared.Objectives.Systems; using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Client.Player; @@ -121,11 +123,17 @@ private void CharacterUpdated(CharacterData data) Modulate = Color.Gray }; - objectiveControl.AddChild(new Label + + var objectiveText = new FormattedMessage(); + objectiveText.TryAddMarkup(groupId, out _); + + var objectiveLabel = new RichTextLabel { - Text = groupId, - Modulate = Color.LightSkyBlue - }); + StyleClasses = {StyleNano.StyleClassTooltipActionTitle} + }; + objectiveLabel.SetMessage(objectiveText); + + objectiveControl.AddChild(objectiveLabel); foreach (var condition in conditions) { diff --git a/Content.Server/CharacterInfo/CharacterInfoSystem.cs b/Content.Server/CharacterInfo/CharacterInfoSystem.cs index cb2216b5e3b..3099b2f90fc 100644 --- a/Content.Server/CharacterInfo/CharacterInfoSystem.cs +++ b/Content.Server/CharacterInfo/CharacterInfoSystem.cs @@ -43,7 +43,7 @@ private void OnRequestCharacterInfoEvent(RequestCharacterInfoEvent msg, EntitySe continue; // group objectives by their issuer - var issuer = Comp(objective).Issuer; + var issuer = Comp(objective).LocIssuer; if (!objectives.ContainsKey(issuer)) objectives[issuer] = new List(); objectives[issuer].Add(info.Value); diff --git a/Content.Server/Objectives/ObjectivesSystem.cs b/Content.Server/Objectives/ObjectivesSystem.cs index c9cdf244e66..382cb1ab441 100644 --- a/Content.Server/Objectives/ObjectivesSystem.cs +++ b/Content.Server/Objectives/ObjectivesSystem.cs @@ -129,12 +129,12 @@ private void AddSummary(StringBuilder result, string agent, List<(EntityUid, str var agentSummary = new StringBuilder(); agentSummary.AppendLine(Loc.GetString("objectives-with-objectives", ("custody", custody), ("title", title), ("agent", agent))); - foreach (var objectiveGroup in objectives.GroupBy(o => Comp(o).Issuer)) + foreach (var objectiveGroup in objectives.GroupBy(o => Comp(o).LocIssuer)) { //TO DO: //check for the right group here. Getting the target issuer is easy: objectiveGroup.Key //It should be compared to the type of the group's issuer. - agentSummary.AppendLine(Loc.GetString($"objective-issuer-{objectiveGroup.Key}")); + agentSummary.AppendLine(objectiveGroup.Key); foreach (var objective in objectiveGroup) { diff --git a/Content.Shared/Objectives/Components/ObjectiveComponent.cs b/Content.Shared/Objectives/Components/ObjectiveComponent.cs index 36d3fa0bded..fb2e6ca0a68 100644 --- a/Content.Shared/Objectives/Components/ObjectiveComponent.cs +++ b/Content.Shared/Objectives/Components/ObjectiveComponent.cs @@ -22,8 +22,11 @@ public sealed partial class ObjectiveComponent : Component ///

/// Organisation that issued this objective, used for grouping and as a header above common objectives. /// - [DataField(required: true)] - public string Issuer = string.Empty; + [DataField("issuer", required: true)] + private LocId Issuer { get; set; } + + [ViewVariables(VVAccess.ReadOnly)] + public string LocIssuer => Loc.GetString(Issuer); /// /// Unique objectives can only have 1 per prototype id. diff --git a/Resources/Prototypes/Objectives/dragon.yml b/Resources/Prototypes/Objectives/dragon.yml index 10ca942cb39..bbdac8faa1a 100644 --- a/Resources/Prototypes/Objectives/dragon.yml +++ b/Resources/Prototypes/Objectives/dragon.yml @@ -6,7 +6,7 @@ - type: Objective # difficulty isn't used at all since objective are fixed difficulty: 1.5 - issuer: dragon + issuer: objective-issuer-dragon - type: RoleRequirement roles: components: diff --git a/Resources/Prototypes/Objectives/ninja.yml b/Resources/Prototypes/Objectives/ninja.yml index 77628a68cf1..4d0cf6c17c8 100644 --- a/Resources/Prototypes/Objectives/ninja.yml +++ b/Resources/Prototypes/Objectives/ninja.yml @@ -6,7 +6,7 @@ - type: Objective # difficulty isn't used since all objectives are picked difficulty: 1.5 - issuer: spiderclan + issuer: objective-issuer-spiderclan - type: RoleRequirement roles: components: diff --git a/Resources/Prototypes/Objectives/thief.yml b/Resources/Prototypes/Objectives/thief.yml index 8b5307e9a09..cc94ab02b34 100644 --- a/Resources/Prototypes/Objectives/thief.yml +++ b/Resources/Prototypes/Objectives/thief.yml @@ -4,7 +4,7 @@ id: BaseThiefObjective components: - type: Objective - issuer: thief + issuer: objective-issuer-thief - type: RoleRequirement roles: components: diff --git a/Resources/Prototypes/Objectives/traitor.yml b/Resources/Prototypes/Objectives/traitor.yml index ad5f56a443e..edf191b420d 100644 --- a/Resources/Prototypes/Objectives/traitor.yml +++ b/Resources/Prototypes/Objectives/traitor.yml @@ -4,7 +4,7 @@ id: BaseTraitorObjective components: - type: Objective - issuer: syndicate + issuer: objective-issuer-syndicate - type: RoleRequirement roles: components: From 1fd8369a9c195d6465a195e7f49f3f1a04d24c60 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Wed, 17 Jul 2024 08:19:13 +0200 Subject: [PATCH 032/134] Add examine for caustic and cold damage (#29989) * Examinable cold damage * lightblue * update grammar * caustic --- .../en-US/health-examinable/health-examinable-carbon.ftl | 8 ++++++++ Resources/Prototypes/Entities/Mobs/base.yml | 2 ++ 2 files changed, 10 insertions(+) diff --git a/Resources/Locale/en-US/health-examinable/health-examinable-carbon.ftl b/Resources/Locale/en-US/health-examinable/health-examinable-carbon.ftl index ddd6de23673..ac536a1e25a 100644 --- a/Resources/Locale/en-US/health-examinable/health-examinable-carbon.ftl +++ b/Resources/Locale/en-US/health-examinable/health-examinable-carbon.ftl @@ -16,3 +16,11 @@ health-examinable-carbon-Heat-50 = [color=orange]{ CAPITALIZE(SUBJECT($target)) health-examinable-carbon-Heat-75 = [color=orange]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } severe third-degree burns across { POSS-ADJ($target) } body![/color] health-examinable-carbon-Shock-50 = [color=lightgoldenrodyellow]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } electrical shock marks across { POSS-ADJ($target) } body![/color] + +health-examinable-carbon-Cold-25 = [color=lightblue]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } minor frostbite across { POSS-ADJ($target) } body.[/color] +health-examinable-carbon-Cold-50 = [color=lightblue]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } major frostbite across { POSS-ADJ($target) } body.[/color] +health-examinable-carbon-Cold-75 = [color=lightblue]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } severe third-degree frostbite across { POSS-ADJ($target) } body![/color] + +health-examinable-carbon-Caustic-25 = [color=yellowgreen]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } minor chemical burns.[/color] +health-examinable-carbon-Caustic-50 = [color=yellowgreen]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } chemical burns across { POSS-ADJ($target) } body.[/color] +health-examinable-carbon-Caustic-75 = [color=yellowgreen]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } severe chemical burns all over { POSS-ADJ($target) } body![/color] diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml index fae47113107..3a555beebfb 100644 --- a/Resources/Prototypes/Entities/Mobs/base.yml +++ b/Resources/Prototypes/Entities/Mobs/base.yml @@ -99,6 +99,8 @@ - Piercing - Heat - Shock + - Cold + - Caustic - type: DamageOnHighSpeedImpact damage: types: From 1ac7739564b525307ac9e3fde72a2d145f54f35f Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 17 Jul 2024 06:20:20 +0000 Subject: [PATCH 033/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 2d6851dcc1c..db39ddaacdc 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Whisper - changes: - - message: Fire stack limit reduced from 20 to 10. Fire transfers will be less effective, - and fires will not last as long. - type: Tweak - id: 6426 - time: '2024-04-23T11:30:01.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27159 - author: brainfood1183 changes: - message: Directional Exit signs for maints! @@ -3805,3 +3797,10 @@ id: 6925 time: '2024-07-17T04:35:19.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29806 +- author: lzk228 + changes: + - message: Added health examine for caustic and cold damage. + type: Add + id: 6926 + time: '2024-07-17T06:19:13.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29989 From 6443c53a8cee6a28d2b885d02d7f6e9adeefafda Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Wed, 17 Jul 2024 08:26:10 +0200 Subject: [PATCH 034/134] Little saw debuff (#29995) --- .../Objects/Specific/Medical/surgery.yml | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml index c4f7798154e..8b1606dc5d3 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml @@ -173,12 +173,12 @@ sprite: Objects/Specific/Medical/Surgery/saw.rsi state: saw - type: Item + size: Normal sprite: Objects/Specific/Medical/Surgery/saw.rsi storedRotation: 90 - type: Tool qualities: - Sawing - speedModifier: 1.0 # No melee for regular saw because have you ever seen someone use a band saw as a weapon? It's dumb. - type: entity @@ -190,6 +190,7 @@ - type: Sprite state: improv - type: Item + size: Small heldPrefix: improv - type: MeleeWeapon damage: @@ -198,8 +199,6 @@ soundHit: path: /Audio/Weapons/bladeslice.ogg - type: Tool - qualities: - - Sawing speedModifier: 0.5 - type: entity @@ -212,7 +211,6 @@ state: electric - type: Item heldPrefix: electric - storedRotation: 90 - type: MeleeWeapon damage: groups: @@ -220,29 +218,19 @@ soundHit: path: /Audio/Items/drill_hit.ogg - type: Tool - qualities: - - Sawing speedModifier: 1.5 - type: entity name: advanced circular saw id: SawAdvanced - parent: Saw + parent: SawElectric description: You think you can cut anything with it. components: - type: Sprite state: advanced - type: Item heldPrefix: advanced - storedRotation: 90 - type: MeleeWeapon attackRate: 1.5 - damage: - groups: - Brute: 15 - soundHit: - path: /Audio/Items/drill_hit.ogg - type: Tool - qualities: - - Sawing speedModifier: 2.0 From 0e02c505487f7443f380b59d9729dc9c05b2c09d Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 17 Jul 2024 06:27:16 +0000 Subject: [PATCH 035/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index db39ddaacdc..ec85d771e3a 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: brainfood1183 - changes: - - message: Directional Exit signs for maints! - type: Add - id: 6427 - time: '2024-04-23T11:31:48.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/26831 - author: pigeonpeas changes: - message: Adds the ability to purchase emitters in cargo. @@ -3804,3 +3797,10 @@ id: 6926 time: '2024-07-17T06:19:13.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29989 +- author: lzk228 + changes: + - message: Surgery saws now are normal-sized (no more pocket circular saw). + type: Tweak + id: 6927 + time: '2024-07-17T06:26:10.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29995 From b20fd4fbd00912b6c94f001d2f3ae15d01f0a23a Mon Sep 17 00:00:00 2001 From: Flareguy <78941145+Flareguy@users.noreply.github.com> Date: Wed, 17 Jul 2024 02:43:11 -0500 Subject: [PATCH 036/134] Vox displacement updates (#29824) * more vox displacement maps * A * remove vox insuls sprites * sci magboots * Update vox.yml * Update meta.json --------- Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> --- .../Prototypes/Entities/Mobs/Species/vox.yml | 48 ++++++++++++++++++ .../Color/yellow.rsi/equipped-HAND-vox.png | Bin 387 -> 0 bytes .../Hands/Gloves/Color/yellow.rsi/meta.json | 27 +++++++++- .../equipped-OUTERCLOTHING-vox.png | Bin 671 -> 605 bytes .../open-equipped-OUTERCLOTHING-vox.png | Bin 672 -> 607 bytes .../equipped-OUTERCLOTHING-vox.png | Bin 699 -> 631 bytes .../open-equipped-OUTERCLOTHING-vox.png | Bin 699 -> 636 bytes .../equipped-OUTERCLOTHING-vox.png | Bin 661 -> 594 bytes .../open-equipped-OUTERCLOTHING-vox.png | Bin 658 -> 591 bytes .../equipped-OUTERCLOTHING-vox.png | Bin 699 -> 631 bytes .../open-equipped-OUTERCLOTHING-vox.png | Bin 699 -> 636 bytes .../equipped-OUTERCLOTHING-vox.png | Bin 699 -> 631 bytes .../open-equipped-OUTERCLOTHING-vox.png | Bin 699 -> 636 bytes .../equipped-OUTERCLOTHING-vox.png | Bin 699 -> 631 bytes .../open-equipped-OUTERCLOTHING-vox.png | Bin 699 -> 636 bytes .../combatboots.rsi/equipped-FEET-vox.png | Bin 0 -> 459 bytes .../Shoes/Boots/combatboots.rsi/meta.json | 6 ++- .../equipped-FEET-vox.png | Bin 0 -> 1164 bytes .../Boots/magboots-science.rsi/meta.json | 10 +++- .../on-equipped-FEET-vox.png | Bin 0 -> 1201 bytes .../speedboots.rsi/equipped-FEET-vox.png | Bin 0 -> 1486 bytes .../Shoes/Boots/speedboots.rsi/meta.json | 10 +++- .../speedboots.rsi/on-equipped-FEET-vox.png | Bin 0 -> 1491 bytes .../vox_parts.rsi/tail_stenciled.png | Bin 615 -> 297 bytes .../Species/Vox/displacement.rsi/back.png | Bin 0 -> 451 bytes .../Species/Vox/displacement.rsi/eyes.png | Bin 0 -> 508 bytes .../Species/Vox/displacement.rsi/hand.png | Bin 0 -> 483 bytes .../Species/Vox/displacement.rsi/meta.json | 14 ++++- .../Mobs/Species/Vox/parts.rsi/torso.png | Bin 866 -> 955 bytes 29 files changed, 110 insertions(+), 5 deletions(-) delete mode 100644 Resources/Textures/Clothing/Hands/Gloves/Color/yellow.rsi/equipped-HAND-vox.png create mode 100644 Resources/Textures/Clothing/Shoes/Boots/combatboots.rsi/equipped-FEET-vox.png create mode 100644 Resources/Textures/Clothing/Shoes/Boots/magboots-science.rsi/equipped-FEET-vox.png create mode 100644 Resources/Textures/Clothing/Shoes/Boots/magboots-science.rsi/on-equipped-FEET-vox.png create mode 100644 Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/equipped-FEET-vox.png create mode 100644 Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-equipped-FEET-vox.png create mode 100644 Resources/Textures/Mobs/Species/Vox/displacement.rsi/back.png create mode 100644 Resources/Textures/Mobs/Species/Vox/displacement.rsi/eyes.png create mode 100644 Resources/Textures/Mobs/Species/Vox/displacement.rsi/hand.png diff --git a/Resources/Prototypes/Entities/Mobs/Species/vox.yml b/Resources/Prototypes/Entities/Mobs/Species/vox.yml index 4d5239e50c5..02e2791e354 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/vox.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/vox.yml @@ -26,6 +26,30 @@ layerKey: dummy parameterTexture: displacementMap parameterUV: displacementUV + eyes: + layer: + sprite: Mobs/Species/Vox/displacement.rsi + state: eyes + copyToShaderParameters: + layerKey: dummy + parameterTexture: displacementMap + parameterUV: displacementUV + gloves: + layer: + sprite: Mobs/Species/Vox/displacement.rsi + state: hand + copyToShaderParameters: + layerKey: dummy + parameterTexture: displacementMap + parameterUV: displacementUV + back: + layer: + sprite: Mobs/Species/Vox/displacement.rsi + state: back + copyToShaderParameters: + layerKey: dummy + parameterTexture: displacementMap + parameterUV: displacementUV - type: Speech speechVerb: Vox speechSounds: Vox @@ -124,4 +148,28 @@ layerKey: dummy parameterTexture: displacementMap parameterUV: displacementUV + eyes: + layer: + sprite: Mobs/Species/Vox/displacement.rsi + state: eyes + copyToShaderParameters: + layerKey: dummy + parameterTexture: displacementMap + parameterUV: displacementUV + gloves: + layer: + sprite: Mobs/Species/Vox/displacement.rsi + state: hand + copyToShaderParameters: + layerKey: dummy + parameterTexture: displacementMap + parameterUV: displacementUV + back: + layer: + sprite: Mobs/Species/Vox/displacement.rsi + state: back + copyToShaderParameters: + layerKey: dummy + parameterTexture: displacementMap + parameterUV: displacementUV diff --git a/Resources/Textures/Clothing/Hands/Gloves/Color/yellow.rsi/equipped-HAND-vox.png b/Resources/Textures/Clothing/Hands/Gloves/Color/yellow.rsi/equipped-HAND-vox.png deleted file mode 100644 index b7f2122c19f5bb439cf0bb625613b5526410247e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 387 zcmV-}0et?6P)NklmZ0Zoi)+R&{1ZRto1s9U+%*3oL z|6i3N?}NviG!qd30000006aTv`>M;hp8{W$Zmz?&uL57}>j%Clm5GW%Pb*mzdP-$t z-9#7ldrdFIi7TVQL#Mus1`ml7S1abP>Q@dR@I}oQ#q;UfIHxD&`?E!nM=SVE>VL1F z%{RdI7_3)A?e#B3p{LfXq1_SK>^$x1mrmE7Y<8YeZ0UYE%Ve56Cb5%g?%XeDtNH){ z000000001JJSZaZ0 h2E3{s006+h_XW$Kw~dZe6Egq+002ovPDHLkV1hjUu0sF- diff --git a/Resources/Textures/Clothing/Hands/Gloves/Color/yellow.rsi/meta.json b/Resources/Textures/Clothing/Hands/Gloves/Color/yellow.rsi/meta.json index ccb1c5dcaf3..88e3ebd509d 100644 --- a/Resources/Textures/Clothing/Hands/Gloves/Color/yellow.rsi/meta.json +++ b/Resources/Textures/Clothing/Hands/Gloves/Color/yellow.rsi/meta.json @@ -1 +1,26 @@ -{"version": 1, "license": "CC-BY-SA-3.0", "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e", "size": {"x": 32, "y": 32}, "states": [{"name": "icon"}, {"name": "equipped-HAND", "directions": 4}, {"name": "inhand-left", "directions": 4}, {"name": "inhand-right", "directions": 4}, {"name": "equipped-HAND-vox", "directions": 4}]} +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-HAND", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/equipped-OUTERCLOTHING-vox.png b/Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/equipped-OUTERCLOTHING-vox.png index fa32996aa89b0b94751422eeed4206e6d123a2fa..a6546c4655791eb62a6a1dc791e48b35ce2c0d69 100644 GIT binary patch delta 502 zcmVFRYF_A$-e*x1;L_t(oh3%H%a)clZgf}5vk@tV#ZuG1uglnhM>HUxy zPjHj(B4JEWe>rdiZovBi@PY~Pan_p^pzB>RMo>>?md^Syr<{F-Oq1c?=Y6z6pw*28 z@Hb0OX#7w50m!sq47@lS0J7-QU0Z#hK@2oVpufVp5L~w{h;@bze~{q5!bruZ9l#$x z0Vn+nz^z3}@{mLkT_RRp_6=zCQ%3l9AEJXD++U;1!3DtZA2Le8Q&%U5MgZ!<2tQRss)m8lA+=z=~ZATHOs?4gtxq;9_vn z_b~)`a&g=Sgk!W%e}}d|7&qVs+PyJ8es%%#MsCzfj<`3f42$i0vBv!G>QO)IkaJKY}pKvyhMAjWRdRS^#N;q zi2#MA|0TfNgD{Px&j7G$d^Mgku^)7TR0Y0f}^88_g&gM}@$hPD_oOg^xbklf+0^!$1Gz|HUKLj!&Py;Sl z7Xp8orKQWr?-sEV0umu#NT(8v*R6?t|sx4Q@CD1~>tf|H2gt;O!ybZ}Q-PXH>wahz?SL0*k2o*LDX8ycAra z02BZX1So;m#eSweFyIwe1svv)9|i2B7dwCLk$?pl9SS6+g-!t-#_zZku+25E-DVik z&{hoBvERTW@CX(*#@v4( zXz!)@6AJpj*r?HbgRcOC7zUZ8`Df6A{%59Yi~iyKe@bF(|9 zSoHW32^6&cW_QdLU_6KfY=UTZ#~4exDjq@N3UCGx67RyQvT`o*Ni3OH(Nj_f;fPp1 z#R9Y`jL+!AY>L7{{0?y43|STtvj7Gj02O9tY002ovPDHLk FV1gCs^p5}l diff --git a/Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/open-equipped-OUTERCLOTHING-vox.png b/Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/open-equipped-OUTERCLOTHING-vox.png index ce7c029026c8319d3be367415183c45fdfedfc96..2ecf1e68e01feba062c1a6211aeffa70f38d4e08 100644 GIT binary patch delta 504 zcmVXdaF_A$-e*x7=L_t(oh3%HnlEWYfMFFv<{{IK>#Wbx(u)DLfvwes& zZB*do8cl%eFB@He3-EaWdc!2PHrl%pk+iFjkAOX?Y8vgYKFrxhl;PsuJ|C?YLA_l; zApB>Z30?ePe*rQ)Qm*)+=KwOxBV2m>(IZxZL#l`u(n*5Zbr;cke>4FS5n^o#*}4~~iw^-Xq{r0< z9L)thH+Mb+Py5mOe_7Y}2kin}fD7<9fN${D5#%JbwZkddt7Ygdiry@B>nUUyaBew1 zP(dyAuM-QhW6~`GZ1`TEQ_~qBBwO$-F}aDQ@C5)#Dcc$&0HFjCjsenYgq4C;JV*#Y z-5@C;y?OB!(7s^8yCS0>`@tZop&_R=2k7T6;vH0_OAV z1dz1?c?)2<#|rMUR6tr4OIRtu65tf>LRG1pR|+y$(HZ~}N|1fT_wF%1M~K}|sb0I`n?{9y%=E=GR<32;bRa{vGizyJUazyWI3i3tDz z0r5#hK~z{r?Uw6ugdhxsLlRcY`#*3`5Ru4b+i8EaGoG1Na{COcyMfXV^#C4#>5l;p zW6q>t^6|zZ;(TQqBM=u=6(7IW2uHIhBIR&7QHZD7ChF4S3IgH3%P4BWJpZ- z!)kv3h=EHvxAAjDK?wf)_d0OB-(iq8oqg%_meLZeInfp8^n&a_wdQQ$s*~xcy6T z2>w&WV;bjvLl58qm>$6I1HQmpSI}UnIduu%B(({>7pv2bdT~FgHvk4hp7E0|Z0ZQF z2Mea7=spAN_`SZ5raOR%v4bH2&K=<;07EI-9%lf;5hTyAOKy#!g&V9o$cG0vx!ivm z=LQzRcq@*Z5D=W7aKI=IlUw8b#Wv!{1UNDKEoTNWLjxo6qd1)4+&E}oE&Bei+Y|S?f)KZzPN(;W znNfk0d=tbmq3th?9>4?megOKwBzEidW=16YQ)rHWo>VpU`Z>;$%x7dt@+3Zs9mb9R z2IQrffTf_I zk7Z(G9}WOt`~r0P8-Q0!De(_Z5NSAwUH<}fdUqlw{F7x!|J=p_Xcv12WMDBsoWK$R zpffVyi^r*}fWRU;|BwI>mWnF`fB@3~Knc38ejCoMkGa*UchIUAhgNq7mqS2O zTIu4@>4!}LezeF032;bRa{vGizyJUazyWI3i3tDz z0su)wK~z{r?Uw6ugfIw&fkez!egD_(A;xTC7Pp=DM?2%0aSZ{!#mfk^{ZKdH2AKXB zU^jdwv8ner7Lnw$&}#(zA;uVb|8qS_P_sybO#4=+N%Rmm{tB4pq!9$dZ<`hBCT`^s51Yd zmjHXXW|h+@a}<>w)9cu8=my*X(+&82z!!Me8I=3$g@%CM#OKKRYq18wrTA(UYgcEX zG2|Za5OTg;G?ppNs_2l;Ck@{;G+)&@waxzom}M-oDqoIMo082S#A= z0MIQvW+w$w0f9wye31YU&LzXc1AqWi2S7okW*~YvgNGg}0hhVesdLC!=iZ^!?WCK|(-#8^srF=YSE5z21lnFo;=;e;*UF-2yQmw=ZC!EO5M! z0NBjJI-D&VtAnJQ0rP(M0Fd(xogi)e8G zgdvDI=Hh2ia>NLwZGZ1e5UJPH{WjV;_(RrXgc!&AJ|Fj^`VW9F>7BTRxS83#00000 LNkvXXu0mjf{_60m delta 583 zcmV-N0=WJB1iJ;0F%1M~K}|sb0I`n?{9y%=E>eF032;bRa{vGi!2kdb!2!6DYwZ94 z0su)wK~z{r?Uvh)-5?A_jqMO7DgXbw-6oKOL&&shA6h9}ngQQd%()rLf2bGm0!;rH z;4tP)3ML=#EFvx|(>(%lQC0Er&wgQvW>FMg4wuuyu_<)%6R@l)DhP!CX&ng`Z|dVG zfD(TaBxd}@l=>zQA>LZxKHhc|)OwVRdS3MMN*!?xrM~Pw4{oavq1KKNZ94$WSphD7 z0`Ss;@Rh$%Uo5W@uK*YC6NyU)d@XMJ06IB9C>;#vZz48A@DJz=#I3t<$v8#IAOvQ0 zPpvCNh;MmA#tZ-gq!R#%a_N9|cn?e@_#l6mdg`Gix5+gHKrrvL<`uA|J~ zbPG7&-0?$j2>zz(G2Q3>hF-u6Fuj1k5BLS%a|M<8`k*1fo1`|O_i7E=Q7`T%^#Z_P zC^LT2g-spdhrzO>71L34p8;bqIKop0I0BMfQC&@xm2-$s z9mJ4XFGZ&ammt(z@vMWq6+%DX9n3FoQRe8Kol5B8k_E%x9d32a`L^IY{r7;Je*zIm VxScxd|3v@*002ovPDHLkV1gL!2cQ4| diff --git a/Resources/Textures/Clothing/OuterClothing/Coats/labcoat_cmo.rsi/equipped-OUTERCLOTHING-vox.png b/Resources/Textures/Clothing/OuterClothing/Coats/labcoat_cmo.rsi/equipped-OUTERCLOTHING-vox.png index 58b84263ac0a4649420ed65c9f2693fcffd3ccf4..eaef9455081cfe399e15427d15ab80aa699db32c 100644 GIT binary patch delta 499 zcmV$N`odhqFpXCz5Pn01W6BTwDNqrC8gRk7 z5vYGGo-Q;0vWS%sPzd=#x|CqN9z}HP{NvZXkmWKeWiuB6TXccI4*|SdDuo*tkmf~n z-UR|b2NIrcW4U>Q2Tp+rK>+19T&V!w9`fTRPY!rS1$>DZAQdREh=zalJ3!#2;YtOd z0B9mW1-x$dv+RKZuedAVFwgufU?;uVY0rNIEWqegpeSv02^cW`g1i zbjakBhHo00@3l2u1!OI9pg$m5_!|K5i|wE~O>nSf0YZV$|{q`Tq~B(DHx03rD<>?%9gmY>8{c^ADT4G@lqir1P zZUEa~hCpIV|H~#1-~s$RfPBLg^|solkqE{W5+i6YW>!}FSD)tUBdK%=Z(q+gi;&rF zBnbbj-U(CuV*dhEdX(DvV=n+y#XB6c{p^XF(4ln3L+mEO?e-Eee|mBQ6cNVy5~_D^ z0H1sV7W)UlM@z!d55|wt1>kl)AHZZ^b_7E~xCgIg-1guC(4ipMg7XGWP-FnwU7czo zK@21)VDUjB0NQ$^M+P8)%@TkV!%zUb?ZL}l27!mUL?>}LG>+TqFx&lA@c0x!LwR3g zz}Z5;XLIj|;A21Ae>@xd{y}>H58wg(8^CYy_7M^!wY|e7*_&tRl;K&U*d=5cXvKyw z;;~OG%#OT82B1K>rluO5t&^;|)3m8W%iS=J>0zfV delta 562 zcmV-20?qx;1d;`iF%1M~K}|sb0I`n?{9y%=E2_^`L8Tl&Kl|aAkMU>TbN);WMBvKqChTrGoDKhXkJ<^8F2(4g9Pw+#*hiDF{K;++FJx68N{g zAz}sq0kR1|qG_o>t$PNPM7+o)KeqlB5N&_Me)9pR;OAF?`BMNKv0i)8erO0dA8!8= z?1KGJwNT^OALs!*0O|q!J>VO>b%qR@no}3xw_@zjQwF<6bU&##02)K-@e@MH*L7n- zcf>7b02GMU=?Qm$3cJFPKs($^0Gd+b8K(e@AfTjj1d2><{907*qoM6N<$g32KE A<^TWy diff --git a/Resources/Textures/Clothing/OuterClothing/Coats/labcoat_gene.rsi/equipped-OUTERCLOTHING-vox.png b/Resources/Textures/Clothing/OuterClothing/Coats/labcoat_gene.rsi/equipped-OUTERCLOTHING-vox.png index fa9a53d3735ecc3d43093d6dcca23556af236b6d..03a4e52f7b9fb145ea77ab8dd02ca45bdb65bf03 100644 GIT binary patch delta 516 zcmV+f0{i{D1@{DyF_A$}e*xi1L_t(oh3%H%vYa3cg_95>E&Bei+Y|S?f)KZzPN(;W znNfk0d=tbmq3th?9>4?megOKwBzEidW=16YQ)rHWo>VpU`Z>;$%x7dt@+3Zs9mb9R z2IQrffTf_I zk7Z(G9}WOt`~r0P8-Q0!De(_Z5NSAwUH<}fdUqlw{F7x!|J=p_Xcv12WMDBsoWK$R zpffVyi^r*}fWRU;|BwI>mWnF`fB@3~Knc38ejCoMkGa*UchIUAhgNq7mqS2O zTIu4@>4!}LezeF032;bRa{vGizW@LZzX3P}QzQTY z0su)wK~z{r?Uw6ugfIw&fkez!egD_(A;xTC7Pp=DM?2%0aSZ{!#mfk^{ZKdH2AKXB zU^jdwv8ner7Lnw$&}#(zA;uVb|8qS_P_sybO#4=+N%Rmm{tB4pq!9$dZ<`hBCT`^s51Yd zmjHXXW|h+@a}<>w)9cu8=my*X(+&82z!!Me8I=3$g@%CM#OKKRYq18wrTA(UYgcEX zG2|Za5OTg;G?ppNs_2l;Ck@{;G+)&@waxzom}M-oDqoIMo082S#A= z0MIQvW+w$w0f9wye31YU&LzXc1AqWi2S7okW*~YvgNGg}0hhVesdLC!=iZ^!?WCK|(-#8^srF=YSE5z21lnFo;=;e;*UF-2yQmw=ZC!EO5M! z0NBjJI-D&VtAnJQ0rP(M0Fd(xogi)e8G zgdvDI=Hh2ia>NLwZGZ1e5UJPH{WjV;_(RrXgc!&AJ|Fj^`VW9F>7BTRxS83#00000 LNkvXXu0mjf{_60m delta 583 zcmV-N0=WJB1iJ;0F%1M~K}|sb0I`n?{9y%=E>eF032;bRa{vGizyJUazyWI3i3tDz z0su)wK~z{r?Uvh)-5?A_jqMO7DgXbw-6oKOL&&shA6h9}ngQQd%()rLf2bGm0!;rH z;4tP)3ML=#EFvx|(>(%lQC0Er&wgQvW>FMg4wuuyu_<)%6R@l)DhP!CX&ng`Z|dVG zfD(TaBxd}@l=>zQA>LZxKHhc|)OwVRdS3MMN*!?xrM~Pw4{oavq1KKNZ94$WSphD7 z0`Ss;@Rh$%Uo5W@uK*YC6NyU)d@XMJ06IB9C>;#vZz48A@DJz=#I3t<$v8#IAOvQ0 zPpvCNh;MmA#tZ-gq!R#%a_N9|cn?e@_#l6mdg`Gix5+gHKrrvL<`uA|J~ zbPG7&-0?$j2>zz(G2Q3>hF-u6Fuj1k5BLS%a|M<8`k*1fo1`|O_i7E=Q7`T%^#Z_P zC^LT2g-spdhrzO>71L34p8;bqIKop0I0BMfQC&@xm2-$s z9mJ4XFGZ&ammt(z@vMWq6+%DX9n3FoQRe8Kol5B8k_E%x9d32a`L^IY{r7;Je*zIm VxScxd|3v@*002ovPDHLkV1i!K2G0Nh diff --git a/Resources/Textures/Clothing/OuterClothing/Coats/labcoat_sci.rsi/equipped-OUTERCLOTHING-vox.png b/Resources/Textures/Clothing/OuterClothing/Coats/labcoat_sci.rsi/equipped-OUTERCLOTHING-vox.png index 89369f8794c1aaa1c8dd4195a9a7f341591e5502..f99be74a5a952c6d3b1dad752e7686af7478cc02 100644 GIT binary patch delta 516 zcmV+f0{i{D1@{DyF_A$}e*xi1L_t(oh3%H%vYa3cg_95>E&Bei+Y|S?f)KZzPN(;W znNfk0d=tbmq3th?9>4?megOKwBzEidW=16YQ)rHWo>VpU`Z>;$%x7dt@+3Zs9mb9R z2IQrffTf_I zk7Z(G9}WOt`~r0P8-Q0!De(_Z5NSAwUH<}fdUqlw{F7x!|J=p_Xcv12WMDBsoWK$R zpffVyi^r*}fWRU;|BwI>mWnF`fB@3~Knc38ejCoMkGa*UchIUAhgNq7mqS2O zTIu4@>4!}LezeF032;bRa{vGizyJUazyWI3i3tDz z0su)wK~z{r?Uw6ugfIw&fkez!egD_(A;xTC7Pp=DM?2%0aSZ{!#mfk^{ZKdH2AKXB zU^jdwv8ner7Lnw$&}#(zA;uVb|8qS_P_sybO#4=+N%Rmm{tB4pq!9$dZ<`hBCT`^s51Yd zmjHXXW|h+@a}<>w)9cu8=my*X(+&82z!!Me8I=3$g@%CM#OKKRYq18wrTA(UYgcEX zG2|Za5OTg;G?ppNs_2l;Ck@{;G+)&@waxzom}M-oDqoIMo082S#A= z0MIQvW+w$w0f9wye31YU&LzXc1AqWi2S7okW*~YvgNGg}0hhVesdLC!=iZ^!?WCK|(-#8^srF=YSE5z21lnFo;=;e;*UF-2yQmw=ZC!EO5M! z0NBjJI-D&VtAnJQ0rP(M0Fd(xogi)e8G zgdvDI=Hh2ia>NLwZGZ1e5UJPH{WjV;_(RrXgc!&AJ|Fj^`VW9F>7BTRxS83#00000 LNkvXXu0mjf{_60m delta 583 zcmV-N0=WJB1iJ;0F%1M~K}|sb0I`n?{9y%=E>eF032;bRa{vGizyJUazyWI3i3tDz z0su)wK~z{r?Uvh)-5?A_jqMO7DgXbw-6oKOL&&shA6h9}ngQQd%()rLf2bGm0!;rH z;4tP)3ML=#EFvx|(>(%lQC0Er&wgQvW>FMg4wuuyu_<)%6R@l)DhP!CX&ng`Z|dVG zfD(TaBxd}@l=>zQA>LZxKHhc|)OwVRdS3MMN*!?xrM~Pw4{oavq1KKNZ94$WSphD7 z0`Ss;@Rh$%Uo5W@uK*YC6NyU)d@XMJ06IB9C>;#vZz48A@DJz=#I3t<$v8#IAOvQ0 zPpvCNh;MmA#tZ-gq!R#%a_N9|cn?e@_#l6mdg`Gix5+gHKrrvL<`uA|J~ zbPG7&-0?$j2>zz(G2Q3>hF-u6Fuj1k5BLS%a|M<8`k*1fo1`|O_i7E=Q7`T%^#Z_P zC^LT2g-spdhrzO>71L34p8;bqIKop0I0BMfQC&@xm2-$s z9mJ4XFGZ&ammt(z@vMWq6+%DX9n3FoQRe8Kol5B8k_E%x9d32a`L^IY{r7;Je*zIm VxScxd|3v@*002ovPDHLkV1i!K2G0Nh diff --git a/Resources/Textures/Clothing/OuterClothing/Coats/labcoat_viro.rsi/equipped-OUTERCLOTHING-vox.png b/Resources/Textures/Clothing/OuterClothing/Coats/labcoat_viro.rsi/equipped-OUTERCLOTHING-vox.png index e432bb2d017b96584e4944928588189c7b21988d..38b48d0a2d482a244bb52aee14ec16382dcf5a62 100644 GIT binary patch delta 516 zcmV+f0{i{D1@{DyF_A$}e*xi1L_t(oh3%H%vYa3cg_95>E&Bei+Y|S?f)KZzPN(;W znNfk0d=tbmq3th?9>4?megOKwBzEidW=16YQ)rHWo>VpU`Z>;$%x7dt@+3Zs9mb9R z2IQrffTf_I zk7Z(G9}WOt`~r0P8-Q0!De(_Z5NSAwUH<}fdUqlw{F7x!|J=p_Xcv12WMDBsoWK$R zpffVyi^r*}fWRU;|BwI>mWnF`fB@3~Knc38ejCoMkGa*UchIUAhgNq7mqS2O zTIu4@>4!}LezeF032;bRa{vGizW@LZzX3P}QzQTY z0su)wK~z{r?Uw6ugfIw&fkez!egD_(A;xTC7Pp=DM?2%0aSZ{!#mfk^{ZKdH2AKXB zU^jdwv8ner7Lnw$&}#(zA;uVb|8qS_P_sybO#4=+N%Rmm{tB4pq!9$dZ<`hBCT`^s51Yd zmjHXXW|h+@a}<>w)9cu8=my*X(+&82z!!Me8I=3$g@%CM#OKKRYq18wrTA(UYgcEX zG2|Za5OTg;G?ppNs_2l;Ck@{;G+)&@waxzom}M-oDqoIMo082S#A= z0MIQvW+w$w0f9wye31YU&LzXc1AqWi2S7okW*~YvgNGg}0hhVesdLC!=iZ^!?WCK|(-#8^srF=YSE5z21lnFo;=;e;*UF-2yQmw=ZC!EO5M! z0NBjJI-D&VtAnJQ0rP(M0Fd(xogi)e8G zgdvDI=Hh2ia>NLwZGZ1e5UJPH{WjV;_(RrXgc!&AJ|Fj^`VW9F>7BTRxS83#00000 LNkvXXu0mjf{_60m delta 583 zcmV-N0=WJB1iJ;0F%1M~K}|sb0I`n?{9y%=E>eF032;bRa{vGizyJUazyWI3i3tDz z0su)wK~z{r?Uvh)-5?A_jqMO7DgXbw-6oKOL&&shA6h9}ngQQd%()rLf2bGm0!;rH z;4tP)3ML=#EFvx|(>(%lQC0Er&wgQvW>FMg4wuuyu_<)%6R@l)DhP!CX&ng`Z|dVG zfD(TaBxd}@l=>zQA>LZxKHhc|)OwVRdS3MMN*!?xrM~Pw4{oavq1KKNZ94$WSphD7 z0`Ss;@Rh$%Uo5W@uK*YC6NyU)d@XMJ06IB9C>;#vZz48A@DJz=#I3t<$v8#IAOvQ0 zPpvCNh;MmA#tZ-gq!R#%a_N9|cn?e@_#l6mdg`Gix5+gHKrrvL<`uA|J~ zbPG7&-0?$j2>zz(G2Q3>hF-u6Fuj1k5BLS%a|M<8`k*1fo1`|O_i7E=Q7`T%^#Z_P zC^LT2g-spdhrzO>71L34p8;bqIKop0I0BMfQC&@xm2-$s z9mJ4XFGZ&ammt(z@vMWq6+%DX9n3FoQRe8Kol5B8k_E%x9d32a`L^IY{r7;Je*zIm VxScxd|3v@*002ovPDHLkV1i!K2G0Nh diff --git a/Resources/Textures/Clothing/Shoes/Boots/combatboots.rsi/equipped-FEET-vox.png b/Resources/Textures/Clothing/Shoes/Boots/combatboots.rsi/equipped-FEET-vox.png new file mode 100644 index 0000000000000000000000000000000000000000..77af7765e57afe2d0b804f60204b9a63c276f992 GIT binary patch literal 459 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zTRmMILn`LH zy=9np$UuVi!Sq#&F6--viPbQ5Z&JLHT+r4b?D9tN`$L5s-BX+iiH@B%Q;*7OxqEu4 zN_U2=cz-+RX61gF>P?JF$l#Tb;P-727J`LJk80vK|G)TYev2dhp$L59JnH} zW;4(4MIC>y_cd$0L8Uh+?D;hS^*IUmEh z=f-}^h1YET8Y5Wv_@l()iyRCaZoh5XFP*hBW>^3B@|rk3hK9or1JZxUe=?GIP-=F# zY&Y*YekqHYK2h4$Hgff6xFw5M??0!Gf3vBTi$>gTe~DWM4fH95vr literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Shoes/Boots/combatboots.rsi/meta.json b/Resources/Textures/Clothing/Shoes/Boots/combatboots.rsi/meta.json index 8eb6b8a626a..b0c4419ddae 100644 --- a/Resources/Textures/Clothing/Shoes/Boots/combatboots.rsi/meta.json +++ b/Resources/Textures/Clothing/Shoes/Boots/combatboots.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Made by @ninruB#7795, based off tgstation's jackboots at commit https://github.com/tgstation/tgstation/commit/7e4e9d432d88981fb9bb463970c5b98ce85c0abe", + "copyright": "Made by @ninruB#7795, based off tgstation's jackboots at commit https://github.com/tgstation/tgstation/commit/7e4e9d432d88981fb9bb463970c5b98ce85c0abe. Vox state modified from jackboots.rsi by Flareguy", "size": { "x": 32, "y": 32 @@ -14,6 +14,10 @@ "name": "equipped-FEET", "directions": 4 }, + { + "name": "equipped-FEET-vox", + "directions": 4 + }, { "name": "inhand-left", "directions": 4 diff --git a/Resources/Textures/Clothing/Shoes/Boots/magboots-science.rsi/equipped-FEET-vox.png b/Resources/Textures/Clothing/Shoes/Boots/magboots-science.rsi/equipped-FEET-vox.png new file mode 100644 index 0000000000000000000000000000000000000000..dc22be4ac27c8b1e5023a512df3b885eb36a0423 GIT binary patch literal 1164 zcmV;71atd|P)Px(MoC0LRCt{2+D}YeMI6BK@2rhRpz^0hTcHG4+NH+CrlApbNt8lGAYh^`jR#pw zj7>11scmAaJ$R@zrY()cKRtNhZH<2*jR}!O6kEL%OenUErmX2>*9Sx??b`*HU}9xF zEIg@c%wU#_&gZguGn4uK=J#gbWd<}&(=<)fG)>bqP17_@(=<)f{wIX$z$X782_S?d zJu?OS<_$gwyeFRXx5&(_EM}tfEJzmuNx(RvJg;*6=0j3S!5Y^s)@Gy;i$)1_zAc)X zUy_+w>xkNONa+ILjB#8!{u-s={)6)IonF$?(gBFaXZYmfvj9w8k5RF+>b5>14oIW( zRMLv@eDi);Q(xme|2!EXI69VyKNV%i_J?`Ex5eofNU8b~lnU_e&}U3f{XjSzrmd|V zfQ5xW5}op|aj(DDLP4P$(==74Rd!3>ohU34i3^wf?Y8~}?jatZUF-*`zOmH`@Mvj0 zF7Z20);)_gISs(Z4LOUy4>CJ5%k0c7FSZe*OfCM2Z z-dae19~5sb#3kpMi_HTt{GAEhr97`v0RqMe(OF|i|NXfjAr=`Y>-shVK;_gUG|Vq> zUtSJEfN@>W+~-f~H{gtMTo^S0*|b>n*qBAn)gl14T`l0L^@7a8JP-n7Ds4sal?FC8 zHcEiGc$}*0Mlv!|Ie%`DfYC0R{0C*lP9L$EIR-xeh}5(+0J^%ml2(M}@pnD(G?8(O z=*>7rXS?t>AC#HvQpw-6i7&tSbj9&qDucY`b)=?jBx>87e)kxcE?*&FvF*MXmk=xBR)13heAcFC@n+j$s%!VK znmeFB*v%`i9^=;;8#5dMpg-8{=sEW;lW=M!1&b z+ab%fjlDsU+s(zP?YIl_F^ePg2fOJq+_*i7Hh>`KmFHa1n|iC`eQAaxn4uBp9Dc&G zC@HJrm&qTUaTAusg`uIO?gDRVsm#sGbDlTkY+-nCfTgy%c-$$%{?-?iV=LVcSYn0~ z6_46BUSBo4_wHk}$II~G027www3U=qtz=pyC1q9Y-n$R4ubK(VVt8Px(Ye_^wRCt{2+Fxu_RUE+a@2!i5ZLmN5mu(pxNVetWiMw+db#x_dDlz&%H0_fTAdhq9}@@D2k#eilQirqA1G$geE(%J+NBzE3)TfmHIqF7ezNAH~Hb0HjjW9R2b*0I|sgtJgF>)Te13LhtU( zTM=Ff?i9@%o9*Wt6A}7`N3;23ah_TE1PlGk?S2g*WM6_*0VZA7xGV|?hlknb-3CA= zb1&N|{uuXZxC?KEhuE@FnXuCCibu1BMIdnC5O*Hx&+r(jRC1;tg#5paKLWBIA@#))E5N#-672c7{1s zOVBjXCpCg!2lDz4IHK><^yZLgpDB7`)TB4O41n73QeK#+QC3q0nuZ=L&MCjtz_zwF z0gz6mXl!buw6utUQ-g%`gIarFmsq{VPhvVv|2JPyR9p-|Pft(Yitu3mb?Y|~88?Yf zrO>+%YJuP`Q8u@T>dH#K`}V7x^GkgKzJ?Zx3KtW%EDnG49v3cNBBUSG07Ci!?c${i z9R6@Gam!*>VFmRK8~@=_|C-;wj;Lu8w=BlYpY6p1=-mgjgq3D&rax+$`2B11nqN^A zMNt$*Q4~c{6h%=KMNt&xKOv{%tCkHL#Ju?)`&pkk9eU7?jy^K;RAg zjQZBiVNUe*<@bI7fZOdB^X7YKX>GCFO3DlE3H2QRUI4UhUi+^s9-ympulDCWJ397= zhKAMlm=nF=b{k@3WJGEn(vx+&-J-6pg_z60Tj3!b9cKB|lK?oERx`V#oStzVZ-s}> z;QRkd5jwix6yfMFZIuCjowhK>A^=>Od)c1T!mCb(hE5<`0O=j@R?XYAdNaUNl+LOI z*Lp%{CIDz%n1SDtJaT4p?yJf{?a>v~vVzuUlRyEz!`WLQhl1H1kSOqi7kVda35>K$ z#gs0<=bR)_m`!914PcC%=h~=2(}tHw6jo!5MKHAUTr-RumnHAr(RWzpbn;VdCC;VQ z7@i0x`;O70J8`OZcjFI#9IegSKSykW2FB4bnaZ%Ic?9fnN zKLcM~ov5g)vY!_%S^o-v7i9eoJL<%EAoeM3 P00000NkvXXu0mjfZD>iO literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/equipped-FEET-vox.png b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/equipped-FEET-vox.png new file mode 100644 index 0000000000000000000000000000000000000000..ff5c3a05894c08d233f91a43833a7b7c4ca78afb GIT binary patch literal 1486 zcma)+X*ARe0LB0FFs30p)0r8|L~<-yvW$H<9Px%GWO<5b#t>3N)|q(`qLd~39wwBO zNS3VG#+D{a#4trnwkD0`;dvk5xA)=x?z#7z`}N+%I$};j;ZOhoPTJX8IUl>(zk+~| zSxpR`0{~DE(b5u2^z{V*rL?d#WBYEbM1pLfb(Ivqv=vgzKh)n`qQ{BNbS}s7wPz_h zxTBt->_kH)J(0Zp@83P|q?FV!tK}fca*Iprlc&W-8!S>7h~Sa#=#6M}Bu{B(kVM<2 zl7#)+{9N0B`kNeg&Uw);E8>|f9V3Ejq2t!ZUQ>nn$Nc!!?W4Bl8XZCuSo;-37?H{r zplg@A#9+26uhX3Rm*R!vS+#;nF;%3tuHTb6lH`lu9SOat@~D7a_(b58Qj_%pd10>1 zOP9Rt)s()6ue+6N(LW@55U>VS zFNdnEZ24rO|Og`6xWMn*d6g}V8f;f~_l7QZ^D8>HQT2cO58LD)j7E{TcVJV09 z&bP5F`aMI@pk7kllwTktj?U~@s3Eu6$V zil7AWoEDwX^VzfK_(gbxFD6dD1$Bfp0=7Ad@|9Jw{Gh}H(un@5kXzOnj~})%^MpnX zhjZD!$5eh~ag-fshp2PP1C>y|D8AibEpgo5AUPZkWFABDb5z&;WcMKiX-GRr3XjVK z4fIy__79h==uO>3!o|fEfE)T^m3Mi1vJ;Xhza%x~$r|m6o)g7^bcf%l2Y3PLO(S6g zG8dV6QM2#>pF-cexw7XB#wkDQ2=h9Z8Y@gS(Z3rs12pX#RpFAEo4cNBvv`#>NJ3&_ zG~S|x{G%65^NDI&(JfjQHH|scgW-t^VxV;Oh^p)oc5_5gA7fiZ0#iTLc%PUDrxNq> zf@Y561+Vto%aKjBGatczY#65gxMHxw2EV=pW6xzbM77BrP6oxUj4~JvVz`&x1VAg9NIN$zHh|66l<5!bH;UJG3@AA?c!hCl`MxkY1?hL1ri>u)vj zy3fT>$J4T#tDg!Z`B1#%`gcXFx;GjE9fPZI!&G`dthn7JC3Eau1%D^iwyv?cOO~d- zx%fVoSt8Kdg658gDQ4)W4ZnV&s#9roeA1K|#8AUgLymYG(k>wHFnOh&X@OffVwv3W@GEQ`~D7f^wX-{qr zlYdN=ZqR70cp!A0v%4AfSX&$qGMH8xj;FB{BDTIAriB^y88*lylFZ5qd3H+N%0qK_ zrkY*NARy$=Wmg%~rN^A*ij-UQ!$XsHlgO^K*|iD29$cs(+1Tboh{(|zj2uFMDd_*= zef40h&W{*u@?c~Cs*oAvFBTeLEUk|bPC-ylaLUHRkWO50!<6pxo4E z74bdYUj~nNg`d1JuEpk~oVp;xArP+SlIP^t^@vpWXJC=kZTMtZl}io42+&ziUG91j j9^TowreTDd89x&6eY%8&L5xO@e;Tl}cC@OsxN`d+GJ(20 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/meta.json b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/meta.json index 3aa61e31c5a..7c3599192c9 100644 --- a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/meta.json +++ b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC0-1.0", - "copyright": "Created by EmoGarbage404", + "copyright": "Created by EmoGarbage404. Vox states made by Flareguy, modified from magboots.rsi", "size": { "x": 32, "y": 32 @@ -15,6 +15,14 @@ "name": "on-equipped-FEET", "directions": 4 }, + { + "name": "equipped-FEET-vox", + "directions": 4 + }, + { + "name": "on-equipped-FEET-vox", + "directions": 4 + }, { "name": "icon" }, diff --git a/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-equipped-FEET-vox.png b/Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/on-equipped-FEET-vox.png new file mode 100644 index 0000000000000000000000000000000000000000..66ae1ee7e843910fe716687d850b1bc9a1914684 GIT binary patch literal 1491 zcma)+Z9EeQ0LHhrwxw&N72(Rub*)-UjFi;O$V)avWwn+{Ha3?_BV(H;u6BwXYUJ%~ z8Z`_lugkn;g_4*1DK@)HXR^>j6X!nOxBKus&+qsD@O*lH&kaAqk#z=U1^@tHotGy* zU?s8t3Ibp#?uyH=&QE!XPkmEWvM0XrsdfCsX=Swo*Eqgjd^6ZoTX(s zT?G~X#y~WFLLz*ca_)JCS6!YZ&DyVT!PB;7IUEc_-6u?IzdjMV_U9x`=$0Gn${fPt zAed^Hq4_P%S_P)~c>IxR(WMgq&i6@%NovV=$arydV+--->_+ynNkUk=RdHPSg4saC z5b}w;ime(cB0I9j{VA_6W?d8&GZj?_XtAUfz+wsWreYTQ8YSt09`v0w{NSz{=uRYmNA9Wvx8H88WS%7#GQ z9v^~@w&gSfJDD@4&JA?ap-~vZ)(WJM#B$CtfYR=C+2e1&Uepb zP@-4Yvy3wIANiw0MqzVrANbAz0AMRGylY@=?ni+ub@;eNJIBl%FMT0R-(l4&3avSe)(QQ{epOgsRfHs1~X5byDod1zvWH7VQ=eFr2D^0E#Z zbwu4gdOO2gxZ-`Iqqi6L3>wg7B<3n^ccH@Rmc0A4F`2m6-k#T|wQRO6*=Wuvo(P2B zSGyFwH0tCwb=9@@hSp954mtWRO*Rr(d$2dZ@PqRJ+Pfh9VZE_?>cDtyTGfoC+OKW( zP}x8laQJbdDrOi%J9gnqsY7>HeWC^$2SpgHj@gj_a!-9N>WnVGCAH56pAAEM%}pQ~ z`kwKCuaN7wLZOz6D^yB)2&;NUol7DY`ml(xyg4T<$BcIL{qx~Yi6N#J z>^85l%y{mZ9AfK`dv@~me)@2`^kIPxr0UN%BdoB3)94JvUq5h9qqk=&LYGNZIuHl4 z98vw*exBoDYV?>}u^y7N+mfCH3|R{^55W$tYWcr7XK;k;#^NnF$Gr3W%s33aWEXWk z#$jDh`d;5z;ZfPeux1uwfon1t`C=DUkbLY>B|{LqyShynnkU%gHh!2R%);VkW2WlJ zB&foNzZf-%>6z*Q>Cm5!v%fxFo{nAgbkr7V>h#1bz>x#?ova*1?$QS}HYWuDiDgvg zGgID9_4|h>fGiHb0=*f2Rg)hk)~%Z_8Jqq+Ra95?vSMW|9mLP`F{jQvObnK(k;4VZKC-jAe3`WOb?PRFa|1C2WfV z7+sGnt+Ud#$szNq8wI<+H3NClaq_Rar_WZ-8sOzlz)Nsvul)l>y3CmX literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/vox_parts.rsi/tail_stenciled.png b/Resources/Textures/Mobs/Customization/vox_parts.rsi/tail_stenciled.png index 50627ac5220bfbc37e5b6f6516b5acacd1d75165..9072c9f4fc3184e3fda883e612f655c2a80f2a9a 100644 GIT binary patch delta 270 zcmV+p0rCFl1gQd$B!2;OQb$4nuFf3k0002vNkl;{Sm|aNRg6DWLu6L2><{90B}Fue+RIanfdmdQo39YhnbnT z)_m)=ARo)j+}*vD;;l6=rL6liMR@#VkiV_gst|&5&XS}Uqkkl6nkGr|BhTRy1u!!o zhCz~)b6(%QnR(y$r|$kbAKu@HF}@`qV^j!1wbr#8_PR^~B)ugsN%K4_gmC!IOBLYN zw*AL({Oob~oC4ePt){@z{=Td(rPST#53sc)eZRy30000000000000000NC#vunKoz URl)?F00000Ne4wvM6N<$fv<0QU!csPxvAmcDTOUXf&~Kv6)Jc?DUN+YReSs@BPmc_}qI@fKd<)RoF8{ zW=%T1Dd*1&{&wdgDL3QxAGhCL`%$mVV)X0q^E#!Lq?q;L?2N|o{*50j%OBR&goe&M znv{6%`R3?2z3F-P-hZDl%kZ`$C&P&kWxGq06z4f@+!wcA{pp9~OE>E)j5f)39hcH# zntCv+!gNUrgTsvZm0Wc;a(stwOcZGdSQ7tl_uY5(_xUQt6|+HD#lgSovgIG|I_LQRbkvJ&7pl{hox0dq z=Bj)X2?$=X^fTK>HlE`)=Z$S%?J8UM`fuI)(zv(xrA@SsoHI#s(0SM(c7%`jf>Uh7 zcg2$E2lXXZrV9^tm`Y5TefC)7M!?)?pf0ILJEFWLAXABJxX%*&{C_8s+ z=Dr%?olHjhW=F1k_))ZThTQExo{tw?Vr6kSSjM4vW3T9DcaEOF&yUTp`grEogn5mQ z3@aumM5uma3Org}So&LDzl~$Q>jN$)78eI7N)r0PB+chhU)FT(3j+{%y85}Sb4q9e E04!bnCIA2c diff --git a/Resources/Textures/Mobs/Species/Vox/displacement.rsi/back.png b/Resources/Textures/Mobs/Species/Vox/displacement.rsi/back.png new file mode 100644 index 0000000000000000000000000000000000000000..c300bba8a5ba9240ca02cb3fa28f619b4ba32b21 GIT binary patch literal 451 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zYdu{YLn`LH zofTblM1hB;J;d(_t8V;-a3y)q+@)oInN)8}tlpn$+>`34IB8~A-Whh?1~r}qtQT4s zw=m2yXb^J{X1l)r*<29M!r;7W}Y{naeg}Ugvu9*ch z7}rkTap;MvW~}RrdO=g{mL)QvxM+de51;CuB}+}i=Q3{Ay*ux-KkuzS=}oHMoLQZJ z58l`(b>VQ~s$l1-jQW4~o#V-P>28*KAbA1Hvi)Cd%TDq8>aLealKf(l5dNM$N4IqH z$}fAkJTB!_em#C?*KPwBwu%DDgwK literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Species/Vox/displacement.rsi/eyes.png b/Resources/Textures/Mobs/Species/Vox/displacement.rsi/eyes.png new file mode 100644 index 0000000000000000000000000000000000000000..f705c337de1c2fa90af22b5c1eb2f18d90396897 GIT binary patch literal 508 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zw|TlahE&XX zJ1aWxkb!{f`zduB=IKmODXEY1XXU!wujJ7reZ2omQfl83{|R$mKi=5LbE!1o%?$oB z2D9DbA5QWKIBluidF`9uv+KXMRo*yqqSPj=g&ux2! z<5hJgZe{)QZ`R~3BCR_V*RA=ytzpU3yVetR9Ntf!eoA%CJ*LgIwllYM2w&Z?cf06D z?Wi}w4o7U`q6MuUB=I{a#2)zLmcQ|rrpL2yKK5l<)z*1IJi4 zFmEtqe8Z6A!(h!IjZdgEtFP?t7UdEy6D2){zL~v~7MtzR*;D_iq$gSKYknA`>ip^Y zrt;@G?=Cob!*Cm0ZrJvHq6b7%wH|bRbz(grPzopr00vCgx&QzG literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Species/Vox/displacement.rsi/hand.png b/Resources/Textures/Mobs/Species/Vox/displacement.rsi/hand.png new file mode 100644 index 0000000000000000000000000000000000000000..4a0266dfd3733b7288b6690a682aa7dd518bed73 GIT binary patch literal 483 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%z=X$z0hE&XX zJKHetumO*&{mXeC!F*3vF2A5@_0(Zz$>K?}O^epWDlTjKA#NalL37&AUjo(*Q$5xe z%#ldt-f)s3htW*3LHB?f^9I%%DGb{fX7d~nOPI`fgDJ;|A-chrt)imgUV_) z{KG-+=jtU6ylL{3W=XxyDa$(l)`GH|r8d?7Ug|e)zsD_Xm%!$*-dVj&S7zsIb^e7)z-;Wa;({}(wy(4h(FzTsglkiE0EQqkyz2)_dBqlOdz zJ0Ao+;7d55DRw|Jpq6{Pwi9{li zNF)-8N9guc+%906+)<0C&ACOOz6i(si9Voleg9vMgN`G);r9>w>pIPy|fVgu~&0X_`PO zU5)$Sdt+t$TYtgVCxjpe_zL*OQc73hxHr=@xd^cGpGMbp=6pUIt+o4{&u0@8ezEe6 zF;1@4C02e=4gfy9z1{1}vOMiBR8_T#02}^QRYk2A>;M2@j5&iTrC^Lj36J4;Jc3f{ z5~1CC$Kx?-y&wm0&JAM><2bGo-#Ct7j71kCAzUsO0Dri73fS>bf+N6s+$O$lM&6rc zS#Y^rT#6}H!)6#iU8o_4iG{hrF6~G)9Dn| zqJ9+H9=F|TDWyA~5KFKF+P2Mn4%~E zJl6@<_@XGFl=^huBetv@&~=@8eSLM;_T&cuvw!`gJsn~r!JE4~lu``Cu+m}c2)kVX zU>JtgxNplZ{|8DbUS3`@;Ll@@5OVj<3L(%mjf(`O6sBpq8!g|(ziS&`A3_L(5H~v7 zZL&SQ#W^>=6P&V~bF890A-`f@V8rt1kaYoc|5{ zNr+9;Aj`5{BfuDAgb=Xj6|MYxx_wfeu58>s25*#a+cuL@LMe4uP@dKE8w-@d)^S-aHPrl027OO!tpcR&y>wyiKUhYU*?W>at-p^_xJIVMMpxXPU2Bv zKIvdI0YQ~Y+<05Iz5k2d>h+hGyQlArsq3i!ANhClzWehuZ+vg~Qnh#0-MsL-dEf7S ztFXCu?s;*kh0Lm#C9hsxZtmBM`2BaE$?NaGpL)*xe{I>WzyH>)?uc7`RqK_7_HxDM zPhYF{?*IPf<<;1=VOJ9jH2AtXel4(5+HcdVH{H9i#6o6TnnnMLGrz-6C2ibsHf{6n z&l47C%!|V;(zdm{Yll^eAy;7rYJ~yV55G_=cze8v0mbN z;~ZhLQj=wuGYwP&bH1bjUrFRt1=0u1D8&mZrgS7 z^9pgV2@8aaiafjnRSbk&4%XQ5*GJ8_{J8%8Y}MI~2d2GXXi;KtkNhCu%9P^LTk&j1 zEk9dC*^`Z`R;E|i|dR1_DPG>fh0%xYGi zrAH$FxM<{Ma24>b3w*x+(i0`+2c|I+2~BH{Zdkdxa{bgTe~DWM4fCLDpr From ba2c5fcdedfcbc0b3cfe0d6a1a19e6547bb3adae Mon Sep 17 00:00:00 2001 From: Winkarst <74284083+Winkarst-cpu@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:50:24 +0300 Subject: [PATCH 037/134] Make the super door remote to be able to control Syndicate doors (#30033) * Make the super door remote to be able to control Syndicate doors * Fix --- Resources/Prototypes/Entities/Objects/Devices/door_remote.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Resources/Prototypes/Entities/Objects/Devices/door_remote.yml b/Resources/Prototypes/Entities/Objects/Devices/door_remote.yml index a368ec2b65d..623efa72769 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/door_remote.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/door_remote.yml @@ -160,3 +160,5 @@ - AllAccess tags: - CentralCommand + - NuclearOperative + - SyndicateAgent From be9acaea356bb50751ad2ccad3f468dabd0748b5 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 17 Jul 2024 13:51:32 +0000 Subject: [PATCH 038/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index ec85d771e3a..fd909d6b12f 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: pigeonpeas - changes: - - message: Adds the ability to purchase emitters in cargo. - type: Add - id: 6428 - time: '2024-04-23T11:34:09.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27229 - author: EmoGarbage404 changes: - message: Fixed cargo telepads not teleporting in orders from linked consoles. @@ -3804,3 +3797,10 @@ id: 6927 time: '2024-07-17T06:26:10.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29995 +- author: Winkarst-cpu + changes: + - message: The super door remote is now able to control Syndicate doors. + type: Fix + id: 6928 + time: '2024-07-17T13:50:25.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30033 From 6f5077803bf4df81c0d56d99e30effe31270c35d Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Wed, 17 Jul 2024 20:25:19 +0200 Subject: [PATCH 039/134] Fix formatting warnings (#30122) --- Content.Server/Botany/Components/SeedComponent.cs | 2 +- Content.Server/Botany/Systems/MutationSystem.cs | 8 ++++---- Content.Server/Botany/Systems/SeedExtractorSystem.cs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Content.Server/Botany/Components/SeedComponent.cs b/Content.Server/Botany/Components/SeedComponent.cs index f475ec3cfc4..ffa1b7ef4e9 100644 --- a/Content.Server/Botany/Components/SeedComponent.cs +++ b/Content.Server/Botany/Components/SeedComponent.cs @@ -24,7 +24,7 @@ public sealed partial class SeedComponent : SharedSeedComponent /// /// Name of a base seed prototype that is used if is null. /// - [DataField("seedId", customTypeSerializer:typeof(PrototypeIdSerializer))] + [DataField("seedId", customTypeSerializer: typeof(PrototypeIdSerializer))] public string? SeedId; } } diff --git a/Content.Server/Botany/Systems/MutationSystem.cs b/Content.Server/Botany/Systems/MutationSystem.cs index c7ce5d47efa..474859823a3 100644 --- a/Content.Server/Botany/Systems/MutationSystem.cs +++ b/Content.Server/Botany/Systems/MutationSystem.cs @@ -2,10 +2,8 @@ using Robust.Shared.Random; using Content.Shared.Random; using Content.Shared.Random.Helpers; -using Content.Shared.Chemistry.Reagent; using System.Linq; using Content.Shared.Atmos; -using FastAccessors; namespace Content.Server.Botany; @@ -42,6 +40,7 @@ public void MutateSeed(ref SeedData seed, float severity) // Add up everything in the bits column and put the number here. const int totalbits = 275; + #pragma warning disable IDE0055 // disable formatting warnings because this looks more readable // Tolerances (55) MutateFloat(ref seed.NutrientConsumption , 0.05f, 1.2f, 5, totalbits, severity); MutateFloat(ref seed.WaterConsumption , 3f , 9f , 5, totalbits, severity); @@ -75,6 +74,7 @@ public void MutateSeed(ref SeedData seed, float severity) MutateBool(ref seed.TurnIntoKudzu , true , 10, totalbits, severity); MutateBool(ref seed.CanScream , true , 10, totalbits, severity); seed.BioluminescentColor = RandomColor(seed.BioluminescentColor, 10, totalbits, severity); + #pragma warning restore IDE0055 // ConstantUpgade (10) MutateHarvestType(ref seed.HarvestRepeat, 10, totalbits, severity); @@ -261,7 +261,7 @@ private void MutateChemicals(ref Dictionary chemicals, { var pick = _randomChems.Pick(_robustRandom); string chemicalId = pick.reagent; - int amount = _robustRandom.Next(1, ((int)pick.quantity)); + int amount = _robustRandom.Next(1, (int)pick.quantity); SeedChemQuantity seedChemQuantity = new SeedChemQuantity(); if (chemicals.ContainsKey(chemicalId)) { @@ -274,7 +274,7 @@ private void MutateChemicals(ref Dictionary chemicals, seedChemQuantity.Max = 1 + amount; seedChemQuantity.Inherent = false; } - int potencyDivisor = (int) Math.Ceiling(100.0f / seedChemQuantity.Max); + int potencyDivisor = (int)Math.Ceiling(100.0f / seedChemQuantity.Max); seedChemQuantity.PotencyDivisor = potencyDivisor; chemicals[chemicalId] = seedChemQuantity; } diff --git a/Content.Server/Botany/Systems/SeedExtractorSystem.cs b/Content.Server/Botany/Systems/SeedExtractorSystem.cs index f1ae6c9f11a..9a5e70762e7 100644 --- a/Content.Server/Botany/Systems/SeedExtractorSystem.cs +++ b/Content.Server/Botany/Systems/SeedExtractorSystem.cs @@ -29,12 +29,12 @@ private void OnInteractUsing(EntityUid uid, SeedExtractorComponent seedExtractor return; if (!_botanySystem.TryGetSeed(produce, out var seed) || seed.Seedless) { - _popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-no-seeds",("name", args.Used)), + _popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-no-seeds", ("name", args.Used)), args.User, PopupType.MediumCaution); return; } - _popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-interact-message",("name", args.Used)), + _popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-interact-message", ("name", args.Used)), args.User, PopupType.Medium); QueueDel(args.Used); From ef02f8c18cb1c5423c9d7bae3aea5b1fa6ac2b86 Mon Sep 17 00:00:00 2001 From: Errant <35878406+Errant-4@users.noreply.github.com> Date: Thu, 18 Jul 2024 00:04:51 +0200 Subject: [PATCH 040/134] Temporarily remove Vox from space ninja and Unknown Shuttle ghostroles (#30099) * no vox ninjas * blacklist vox from UnknownShuttleEvent --- Resources/Prototypes/Entities/Mobs/Player/humanoid.yml | 10 ++++++++++ Resources/Prototypes/GameRules/events.yml | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml b/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml index 5bcc33b5f6d..47baca61347 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml @@ -607,6 +607,8 @@ - type: randomHumanoidSettings id: LostCargoTechnician parent: EventHumanoid + speciesBlacklist: + - Vox components: - type: GhostRole name: ghost-role-information-lost-cargo-technical-name @@ -658,6 +660,8 @@ id: ClownTroupe parent: EventHumanoid randomizeName: false + speciesBlacklist: + - Vox components: - type: GhostRole name: ghost-role-information-clown-troupe-name @@ -708,6 +712,8 @@ - type: randomHumanoidSettings id: TravelingChef parent: EventHumanoid + speciesBlacklist: + - Vox components: - type: GhostRole name: ghost-role-information-traveling-chef-name @@ -768,6 +774,8 @@ - type: randomHumanoidSettings id: DisasterVictimHead parent: EventHumanoidMindShielded + speciesBlacklist: + - Vox components: - type: GhostRole name: ghost-role-information-disaster-victim-name @@ -826,6 +834,8 @@ - type: randomHumanoidSettings id: SyndieDisasterVictim parent: EventHumanoid + speciesBlacklist: + - Vox components: - type: NpcFactionMember factions: diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index 0b183039a99..7784b725564 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -151,6 +151,10 @@ minimumPlayers: 30 - type: SpaceSpawnRule - type: AntagLoadProfileRule + # Vox disabled until loadouts work on AntagSelection-based spawns + speciesOverride: Human + speciesOverrideBlacklist: + - Vox - type: AntagObjectives objectives: - StealResearchObjective From 2d5bb92f463d964c096904af64c7e442be4aaeed Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 17 Jul 2024 22:05:58 +0000 Subject: [PATCH 041/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index fd909d6b12f..99fa3976e32 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: EmoGarbage404 - changes: - - message: Fixed cargo telepads not teleporting in orders from linked consoles. - type: Fix - id: 6429 - time: '2024-04-23T12:07:12.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27255 - author: Plykiya changes: - message: Do-after bars of other players are now shaded and harder to see in the @@ -3804,3 +3797,11 @@ id: 6928 time: '2024-07-17T13:50:25.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30033 +- author: Errant + changes: + - message: Vox are temporarily removed from Space Ninjas and all Unknown Shuttle + ghostroles, until code supports giving them species-specific gear. + type: Tweak + id: 6929 + time: '2024-07-17T22:04:51.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30099 From e1f429b6b3a7759587d26a99e741d66e37a32add Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Thu, 18 Jul 2024 01:37:03 +0300 Subject: [PATCH 042/134] DungeonSystem.Rooms bugfix (#30125) Update DungeonSystem.Rooms.cs --- Content.Server/Procedural/DungeonSystem.Rooms.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Procedural/DungeonSystem.Rooms.cs b/Content.Server/Procedural/DungeonSystem.Rooms.cs index 8a1606c4889..20d64acff15 100644 --- a/Content.Server/Procedural/DungeonSystem.Rooms.cs +++ b/Content.Server/Procedural/DungeonSystem.Rooms.cs @@ -118,7 +118,7 @@ public void SpawnRoom( // go BRRNNTTT on existing stuff if (clearExisting) { - var gridBounds = new Box2(Vector2.Transform(Vector2.Zero, roomTransform), Vector2.Transform(room.Size, roomTransform)); + var gridBounds = new Box2(Vector2.Transform(-room.Size/2, roomTransform), Vector2.Transform(room.Size/2, roomTransform)); _entitySet.Clear(); // Polygon skin moment gridBounds = gridBounds.Enlarged(-0.05f); From c7ea0490a67ec503f36e2ddeedb93a45dc914ce9 Mon Sep 17 00:00:00 2001 From: kbailey-git <84491830+kbailey-git@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:54:08 -0700 Subject: [PATCH 043/134] Updated slime storage capacity text in guidebook (#30121) --- Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml b/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml index 0374d4cb958..2c11508749e 100644 --- a/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml +++ b/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml @@ -18,7 +18,7 @@ - Slimepeople have an [bold]internal 2x2 storage inventory[/bold] inside of their slime membrane. Anyone can see what's inside and take it out of you without asking, + Slimepeople have an [bold]internal 2x3 storage inventory[/bold] inside of their slime membrane. Anyone can see what's inside and take it out of you without asking, so be careful. They [bold]don't drop their internal storage when they morph into a geras, however![/bold] Slimepeople have slight accelerated regeneration compared to other humanoids. They're also capable of hardening their fists, and as such have stronger punches, From 95b56ad4ce8cd9f1be995c5d9a02a612e5434316 Mon Sep 17 00:00:00 2001 From: Cojoke <83733158+Cojoke-dot@users.noreply.github.com> Date: Wed, 17 Jul 2024 19:40:54 -0500 Subject: [PATCH 044/134] Prevent Quantum Spin Inverter from Teleporting Things into Microwaves (#29200) * Prevent Quantum Spin Inverter from Teleporting Things into Microwaves * Simplifies code, GetTeleportingEntity instead of TryGet, adds failed teleport message * remove using Linguini.Syntax.Ast; * capital... * re-add CanInsert and Fixes microwave issue * beb * beeb --- .../Kitchen/EntitySystems/MicrowaveSystem.cs | 27 +++++++++++++++++++ .../Systems/SwapTeleporterSystem.cs | 23 +++++++++++----- .../Locale/en-US/portal/swap-teleporter.ftl | 1 + 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs index eefa539149b..71986ae859e 100644 --- a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs @@ -79,6 +79,7 @@ public override void Initialize() SubscribeLocalEvent(OnContentUpdate); SubscribeLocalEvent(OnContentUpdate); SubscribeLocalEvent(OnInteractUsing, after: new[] { typeof(AnchorableSystem) }); + SubscribeLocalEvent(OnInsertAttempt); SubscribeLocalEvent(OnBreak); SubscribeLocalEvent(OnPowerChanged); SubscribeLocalEvent(OnAnchorChanged); @@ -309,6 +310,32 @@ private void OnContentUpdate(EntityUid uid, MicrowaveComponent component, Contai UpdateUserInterfaceState(uid, component); } + private void OnInsertAttempt(Entity ent, ref ContainerIsInsertingAttemptEvent args) + { + if (ent.Comp.Broken) + { + args.Cancel(); + return; + } + + if (TryComp(args.EntityUid, out var item)) + { + if (_item.GetSizePrototype(item.Size) > _item.GetSizePrototype(ent.Comp.MaxItemSize)) + { + args.Cancel(); + return; + } + } + else + { + args.Cancel(); + return; + } + + if (ent.Comp.Storage.Count >= ent.Comp.Capacity) + args.Cancel(); + } + private void OnInteractUsing(Entity ent, ref InteractUsingEvent args) { if (args.Handled) diff --git a/Content.Shared/Teleportation/Systems/SwapTeleporterSystem.cs b/Content.Shared/Teleportation/Systems/SwapTeleporterSystem.cs index 58c249fec54..a5ad77d43bf 100644 --- a/Content.Shared/Teleportation/Systems/SwapTeleporterSystem.cs +++ b/Content.Shared/Teleportation/Systems/SwapTeleporterSystem.cs @@ -150,8 +150,19 @@ public void DoTeleport(Entity ent) return; } - var teleEnt = GetTeleportingEntity((uid, xform)); - var otherTeleEnt = GetTeleportingEntity((linkedEnt, Transform(linkedEnt))); + var (teleEnt, cont) = GetTeleportingEntity((uid, xform)); + var (otherTeleEnt, otherCont) = GetTeleportingEntity((linkedEnt, Transform(linkedEnt))); + + if (otherCont != null && !_container.CanInsert(teleEnt, otherCont) || + cont != null && !_container.CanInsert(otherTeleEnt, cont)) + { + _popup.PopupEntity(Loc.GetString("swap-teleporter-popup-teleport-fail", + ("entity", Identity.Entity(linkedEnt, EntityManager))), + teleEnt, + teleEnt, + PopupType.MediumCaution); + return; + } _popup.PopupEntity(Loc.GetString("swap-teleporter-popup-teleport-other", ("entity", Identity.Entity(linkedEnt, EntityManager))), @@ -184,20 +195,20 @@ public void DestroyLink(Entity ent, EntityUid? user) DestroyLink(linked, user); // the linked one is shown globally } - private EntityUid GetTeleportingEntity(Entity ent) + private (EntityUid, BaseContainer?) GetTeleportingEntity(Entity ent) { var parent = ent.Comp.ParentUid; if (_container.TryGetOuterContainer(ent, ent, out var container)) parent = container.Owner; if (HasComp(parent) || HasComp(parent)) - return ent; + return (ent, container); if (!_xformQuery.TryGetComponent(parent, out var parentXform) || parentXform.Anchored) - return ent; + return (ent, container); if (!TryComp(parent, out var body) || body.BodyType == BodyType.Static) - return ent; + return (ent, container); return GetTeleportingEntity((parent, parentXform)); } diff --git a/Resources/Locale/en-US/portal/swap-teleporter.ftl b/Resources/Locale/en-US/portal/swap-teleporter.ftl index f13fa9be423..0040ad0a88b 100644 --- a/Resources/Locale/en-US/portal/swap-teleporter.ftl +++ b/Resources/Locale/en-US/portal/swap-teleporter.ftl @@ -5,6 +5,7 @@ swap-teleporter-popup-link-destroyed = Quantum link destroyed! swap-teleporter-popup-teleport-cancel-time = It's still recharging! swap-teleporter-popup-teleport-cancel-link = It's not linked with another device! swap-teleporter-popup-teleport-other = {CAPITALIZE(THE($entity))} activates, and you find yourself somewhere else. +swap-teleporter-popup-teleport-fail = {CAPITALIZE(THE($entity))} activates and fails to transport you anywhere. swap-teleporter-verb-destroy-link = Destroy Quantum Link From 3f014e84ebf3dd860ec3595ad59f580fcff3b852 Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Thu, 18 Jul 2024 02:41:15 +0200 Subject: [PATCH 045/134] minor SharedInteractionSystem cleanup (#30139) cleanup SharedInteractionSystem --- Content.Shared/Interaction/SharedInteractionSystem.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 48076ca360f..c32b4bcf780 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -38,8 +38,6 @@ using Robust.Shared.Timing; using Robust.Shared.Utility; -#pragma warning disable 618 - namespace Content.Shared.Interaction { /// @@ -522,11 +520,11 @@ public void InteractUsingRanged(EntityUid user, EntityUid used, EntityUid? targe protected bool ValidateInteractAndFace(EntityUid user, EntityCoordinates coordinates) { // Verify user is on the same map as the entity they clicked on - if (coordinates.GetMapId(EntityManager) != Transform(user).MapID) + if (_transform.GetMapId(coordinates) != Transform(user).MapID) return false; if (!HasComp(user)) - _rotateToFaceSystem.TryFaceCoordinates(user, coordinates.ToMapPos(EntityManager, _transform)); + _rotateToFaceSystem.TryFaceCoordinates(user, _transform.ToMapCoordinates(coordinates).Position); return true; } @@ -859,7 +857,7 @@ public bool InRangeUnobstructed( Ignored? predicate = null, bool popup = false) { - return InRangeUnobstructed(origin, other.ToMap(EntityManager, _transform), range, collisionMask, predicate, popup); + return InRangeUnobstructed(origin, _transform.ToMapCoordinates(other), range, collisionMask, predicate, popup); } /// @@ -966,7 +964,7 @@ public void InteractUsing( /// public void InteractDoAfter(EntityUid user, EntityUid used, EntityUid? target, EntityCoordinates clickLocation, bool canReach) { - if (target is {Valid: false}) + if (target is { Valid: false }) target = null; var afterInteractEvent = new AfterInteractEvent(user, used, target, clickLocation, canReach); From d7b2e728821697210a8d67ec0464dba642c0ff3c Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 18 Jul 2024 00:42:02 +0000 Subject: [PATCH 046/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 99fa3976e32..c768ac40e77 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Plykiya - changes: - - message: Do-after bars of other players are now shaded and harder to see in the - dark. - type: Tweak - id: 6430 - time: '2024-04-24T02:42:34.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27273 - author: Blackern5000 changes: - message: The cargo telepad is now tier 2 technology rather than tier 3. @@ -3805,3 +3797,11 @@ id: 6929 time: '2024-07-17T22:04:51.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30099 +- author: Cojoke-dot + changes: + - message: You can no longer teleport objects that should not be in other objects + into other objects with the Quantum Spin Inverter + type: Fix + id: 6930 + time: '2024-07-18T00:40:54.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29200 From 961a553fa2e335bfb7edbf7c4dd2214aa68c2014 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:48:08 -0700 Subject: [PATCH 047/134] Fix stun batons using excess charges when thrown (#30136) Fix stun batons Co-authored-by: plykiya --- Content.Shared/Damage/Systems/StaminaSystem.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Content.Shared/Damage/Systems/StaminaSystem.cs b/Content.Shared/Damage/Systems/StaminaSystem.cs index 1f9a7f1dd84..a5c8a4b38de 100644 --- a/Content.Shared/Damage/Systems/StaminaSystem.cs +++ b/Content.Shared/Damage/Systems/StaminaSystem.cs @@ -192,6 +192,11 @@ private void OnThrowHit(EntityUid uid, StaminaDamageOnCollideComponent component private void OnCollide(EntityUid uid, StaminaDamageOnCollideComponent component, EntityUid target) { + // you can't inflict stamina damage on things with no stamina component + // this prevents stun batons from using up charges when throwing it at lockers or lights + if (!HasComp(target)) + return; + var ev = new StaminaDamageOnHitAttemptEvent(); RaiseLocalEvent(uid, ref ev); if (ev.Cancelled) From 58a2a4c932dfa5593221de1d315470fc4ffa8976 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 18 Jul 2024 00:49:15 +0000 Subject: [PATCH 048/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index c768ac40e77..2ba6a098e0e 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Blackern5000 - changes: - - message: The cargo telepad is now tier 2 technology rather than tier 3. - type: Tweak - id: 6431 - time: '2024-04-24T13:21:29.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/26270 - author: FungiFellow changes: - message: Truncheon now fits in SecBelt @@ -3805,3 +3798,10 @@ id: 6930 time: '2024-07-18T00:40:54.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29200 +- author: Plykiya + changes: + - message: Stun batons no longer use up charges when hitting objects without stamina. + type: Fix + id: 6931 + time: '2024-07-18T00:48:09.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30136 From 73111b5170d76cfe2df0e5c21e1b6e923ec214ec Mon Sep 17 00:00:00 2001 From: Brandon Hu <103440971+Brandon-Huu@users.noreply.github.com> Date: Thu, 18 Jul 2024 07:17:57 +0000 Subject: [PATCH 049/134] fix(dev_map): resave dev map (#30098) fix(dev_map): Resave devmap Co-authored-by: 4llv07e --- Resources/Maps/Test/dev_map.yml | 121 +++----------------------------- 1 file changed, 10 insertions(+), 111 deletions(-) diff --git a/Resources/Maps/Test/dev_map.yml b/Resources/Maps/Test/dev_map.yml index ca885d584bd..520a4da5ae7 100644 --- a/Resources/Maps/Test/dev_map.yml +++ b/Resources/Maps/Test/dev_map.yml @@ -385,11 +385,11 @@ entities: - type: Transform - type: Map - type: PhysicsMap + - type: GridTree + - type: MovedGrids - type: Broadphase - type: OccluderTree - type: LoadedMap - - type: GridTree - - type: MovedGrids - proto: AirAlarm entities: - uid: 800 @@ -401,8 +401,6 @@ entities: - type: DeviceList devices: - 801 - - type: AtmosDevice - joinedGrid: 179 - proto: AirCanister entities: - uid: 458 @@ -410,8 +408,6 @@ entities: - type: Transform pos: 7.5,-0.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: Airlock entities: - uid: 48 @@ -901,33 +897,21 @@ entities: - type: Transform pos: -2.5,-14.5 parent: 179 - - type: DeviceLinkSink - links: - - 1013 - uid: 697 components: - type: Transform pos: 1.5,-14.5 parent: 179 - - type: DeviceLinkSink - links: - - 1014 - uid: 698 components: - type: Transform pos: 1.5,-16.5 parent: 179 - - type: DeviceLinkSink - links: - - 1014 - uid: 984 components: - type: Transform pos: -2.5,-16.5 parent: 179 - - type: DeviceLinkSink - links: - - 1013 - proto: BoozeDispenser entities: - uid: 752 @@ -2660,13 +2644,6 @@ entities: - type: Transform pos: 24.5,5.5 parent: 179 -- proto: chem_master - entities: - - uid: 311 - components: - - type: Transform - pos: 8.5,11.5 - parent: 179 - proto: ChemDispenser entities: - uid: 583 @@ -2704,6 +2681,13 @@ entities: - type: Transform pos: 6.4651074,9.828774 parent: 179 +- proto: ChemMaster + entities: + - uid: 311 + components: + - type: Transform + pos: 8.5,11.5 + parent: 179 - proto: ChemMasterMachineCircuitboard entities: - uid: 718 @@ -3031,27 +3015,18 @@ entities: - type: Transform pos: -2.5,-15.5 parent: 179 - - type: DeviceLinkSink - links: - - 699 - uid: 259 components: - type: Transform rot: 3.141592653589793 rad pos: 1.5,-14.5 parent: 179 - - type: DeviceLinkSink - links: - - 983 - uid: 463 components: - type: Transform rot: 3.141592653589793 rad pos: 1.5,-16.5 parent: 179 - - type: DeviceLinkSink - links: - - 983 - uid: 677 components: - type: Transform @@ -3063,61 +3038,40 @@ entities: rot: -1.5707963267948966 rad pos: -1.5,11.5 parent: 179 - - type: DeviceLinkSink - links: - - 722 - uid: 720 components: - type: Transform rot: -1.5707963267948966 rad pos: -0.5,11.5 parent: 179 - - type: DeviceLinkSink - links: - - 722 - uid: 721 components: - type: Transform rot: -1.5707963267948966 rad pos: 0.5,11.5 parent: 179 - - type: DeviceLinkSink - links: - - 722 - uid: 985 components: - type: Transform rot: 3.141592653589793 rad pos: 1.5,-13.5 parent: 179 - - type: DeviceLinkSink - links: - - 983 - uid: 989 components: - type: Transform rot: 3.141592653589793 rad pos: 1.5,-15.5 parent: 179 - - type: DeviceLinkSink - links: - - 983 - uid: 990 components: - type: Transform pos: -2.5,-13.5 parent: 179 - - type: DeviceLinkSink - links: - - 699 - uid: 991 components: - type: Transform pos: -2.5,-16.5 parent: 179 - - type: DeviceLinkSink - links: - - 699 - proto: CrateEngineeringToolbox entities: - uid: 692 @@ -3575,8 +3529,6 @@ entities: rot: -1.5707963267948966 rad pos: 3.5,-3.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: GasMixer entities: - uid: 747 @@ -3585,8 +3537,6 @@ entities: rot: -1.5707963267948966 rad pos: 3.5,-2.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: GasOutletInjector entities: - uid: 429 @@ -3595,8 +3545,6 @@ entities: rot: -1.5707963267948966 rad pos: 6.5,-1.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: GasPipeBend entities: - uid: 727 @@ -3635,8 +3583,6 @@ entities: rot: -1.5707963267948966 rad pos: 6.5,-0.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: GasPressurePump entities: - uid: 171 @@ -3645,8 +3591,6 @@ entities: rot: -1.5707963267948966 rad pos: 4.5,-3.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: GasValve entities: - uid: 168 @@ -3655,8 +3599,6 @@ entities: rot: -1.5707963267948966 rad pos: 4.5,-2.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: GasVentPump entities: - uid: 729 @@ -3665,8 +3607,6 @@ entities: rot: -1.5707963267948966 rad pos: 6.5,-3.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: GasVentScrubber entities: - uid: 452 @@ -3675,8 +3615,6 @@ entities: rot: -1.5707963267948966 rad pos: 6.5,-2.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: GasVolumePump entities: - uid: 160 @@ -3685,8 +3623,6 @@ entities: rot: -1.5707963267948966 rad pos: 4.5,-1.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: GeigerCounter entities: - uid: 759 @@ -4223,9 +4159,6 @@ entities: - type: Transform pos: 12.5,24.5 parent: 179 - - type: DeviceLinkSink - links: - - 1083 - proto: MachineFrame entities: - uid: 533 @@ -4379,8 +4312,6 @@ entities: - type: Transform pos: 7.5,-1.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: Ointment entities: - uid: 148 @@ -4400,8 +4331,6 @@ entities: - type: Transform pos: 7.5,-3.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: PaperBin10 entities: - uid: 977 @@ -4435,8 +4364,6 @@ entities: - type: Transform pos: 7.5,-2.5 parent: 179 - - type: AtmosDevice - joinedGrid: 179 - proto: PlasticFlapsAirtightClear entities: - uid: 997 @@ -5112,7 +5039,7 @@ entities: - type: Transform pos: -6.5,-12.5 parent: 179 -- proto: soda_dispenser +- proto: SodaDispenser entities: - uid: 751 components: @@ -5164,20 +5091,6 @@ entities: - type: Transform pos: -3.5,4.5 parent: 179 -- proto: SpawnVehicleATV - entities: - - uid: 1176 - components: - - type: Transform - pos: -7.5,1.5 - parent: 179 -- proto: SpawnVehicleJanicart - entities: - - uid: 904 - components: - - type: Transform - pos: 5.5,16.5 - parent: 179 - proto: Spear entities: - uid: 185 @@ -5809,20 +5722,6 @@ entities: - type: Transform pos: -7.5,4.5 parent: 179 -- proto: VehicleKeyATV - entities: - - uid: 1187 - components: - - type: Transform - pos: -6.8905525,1.5128828 - parent: 179 -- proto: VehicleKeyJanicart - entities: - - uid: 14 - components: - - type: Transform - pos: 6.5,16.5 - parent: 179 - proto: VendingMachineCigs entities: - uid: 870 From a94f1f0fe0b985236b508da25311d21aa92130b5 Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Thu, 18 Jul 2024 20:43:20 +0200 Subject: [PATCH 050/134] Correct .editorconfig to use no space after casting (#30132) --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index a5dfab07a50..1583c600aa5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -129,7 +129,7 @@ csharp_indent_braces = false csharp_indent_switch_labels = true # Space preferences -csharp_space_after_cast = true +csharp_space_after_cast = false csharp_space_after_colon_in_inheritance_clause = true csharp_space_after_comma = true csharp_space_after_dot = false From 437fc936a2faacd409c56b164fd4cb1974d2f454 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Thu, 18 Jul 2024 22:29:20 +0300 Subject: [PATCH 051/134] LatheSystem independently of energy (#30148) * Update LatheSystem.cs * Emo --- Content.Server/Power/EntitySystems/StaticPowerSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Power/EntitySystems/StaticPowerSystem.cs b/Content.Server/Power/EntitySystems/StaticPowerSystem.cs index 9e11d9311af..61a23e501df 100644 --- a/Content.Server/Power/EntitySystems/StaticPowerSystem.cs +++ b/Content.Server/Power/EntitySystems/StaticPowerSystem.cs @@ -9,7 +9,7 @@ public static class StaticPowerSystem public static bool IsPowered(this EntitySystem system, EntityUid uid, IEntityManager entManager, ApcPowerReceiverComponent? receiver = null) { if (receiver == null && !entManager.TryGetComponent(uid, out receiver)) - return false; + return true; return receiver.Powered; } From 2fb2cde1253f08488df14cb3c6bc6735903cc0fc Mon Sep 17 00:00:00 2001 From: Smirnov Peter <131467813+Sh18RW@users.noreply.github.com> Date: Fri, 19 Jul 2024 01:34:18 +0300 Subject: [PATCH 052/134] Add item checking for moth food (#30019) * Add ContainerContainer component checking for moth food * Use ItemSlotsComponent checking on food item --- Content.Server/Nutrition/EntitySystems/FoodSystem.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Content.Server/Nutrition/EntitySystems/FoodSystem.cs b/Content.Server/Nutrition/EntitySystems/FoodSystem.cs index fc9d228b056..d609f737e72 100644 --- a/Content.Server/Nutrition/EntitySystems/FoodSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/FoodSystem.cs @@ -10,7 +10,6 @@ using Content.Shared.Body.Components; using Content.Shared.Body.Organ; using Content.Shared.Chemistry; -using Content.Shared.Chemistry.Reagent; using Content.Shared.Database; using Content.Shared.DoAfter; using Content.Shared.FixedPoint; @@ -31,6 +30,7 @@ using Robust.Shared.Audio.Systems; using Robust.Shared.Utility; using System.Linq; +using Content.Shared.Containers.ItemSlots; using Robust.Server.GameObjects; using Content.Shared.Whitelist; @@ -138,6 +138,16 @@ private void OnFeedFood(Entity entity, ref AfterInteractEvent arg return (false, true); } + // Checks for used item slots + if (TryComp(food, out var itemSlots)) + { + if (itemSlots.Slots.Any(slot => slot.Value.HasItem)) + { + _popup.PopupEntity(Loc.GetString("food-has-used-storage", ("food", food)), user, user); + return (false, true); + } + } + var flavors = _flavorProfile.GetLocalizedFlavorsMessage(food, user, foodSolution); if (GetUsesRemaining(food, foodComp) <= 0) From 0c2b56962267d006965b4b3b3ee20fbbbfdb0280 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 18 Jul 2024 22:35:26 +0000 Subject: [PATCH 053/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 2ba6a098e0e..e2ceb5193a9 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: FungiFellow - changes: - - message: Truncheon now fits in SecBelt - type: Tweak - id: 6432 - time: '2024-04-24T13:43:56.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27281 - author: pigeonpeas changes: - message: Adds a trash bag to the advanced cleaning module. @@ -3805,3 +3798,10 @@ id: 6931 time: '2024-07-18T00:48:09.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30136 +- author: Sh18RW + changes: + - message: Moth can't eat boots with an item more + type: Fix + id: 6932 + time: '2024-07-18T22:34:18.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30019 From 3ef5f521e2e162b2372b563cc0879313deddcd7b Mon Sep 17 00:00:00 2001 From: portfiend <109661617+portfiend@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:36:53 -0400 Subject: [PATCH 054/134] fix: give reptilians species mask sprites in lobby (#30095) --- Resources/Prototypes/Entities/Mobs/Species/reptilian.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml index ad543620cf8..0d93e6fe51a 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml @@ -71,5 +71,11 @@ components: - type: HumanoidAppearance species: Reptilian + hideLayersOnEquip: + - Snout + - HeadTop + - HeadSide + - type: Inventory + speciesId: reptilian #Weh From d30b45f23f17d396c7c55ce33806939d9af66c94 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 18 Jul 2024 22:37:59 +0000 Subject: [PATCH 055/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e2ceb5193a9..6f0ba27d307 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: pigeonpeas - changes: - - message: Adds a trash bag to the advanced cleaning module. - type: Add - id: 6433 - time: '2024-04-24T21:27:34.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27226 - author: Beck Thompson changes: - message: Radio jammer now has 3 selectable power operating levels and a battery @@ -3805,3 +3798,10 @@ id: 6932 time: '2024-07-18T22:34:18.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30019 +- author: portfiend + changes: + - message: Reptilians display correct mask sprites in character customization screen. + type: Fix + id: 6933 + time: '2024-07-18T22:36:53.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30095 From 84fe6bcde4acc7334523c46c9564dcc8d79015de Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:21:01 -0700 Subject: [PATCH 056/134] Fix arrow pointing animation (#30134) Fixa the arrows Co-authored-by: plykiya --- Content.Server/Pointing/EntitySystems/PointingSystem.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Content.Server/Pointing/EntitySystems/PointingSystem.cs b/Content.Server/Pointing/EntitySystems/PointingSystem.cs index 4b7f50fb86c..f2f60f3063e 100644 --- a/Content.Server/Pointing/EntitySystems/PointingSystem.cs +++ b/Content.Server/Pointing/EntitySystems/PointingSystem.cs @@ -152,9 +152,7 @@ public bool TryPoint(ICommonSession? session, EntityCoordinates coordsPointed, E if (TryComp(arrow, out var pointing)) { - if (TryComp(player, out TransformComponent? xformPlayer)) - pointing.StartPosition = _transform.ToCoordinates((player, xformPlayer), _transform.ToMapCoordinates(xformPlayer.Coordinates)).Position; - + pointing.StartPosition = _transform.ToCoordinates((arrow, Transform(arrow)), _transform.ToMapCoordinates(Transform(player).Coordinates)).Position; pointing.EndTime = _gameTiming.CurTime + PointDuration; Dirty(arrow, pointing); From b57174007c8d455d10cfa6a2e8563993e935838e Mon Sep 17 00:00:00 2001 From: Cojoke <83733158+Cojoke-dot@users.noreply.github.com> Date: Thu, 18 Jul 2024 19:22:23 -0500 Subject: [PATCH 057/134] Remove all Assigned Values that are Never Used (#30110) Remove all Assigned Values that are never used --- .../Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs | 1 - Content.Client/Construction/ConstructionSystem.cs | 1 - Content.Client/Lathe/UI/LatheMenu.xaml.cs | 1 - Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs | 1 - Content.Server/Ame/EntitySystems/AmeControllerSystem.cs | 2 -- Content.Server/Chat/Systems/ChatSystem.cs | 1 - Content.Server/Cluwne/CluwneSystem.cs | 1 - Content.Server/Doors/Systems/FirelockSystem.cs | 1 - Content.Server/Dragon/DragonSystem.cs | 1 - Content.Server/GameTicking/Rules/LoadMapRuleSystem.cs | 1 - Content.Server/GameTicking/Rules/SecretRuleSystem.cs | 1 - Content.Server/GameTicking/Rules/ThiefRuleSystem.cs | 2 -- Content.Server/GameTicking/Rules/TraitorRuleSystem.cs | 1 - Content.Server/Instruments/InstrumentSystem.cs | 1 - Content.Server/Medical/DefibrillatorSystem.cs | 1 - Content.Server/Ninja/Systems/SpaceNinjaSystem.cs | 3 --- Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs | 1 - .../Players/PlayTimeTracking/PlayTimeTrackingSystem.cs | 1 - Content.Server/Power/EntitySystems/PowerNetSystem.cs | 1 - Content.Server/Power/EntitySystems/PowerReceiverSystem.cs | 1 - Content.Server/Procedural/DungeonSystem.cs | 1 - Content.Server/Silicons/Borgs/BorgSystem.cs | 1 - Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs | 1 - Content.Server/Station/Systems/StationSystem.cs | 2 -- Content.Server/Traits/TraitSystem.cs | 1 - Content.Shared/Actions/SharedActionsSystem.cs | 1 - Content.Shared/Beeper/Systems/ProximityBeeperSystem.cs | 2 -- Content.Shared/Clothing/ClothingSpeedModifierSystem.cs | 3 --- Content.Shared/Movement/Pulling/Systems/PullingSystem.cs | 1 - Content.Shared/Ninja/Systems/DashAbilitySystem.cs | 1 - 30 files changed, 38 deletions(-) diff --git a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs index 78eefa34628..7082617c944 100644 --- a/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs @@ -14,7 +14,6 @@ namespace Content.Client.Administration.UI.Tabs.ObjectsTab; public sealed partial class ObjectsTab : Control { [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IGameTiming _timing = default!; private readonly Color _altColor = Color.FromHex("#292B38"); private readonly Color _defaultColor = Color.FromHex("#2F2F3B"); diff --git a/Content.Client/Construction/ConstructionSystem.cs b/Content.Client/Construction/ConstructionSystem.cs index 889c992f7f6..f909b23423d 100644 --- a/Content.Client/Construction/ConstructionSystem.cs +++ b/Content.Client/Construction/ConstructionSystem.cs @@ -26,7 +26,6 @@ public sealed class ConstructionSystem : SharedConstructionSystem { [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly ExamineSystemShared _examineSystem = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml.cs b/Content.Client/Lathe/UI/LatheMenu.xaml.cs index 265130d15d3..f2f52b67b5b 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml.cs +++ b/Content.Client/Lathe/UI/LatheMenu.xaml.cs @@ -21,7 +21,6 @@ public sealed partial class LatheMenu : DefaultWindow { [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IResourceCache _resources = default!; private EntityUid _owner; private readonly SpriteSystem _spriteSystem; diff --git a/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs b/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs index 2c71fa8c40e..ac51cdbac5e 100644 --- a/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs +++ b/Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs @@ -17,7 +17,6 @@ public sealed partial class VendingMachineMenu : FancyWindow { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IGameTiming _timing = default!; private readonly Dictionary _dummies = []; diff --git a/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs b/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs index eda91582739..bac2648307c 100644 --- a/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs +++ b/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs @@ -22,8 +22,6 @@ namespace Content.Server.Ame.EntitySystems; public sealed class AmeControllerSystem : EntitySystem { [Dependency] private readonly IAdminLogManager _adminLogger = default!; - [Dependency] private readonly IAdminManager _adminManager = default!; - [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly AppearanceSystem _appearanceSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 5358cdb4420..88b306c6ade 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -60,7 +60,6 @@ public sealed partial class ChatSystem : SharedChatSystem [Dependency] private readonly StationSystem _stationSystem = default!; [Dependency] private readonly MobStateSystem _mobStateSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly ReplacementAccentSystem _wordreplacement = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; [Dependency] private readonly ExamineSystemShared _examineSystem = default!; diff --git a/Content.Server/Cluwne/CluwneSystem.cs b/Content.Server/Cluwne/CluwneSystem.cs index 18d82659deb..f24f0143f31 100644 --- a/Content.Server/Cluwne/CluwneSystem.cs +++ b/Content.Server/Cluwne/CluwneSystem.cs @@ -29,7 +29,6 @@ public sealed class CluwneSystem : EntitySystem [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly ChatSystem _chat = default!; [Dependency] private readonly AutoEmoteSystem _autoEmote = default!; - [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly NameModifierSystem _nameMod = default!; public override void Initialize() diff --git a/Content.Server/Doors/Systems/FirelockSystem.cs b/Content.Server/Doors/Systems/FirelockSystem.cs index 93ee18f6831..87e5887c422 100644 --- a/Content.Server/Doors/Systems/FirelockSystem.cs +++ b/Content.Server/Doors/Systems/FirelockSystem.cs @@ -16,7 +16,6 @@ namespace Content.Server.Doors.Systems public sealed class FirelockSystem : SharedFirelockSystem { [Dependency] private readonly SharedDoorSystem _doorSystem = default!; - [Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!; [Dependency] private readonly AtmosphereSystem _atmosSystem = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedMapSystem _mapping = default!; diff --git a/Content.Server/Dragon/DragonSystem.cs b/Content.Server/Dragon/DragonSystem.cs index e626edeb269..1f15def5ce5 100644 --- a/Content.Server/Dragon/DragonSystem.cs +++ b/Content.Server/Dragon/DragonSystem.cs @@ -24,7 +24,6 @@ public sealed partial class DragonSystem : EntitySystem [Dependency] private readonly MovementSpeedModifierSystem _movement = default!; [Dependency] private readonly NpcFactionSystem _faction = default!; [Dependency] private readonly PopupSystem _popup = default!; - [Dependency] private readonly RoleSystem _role = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; diff --git a/Content.Server/GameTicking/Rules/LoadMapRuleSystem.cs b/Content.Server/GameTicking/Rules/LoadMapRuleSystem.cs index 3594242bcde..d2686ecdcdd 100644 --- a/Content.Server/GameTicking/Rules/LoadMapRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/LoadMapRuleSystem.cs @@ -13,7 +13,6 @@ public sealed class LoadMapRuleSystem : GameRuleSystem [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly MapSystem _map = default!; [Dependency] private readonly MapLoaderSystem _mapLoader = default!; - [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly TransformSystem _transform = default!; [Dependency] private readonly GridPreloaderSystem _gridPreloader = default!; diff --git a/Content.Server/GameTicking/Rules/SecretRuleSystem.cs b/Content.Server/GameTicking/Rules/SecretRuleSystem.cs index 8608f250d48..e82cecde368 100644 --- a/Content.Server/GameTicking/Rules/SecretRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/SecretRuleSystem.cs @@ -21,7 +21,6 @@ public sealed class SecretRuleSystem : GameRuleSystem [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IConfigurationManager _configurationManager = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; - [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly IComponentFactory _compFact = default!; private string _ruleCompName = default!; diff --git a/Content.Server/GameTicking/Rules/ThiefRuleSystem.cs b/Content.Server/GameTicking/Rules/ThiefRuleSystem.cs index faec4a9e9ca..074b4c0df7a 100644 --- a/Content.Server/GameTicking/Rules/ThiefRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/ThiefRuleSystem.cs @@ -12,10 +12,8 @@ namespace Content.Server.GameTicking.Rules; public sealed class ThiefRuleSystem : GameRuleSystem { - [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly AntagSelectionSystem _antag = default!; - [Dependency] private readonly ObjectivesSystem _objectives = default!; public override void Initialize() { diff --git a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs index 17442da8577..a96020d0e3a 100644 --- a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs @@ -29,7 +29,6 @@ public sealed class TraitorRuleSystem : GameRuleSystem [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly SharedRoleSystem _roleSystem = default!; [Dependency] private readonly SharedJobSystem _jobs = default!; - [Dependency] private readonly ObjectivesSystem _objectives = default!; public override void Initialize() { diff --git a/Content.Server/Instruments/InstrumentSystem.cs b/Content.Server/Instruments/InstrumentSystem.cs index 6814b596dc5..f74dd7fb131 100644 --- a/Content.Server/Instruments/InstrumentSystem.cs +++ b/Content.Server/Instruments/InstrumentSystem.cs @@ -30,7 +30,6 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem [Dependency] private readonly UserInterfaceSystem _bui = default!; [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly TransformSystem _transform = default!; - [Dependency] private readonly InteractionSystem _interactions = default!; [Dependency] private readonly ExamineSystemShared _examineSystem = default!; private const float MaxInstrumentBandRange = 10f; diff --git a/Content.Server/Medical/DefibrillatorSystem.cs b/Content.Server/Medical/DefibrillatorSystem.cs index 1896f51eddc..b6b50d4215f 100644 --- a/Content.Server/Medical/DefibrillatorSystem.cs +++ b/Content.Server/Medical/DefibrillatorSystem.cs @@ -46,7 +46,6 @@ public sealed class DefibrillatorSystem : EntitySystem [Dependency] private readonly PowerCellSystem _powerCell = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly UseDelaySystem _useDelay = default!; [Dependency] private readonly SharedMindSystem _mind = default!; /// diff --git a/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs b/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs index 28ab6332276..1ece045774c 100644 --- a/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs +++ b/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs @@ -32,10 +32,7 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem [Dependency] private readonly AlertsSystem _alerts = default!; [Dependency] private readonly BatterySystem _battery = default!; [Dependency] private readonly CodeConditionSystem _codeCondition = default!; - [Dependency] private readonly IChatManager _chatMan = default!; [Dependency] private readonly PowerCellSystem _powerCell = default!; - [Dependency] private readonly RoleSystem _role = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedMindSystem _mind = default!; public override void Initialize() diff --git a/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs b/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs index f5d434090e7..ac3df5868fe 100644 --- a/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs @@ -17,7 +17,6 @@ public sealed class SliceableFoodSystem : EntitySystem { [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly TransformSystem _xformSystem = default!; public override void Initialize() diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs index 09956e313f3..ea6f0ad3f45 100644 --- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs +++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs @@ -35,7 +35,6 @@ public sealed class PlayTimeTrackingSystem : EntitySystem [Dependency] private readonly MindSystem _minds = default!; [Dependency] private readonly PlayTimeTrackingManager _tracking = default!; [Dependency] private readonly IAdminManager _adminManager = default!; - [Dependency] private readonly SharedRoleSystem _role = default!; public override void Initialize() { diff --git a/Content.Server/Power/EntitySystems/PowerNetSystem.cs b/Content.Server/Power/EntitySystems/PowerNetSystem.cs index 6c35ba20083..a7098649cef 100644 --- a/Content.Server/Power/EntitySystems/PowerNetSystem.cs +++ b/Content.Server/Power/EntitySystems/PowerNetSystem.cs @@ -22,7 +22,6 @@ public sealed class PowerNetSystem : EntitySystem [Dependency] private readonly PowerNetConnectorSystem _powerNetConnector = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IParallelManager _parMan = default!; - [Dependency] private readonly PowerReceiverSystem _powerReceiver = default!; private readonly PowerState _powerState = new(); private readonly HashSet _powerNetReconnectQueue = new(); diff --git a/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs b/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs index 51520f04644..191d3fc4bdb 100644 --- a/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs +++ b/Content.Server/Power/EntitySystems/PowerReceiverSystem.cs @@ -21,7 +21,6 @@ public sealed class PowerReceiverSystem : SharedPowerReceiverSystem { [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly IAdminManager _adminManager = default!; - [Dependency] private readonly AppearanceSystem _appearance = default!; [Dependency] private readonly AudioSystem _audio = default!; private EntityQuery _recQuery; private EntityQuery _provQuery; diff --git a/Content.Server/Procedural/DungeonSystem.cs b/Content.Server/Procedural/DungeonSystem.cs index b73e843fffd..9a7abb7e334 100644 --- a/Content.Server/Procedural/DungeonSystem.cs +++ b/Content.Server/Procedural/DungeonSystem.cs @@ -33,7 +33,6 @@ public sealed partial class DungeonSystem : SharedDungeonSystem [Dependency] private readonly AnchorableSystem _anchorable = default!; [Dependency] private readonly DecalSystem _decals = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; - [Dependency] private readonly TagSystem _tag = default!; [Dependency] private readonly TileSystem _tile = default!; [Dependency] private readonly MapLoaderSystem _loader = default!; [Dependency] private readonly SharedMapSystem _maps = default!; diff --git a/Content.Server/Silicons/Borgs/BorgSystem.cs b/Content.Server/Silicons/Borgs/BorgSystem.cs index 1c40e9489eb..3f32afbffbd 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.cs @@ -40,7 +40,6 @@ public sealed partial class BorgSystem : SharedBorgSystem [Dependency] private readonly IBanManager _banManager = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly SharedAccessSystem _access = default!; [Dependency] private readonly ActionsSystem _actions = default!; [Dependency] private readonly AlertsSystem _alerts = default!; [Dependency] private readonly DeviceNetworkSystem _deviceNetwork = default!; diff --git a/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs b/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs index e145e233e9e..8a918bd2fd0 100644 --- a/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs +++ b/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs @@ -17,7 +17,6 @@ public sealed partial class StationJobsSystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IBanManager _banManager = default!; - [Dependency] private readonly PlayTimeTrackingSystem _playTime = default!; private Dictionary> _jobsByWeight = default!; private List _orderedWeights = default!; diff --git a/Content.Server/Station/Systems/StationSystem.cs b/Content.Server/Station/Systems/StationSystem.cs index 84e44b6469c..5930eef39bd 100644 --- a/Content.Server/Station/Systems/StationSystem.cs +++ b/Content.Server/Station/Systems/StationSystem.cs @@ -27,10 +27,8 @@ namespace Content.Server.Station.Systems; [PublicAPI] public sealed class StationSystem : EntitySystem { - [Dependency] private readonly IConfigurationManager _cfgManager = default!; [Dependency] private readonly ILogManager _logManager = default!; [Dependency] private readonly IPlayerManager _player = default!; - [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ChatSystem _chatSystem = default!; [Dependency] private readonly GameTicker _ticker = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; diff --git a/Content.Server/Traits/TraitSystem.cs b/Content.Server/Traits/TraitSystem.cs index f41512b6ac2..3bd540a3049 100644 --- a/Content.Server/Traits/TraitSystem.cs +++ b/Content.Server/Traits/TraitSystem.cs @@ -11,7 +11,6 @@ namespace Content.Server.Traits; public sealed class TraitSystem : EntitySystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly ISerializationManager _serializationManager = default!; [Dependency] private readonly SharedHandsSystem _sharedHandsSystem = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; diff --git a/Content.Shared/Actions/SharedActionsSystem.cs b/Content.Shared/Actions/SharedActionsSystem.cs index 013348eb4f7..ca6bd1dcc2a 100644 --- a/Content.Shared/Actions/SharedActionsSystem.cs +++ b/Content.Shared/Actions/SharedActionsSystem.cs @@ -25,7 +25,6 @@ public abstract class SharedActionsSystem : EntitySystem [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; - [Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly RotateToFaceSystem _rotateToFaceSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!; diff --git a/Content.Shared/Beeper/Systems/ProximityBeeperSystem.cs b/Content.Shared/Beeper/Systems/ProximityBeeperSystem.cs index ed3c6366c13..9830e165e56 100644 --- a/Content.Shared/Beeper/Systems/ProximityBeeperSystem.cs +++ b/Content.Shared/Beeper/Systems/ProximityBeeperSystem.cs @@ -12,8 +12,6 @@ namespace Content.Shared.Beeper.Systems; /// public sealed class ProximityBeeperSystem : EntitySystem { - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly ProximityDetectionSystem _proximity = default!; [Dependency] private readonly BeeperSystem _beeper = default!; /// diff --git a/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs b/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs index c1efe0b3ddd..897f3791561 100644 --- a/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs +++ b/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs @@ -14,13 +14,10 @@ namespace Content.Shared.Clothing; public sealed class ClothingSpeedModifierSystem : EntitySystem { - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly ClothingSpeedModifierSystem _clothingSpeedModifier = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly ExamineSystemShared _examine = default!; [Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!; [Dependency] private readonly ItemToggleSystem _toggle = default!; - [Dependency] private readonly SharedPowerCellSystem _powerCell = default!; public override void Initialize() { diff --git a/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs b/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs index f563440af04..557c316e26d 100644 --- a/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs +++ b/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs @@ -43,7 +43,6 @@ public sealed class PullingSystem : EntitySystem [Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedInteractionSystem _interaction = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; - [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly HeldSpeedModifierSystem _clothingMoveSpeed = default!; public override void Initialize() diff --git a/Content.Shared/Ninja/Systems/DashAbilitySystem.cs b/Content.Shared/Ninja/Systems/DashAbilitySystem.cs index 1385219e473..09be1085058 100644 --- a/Content.Shared/Ninja/Systems/DashAbilitySystem.cs +++ b/Content.Shared/Ninja/Systems/DashAbilitySystem.cs @@ -18,7 +18,6 @@ public sealed class DashAbilitySystem : EntitySystem { [Dependency] private readonly ActionContainerSystem _actionContainer = default!; [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedChargesSystem _charges = default!; [Dependency] private readonly SharedHandsSystem _hands = default!; [Dependency] private readonly ExamineSystemShared _examine = default!; From 6d18dff33de3e94ebcfaa00a7b89243bf5110f84 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:08:52 -0700 Subject: [PATCH 058/134] Fix for thrown items dealing damage twice to first target (#30115) * FUCK YOU * fine --------- Co-authored-by: plykiya --- .../Damage/Systems/DamageOtherOnHitSystem.cs | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/Content.Server/Damage/Systems/DamageOtherOnHitSystem.cs b/Content.Server/Damage/Systems/DamageOtherOnHitSystem.cs index ff4d1cabe98..8a7b3df0b24 100644 --- a/Content.Server/Damage/Systems/DamageOtherOnHitSystem.cs +++ b/Content.Server/Damage/Systems/DamageOtherOnHitSystem.cs @@ -32,31 +32,25 @@ public override void Initialize() private void OnDoHit(EntityUid uid, DamageOtherOnHitComponent component, ThrowDoHitEvent args) { - if (!TerminatingOrDeleted(args.Target)) - { - var dmg = _damageable.TryChangeDamage(args.Target, component.Damage, component.IgnoreResistances, origin: args.Component.Thrower); + if (TerminatingOrDeleted(args.Target)) + return; - // Log damage only for mobs. Useful for when people throw spears at each other, but also avoids log-spam when explosions send glass shards flying. - if (dmg != null && HasComp(args.Target)) - _adminLogger.Add(LogType.ThrowHit, $"{ToPrettyString(args.Target):target} received {dmg.GetTotal():damage} damage from collision"); + var dmg = _damageable.TryChangeDamage(args.Target, component.Damage, component.IgnoreResistances, origin: args.Component.Thrower); - if (dmg is { Empty: false }) - { - _color.RaiseEffect(Color.Red, new List() { args.Target }, Filter.Pvs(args.Target, entityManager: EntityManager)); - } + // Log damage only for mobs. Useful for when people throw spears at each other, but also avoids log-spam when explosions send glass shards flying. + if (dmg != null && HasComp(args.Target)) + _adminLogger.Add(LogType.ThrowHit, $"{ToPrettyString(args.Target):target} received {dmg.GetTotal():damage} damage from collision"); - _guns.PlayImpactSound(args.Target, dmg, null, false); - if (TryComp(uid, out var body) && body.LinearVelocity.LengthSquared() > 0f) - { - var direction = body.LinearVelocity.Normalized(); - _sharedCameraRecoil.KickCamera(args.Target, direction); - } + if (dmg is { Empty: false }) + { + _color.RaiseEffect(Color.Red, new List() { args.Target }, Filter.Pvs(args.Target, entityManager: EntityManager)); } - // TODO: If more stuff touches this then handle it after. - if (TryComp(uid, out var physics)) + _guns.PlayImpactSound(args.Target, dmg, null, false); + if (TryComp(uid, out var body) && body.LinearVelocity.LengthSquared() > 0f) { - _thrownItem.LandComponent(args.Thrown, args.Component, physics, false); + var direction = body.LinearVelocity.Normalized(); + _sharedCameraRecoil.KickCamera(args.Target, direction); } } From 56ee4da5352d94e45bfe45977a2ac05a16785430 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 19 Jul 2024 01:10:01 +0000 Subject: [PATCH 059/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 6f0ba27d307..74a116880f6 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Beck Thompson - changes: - - message: Radio jammer now has 3 selectable power operating levels and a battery - level led indicator! - type: Tweak - id: 6434 - time: '2024-04-25T02:19:17.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/25912 - author: cooldolphin changes: - message: Three variants of glasses are now available in the loadout menu. @@ -3805,3 +3797,11 @@ id: 6933 time: '2024-07-18T22:36:53.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30095 +- author: Plykiya + changes: + - message: You no longer deal double damage to your first target when throwing an + item. + type: Fix + id: 6934 + time: '2024-07-19T01:08:52.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30115 From 6005a9f4cb9604a6c8cb5621746df7e078c12fbd Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:19:15 +1000 Subject: [PATCH 060/134] Fix door access in mapping mode (#30030) Fix shouldn't break anythingTM. --- .../DeviceNetwork/Systems/NetworkConfiguratorSystem.cs | 4 ++-- Content.Shared/Access/Systems/AccessReaderSystem.cs | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs b/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs index 402d005dd47..59b58c69338 100644 --- a/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs +++ b/Content.Server/DeviceNetwork/Systems/NetworkConfiguratorSystem.cs @@ -423,11 +423,11 @@ private void OpenDeviceLinkUi(EntityUid configuratorUid, EntityUid? targetUid, E if (Delay(configurator)) return; - if (!targetUid.HasValue || !configurator.ActiveDeviceLink.HasValue || !TryComp(userUid, out ActorComponent? actor) || !AccessCheck(targetUid.Value, userUid, configurator)) + if (!targetUid.HasValue || !configurator.ActiveDeviceLink.HasValue || !AccessCheck(targetUid.Value, userUid, configurator)) return; - _uiSystem.OpenUi(configuratorUid, NetworkConfiguratorUiKey.Link, actor.PlayerSession); + _uiSystem.OpenUi(configuratorUid, NetworkConfiguratorUiKey.Link, userUid); configurator.DeviceLinkTarget = targetUid; diff --git a/Content.Shared/Access/Systems/AccessReaderSystem.cs b/Content.Shared/Access/Systems/AccessReaderSystem.cs index 5d1932a959c..2e0737c6ab2 100644 --- a/Content.Shared/Access/Systems/AccessReaderSystem.cs +++ b/Content.Shared/Access/Systems/AccessReaderSystem.cs @@ -155,7 +155,12 @@ public bool IsAllowed( return IsAllowedInternal(access, stationKeys, reader); if (!_containerSystem.TryGetContainer(target, reader.ContainerAccessProvider, out var container)) - return Paused(target); // when mapping, containers with electronics arent spawned + return false; + + // If entity is paused then always allow it at this point. + // Door electronics is kind of a mess but yeah, it should only be an unpaused ent interacting with it + if (Paused(target)) + return true; foreach (var entity in container.ContainedEntities) { From d6e0114126f778c298763d05fa59ee62c28f595a Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Fri, 19 Jul 2024 11:13:35 +0300 Subject: [PATCH 061/134] randomize iconSmoothing (#28158) * randomize iconSmoothing * Revert "randomize iconSmoothing" This reverts commit 094356f975737c0af24ce39d849aec7852b9af6e. * try 2 * trying work with client-server communication * still dont work * Tayrtahn good suggestion * remove outdated code * Fix! * move data to Appearance * Update RandomIconSmoothComponent.cs --- .../ClientRandomIconSmoothSystem.cs | 29 ++++++++ .../IconSmoothing/IconSmoothComponent.cs | 2 +- .../IconSmoothing/IconSmoothSystem.cs | 35 +++++++--- .../IconSmoothing/RandomIconSmoothSystem.cs | 26 +++++++ .../RandomIconSmoothComponent.cs | 16 +++++ .../SharedRandomIconSmoothSystem.cs | 12 ++++ .../Entities/Structures/Walls/walls.yml | 5 ++ .../Structures/Walls/mining.rsi/meta.json | 66 +++++++++++++----- .../Structures/Walls/mining.rsi/miningB0.png | Bin 0 -> 1192 bytes .../Structures/Walls/mining.rsi/miningB1.png | Bin 0 -> 1470 bytes .../Structures/Walls/mining.rsi/miningB2.png | Bin 0 -> 1192 bytes .../Structures/Walls/mining.rsi/miningB3.png | Bin 0 -> 1470 bytes .../Structures/Walls/mining.rsi/miningB4.png | Bin 0 -> 1446 bytes .../Structures/Walls/mining.rsi/miningB5.png | Bin 0 -> 1451 bytes .../Structures/Walls/mining.rsi/miningB6.png | Bin 0 -> 1446 bytes .../Structures/Walls/mining.rsi/miningB7.png | Bin 0 -> 962 bytes 16 files changed, 165 insertions(+), 26 deletions(-) create mode 100644 Content.Client/IconSmoothing/ClientRandomIconSmoothSystem.cs create mode 100644 Content.Server/IconSmoothing/RandomIconSmoothSystem.cs create mode 100644 Content.Shared/IconSmoothing/RandomIconSmoothComponent.cs create mode 100644 Content.Shared/IconSmoothing/SharedRandomIconSmoothSystem.cs create mode 100644 Resources/Textures/Structures/Walls/mining.rsi/miningB0.png create mode 100644 Resources/Textures/Structures/Walls/mining.rsi/miningB1.png create mode 100644 Resources/Textures/Structures/Walls/mining.rsi/miningB2.png create mode 100644 Resources/Textures/Structures/Walls/mining.rsi/miningB3.png create mode 100644 Resources/Textures/Structures/Walls/mining.rsi/miningB4.png create mode 100644 Resources/Textures/Structures/Walls/mining.rsi/miningB5.png create mode 100644 Resources/Textures/Structures/Walls/mining.rsi/miningB6.png create mode 100644 Resources/Textures/Structures/Walls/mining.rsi/miningB7.png diff --git a/Content.Client/IconSmoothing/ClientRandomIconSmoothSystem.cs b/Content.Client/IconSmoothing/ClientRandomIconSmoothSystem.cs new file mode 100644 index 00000000000..73db9e1ab95 --- /dev/null +++ b/Content.Client/IconSmoothing/ClientRandomIconSmoothSystem.cs @@ -0,0 +1,29 @@ +using Content.Shared.IconSmoothing; +using Robust.Client.GameObjects; + +namespace Content.Client.IconSmoothing; + +public sealed class ClientRandomIconSmoothSystem : SharedRandomIconSmoothSystem +{ + [Dependency] private readonly IconSmoothSystem _iconSmooth = default!; + [Dependency] private readonly AppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAppearanceChange); + } + + private void OnAppearanceChange(Entity ent, ref AppearanceChangeEvent args) + { + if (!TryComp(ent, out var smooth)) + return; + + if (!_appearance.TryGetData(ent, RandomIconSmoothState.State, out var state, args.Component)) + return; + + smooth.StateBase = state; + _iconSmooth.SetStateBase(ent, smooth, state); + } +} diff --git a/Content.Client/IconSmoothing/IconSmoothComponent.cs b/Content.Client/IconSmoothing/IconSmoothComponent.cs index 88b1f613cb7..040198529c7 100644 --- a/Content.Client/IconSmoothing/IconSmoothComponent.cs +++ b/Content.Client/IconSmoothing/IconSmoothComponent.cs @@ -30,7 +30,7 @@ public sealed partial class IconSmoothComponent : Component /// Prepended to the RSI state. /// [ViewVariables(VVAccess.ReadWrite), DataField("base")] - public string StateBase { get; private set; } = string.Empty; + public string StateBase { get; set; } = string.Empty; [DataField("shader", customTypeSerializer:typeof(PrototypeIdSerializer))] public string? Shader; diff --git a/Content.Client/IconSmoothing/IconSmoothSystem.cs b/Content.Client/IconSmoothing/IconSmoothSystem.cs index 4b025608465..11ca75bc824 100644 --- a/Content.Client/IconSmoothing/IconSmoothSystem.cs +++ b/Content.Client/IconSmoothing/IconSmoothSystem.cs @@ -55,6 +55,33 @@ private void OnStartup(EntityUid uid, IconSmoothComponent component, ComponentSt if (component.Mode != IconSmoothingMode.Corners || !TryComp(uid, out SpriteComponent? sprite)) return; + SetCornerLayers(sprite, component); + + if (component.Shader != null) + { + sprite.LayerSetShader(CornerLayers.SE, component.Shader); + sprite.LayerSetShader(CornerLayers.NE, component.Shader); + sprite.LayerSetShader(CornerLayers.NW, component.Shader); + sprite.LayerSetShader(CornerLayers.SW, component.Shader); + } + } + + public void SetStateBase(EntityUid uid, IconSmoothComponent component, string newState) + { + if (!TryComp(uid, out var sprite)) + return; + + component.StateBase = newState; + SetCornerLayers(sprite, component); + } + + private void SetCornerLayers(SpriteComponent sprite, IconSmoothComponent component) + { + sprite.LayerMapRemove(CornerLayers.SE); + sprite.LayerMapRemove(CornerLayers.NE); + sprite.LayerMapRemove(CornerLayers.NW); + sprite.LayerMapRemove(CornerLayers.SW); + var state0 = $"{component.StateBase}0"; sprite.LayerMapSet(CornerLayers.SE, sprite.AddLayerState(state0)); sprite.LayerSetDirOffset(CornerLayers.SE, DirectionOffset.None); @@ -64,14 +91,6 @@ private void OnStartup(EntityUid uid, IconSmoothComponent component, ComponentSt sprite.LayerSetDirOffset(CornerLayers.NW, DirectionOffset.Flip); sprite.LayerMapSet(CornerLayers.SW, sprite.AddLayerState(state0)); sprite.LayerSetDirOffset(CornerLayers.SW, DirectionOffset.Clockwise); - - if (component.Shader != null) - { - sprite.LayerSetShader(CornerLayers.SE, component.Shader); - sprite.LayerSetShader(CornerLayers.NE, component.Shader); - sprite.LayerSetShader(CornerLayers.NW, component.Shader); - sprite.LayerSetShader(CornerLayers.SW, component.Shader); - } } private void OnShutdown(EntityUid uid, IconSmoothComponent component, ComponentShutdown args) diff --git a/Content.Server/IconSmoothing/RandomIconSmoothSystem.cs b/Content.Server/IconSmoothing/RandomIconSmoothSystem.cs new file mode 100644 index 00000000000..4ddfb17ac84 --- /dev/null +++ b/Content.Server/IconSmoothing/RandomIconSmoothSystem.cs @@ -0,0 +1,26 @@ +using Content.Shared.IconSmoothing; +using Robust.Shared.Random; + +namespace Content.Server.IconSmoothing; + +public sealed partial class RandomIconSmoothSystem : SharedRandomIconSmoothSystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + if (ent.Comp.RandomStates.Count == 0) + return; + + var state = _random.Pick(ent.Comp.RandomStates); + _appearance.SetData(ent, RandomIconSmoothState.State, state); + } +} diff --git a/Content.Shared/IconSmoothing/RandomIconSmoothComponent.cs b/Content.Shared/IconSmoothing/RandomIconSmoothComponent.cs new file mode 100644 index 00000000000..6cdf167b295 --- /dev/null +++ b/Content.Shared/IconSmoothing/RandomIconSmoothComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.IconSmoothing; + +/// +/// Allow randomize StateBase of IconSmoothComponent for random visual variation +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class RandomIconSmoothComponent : Component +{ + /// + /// StateBase will be randomly selected from this list. Allows to randomize the visual. + /// + [DataField(required: true)] + public List RandomStates = new(); +} diff --git a/Content.Shared/IconSmoothing/SharedRandomIconSmoothSystem.cs b/Content.Shared/IconSmoothing/SharedRandomIconSmoothSystem.cs new file mode 100644 index 00000000000..5cb5299858c --- /dev/null +++ b/Content.Shared/IconSmoothing/SharedRandomIconSmoothSystem.cs @@ -0,0 +1,12 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.IconSmoothing; + +public abstract class SharedRandomIconSmoothSystem : EntitySystem +{ +} +[Serializable, NetSerializable] +public enum RandomIconSmoothState : byte +{ + State +} diff --git a/Resources/Prototypes/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/Entities/Structures/Walls/walls.yml index 7af99812555..1ab770812a6 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/walls.yml @@ -1109,6 +1109,11 @@ - type: IconSmooth key: walls base: mining + - type: RandomIconSmooth + randomStates: + - mining + - miningB + - type: Appearance - type: entity parent: WallShuttleDiagonal diff --git a/Resources/Textures/Structures/Walls/mining.rsi/meta.json b/Resources/Textures/Structures/Walls/mining.rsi/meta.json index 4ce4691c516..77f43229984 100644 --- a/Resources/Textures/Structures/Walls/mining.rsi/meta.json +++ b/Resources/Textures/Structures/Walls/mining.rsi/meta.json @@ -7,40 +7,72 @@ "y": 32 }, "states": [ - { + { "name": "full" }, - { + { "name": "mining0", - "directions": 4 + "directions": 4 }, - { + { "name": "mining1", - "directions": 4 + "directions": 4 }, - { + { "name": "mining2", - "directions": 4 + "directions": 4 }, - { + { "name": "mining3", - "directions": 4 + "directions": 4 }, - { + { "name": "mining4", - "directions": 4 + "directions": 4 }, - { + { "name": "mining5", - "directions": 4 + "directions": 4 }, - { + { "name": "mining6", - "directions": 4 + "directions": 4 }, - { + { "name": "mining7", - "directions": 4 + "directions": 4 + }, + { + "name": "miningB0", + "directions": 4 + }, + { + "name": "miningB1", + "directions": 4 + }, + { + "name": "miningB2", + "directions": 4 + }, + { + "name": "miningB3", + "directions": 4 + }, + { + "name": "miningB4", + "directions": 4 + }, + { + "name": "miningB5", + "directions": 4 + }, + { + "name": "miningB6", + "directions": 4 + }, + { + "name": "miningB7", + "directions": 4 } ] } diff --git a/Resources/Textures/Structures/Walls/mining.rsi/miningB0.png b/Resources/Textures/Structures/Walls/mining.rsi/miningB0.png new file mode 100644 index 0000000000000000000000000000000000000000..f65f066b65aa26487dec4d03b79e560239294cff GIT binary patch literal 1192 zcmV;Z1XufsP)Px(Vo5|nRCt`-TTN=*Fckh$x|&^(jAj$M8cd<|08@jHP>L^CdWRfB;P?Qg5X7uX zH+C(P-E5}|^=V{{JxMFI7XBbiMwa8~`RTpy{pbb@W3$!d*BC z!dKcZV$TFG|f7^z#N*UnHe{#&seq& zFW`ba0)6KBTa;yquIua^Aq1q9Q0g)GdC3UCRc|tM08o}C?(gqMTcYnflw}F6^*S_Q ziue$^u0@{jFbq#tC^Wtr9^m?ar4A^H0!kf5a~QiFu|+esLLOi+9UizEa5}Aw3DOqG z^BwB?!R~n>wv+R>+iesLNWuoVZ#K)sNd2Xhzr8?f$As8IO1T~;2$=mm4E-N}h7zG* z0T7k_n|~e%kLN=XWeaf5QB~Efn&$ZqN&!Vtpzn#$>}HwX|3t6=7|T$WCBA+8IvVf$ zpD4?6#Mb)0yKrSoBiIWJLyxv?C$Eu47~lQ@N*yi|9ZMrv0E}h0adz?i8#a^X7~fKe zq5&?Z7@P6!^@z`>q6twnz$Ysd)BEET(_iEM{~N(Za2R@rteivEckkXqO8I+^(Fm9D zq=G13K&i*8u{q`QT%@uEqG-T=zXt$IVW+}ZADr_jR5ldBEbQ*?jSbzVl9uOdCei68 zKVwkYP(-1^A3uIV-*+Po05H-5r4ARx4W%9z7eEvnKn#x-=2m(LsaSm<(RsjgNKFt? zcz_SLyhXqJRzDS&7{vyJ+`qI9NG2t=6r$t2>|B>5)pDOJrSYQ5G^SR5EZ_esqL?n3g6wmInf(`jtWzdL|6qC z9){l5>k0mMiWXg@Vhf_!0M7Yr^~TK;xLqEpgu_uZpsK2iw0K=VpsFe;^_X-t>@Llz+-1}CEc0000Px)cu7P-RCt`-ThD9bMil#?ycD7+LJ$O?lx_wOm`o<{{dS2AmHRA&XKV)F zZzD;P&Eo-lwpaa@En#DLKqf43QNZQC<+hEn0MGNJXR~7FW%K9oJWq=S)b0ccaq-#q z89v;%@%&ka(+dlLjiZx!Ve*GJZNOGBF8XJ(ITmns`RGPK6xYLjyYK-=Cv%)$SU1Ya zaX{u;EI^qEwOYH`k6(O@>+6330H+rgj!x!F{T8#B|#T#Z9 zzn?$L@cQKz4)<*w?k}G6Sp;$=?QOr)GJ~p6_5p;r`1@%S-~Kkav#)3woz4p|_KWK4 zm7&D~l4Lc7T}5t^Br(DQlocQgu}WaM&9W>lUR)JgEMRdzTOunWn_Fgj8)5;T=OK>A zD@jYae;&+iHk(FRfbte(+ji#rA7L;UlzaiDQ@HL903b~l_W;mr=Eqq|sq%SV6#4=D;aXTj<~)mv{(SYuL@dwAs9>H`)$N=z73}7^k!rm zqtQt9^~z9IK`Ar^Py;WeJF(E?|+o;Hj=S9;4sy z6+FNsXi>oFg(d9m%SU1nJjZVew1vg_F}I2Z`hFY3VN^&%l#bN=o(EfW!UzRapjya|l3QQ6`t* z0eV;g>&7VlCulL5J3=NGRbR^vn+$>dGNQ-aCZ4f`Q65RH%N#J#?l90RqG4> Y0~R0y=v@s6*Z=?k07*qoM6N<$f>*Mv2><{9 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Walls/mining.rsi/miningB2.png b/Resources/Textures/Structures/Walls/mining.rsi/miningB2.png new file mode 100644 index 0000000000000000000000000000000000000000..f65f066b65aa26487dec4d03b79e560239294cff GIT binary patch literal 1192 zcmV;Z1XufsP)Px(Vo5|nRCt`-TTN=*Fckh$x|&^(jAj$M8cd<|08@jHP>L^CdWRfB;P?Qg5X7uX zH+C(P-E5}|^=V{{JxMFI7XBbiMwa8~`RTpy{pbb@W3$!d*BC z!dKcZV$TFG|f7^z#N*UnHe{#&seq& zFW`ba0)6KBTa;yquIua^Aq1q9Q0g)GdC3UCRc|tM08o}C?(gqMTcYnflw}F6^*S_Q ziue$^u0@{jFbq#tC^Wtr9^m?ar4A^H0!kf5a~QiFu|+esLLOi+9UizEa5}Aw3DOqG z^BwB?!R~n>wv+R>+iesLNWuoVZ#K)sNd2Xhzr8?f$As8IO1T~;2$=mm4E-N}h7zG* z0T7k_n|~e%kLN=XWeaf5QB~Efn&$ZqN&!Vtpzn#$>}HwX|3t6=7|T$WCBA+8IvVf$ zpD4?6#Mb)0yKrSoBiIWJLyxv?C$Eu47~lQ@N*yi|9ZMrv0E}h0adz?i8#a^X7~fKe zq5&?Z7@P6!^@z`>q6twnz$Ysd)BEET(_iEM{~N(Za2R@rteivEckkXqO8I+^(Fm9D zq=G13K&i*8u{q`QT%@uEqG-T=zXt$IVW+}ZADr_jR5ldBEbQ*?jSbzVl9uOdCei68 zKVwkYP(-1^A3uIV-*+Po05H-5r4ARx4W%9z7eEvnKn#x-=2m(LsaSm<(RsjgNKFt? zcz_SLyhXqJRzDS&7{vyJ+`qI9NG2t=6r$t2>|B>5)pDOJrSYQ5G^SR5EZ_esqL?n3g6wmInf(`jtWzdL|6qC z9){l5>k0mMiWXg@Vhf_!0M7Yr^~TK;xLqEpgu_uZpsK2iw0K=VpsFe;^_X-t>@Llz+-1}CEc0000Px)cu7P-RCt`-ThD9bMil#?ycD7+LJ$O?lx_wOm`o<{{dS2AmHRA&XKV)F zZzD;P&Eo-lwpaa@En#DLKqf43QNZQC<+hEn0MGNJXR~7FW%K9oJWq=S)b0ccaq-#q z89v;%@%&ka(+dlLjiZx!Ve*GJZNOGBF8XJ(ITmns`RGPK6xYLjyYK-=Cv%)$SU1Ya zaX{u;EI^qEwOYH`k6(O@>+6330H+rgj!x!F{T8#B|#T#Z9 zzn?$L@cQKz4)<*w?k}G6Sp;$=?QOr)GJ~p6_5p;r`1@%S-~Kkav#)3woz4p|_KWK4 zm7&D~l4Lc7T}5t^Br(DQlocQgu}WaM&9W>lUR)JgEMRdzTOunWn_Fgj8)5;T=OK>A zD@jYae;&+iHk(FRfbte(+ji#rA7L;UlzaiDQ@HL903b~l_W;mr=Eqq|sq%SV6#4=D;aXTj<~)mv{(SYuL@dwAs9>H`)$N=z73}7^k!rm zqtQt9^~z9IK`Ar^Py;WeJF(E?|+o;Hj=S9;4sy z6+FNsXi>oFg(d9m%SU1nJjZVew1vg_F}I2Z`hFY3VN^&%l#bN=o(EfW!UzRapjya|l3QQ6`t* z0eV;g>&7VlCulL5J3=NGRbR^vn+$>dGNQ-aCZ4f`Q65RH%N#J#?l90RqG4> Y0~R0y=v@s6*Z=?k07*qoM6N<$f>*Mv2><{9 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Walls/mining.rsi/miningB4.png b/Resources/Textures/Structures/Walls/mining.rsi/miningB4.png new file mode 100644 index 0000000000000000000000000000000000000000..1412f0026964552f50657b6c65ef5cb0c17fe7dc GIT binary patch literal 1446 zcmV;X1zGxuP)Px)U`a$lRCt`-ThD9bMilXKlGX`pgVHjzm3-Up z$bW?zknv$SLBHQe7)}5HQ4|%77jbglkZxBS2iye4nn;p){(N%Yz<0m=DgC`#IDm7W zUtPC@APAOup$IVo4v!Z~+SbAWrfF`>0gYvpi@i_J_+4&0qnoL=0MZd;8T zC14mv3IL2*NRrtbUl)solnv4jFbpHT>pu@b+5lNd4}ot#{}_8aukqu>9-=5hW651@ z+lKG^NRrud`T_=ne$MQG4#wlLZ1d8Pc0l{#CBk_FzaRfrct0AA;CUXx@Q?i6Y&Kn^ zx^+XzEKr`3Xugi)OvMSq2?m4y8k5rjN*r)<-pG6Qrd1l}{8r5GZ9&;INUOD~b-XyY zlcRKTf|3Xzae}z|ZN~X^tnY0?+5u%oMoU)F3A!ad5lX4BxMXFlSr9X*oUk=R;P7}+ zP-(<*Zdt8DU2?=G`Kt~{JD@7-({oy}U?bzVCIWz>I8im;MXjHDerqD&i;vzb5TSAc z)E&|esA7S{2^_}(fHkdOm+%J^5TOST?&D=*pxf;riXxb1miW5er|^BhP?yS7E4#Hq zW^0?YfI6W>50Lr%|6UIOfL^b+MsmtozWk2z#9|@0zb^~vB*>VR-&1nC$#?>(LUlp` z5n35>TY^J%MCa87B@tj*t>wuLGOU^Z0jmWPX#uX=foZn1hyZ1xD3ED>04jHN0HEK` z%7b84es=b%)+8w1c)Puu62YOBAU&7Y3FY$fcwGA|Q0p|vm{ofONKb=|Sujl#!{IO& zL8~CH3?0XT@B0PCxGqRLAW3HMJTE`WRxF$6iz9I;1VI4L^T0XZ4jvH4aX|=Kud_0q zB=abWw3r2y@__PExJnx=p8VJn9+0L*Jz#U)V%gS20ImC1@8$)aP<&5t97l@?P%;aA zvU7^}_YFLGoGxW@BNt2QI9n#1Jjy>8{2gyk1e{*n%atLzzSuYN9B_ENz{z=|u!nHK z7Ft9=?FS^K_2Bjh6CJ*i{r|IJ- z+8t0f;<`Nrv8>T(D49iScYtWbrfoKnQxuuzmPCN#tRIHFZe0!6ccX*XsdTm(0p2m#f%U z&>{lpzDhI|Q5IdbI4Ua(!!Xk4&p!p{(>IC$%W7dX3Z!#D?L&Yu3!G;sNH_g(icl`! zIvyZG++o_Z+q5-2po~qMtL6Kx;Q=zAmra8I0^6hPx)Wl2OqRCt`-Tfb`~M-={)tcuf}3b89|a5%zYMh#cEcwv#TG`Oft)U&3b3Y z8s6JC?|t*$Tfi_1g~H_F!%rvcURBq(bO@n}dc6+cznR`uL1`DYS`D2}2d?`W8jS`# z&kN@hLh$YVYXHDkKmDn+ws8g6b{W2Z1I7l^`%>h2qtU?0$q8Jy8jkt?4IXb7uvJtx z0DPqU3yNT@zwo)|d2roos34B5;sjU2obvj{6=2)t>9rJl`_Xx&L?x)g_!eNS4@#qB z^?Ducb~`p#RM6EhmkkBjb~&=Y0ifM(!*#3Zbb{@{*dS&dI)n#Opa91Dp`aqfF>d~g zw#d3Lt^nIE!*Lum8V&S%vrspgzFO6;n}V7 z`o|vUA$mc>>1Xs4lMzWeeaY zFB6$Xo*V#rJuej&pw$V=e4YO-UpbZ~L;eqFj{+i*kxy|l)60wn@CdL9IFYGTNGdEq z3lZ8XP7=@SJ3CKsad8gE*+4EA9dET-u8y2waXi8}}G0~YRAHb313tYDvCOSn>3gZ@_90laJzbK0XM31{^ zumCMgFi8oNc0mZ4^Iv?Pc^;s=1uV;gTM9y(Sit0=P6po|ja2(c1WO524(K~Hr< z0m@r|u|90Oyw)`hP~HN6{O~mZ;J3dXMG7003PG#Y0%Lu+ZWWYb8U=z#;5b28G#v$$ z74YH17+1p_E-ud_<8R-#(QGzB>HEld^vG=93bY)C`d?Pjrgyb`T`CpZtXHKc(DXvqigVx=e`KljUNauJ!Z0GVF_F4_`= zkW^TJvJ=ebEdY0T_55kL6+}gR|K%s)T(QLM-oM5#DX;)#1-yPY3=5>d%m)O5$D18Q z>YN51V6-+51PPU2zxy2H@i?*ll~L)oPJ3-b=77Wu~KF*th}$3+P71!~|+CmvoBM z_xX%*1teL3{L$2G?jUyJR7EPH0I(jJXPoD_~htq*958NFd+=M|+#f z>l@z!!B=A&bD#4NDHmQJKe*PizVYKQ?-5wH#ID+I{}1==6A-gv-!lLJ002ovPDHLk FV1kdcq8Px)U`a$lRCt`-ThD9bMilXKlGX`pgVHjzm3-Up z$bW?zknv$SLBHQe7)}5HQ4|%77jbglkZxBS2iye4nn;p){(N%Yz<0m=DgC`#IDm7W zUtPC@APAOup$IVo4v!Z~+SbAWrfF`>0gYvpi@i_J_+4&0qnoL=0MZd;8T zC14mv3IL2*NRrtbUl)solnv4jFbpHT>pu@b+5lNd4}ot#{}_8aukqu>9-=5hW651@ z+lKG^NRrud`T_=ne$MQG4#wlLZ1d8Pc0l{#CBk_FzaRfrct0AA;CUXx@Q?i6Y&Kn^ zx^+XzEKr`3Xugi)OvMSq2?m4y8k5rjN*r)<-pG6Qrd1l}{8r5GZ9&;INUOD~b-XyY zlcRKTf|3Xzae}z|ZN~X^tnY0?+5u%oMoU)F3A!ad5lX4BxMXFlSr9X*oUk=R;P7}+ zP-(<*Zdt8DU2?=G`Kt~{JD@7-({oy}U?bzVCIWz>I8im;MXjHDerqD&i;vzb5TSAc z)E&|esA7S{2^_}(fHkdOm+%J^5TOST?&D=*pxf;riXxb1miW5er|^BhP?yS7E4#Hq zW^0?YfI6W>50Lr%|6UIOfL^b+MsmtozWk2z#9|@0zb^~vB*>VR-&1nC$#?>(LUlp` z5n35>TY^J%MCa87B@tj*t>wuLGOU^Z0jmWPX#uX=foZn1hyZ1xD3ED>04jHN0HEK` z%7b84es=b%)+8w1c)Puu62YOBAU&7Y3FY$fcwGA|Q0p|vm{ofONKb=|Sujl#!{IO& zL8~CH3?0XT@B0PCxGqRLAW3HMJTE`WRxF$6iz9I;1VI4L^T0XZ4jvH4aX|=Kud_0q zB=abWw3r2y@__PExJnx=p8VJn9+0L*Jz#U)V%gS20ImC1@8$)aP<&5t97l@?P%;aA zvU7^}_YFLGoGxW@BNt2QI9n#1Jjy>8{2gyk1e{*n%atLzzSuYN9B_ENz{z=|u!nHK z7Ft9=?FS^K_2Bjh6CJ*i{r|IJ- z+8t0f;<`Nrv8>T(D49iScYtWbrfoKnQxuuzmPCN#tRIHFZe0!6ccX*XsdTm(0p2m#f%U z&>{lpzDhI|Q5IdbI4Ua(!!Xk4&p!p{(>IC$%W7dX3Z!#D?L&Yu3!G;sNH_g(icl`! zIvyZG++o_Z+q5-2po~qMtL6Kx;Q=zAmra8I0^6hPx&d`Uz>RCt{2TQO_fKotJmT0@m&a4sTRLJ7f^2a`bi144&VD1;W|xj&*yhOX(5 zrE|&HIfj-%A#~CZ$kM%vF{Yc0qh?U64t7xobB?SK$GUgn#M$2>$&!7(Pv70W_wGGF zF-+4;HZ~q7qDN}`Wf`5IVr^{=uInNQf|;JTZ5ywax&VM@?|+ioR!#t87It@c(Q38e zIMtcHb9Q!y`rZz%Ut1M)8r5r%yPK>)|8A`Gu)c>W5GQ^nRwf=*N-x38Q4#;nwN zWhx0_cm>8P<7*iTP(B30us?B~?qC+_d!49+6#B2v{gU zPyw=_oB+lwlmu6^X3ZqGubhCa0`6J{)6l{YO3wk=b^hkF*LK4G(??R;S580}_OZTh z!}r@$JI}#b1-{>wVg&*PFoYPh@OrsBw(SqU|DCwsteL2#`1KFR7cm^CI{u6b zji~S z0GWXF+s*6Gt2Tpyd$0p$_2);|8Yn;%NusF&@<0m(P>d066d+2177C!aq}nJTO+p@j zUJC`J-O@b%{OEZN6u@_A^7`|(Z5KiTWM80MF2kuH*XCxUu?^4j3ZVcpC|ld6Y0`sw zM39F-81})KC3GwT$V1@k+ZOs=3lWXij>Z5y8F;qvklaZKCar-DqtU@$}{ zDxr0fZ-3u)T^t>Kq&826G&>+~JRk@(i3b4b5Z59eFn{p?$_9lt3J~3^*Fpi5Lm?P7z~DZet1IaLt!#R(#qhSO&eMKoZqXj zUgsuIpqv24EPVO1IdeRL=OVmY)C(-?1s3%Jb6qc>O}e~lb67b6s?A~L1c)j?MwTd0 z00Kl6AY%mp3P6Bpy+9`_=}|BtS}&lL0&H8XUO)>&h%pPE=iQlKkgh9gG`3M+?n-H2 kxjW2r1Vp#ksp Date: Fri, 19 Jul 2024 05:04:43 -0400 Subject: [PATCH 062/134] Remove geras description in Slime Person guidebook page (#30140) remove entry --- Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml b/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml index 2c11508749e..976ab472a9c 100644 --- a/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml +++ b/Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml @@ -10,16 +10,8 @@ They exhale nitrous oxide and are unaffected by it. Their body can process 6 reagents at the same time instead of just 2. - Slimepeople can morph into a [bold]"geras"[/bold] (an archaic slimefolk term), which is a smaller slime form that can [bold]pass through grilles[/bold], - but forces them to drop their inventory and held items. It's handy for a quick getaway. A geras is small enough to pick up (with two hands) - and fits in a duffelbag. - - - - - Slimepeople have an [bold]internal 2x3 storage inventory[/bold] inside of their slime membrane. Anyone can see what's inside and take it out of you without asking, - so be careful. They [bold]don't drop their internal storage when they morph into a geras, however![/bold] + so be careful. Slimepeople have slight accelerated regeneration compared to other humanoids. They're also capable of hardening their fists, and as such have stronger punches, although they punch a little slower. From c4b6917cfcc315d4bcfb365fd615a487c2d28283 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 19 Jul 2024 09:05:50 +0000 Subject: [PATCH 063/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 74a116880f6..88915109f55 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: cooldolphin - changes: - - message: Three variants of glasses are now available in the loadout menu. - type: Add - id: 6435 - time: '2024-04-25T23:18:39.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27286 - author: EmoGarbage404 changes: - message: Traitors now have the correct number of objectives. @@ -3805,3 +3798,10 @@ id: 6934 time: '2024-07-19T01:08:52.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30115 +- author: deepdarkdepths + changes: + - message: Removed the description about geras in the Slime guidebook section. + type: Remove + id: 6935 + time: '2024-07-19T09:04:43.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30140 From 93dc22b67da22267c4e60600ea68a6b5deae6b0c Mon Sep 17 00:00:00 2001 From: Alzore <140123969+Blackern5000@users.noreply.github.com> Date: Fri, 19 Jul 2024 04:38:26 -0500 Subject: [PATCH 064/134] Add the Syndicate Raid Suit (#29845) * Syndicate Raid Suit * Raid suit speed and whitelist * Fix copyright for the syndicate raid helmet --- .../Locale/en-US/store/uplink-catalog.ftl | 3 + .../Catalog/Fills/Backpacks/duffelbag.yml | 13 ++++ .../Prototypes/Catalog/uplink_catalog.yml | 16 ++++ .../Entities/Clothing/Head/helmets.yml | 18 +++++ .../Entities/Clothing/OuterClothing/armor.yml | 72 ++++++++++++++++++ .../syndie-raid.rsi/equipped-HELMET-vox.png | Bin 0 -> 464 bytes .../syndie-raid.rsi/equipped-HELMET.png | Bin 0 -> 439 bytes .../Head/Helmets/syndie-raid.rsi/icon.png | Bin 0 -> 289 bytes .../Helmets/syndie-raid.rsi/inhand-left.png | Bin 0 -> 388 bytes .../Helmets/syndie-raid.rsi/inhand-right.png | Bin 0 -> 376 bytes .../Head/Helmets/syndie-raid.rsi/meta.json | 30 ++++++++ .../equipped-OUTERCLOTHING-light-vox.png | Bin 0 -> 264 bytes .../equipped-OUTERCLOTHING-light.png | Bin 0 -> 268 bytes .../equipped-OUTERCLOTHING-vox.png | Bin 0 -> 743 bytes .../equipped-OUTERCLOTHING.png | Bin 0 -> 740 bytes .../Armor/syndie-raid.rsi/icon.png | Bin 0 -> 349 bytes .../Armor/syndie-raid.rsi/inhand-left.png | Bin 0 -> 422 bytes .../Armor/syndie-raid.rsi/inhand-right.png | Bin 0 -> 412 bytes .../Armor/syndie-raid.rsi/light-overlay.png | Bin 0 -> 199 bytes .../Armor/syndie-raid.rsi/meta.json | 41 ++++++++++ 20 files changed, 193 insertions(+) create mode 100644 Resources/Textures/Clothing/Head/Helmets/syndie-raid.rsi/equipped-HELMET-vox.png create mode 100644 Resources/Textures/Clothing/Head/Helmets/syndie-raid.rsi/equipped-HELMET.png create mode 100644 Resources/Textures/Clothing/Head/Helmets/syndie-raid.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Head/Helmets/syndie-raid.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Head/Helmets/syndie-raid.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/Head/Helmets/syndie-raid.rsi/meta.json create mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/equipped-OUTERCLOTHING-light-vox.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/equipped-OUTERCLOTHING-light.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/equipped-OUTERCLOTHING-vox.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/equipped-OUTERCLOTHING.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/icon.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/light-overlay.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/meta.json diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index 2598970cefb..8edbde9bdc9 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -318,6 +318,9 @@ uplink-hardsuit-carp-desc = Looks like an ordinary carp suit, except fully space uplink-hardsuit-syndie-name = Syndicate Hardsuit uplink-hardsuit-syndie-desc = The Syndicate's well known armored blood red hardsuit, capable of space walks and bullet resistant. +uplink-syndie-raid-name = Syndicate Raid Suit +uplink-syndie-raid-desc = A very durable and reasonably flexible suit of blood-red armor, reinforced against all common forms of damage but not capable of space walks. Comes with a sick helmet. + uplink-hardsuit-syndieelite-name = Syndicate Elite Hardsuit uplink-hardsuit-syndieelite-desc = An elite version of the blood-red hardsuit, with improved mobility and fireproofing. Property of Gorlex Marauders. diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml index ae57ea63421..71d3f00df35 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/duffelbag.yml @@ -247,6 +247,19 @@ - id: DoubleEmergencyOxygenTankFilled - id: DoubleEmergencyNitrogenTankFilled +- type: entity + parent: ClothingBackpackDuffelSyndicateBundle + id: ClothingBackpackDuffelSyndicateRaidBundle + name: syndicate raid suit bundle + description: "Contains the Syndicate's durable raid armor suit." + components: + - type: StorageFill + contents: + - id: ClothingOuterArmorRaid + - id: ClothingHeadHelmetRaid + - id: ClothingMaskGasSyndicate + - id: ClothingHandsGlovesCombat + - type: entity parent: ClothingBackpackDuffelSyndicateBundle id: ClothingBackpackDuffelSyndicateHardsuitBundle diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index c9dc048cd38..420982dcaec 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -1298,6 +1298,22 @@ categories: - UplinkWearables +- type: listing + id: UplinkClothingOuterArmorRaid + name: uplink-syndie-raid-name + description: uplink-syndie-raid-desc + icon: { sprite: /Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi, state: icon } + productEntity: ClothingBackpackDuffelSyndicateRaidBundle + cost: + Telecrystal: 8 + categories: + - UplinkWearables + conditions: + - !type:StoreWhitelistCondition + whitelist: + tags: + - NukeOpsUplink + - type: listing id: UplinkHardsuitSyndieElite name: uplink-hardsuit-syndieelite-name diff --git a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml index a01d6fae519..b44508d4a37 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml @@ -357,6 +357,24 @@ - type: Clothing sprite: Clothing/Head/Helmets/ert_janitor.rsi +- type: entity + parent: ClothingHeadHelmetBasic + id: ClothingHeadHelmetRaid + name: syndicate raid helmet + description: An armored helmet for use with the syndicate raid suit. Very stylish. + components: + - type: Sprite + sprite: Clothing/Head/Helmets/syndie-raid.rsi + - type: Clothing + sprite: Clothing/Head/Helmets/syndie-raid.rsi + - type: Armor + modifiers: #There's gotta be SOME reason to use this over other helmets. + coefficients: + Blunt: 0.85 + Slash: 0.85 + Piercing: 0.85 + Heat: 0.85 + #Bone Helmet - type: entity parent: ClothingHeadHelmetBasic diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index 606af0b127a..6de0c78220f 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -99,6 +99,78 @@ reflects: - Energy +- type: entity + parent: [ClothingOuterBaseLarge, AllowSuitStorageClothing] + id: ClothingOuterArmorRaid + name: syndicate raid suit + description: A somewhat flexible and well-armored suit with a powerful shoulder mounted flashlight manufactured in the Gorlex Marauder's iconic blood-red color scheme, it does not protect it's wearer from space. + components: + - type: Sprite + sprite: Clothing/OuterClothing/Armor/syndie-raid.rsi + layers: + - state: icon + - state: light-overlay + visible: false + shader: unshaded + - type: Clothing + sprite: Clothing/OuterClothing/Armor/syndie-raid.rsi + - type: Armor + modifiers: + coefficients: + Blunt: 0.35 + Slash: 0.35 + Piercing: 0.35 + Heat: 0.35 + Caustic: 0.5 + - type: ExplosionResistance + damageCoefficient: 0.35 + - type: ClothingSpeedModifier + walkModifier: 0.9 + sprintModifier: 0.9 + #Shoulder mounted flashlight + - type: ToggleableLightVisuals + spriteLayer: light + clothingVisuals: + outerClothing: + - state: equipped-OUTERCLOTHING-light + shader: unshaded + - type: Appearance + - type: HandheldLight + addPrefix: false + blinkingBehaviourId: blinking + radiatingBehaviourId: radiating + - type: PointLight + enabled: false + color: "#80ff80" + radius: 5 + energy: 2 + mask: /Textures/Effects/LightMasks/cone.png + autoRot: true + netsync: false + - type: LightBehaviour + behaviours: + - !type:FadeBehaviour + id: radiating + interpolate: Linear + maxDuration: 2.0 + startValue: 3.0 + endValue: 2.0 + isLooped: true + reverseWhenFinished: true + - !type:PulseBehaviour + id: blinking + interpolate: Nearest + maxDuration: 1.0 + minValue: 0.1 + maxValue: 2.0 + isLooped: true + - type: Battery + maxCharge: 600 + startingCharge: 600 + - type: BatterySelfRecharger + autoRecharge: true + autoRechargeRate: 2 + - type: entity parent: ClothingOuterBaseLarge id: ClothingOuterArmorCult diff --git a/Resources/Textures/Clothing/Head/Helmets/syndie-raid.rsi/equipped-HELMET-vox.png b/Resources/Textures/Clothing/Head/Helmets/syndie-raid.rsi/equipped-HELMET-vox.png new file mode 100644 index 0000000000000000000000000000000000000000..c7ab17e261db024cc28cc4bd39ccd9b5c96b9e2c GIT binary patch literal 464 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O_~u2Ka=ydOBK|D5)edGlyE*WV*T^^$qqgFsxVCZusA@-rNePDzB9}XD2{24z1g*gj6B8wRq_>O=u<5X=vX`rQwo-U3d5$KYp zo1ahp)c&2EIj1>9HZ?vtR&m=uQ~n`y)x$JBlT(?8f81hY)r)t=;*IBdW1O3>m)3D1K|TW(6Tw5}F070Fl7`&Bbh>b$(8 z!l7TUpR=4Ut$MT~Do_0lqmk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O_~u2Ka=ydOBK|D5)edGlyE*WV*T^^$qqgFsxVCZusA@-rNePDzB9}XD2{24z1g*gj6B8wRq_zr?F*gaY|`gSWBu+v0fK#xHIwTw0HJA9&^9ExzxN|qQxZc_WQbyUk7uTqjob2MX5H| TzhwLcw4K4z)z4*}Q$iB}x@KnK literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Helmets/syndie-raid.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Helmets/syndie-raid.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..e8db961b7709cc1d13fba055e3128a3caa51f270 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`032l#}zdOBK|D5)edGlyE*9Q6(MFfgoF*KYXV0F;*(J!=G{I7@>3g8xGS zL$H5^5J<4VBeIx*f$snaGiF`ulFziEw{A?KIzE1s;~l)=&TAW6Um`I_5oP zMUekIXO3+%UFMi=kuPlIZs3k#Sks`XZ+Do*@Z5F%=TlbB6L9p3ICs3gAy)1^ci03k zt6xD&6sP`kxa!1W`Yr$HDweJP|G%|gp}&D6V3stm;1cEMH9fOu^xV3Wu_j?!Npp{H z1pC&l`%Evmacn!2m5{x!8)!q!1EvQ}`?*hi32r>e$IohJUC=mZ!k0Gk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`032l#}zdOBK|D5)edGlyE*9Q6(MFfgoF*KYXV0F;*(J!=G{I7@>3g8xGS zL$H5^5J<4VBeIx*f$snaGiF`uVFq{;NbRCFAJD{u<7Ts+qlFrREavMK94z3&HQ23@(aD*ce`Jke-+62SM_CGP3a1t zfg%kI9ZVnO4@iB!`!-)FG+x3?U*4l4*S99W|N`g~UXwE0V; zL~L4A#JFaiIk0I`^NUSSHu*6yxF3?5S9x>mwPL%XH2+muJq1VgW)$BG$(`~^`xkHO1>s-RwWNGrB=3e_GPZzmMvTy?$^1B+LS|ih_pf4;%)4?`V&Qj9jjvm;SU%sg@>jsA zeu?uE-c^FnKAhYeHM=n2c^-4upN%5k@7e#)oVHP_b3V{s5K#Yfc-Naxt2eHf4lp~m z*#F?luN7;p3QjrSmArB3PQxM}2cB{^w`X-=wbPA!^A&?kn+1*Z7JvjiUHx3vIVCg! E0L}ztoB#j- literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/equipped-OUTERCLOTHING-vox.png b/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/equipped-OUTERCLOTHING-vox.png new file mode 100644 index 0000000000000000000000000000000000000000..1ab6e6cfefe51dee46c988f49638bdb6991abdd1 GIT binary patch literal 743 zcmV?P)Px#1ZP1_K>z@;j|==^1poj5Ay7MMqCTIaN74 zNH8$~006-buL}SG01I?dPE-H?|NsC0|NsC007_2*@&Et;32;bRa{vGi!2kdb!2!6D zYwZ940ys%TK~z{r?N-~8>>volRiozrKX@A?33%Dm);SORFrCV%w01xph0cG(N8lsC z_@4r=T0u+K^QqGpMXAKt%Mq77Qe1vEP)yvSl=Dg<=A77vkTTuA7y-&DQeZ$Rn@=c& zKR_Rze*_}N7X}opkBS|C*9uWMj-%iWL`AI+m@gH4g@WN9DM(j+$~?aFMIOgLA;5wA zp+yK3TCJs(TASss8l`kQP(zaSun@krR`5Fh7Qhre0&b-RM3FtH@`m`hpcP_EX!>Z| zgTQwW!V~x{An4lw8$sJ6mb}#}*o1gcs>K6#rnBd*K!yUQr!4j%W6e8(gxx}AwUHTX z-qd+<2-AlJQ;P=(<#z%+{iYm&>2qa=6{wXNEoNX9h3~}$D}YZ2{apdd7|PpeBft{Z z&k{YhAwnnchSdjtC9uLr;3L5Ja{}{W{02XO;@6wPm_4}u5qH*$z?41M{x~&Ll#^c# z1B8lcd#G{>aOD7MaS(!&19$J)x*Xb^Bpho2W`cB53&RTVH;#iZ*JTWW?_G#{|C|8C zabj|UpausaY8~d;g@Y>tXEwW_76&0(+g~hbME2lE0eIkZ2iw5CPwc|xV&EGC4j=+c zJ2i$Zw$=wMsYw7KZf#_S002ovPDHLkV1h+HHWUB= literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/equipped-OUTERCLOTHING.png b/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/equipped-OUTERCLOTHING.png new file mode 100644 index 0000000000000000000000000000000000000000..e6a0733e3e7a11c8d9eb3f1203348634d169174b GIT binary patch literal 740 zcmVPx#1ZP1_K>z@;j|==^1poj5Ay7vPg zlxW}gf=8;>dZP2S)QLZ8g@|i~L#<3yto4NO=v|=U_*1GBu2#ymKX_)yOJN@Pw?HYG z_oL*CgzyakHiXzl{w+W`9RXBMmswQ4wN~&r{t!r*f}^;VRuDD`BB=UcD_jLo;bx_q z69{~dfRA3l=t$Tmf@|lFB|jR4@`kcl!;V5iZ=QD%KmnVqgb}QGC$M3+P}xF(74HSG zI(Us(V8M?D%SVDJ!*fB`W?CR8APZ=}OR(~ub^`d0`p+8J2jJyrfD@3x@q_}a0sIT0 zZ`d8M0nF;~0#8^B@H>G8J^~*B!G8BzMr{AQFH)Nq$fx0p;K`@}q!A;K0KDZ{`Ff2sqHD zH}nx?s+u2I!vv)&`Q*X94yLE+^==IllxmpjXbv_eT8j_yT+hQ~EHu z-(?2^O(7g6^X6_==mqZJ1?2L761csc*t~X0000B9}XD2{24z1g*gj6B8wRq_zr_Go-U3d7XEK11o9nL;BlVI%Jldj z`@GA`RM%YnW}C^kBEeR{^qBbH##qjVBS{xoJ~UVW-hB4pr}agAMMoY}hL&`rDUtLY2t7Di867xAXpqHaJ8kuCuk- zE79KnL5!itljSH!%T^|y)e(ZnQa-zj9e8YFcUbV4^?@xmdfTLab36R3{K;Y=#C=_M e!wdEX!#IO?%1Re@d_4_xIfJLGpUXO@geCxweu13; literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/inhand-left.png b/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..64d25308ab68dab7296df91bbd2c646a2ef7698b GIT binary patch literal 422 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`032l#}zCNVQN{BNjN*EUg7*(%59?`WCn>K8JN?v*SZ zX&$$@MDMfTFJ5eH{Gh02z?jG+ETB`7l6k0vTmQ}qH3~CuF-aCJgyYjbohQ0ZG{kWivL!KKf_g!Ntwcwsq92n5LU%8{3=eky@ z1?P*kul_eWiR!Vg*>k9g$NolHKc|nwi~}r3;yFdGuBct7?d+6UF2Xqf_tFPbx$=tl zKNUIC&XTv>;qX`CM?2-27b`X%Z?X_CiFsL**4Ne&=*{t}c)#k_&%F*@mza52zxRJ| zb?iA&yg&JZ2ve@df-*hUt8A$rJ97QY*L=u!T6l{an^LB{Ts5 D1;C-U literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/inhand-right.png b/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..fd3c44d4ad09e49a525fcb1f0e7f0ddd22400859 GIT binary patch literal 412 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`032l#}zCNVQN{BNjN*EUg7*(%59?`WCn>KB*Ojew1a#t3Op{mLmU79Pl|SMv67hF zd-L$ON`YlhDnA?u_$4I1!=bQ|TSS}T)b8~&Bx@@!nj1gg%dlv2pu=mg+uNodHF;&g z^h}^ca0Y*4ua%FJNV1QnTb8oG+#4C4UsqN$y6`GQIMr1(_DXpK>?;$TvEpNsLtpwU zJ?2Hs3K#y{{woj&P4N0w-?+k{bN*u{aSgqK#!ux;1ybAz!V?ZJ&`4m+VOpvo(>;eH zf?+m;9+!tgE!lvI6;>1s;*b3=DjSK$uZf!>a)(7~|>U7!u+B_EI8Og91<6!<#4fM7~bDcP7o} zgL}(F!K=Ry{5WDi+nMo$)GX6qg)2^eHjHKd@%piBG{?N%v)WYCS0B}y%FVm$X=poh qNGWqzX2|2qcE33p85sWgrLaa6iMXCUbW#Fn4}+(xpUXO@geCyZ)kISO literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/meta.json b/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/meta.json new file mode 100644 index 00000000000..ff590848daa --- /dev/null +++ b/Resources/Textures/Clothing/OuterClothing/Armor/syndie-raid.rsi/meta.json @@ -0,0 +1,41 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Made by alzore_(Discord) for SS14 using the colors of the blood-red hardsuit", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "light-overlay" + }, + { + "name": "equipped-OUTERCLOTHING", + "directions": 4 + }, + { + "name": "equipped-OUTERCLOTHING-light", + "directions": 4 + }, + { + "name": "equipped-OUTERCLOTHING-vox", + "directions": 4 + }, + { + "name": "equipped-OUTERCLOTHING-light-vox", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} From e7911c3720bc6feb0c5ca5313645300b2b03f3e3 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 19 Jul 2024 09:39:32 +0000 Subject: [PATCH 065/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 88915109f55..762d5d942d9 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,16 +1,4 @@ Entries: -- author: EmoGarbage404 - changes: - - message: Traitors now have the correct number of objectives. - type: Fix - - message: Declaring war now gives TC again. - type: Fix - - message: Latejoining antagonists will now properly exclude command and security - staff. - type: Fix - id: 6436 - time: '2024-04-26T00:25:57.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27319 - author: Tayrtahn changes: - message: Fixed Bibles not healing. @@ -3805,3 +3793,11 @@ id: 6935 time: '2024-07-19T09:04:43.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30140 +- author: Blackern5000 + changes: + - message: Nuclear operatives are now able to purchase durable armor which is NOT + space-proof. + type: Add + id: 6936 + time: '2024-07-19T09:38:26.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29845 From eaace152aeb30622849826572f2aab62f5575d3a Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Fri, 19 Jul 2024 11:42:58 +0200 Subject: [PATCH 066/134] Fix EmbeddableProjectileComponent and ThrowingAngleComponent interaction (#30112) * fix embeddable offset with throwing angle * number --- Content.Shared/Projectiles/SharedProjectileSystem.cs | 5 ++++- .../Prototypes/Entities/Objects/Weapons/Melee/spear.yml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Content.Shared/Projectiles/SharedProjectileSystem.cs b/Content.Shared/Projectiles/SharedProjectileSystem.cs index b718c3a6900..1f6f2b6918f 100644 --- a/Content.Shared/Projectiles/SharedProjectileSystem.cs +++ b/Content.Shared/Projectiles/SharedProjectileSystem.cs @@ -120,7 +120,10 @@ private void Embed(EntityUid uid, EntityUid target, EntityUid? user, EmbeddableP if (component.Offset != Vector2.Zero) { - _transform.SetLocalPosition(uid, xform.LocalPosition + xform.LocalRotation.RotateVec(component.Offset), + var rotation = xform.LocalRotation; + if (TryComp(uid, out var throwingAngleComp)) + rotation += throwingAngleComp.Angle; + _transform.SetLocalPosition(uid, xform.LocalPosition + rotation.RotateVec(component.Offset), xform); } diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index ea2e73ac151..608fb2544ae 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -5,7 +5,7 @@ description: Definition of a Classic. Keeping murder affordable since 200,000 BCE. components: - type: EmbeddableProjectile - offset: 0.15,0.15 + offset: -0.15,0.0 - type: ThrowingAngle angle: 225 - type: LandAtCursor From 58e5a7a6686c508578a547dd02f97ed4a9056d61 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 19 Jul 2024 09:44:04 +0000 Subject: [PATCH 067/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 762d5d942d9..bf3d66cacee 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: Tayrtahn - changes: - - message: Fixed Bibles not healing. - type: Fix - - message: Fixed quick insert and area insert not working on ore/plant/trash bags. - type: Fix - id: 6437 - time: '2024-04-26T02:25:52.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27234 - author: SkaldetSkaeg changes: - message: The handheld radio no longer plays a message spoken into it. @@ -3801,3 +3792,10 @@ id: 6936 time: '2024-07-19T09:38:26.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29845 +- author: Plykiya, slarticodefast + changes: + - message: Explosive pens now correctly embed into their target. + type: Fix + id: 6937 + time: '2024-07-19T09:42:58.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30112 From f2b9cd7a2536d75f52a4e5554524884d603a1c64 Mon Sep 17 00:00:00 2001 From: DakotaGay Date: Fri, 19 Jul 2024 16:18:39 +0200 Subject: [PATCH 068/134] Fix Markup Tags in Station News (#30169) * Fix (hopefully) * Fixed Spelling Mistake and minor Code Cleanup * Revert "Fixed Spelling Mistake and minor Code Cleanup" due to Pull Request Guidelines This reverts commit cee3e0226b349187bd8fd8b639e161fb877e8bdb. --- .../CartridgeLoader/Cartridges/NewsReaderUiFragment.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Client/CartridgeLoader/Cartridges/NewsReaderUiFragment.xaml.cs b/Content.Client/CartridgeLoader/Cartridges/NewsReaderUiFragment.xaml.cs index f3b2d373d74..2d4d192ea8a 100644 --- a/Content.Client/CartridgeLoader/Cartridges/NewsReaderUiFragment.xaml.cs +++ b/Content.Client/CartridgeLoader/Cartridges/NewsReaderUiFragment.xaml.cs @@ -31,7 +31,7 @@ public void UpdateState(NewsArticle article, int targetNum, int totalNum, bool n Author.Visible = true; PageName.Text = article.Title; - PageText.SetMarkup(article.Content); + PageText.SetMarkupPermissive(article.Content); PageNum.Text = $"{targetNum}/{totalNum}"; From 3c7d14ad50b06341366d411f4727fa92e3339d4d Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 19 Jul 2024 14:19:45 +0000 Subject: [PATCH 069/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index bf3d66cacee..dc929e08dc6 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: SkaldetSkaeg - changes: - - message: The handheld radio no longer plays a message spoken into it. - type: Tweak - id: 6438 - time: '2024-04-26T07:34:20.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27046 - author: FungiFellow changes: - message: Added SecBelt whitelist to Sec webbing @@ -3799,3 +3792,11 @@ id: 6937 time: '2024-07-19T09:42:58.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30112 +- author: ThatOneEnby1337 + changes: + - message: News Reporters are now able to use markup tags in their reports without + bricking the PDAs of readers + type: Fix + id: 6938 + time: '2024-07-19T14:18:39.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30169 From 5dfca4c2dce672b629a08e026f6763fd38f0ca99 Mon Sep 17 00:00:00 2001 From: themias <89101928+themias@users.noreply.github.com> Date: Fri, 19 Jul 2024 22:31:26 -0400 Subject: [PATCH 070/134] Fix mailing unit UI (#30174) --- Content.Client/Disposal/UI/MailingUnitWindow.xaml.cs | 9 +++++++-- Content.Server/Disposal/Mailing/MailingUnitSystem.cs | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Content.Client/Disposal/UI/MailingUnitWindow.xaml.cs b/Content.Client/Disposal/UI/MailingUnitWindow.xaml.cs index 797e20ae7d2..489d749a0cf 100644 --- a/Content.Client/Disposal/UI/MailingUnitWindow.xaml.cs +++ b/Content.Client/Disposal/UI/MailingUnitWindow.xaml.cs @@ -2,6 +2,7 @@ using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; +using Robust.Shared.Timing; namespace Content.Client.Disposal.UI { @@ -11,6 +12,8 @@ namespace Content.Client.Disposal.UI [GenerateTypedNameReferences] public sealed partial class MailingUnitWindow : DefaultWindow { + public TimeSpan FullPressure; + public MailingUnitWindow() { RobustXamlLoader.Load(this); @@ -26,6 +29,7 @@ public bool UpdateState(MailingUnitBoundUserInterfaceState state) Title = Loc.GetString("ui-mailing-unit-window-title", ("tag", state.Tag ?? " ")); UnitState.Text = disposalState.UnitState; + FullPressure = disposalState.FullPressureTime; var pressureReached = PressureBar.UpdatePressure(disposalState.FullPressureTime); Power.Pressed = disposalState.Powered; Engage.Pressed = disposalState.Engaged; @@ -42,9 +46,10 @@ public bool UpdateState(MailingUnitBoundUserInterfaceState state) return !disposalState.Powered || pressureReached; } - public bool UpdatePressure(TimeSpan stateFullPressureTime) + protected override void FrameUpdate(FrameEventArgs args) { - return PressureBar.UpdatePressure(stateFullPressureTime); + base.FrameUpdate(args); + PressureBar.UpdatePressure(FullPressure); } } } diff --git a/Content.Server/Disposal/Mailing/MailingUnitSystem.cs b/Content.Server/Disposal/Mailing/MailingUnitSystem.cs index e1fbdbf0894..6249b9497d8 100644 --- a/Content.Server/Disposal/Mailing/MailingUnitSystem.cs +++ b/Content.Server/Disposal/Mailing/MailingUnitSystem.cs @@ -9,6 +9,7 @@ using Content.Shared.Interaction; using Robust.Server.GameObjects; using Robust.Shared.Player; +using Robust.Shared.Utility; namespace Content.Server.Disposal.Mailing; @@ -35,7 +36,7 @@ public override void Initialize() SubscribeLocalEvent(OnPacketReceived); SubscribeLocalEvent(OnBeforeFlush); SubscribeLocalEvent(OnConfigurationUpdated); - SubscribeLocalEvent(HandleActivate); + SubscribeLocalEvent(HandleActivate, before: new[] { typeof(DisposalUnitSystem) }); SubscribeLocalEvent(OnDisposalUnitUIStateChange); SubscribeLocalEvent(OnTargetSelected); } @@ -179,7 +180,7 @@ private void UpdateUserInterface(EntityUid uid, MailingUnitComponent component) if (component.DisposalUnitInterfaceState == null) return; - var state = new MailingUnitBoundUserInterfaceState(component.DisposalUnitInterfaceState, component.Target, component.TargetList, component.Tag); + var state = new MailingUnitBoundUserInterfaceState(component.DisposalUnitInterfaceState, component.Target, component.TargetList.ShallowClone(), component.Tag); _userInterfaceSystem.SetUiState(uid, MailingUnitUiKey.Key, state); } From 93eeab2d10f3320aaf5e6533a3ae8a78320582ff Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 20 Jul 2024 02:32:34 +0000 Subject: [PATCH 071/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index dc929e08dc6..fcbbd0bc204 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: FungiFellow - changes: - - message: Added SecBelt whitelist to Sec webbing - type: Tweak - - message: Added more Ammo holders to SecBelt whitelist - type: Tweak - id: 6439 - time: '2024-04-26T07:44:41.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27303 - author: IlyaElDunaev changes: - message: Ammonia heal blood loss in the Rat King @@ -3800,3 +3791,10 @@ id: 6938 time: '2024-07-19T14:18:39.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30169 +- author: themias + changes: + - message: Mailing units are functional again + type: Fix + id: 6939 + time: '2024-07-20T02:31:26.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30174 From e6b171645c2f880a36ff23ca87933e91ba53ebcc Mon Sep 17 00:00:00 2001 From: Ghagliiarghii <68826635+Ghagliiarghii@users.noreply.github.com> Date: Fri, 19 Jul 2024 22:59:31 -0400 Subject: [PATCH 072/134] Give NukeOps Reinforcements an ID Card (in a PDA) (#28088) * Give NukeOps Reinforcements an ID Card (in a PDA) * add warning comment * create syndicateoperativegeatreinforcementnukeops in traitor.yml * revert fun/misc_startinggear.yml --- Resources/Prototypes/Entities/Mobs/Player/human.yml | 2 ++ Resources/Prototypes/Roles/Antags/traitor.yml | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml index 0b26668e103..cb0203ebe0e 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -38,6 +38,8 @@ id: MobHumanSyndicateAgentNukeops # Reinforcement exclusive to nukeops uplink suffix: Human, NukeOps components: + - type: Loadout + prototypes: [SyndicateOperativeGearReinforcementNukeOps] - type: NukeOperative # Nuclear Operative diff --git a/Resources/Prototypes/Roles/Antags/traitor.yml b/Resources/Prototypes/Roles/Antags/traitor.yml index 205f04b05ea..59390d2b103 100644 --- a/Resources/Prototypes/Roles/Antags/traitor.yml +++ b/Resources/Prototypes/Roles/Antags/traitor.yml @@ -36,6 +36,13 @@ - PinpointerSyndicateNuclear - DeathAcidifierImplanter +# Syndicate Reinforcement NukeOps +- type: startingGear + id: SyndicateOperativeGearReinforcementNukeOps + parent: SyndicateOperativeGearExtremelyBasic + equipment: + id: SyndiPDA #Do not give a PDA to the normal Reinforcement - it will spawn with a 20TC uplink + #Syndicate Operative Outfit - Basic - type: startingGear id: SyndicateOperativeGearBasic From aedf52f8ecc6bcce00a04580a26fdf0baf7d0155 Mon Sep 17 00:00:00 2001 From: JIPDawg <51352440+JIPDawg@users.noreply.github.com> Date: Fri, 19 Jul 2024 22:00:00 -0500 Subject: [PATCH 073/134] Removed references to pipestacking and changed example setup in Guidebook (#30181) Removed references to pipestacking and changed example setup Co-authored-by: JIP --- Resources/ServerInfo/Guidebook/Engineering/TEG.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Resources/ServerInfo/Guidebook/Engineering/TEG.xml b/Resources/ServerInfo/Guidebook/Engineering/TEG.xml index 63a62fecf80..786990c92f8 100644 --- a/Resources/ServerInfo/Guidebook/Engineering/TEG.xml +++ b/Resources/ServerInfo/Guidebook/Engineering/TEG.xml @@ -70,7 +70,7 @@ - The Space Vent - The Scrubber Array - Here is one layer of an example setup: (pipes can and do need to be layered under the scrubbers below to connect them!) + Here is one layer of an example setup: @@ -81,15 +81,15 @@ - - + + - - + + From 7683acab5e112a2674ce14d4cdd55a1c8c7f8a1e Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:00:28 -0700 Subject: [PATCH 074/134] Fix Chameleon Scarf menu being blank (#30156) fixa the scarfa Co-authored-by: plykiya --- .../Prototypes/Entities/Clothing/Neck/base_clothingneck.yml | 1 + Resources/Prototypes/Entities/Clothing/Neck/specific.yml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml index d7f04f49bc3..608f061dd89 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml @@ -39,3 +39,4 @@ tags: - Scarf - ClothMade + - WhitelistChameleon diff --git a/Resources/Prototypes/Entities/Clothing/Neck/specific.yml b/Resources/Prototypes/Entities/Clothing/Neck/specific.yml index 56fddceaad6..b98cdd02e0c 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/specific.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity parent: ClothingNeckBase id: ClothingNeckChameleon name: striped red scarf @@ -12,7 +12,7 @@ - type: Clothing sprite: Clothing/Neck/Scarfs/red.rsi - type: ChameleonClothing - slot: [neck] + slot: [NECK] default: ClothingNeckScarfStripedRed - type: UserInterface interfaces: From a2b021dffb89bdd2754832f860d117ec27ca9fcc Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 20 Jul 2024 03:01:35 +0000 Subject: [PATCH 075/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index fcbbd0bc204..09ab407edd9 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,18 +1,4 @@ Entries: -- author: IlyaElDunaev - changes: - - message: Ammonia heal blood loss in the Rat King - type: Add - id: 6440 - time: '2024-04-26T07:47:02.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/26887 -- author: FungiFellow - changes: - - message: Added Quiver Recipe, go wild Robin Hood. - type: Add - id: 6441 - time: '2024-04-26T07:48:15.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27198 - author: Boaz1111 changes: - message: Refactored Cluster's medbay, including cryo in the bottom left room @@ -3798,3 +3784,17 @@ id: 6939 time: '2024-07-20T02:31:26.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30174 +- author: Ghagliiarghii + changes: + - message: Nuclear Operatives' Reinforcements now have a PDA! + type: Tweak + id: 6940 + time: '2024-07-20T02:59:31.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28088 +- author: Plykiya + changes: + - message: Chameleon scarves now work again. + type: Fix + id: 6941 + time: '2024-07-20T03:00:28.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30156 From 78f3ffc2a45a4b74449478cd9dde4f319610b0df Mon Sep 17 00:00:00 2001 From: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:03:43 -0700 Subject: [PATCH 076/134] Make ActionsSystem.UpdateAction public (#30056) --- Content.Client/Actions/ActionsSystem.cs | 2 +- Content.Shared/Actions/SharedActionsSystem.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index aff6c1ff7be..7f261f5df2d 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -107,7 +107,7 @@ private void BaseHandleState(EntityUid uid, BaseActionComponent component, Ba UpdateAction(uid, component); } - protected override void UpdateAction(EntityUid? actionId, BaseActionComponent? action = null) + public override void UpdateAction(EntityUid? actionId, BaseActionComponent? action = null) { if (!ResolveActionData(actionId, ref action)) return; diff --git a/Content.Shared/Actions/SharedActionsSystem.cs b/Content.Shared/Actions/SharedActionsSystem.cs index ca6bd1dcc2a..0033078b1b7 100644 --- a/Content.Shared/Actions/SharedActionsSystem.cs +++ b/Content.Shared/Actions/SharedActionsSystem.cs @@ -237,7 +237,7 @@ private void OnRejuventate(EntityUid uid, ActionsComponent component, Rejuvenate } #region ComponentStateManagement - protected virtual void UpdateAction(EntityUid? actionId, BaseActionComponent? action = null) + public virtual void UpdateAction(EntityUid? actionId, BaseActionComponent? action = null) { // See client-side code. } From 6972bc26a703954921b32dd190db69192103ce10 Mon Sep 17 00:00:00 2001 From: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Date: Sat, 20 Jul 2024 05:18:34 +0200 Subject: [PATCH 077/134] Directional Fans (#27772) * Initial commit * Description update * Updated texture --- .../Piping/Atmospherics/special.yml | 29 ++++++++++++++++++ .../Atmospherics/directionalfan.rsi/icon.png | Bin 0 -> 16522 bytes .../Atmospherics/directionalfan.rsi/meta.json | 29 ++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 Resources/Textures/Structures/Piping/Atmospherics/directionalfan.rsi/icon.png create mode 100644 Resources/Textures/Structures/Piping/Atmospherics/directionalfan.rsi/meta.json diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/special.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/special.yml index 4eec014f11b..eff831fa9ea 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/special.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/special.yml @@ -25,3 +25,32 @@ - type: Tag tags: - SpreaderIgnore + +- type: entity + id: AtmosDeviceFanDirectional + name: directional fan + description: A thin fan, stopping the movement of gases across it. + placement: + mode: SnapgridCenter + components: + - type: Transform + anchored: true + - type: Physics + bodyType: Static + - type: Sprite + sprite: Structures/Piping/Atmospherics/directionalfan.rsi + state: icon + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.48,-0.48,0.48,-0.40" + - type: Airtight + noAirWhenFullyAirBlocked: false + airBlockedDirection: + - South + - type: Clickable + - type: Tag + tags: + - SpreaderIgnore diff --git a/Resources/Textures/Structures/Piping/Atmospherics/directionalfan.rsi/icon.png b/Resources/Textures/Structures/Piping/Atmospherics/directionalfan.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..577175edcd281daf52757d9005f3b4be3bc4794c GIT binary patch literal 16522 zcmeI4e{j>*9l#Y}nVSJ)Sv%-p;5sl^!ItFT7Pdng2a+qM88IbrkVKK?L=ao9C1WQW zNk&I0U4b5D3#F_b9lNF+bjOVXWn`h0(k*mZDWM%SgpH1L%lJ`XSs*3Jo@^&}UYvL7 z+PmF)vd)&i@B6;r?|Yx`(^t|T^2Yo{3&y2=I}O9Iae29p#b946eHE$T_f0!}3heIj z=Pna4Z2Sr7oAT4y<0oU7mEl~4Vxe;(#qeGY?dD5aP1x%Py@4(>?5CO4tf(wy%Q&A+ zb^W)EDkbN(sg@d?gwvnRmUFpP0k)uOk&CHX%~;&3OnaI&OaTX8R-~0-Z-q~w!ZuaJ zF9nXJW?ZF=bP-qER9R9$WuY@)nau}Sr9op>HeimQM3VblYusLhMR5FsyUgSLSFlQdDY$Wn-A z$O`64Wd~SV>{-kDXr;59|=8SAK?6P(;_`0 zFNu8<{J0s)!w0;yXy?3i8H@XUWmY`in9y@zRZ-b|1s?#zV(mIBo~${km4j!3(z4F- zF{}WRAtWRTq$+aaK17!dZtYi8aCVRsjhk~*jMhMyXb+<{)1*%AaqCI7nIz3>nkm&< zbe2*E99VJbbOlE7kw~5*t%GAEP5?DRDe+DxmFE*g8cZP15g88$#-nFJKqG5W8wfX{ z_GtBHwb@LwU{&aeQjd`_(PnpKH4HY7k1Xc8KYGmd$fp_|S%Ucx*N+4^P_pTYgg&2* zW;8?+H$y_@a#C(9A@EW*3fRX6x5jfDDXxAxAh1&Du&MfM$3Qg(T?anaNC~27Mk>p8 zMmn=u0C-Sqd|0p|iu4-ZiNJfr5FKE%%D_1@lA;y$ zI@k<$pZvT4j3Q@W1@}1;A<%0+UmEn5QkpdDb!s=Q*Q*&F_$hUhMzzUgwivWV3(1hi z{xtu$X)q9!&e&gE|95GSfJdV<<+QJib=&d&ne{jPUuAAY6)-yC&ziZUm&GqZ=Avif z;F{Qfl^9w>tlPZL5ngjG#^MSN(#p6XAZSs>h2{fkWn2&tv?$|3 z^MSN7E(i!(lyRZ?Kw23W1OzS0xX^qct&9r-f)-_5Xg-iu#svXEi!v@WA4n_Xf`Fh! zB(Ajho5QRRye=F9?*-q=^KJs~6f2qB#ZC;XngQNTejLN@^nv|9Ff2%5SVswlQQI+W zBEPlxt@#)>dRLw!%N0I<<>&i-yNP>qF6N#oymr@CuzT0`)ST1R?W^uRoqzbbb=P-g zYtDH#DNb*_e2$s_rp4Jh9X~m<^^N_1tempoM;`^+)0NoBx1)Qp_s_3*K6O#k^}daPv*q;_Z7o+P9IrpDU=&#$-Pxc~^^$Kg1sQ4Y3K7)`soAN ziap(rVLCgW5<-nRUe+5w4}#ed;hiCJ>54x zEx3-Y?#cZ18Pph^-RSkM7Eo0&#Zp1@YbY% zb&;F9GfVb4t9H!N-gjl~TwjCY#{K5E7w$Y*-TX?4x3AdqU|}{m8fSTVoq@RT9T!pX z#=@^;-f?}BQFiLUv==tJUVLueJZz-f7;Mn?`%`!8pS7)No!ZcQxBkV;o39HSoByaUVF*5Z~FQvZ(rU` zWUeZ!T>gjGTd>_z>$Xx@pRl4Sr;&a*>X5Eb%$1JjXMh%&5IrXW%Ji_iWo&Q#8K!hj?EAuiV%?trD-fQggSfa%1?P*?1D>VvO8@bquK*7$JWM@7BqosAb#4vz08#-78EH}4PE rckfNJn-#U-p9N|$|H9s}*t_3+K)CStye-nd1?1%{a=iLb$-4gl(nVV- literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Piping/Atmospherics/directionalfan.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/directionalfan.rsi/meta.json new file mode 100644 index 00000000000..217a9f3d782 --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/directionalfan.rsi/meta.json @@ -0,0 +1,29 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Made by SlamBamActionman", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "directions": 4, + "delays":[ + [ + 0.01,0.01,0.01,0.01 + ], + [ + 0.01,0.01,0.01,0.01 + ], + [ + 0.01,0.01,0.01,0.01 + ], + [ + 0.01,0.01,0.01,0.01 + ] + ] + } + ] +} From 8be13bf4955b43221c6537986dd4a72b4b87ebdb Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Sat, 20 Jul 2024 03:23:46 +0000 Subject: [PATCH 078/134] fix fish petting misprediction (#30175) * make fish petting ignore use delay * m * troll --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Friends/Systems/PettableFriendSystem.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Content.Shared/Friends/Systems/PettableFriendSystem.cs b/Content.Shared/Friends/Systems/PettableFriendSystem.cs index 00a4ddd155c..6e41f4bdea9 100644 --- a/Content.Shared/Friends/Systems/PettableFriendSystem.cs +++ b/Content.Shared/Friends/Systems/PettableFriendSystem.cs @@ -32,23 +32,23 @@ private void OnUseInHand(Entity ent, ref UseInHandEvent { var (uid, comp) = ent; var user = args.User; - if (args.Handled || !_exceptionQuery.TryGetComponent(uid, out var exceptionComp)) - return; - - if (_useDelayQuery.TryGetComponent(uid, out var useDelay) && !_useDelay.TryResetDelay((uid, useDelay), true)) + if (args.Handled || !_exceptionQuery.TryComp(uid, out var exceptionComp)) return; var exception = (uid, exceptionComp); - if (_factionException.IsIgnored(exception, user)) + if (!_factionException.IsIgnored(exception, user)) { - _popup.PopupClient(Loc.GetString(comp.FailureString, ("target", uid)), user, user); + // you have made a new friend :) + _popup.PopupClient(Loc.GetString(comp.SuccessString, ("target", uid)), user, user); + _factionException.IgnoreEntity(exception, user); + args.Handled = true; return; } - // you have made a new friend :) - _popup.PopupClient(Loc.GetString(comp.SuccessString, ("target", uid)), user, user); - _factionException.IgnoreEntity(exception, user); - args.Handled = true; + if (_useDelayQuery.TryComp(uid, out var useDelay) && !_useDelay.TryResetDelay((uid, useDelay), true)) + return; + + _popup.PopupClient(Loc.GetString(comp.FailureString, ("target", uid)), user, user); } private void OnRehydrated(Entity ent, ref GotRehydratedEvent args) From b04f98513c498c9994caaa7c8412e67a19dc6c3e Mon Sep 17 00:00:00 2001 From: CaasGit <87243814+CaasGit@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:36:22 -0700 Subject: [PATCH 079/134] fix(FaxVisualsSystem): Fax can Play() when a anim key has been added. (#30013) Adds a check to see if a faxecute animation is being played before playing another animation. The old code can thrown an exception which I've seen on live while ghosting. --- Content.Client/Fax/System/FaxVisualsSystem.cs | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Content.Client/Fax/System/FaxVisualsSystem.cs b/Content.Client/Fax/System/FaxVisualsSystem.cs index 892aec1d954..e752fbf48e6 100644 --- a/Content.Client/Fax/System/FaxVisualsSystem.cs +++ b/Content.Client/Fax/System/FaxVisualsSystem.cs @@ -25,24 +25,30 @@ private void OnAppearanceChanged(EntityUid uid, FaxMachineComponent component, r if (args.Sprite == null) return; - if (_appearance.TryGetData(uid, FaxMachineVisuals.VisualState, out FaxMachineVisualState visuals) && visuals == FaxMachineVisualState.Inserting) + if (_player.HasRunningAnimation(uid, "faxecute")) + return; + + if (_appearance.TryGetData(uid, FaxMachineVisuals.VisualState, out FaxMachineVisualState visuals) && + visuals == FaxMachineVisualState.Inserting) { - _player.Play(uid, new Animation() - { - Length = TimeSpan.FromSeconds(2.4), - AnimationTracks = + _player.Play(uid, + new Animation() { - new AnimationTrackSpriteFlick() + Length = TimeSpan.FromSeconds(2.4), + AnimationTracks = { - LayerKey = FaxMachineVisuals.VisualState, - KeyFrames = + new AnimationTrackSpriteFlick() { - new AnimationTrackSpriteFlick.KeyFrame(component.InsertingState, 0f), - new AnimationTrackSpriteFlick.KeyFrame("icon", 2.4f), - } - } - } - }, "faxecute"); + LayerKey = FaxMachineVisuals.VisualState, + KeyFrames = + { + new AnimationTrackSpriteFlick.KeyFrame(component.InsertingState, 0f), + new AnimationTrackSpriteFlick.KeyFrame("icon", 2.4f), + }, + }, + }, + }, + "faxecute"); } } } From 1783e0e4c2dc9e376c4fc1da91628e90d72e0c8a Mon Sep 17 00:00:00 2001 From: eoineoineoin Date: Sat, 20 Jul 2024 04:54:36 +0100 Subject: [PATCH 080/134] Add a background for OptionsButton popup (#29792) Add a reasonable background for OptionsButton popup Co-authored-by: Eoin Mcloughlin Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> --- Content.Client/Stylesheets/StyleNano.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Content.Client/Stylesheets/StyleNano.cs b/Content.Client/Stylesheets/StyleNano.cs index b9a4e63f315..dba48a119da 100644 --- a/Content.Client/Stylesheets/StyleNano.cs +++ b/Content.Client/Stylesheets/StyleNano.cs @@ -1343,6 +1343,9 @@ public StyleNano(IResourceCache resCache) : base(resCache) new StyleProperty(Label.StylePropertyAlignMode, Label.AlignMode.Center), }), + Element().Class(OptionButton.StyleClassOptionsBackground) + .Prop(PanelContainer.StylePropertyPanel, new StyleBoxFlat(Color.FromHex("#25252A"))), + new StyleRule(new SelectorElement(typeof(PanelContainer), new []{ ClassHighDivider}, null, null), new [] { new StyleProperty(PanelContainer.StylePropertyPanel, new StyleBoxFlat { BackgroundColor = NanoGold, ContentMarginBottomOverride = 2, ContentMarginLeftOverride = 2}), From 4aba9ec131a0fc716f985cff6476b6755df49e8c Mon Sep 17 00:00:00 2001 From: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:58:33 -0700 Subject: [PATCH 081/134] Fix NPC line of sight not working if trying to ranged target a blocking entity (#30055) --- Content.Server/NPC/Systems/NPCCombatSystem.Ranged.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Content.Server/NPC/Systems/NPCCombatSystem.Ranged.cs b/Content.Server/NPC/Systems/NPCCombatSystem.Ranged.cs index 10ec54c8954..d7196ea73c7 100644 --- a/Content.Server/NPC/Systems/NPCCombatSystem.Ranged.cs +++ b/Content.Server/NPC/Systems/NPCCombatSystem.Ranged.cs @@ -1,7 +1,6 @@ using Content.Server.NPC.Components; using Content.Shared.CombatMode; using Content.Shared.Interaction; -using Content.Shared.Physics; using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Events; using Robust.Shared.Map; @@ -134,7 +133,7 @@ private void UpdateRanged(float frameTime) { comp.LOSAccumulator += UnoccludedCooldown; // For consistency with NPC steering. - comp.TargetInLOS = _interaction.InRangeUnobstructed(uid, Transform(comp.Target).Coordinates, distance + 0.1f); + comp.TargetInLOS = _interaction.InRangeUnobstructed(uid, comp.Target, distance + 0.1f); } if (!comp.TargetInLOS) From cbf329a82d77eed2bb5e51666dab5d8a21fd3fff Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 20 Jul 2024 15:40:16 +1000 Subject: [PATCH 082/134] Remove some BUI boilerplate (#28399) * Remove some BUI boilerplate - The disposals overrides got removed due to the helper method handling it. - Replace window creation with CreateWindow helper. - Fixed some stinky code which would cause exceptions. * More * moar * weh * done * More BUIs * More updates * weh * moar * look who it is * weh * merge * weh * fixes --- .../UI/AccessOverriderBoundUserInterface.cs | 45 +++-- .../Access/UI/AccessOverriderWindow.xaml.cs | 41 ++--- .../UI/AgentIDCardBoundUserInterface.cs | 19 +- .../Access/UI/AgentIDCardWindow.xaml.cs | 10 +- .../Ame/UI/AmeControllerBoundUserInterface.cs | 16 +- Content.Client/Ame/UI/AmeWindow.xaml.cs | 19 +- .../Ui/AnomalyGeneratorBoundUserInterface.cs | 20 +- .../Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs | 8 +- Content.Client/Arcade/BlockGameMenu.cs | 45 +++-- .../Arcade/SpaceVillainArcadeMenu.cs | 45 ++--- .../Arcade/UI/BlockGameBoundUserInterface.cs | 5 +- .../SpaceVillainArcadeBoundUserInterface.cs | 16 +- .../Monitor/UI/AirAlarmBoundUserInterface.cs | 12 +- .../Atmos/Monitor/UI/AirAlarmWindow.xaml.cs | 7 +- .../Atmos/UI/GasCanisterBoundUserInterface.cs | 9 +- .../Atmos/UI/GasFilterBoundUserInterface.cs | 11 +- .../Atmos/UI/GasFilterWindow.xaml.cs | 7 +- .../Atmos/UI/GasMixerBoundUserInteface.cs | 18 +- .../UI/GasPressurePumpBoundUserInterface.cs | 17 +- .../UI/GasThermomachineBoundUserInterface.cs | 17 +- .../UI/GasVolumePumpBoundUserInterface.cs | 19 +- .../Atmos/UI/SpaceHeaterBoundUserInterface.cs | 10 +- .../Jukebox/JukeboxBoundUserInterface.cs | 21 +-- .../CryostorageBoundUserInterface.cs | 15 +- .../CargoBountyConsoleBoundUserInterface.cs | 17 +- .../CargoPalletConsoleBoundUserInterface.cs | 15 +- .../CargoShuttleConsoleBoundUserInterface.cs | 24 +-- .../Cargo/UI/CargoShuttleMenu.xaml.cs | 13 +- .../UI/ChemMasterBoundUserInterface.cs | 20 +- .../UI/ReagentDispenserBoundUserInterface.cs | 27 +-- .../UI/TransferAmountBoundUserInterface.cs | 12 +- .../UI/CloningConsoleBoundUserInterface.cs | 25 +-- .../UI/ChameleonBoundUserInterface.cs | 16 +- ...CommunicationsConsoleBoundUserInterface.cs | 72 +++----- .../UI/CommunicationsConsoleMenu.xaml.cs | 81 +++++---- .../Computer/ComputerBoundUserInterface.cs | 15 +- .../UI/ConfigurationBoundUserInterface.cs | 28 +-- .../Configurable/UI/ConfigurationMenu.cs | 18 +- .../UI/FlatpackCreatorBoundUserInterface.cs | 14 +- .../UI/FlatpackCreatorMenu.xaml.cs | 13 +- .../Crayon/UI/CrayonBoundUserInterface.cs | 40 ++-- Content.Client/Crayon/UI/CrayonWindow.xaml.cs | 18 +- .../UI/DisposalRouterBoundUserInterface.cs | 22 +-- .../UI/DisposalTaggerBoundUserInterface.cs | 23 +-- .../DoorElectronicsBoundUserInterface.cs | 31 ++-- .../DoorElectronicsConfigurationMenu.xaml.cs | 21 ++- Content.Client/Fax/UI/FaxBoundUi.cs | 12 +- .../ForensicScannerBoundUserInterface.cs | 15 +- .../Gateway/UI/GatewayBoundUserInterface.cs | 16 +- .../Gateway/UI/GatewayWindow.xaml.cs | 10 +- .../UI/GravityGeneratorBoundUserInterface.cs | 23 +-- .../Gravity/UI/GravityGeneratorWindow.xaml.cs | 15 +- .../UI/HealthAnalyzerBoundUserInterface.cs | 23 +-- ...manoidMarkingModifierBoundUserInterface.cs | 4 +- .../Instruments/UI/BandMenu.xaml.cs | 6 +- .../Instruments/UI/ChannelsMenu.xaml.cs | 5 +- .../UI/InstrumentBoundUserInterface.cs | 36 +++- .../Instruments/UI/InstrumentMenu.xaml.cs | 171 ++++++++++-------- .../Inventory/StrippableBoundUserInterface.cs | 25 ++- Content.Client/Kitchen/UI/GrinderMenu.xaml.cs | 42 ++--- .../Kitchen/UI/MicrowaveBoundUserInterface.cs | 43 +---- .../Kitchen/UI/MicrowaveMenu.xaml.cs | 24 ++- .../UI/ReagentGrinderBoundUserInterface.cs | 34 ++-- .../UI/HandLabelerBoundUserInterface.cs | 16 +- .../Lathe/UI/LatheBoundUserInterface.cs | 17 +- Content.Client/Lathe/UI/LatheMenu.xaml.cs | 29 +-- .../UI/SignalTimerBoundUserInterface.cs | 24 +-- .../UI/SignalTimerWindow.xaml.cs | 24 +-- .../MagicMirrorBoundUserInterface.cs | 15 +- .../Ui/NewsWriterBoundUserInterface.cs | 18 +- .../MassMedia/Ui/NewsWriterMenu.xaml.cs | 6 +- .../Mech/Ui/MechBoundUserInterface.cs | 16 +- Content.Client/Mech/Ui/MechMenu.xaml.cs | 9 +- .../CrewMonitoringBoundUserInterface.cs | 18 +- .../CrewMonitoringWindow.xaml.cs | 17 +- .../NetworkConfiguratorBoundUserInterface.cs | 39 ++-- ...tworkConfiguratorConfigurationMenu.xaml.cs | 8 +- .../NetworkConfiguratorDeviceList.xaml.cs | 12 +- .../NetworkConfiguratorLinkMenu.xaml.cs | 16 +- .../NetworkConfiguratorListMenu.xaml.cs | 13 +- Content.Client/Nuke/NukeBoundUserInterface.cs | 17 +- .../WarDeclaratorBoundUserInterface.cs | 18 +- .../NukeOps/WarDeclaratorWindow.xaml.cs | 9 +- Content.Client/PDA/PdaBoundUserInterface.cs | 17 +- .../PDA/Ringer/RingerBoundUserInterface.cs | 4 +- .../Paper/UI/PaperBoundUserInterface.cs | 17 +- Content.Client/Paper/UI/PaperWindow.xaml.cs | 6 +- .../ParticleAcceleratorBoundUserInterface.cs | 16 +- .../UI/ParticleAcceleratorControlMenu.cs | 30 +-- .../UI/NavMapBeaconBoundUserInterface.cs | 16 +- .../Pinpointer/UI/NavMapBeaconWindow.xaml.cs | 25 ++- .../UI/StationMapBoundUserInterface.cs | 15 +- .../Pinpointer/UI/StationMapWindow.xaml.cs | 11 +- .../UI/UntrackedMapBoundUserInterface.cs | 15 +- .../Power/APC/ApcBoundUserInterface.cs | 16 +- Content.Client/Power/APC/UI/ApcMenu.xaml.cs | 12 +- .../Power/Generator/GeneratorWindow.xaml.cs | 52 +++--- .../PortableGeneratorBoundUserInterface.cs | 25 ++- ...owerMonitoringConsoleBoundUserInterface.cs | 19 +- .../PowerMonitoringWindow.xaml.Widgets.cs | 6 +- .../Power/PowerMonitoringWindow.xaml.cs | 84 +++++---- Content.Client/RCD/RCDMenu.xaml.cs | 35 ++-- .../RCD/RCDMenuBoundUserInterface.cs | 16 +- .../Radio/Ui/IntercomBoundUserInterface.cs | 20 +- Content.Client/Radio/Ui/IntercomMenu.xaml.cs | 4 +- .../UI/DiskConsoleBoundUserInterface.cs | 15 +- .../UI/ResearchClientBoundUserInterface.cs | 16 +- .../ResearchClientServerSelectionMenu.xaml.cs | 11 +- .../UI/ResearchConsoleBoundUserInterface.cs | 28 +-- .../Research/UI/ResearchConsoleMenu.xaml.cs | 29 +-- .../UI/RoboticsConsoleBoundUserInterface.cs | 18 +- .../Robotics/UI/RoboticsConsoleWindow.xaml.cs | 25 ++- ...vageExpeditionConsoleBoundUserInterface.cs | 12 +- .../UI/SalvageMagnetBoundUserInterface.cs | 21 +-- .../BUI/IFFConsoleBoundUserInterface.cs | 4 +- .../BUI/RadarConsoleBoundUserInterface.cs | 14 +- .../BUI/ShuttleConsoleBoundUserInterface.cs | 5 +- .../Silicons/Borgs/BorgBoundUserInterface.cs | 18 +- Content.Client/Silicons/Borgs/BorgMenu.xaml | 2 +- .../Silicons/Borgs/BorgMenu.xaml.cs | 49 +++-- .../Laws/Ui/SiliconLawBoundUserInterface.cs | 14 +- .../UI/SprayPainterBoundUserInterface.cs | 27 +-- ...lStationRecordConsoleBoundUserInterface.cs | 13 +- .../Store/Ui/StoreBoundUserInterface.cs | 15 +- Content.Client/Strip/StrippingMenu.cs | 11 +- .../UI/SurveillanceCameraMonitorBoundUi.cs | 11 +- .../Thief/ThiefBackpackBoundUserInterface.cs | 19 +- .../Thief/ThiefBackpackMenu.xaml.cs | 28 ++- .../GasTank/GasTankBoundUserInterface.cs | 11 +- .../Systems/Atmos/GasTank/GasTankWindow.cs | 43 +++-- .../VendingMachineBoundUserInterface.cs | 8 +- .../VoiceMask/VoiceMaskBoundUserInterface.cs | 8 +- .../VoiceMaskNameChangeWindow.xaml.cs | 6 +- .../Melee/UI/MeleeSpeechBoundUserInterface.cs | 10 +- .../Wires/UI/WiresBoundUserInterface.cs | 7 +- Content.Client/Wires/UI/WiresMenu.cs | 16 +- .../Ui/AnalysisConsoleBoundUserInterface.cs | 6 +- 137 files changed, 1092 insertions(+), 1751 deletions(-) diff --git a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs index c1b63dc4d05..d80c600c03e 100644 --- a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs +++ b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.Containers.ItemSlots; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; using static Content.Shared.Access.Components.AccessOverriderComponent; @@ -23,6 +24,28 @@ protected override void Open() { base.Open(); + _window = this.CreateWindow(); + RefreshAccess(); + _window.Title = EntMan.GetComponent(Owner).EntityName; + _window.OnSubmit += SubmitData; + + _window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId)); + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + if (!args.WasModified()) + return; + + RefreshAccess(); + + if (State != null) + _window?.UpdateState(_prototypeManager, (AccessOverriderBoundUserInterfaceState) State); + } + + private void RefreshAccess() + { List> accessLevels; if (EntMan.TryGetComponent(Owner, out var accessOverrider)) @@ -30,38 +53,20 @@ protected override void Open() accessLevels = accessOverrider.AccessLevels; accessLevels.Sort(); } - else { accessLevels = new List>(); _accessOverriderSystem.Log.Error($"No AccessOverrider component found for {EntMan.ToPrettyString(Owner)}!"); } - _window = new AccessOverriderWindow(this, _prototypeManager, accessLevels) - { - Title = EntMan.GetComponent(Owner).EntityName - }; - - _window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId)); - - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); + _window?.SetAccessLevels(_prototypeManager, accessLevels); } protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); var castState = (AccessOverriderBoundUserInterfaceState) state; - _window?.UpdateState(castState); + _window?.UpdateState(_prototypeManager, castState); } public void SubmitData(List> newAccessList) diff --git a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs index 6025c3b551f..ba087718583 100644 --- a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs +++ b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs @@ -13,26 +13,24 @@ namespace Content.Client.Access.UI [GenerateTypedNameReferences] public sealed partial class AccessOverriderWindow : DefaultWindow { - [Dependency] private readonly ILogManager _logManager = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - - private readonly AccessOverriderBoundUserInterface _owner; private readonly Dictionary _accessButtons = new(); - public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototypeManager prototypeManager, - List> accessLevels) + public event Action>>? OnSubmit; + + public AccessOverriderWindow() { RobustXamlLoader.Load(this); - IoCManager.InjectDependencies(this); - var logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill); + } - _owner = owner; + public void SetAccessLevels(IPrototypeManager protoManager, List> accessLevels) + { + _accessButtons.Clear(); + AccessLevelGrid.DisposeAllChildren(); foreach (var access in accessLevels) { - if (!prototypeManager.TryIndex(access, out var accessLevel)) + if (!protoManager.TryIndex(access, out var accessLevel)) { - logMill.Error($"Unable to find accesslevel for {access}"); continue; } @@ -44,11 +42,16 @@ public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototype AccessLevelGrid.AddChild(newButton); _accessButtons.Add(accessLevel.ID, newButton); - newButton.OnPressed += _ => SubmitData(); + newButton.OnPressed += _ => + { + OnSubmit?.Invoke( + // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair + _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList()); + }; } } - public void UpdateState(AccessOverriderBoundUserInterfaceState state) + public void UpdateState(IPrototypeManager protoManager, AccessOverriderBoundUserInterfaceState state) { PrivilegedIdLabel.Text = state.PrivilegedIdName; PrivilegedIdButton.Text = state.IsPrivilegedIdPresent @@ -66,11 +69,11 @@ public void UpdateState(AccessOverriderBoundUserInterfaceState state) if (state.MissingPrivilegesList != null && state.MissingPrivilegesList.Any()) { - List missingPrivileges = new List(); + var missingPrivileges = new List(); foreach (string tag in state.MissingPrivilegesList) { - string privilege = Loc.GetString(_prototypeManager.Index(tag)?.Name ?? "generic-unknown"); + var privilege = Loc.GetString(protoManager.Index(tag)?.Name ?? "generic-unknown"); missingPrivileges.Add(privilege); } @@ -90,13 +93,5 @@ public void UpdateState(AccessOverriderBoundUserInterfaceState state) } } } - - private void SubmitData() - { - _owner.SubmitData( - - // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair - _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList()); - } } } diff --git a/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs b/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs index 761f52988a9..50add43dc91 100644 --- a/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs +++ b/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Access.Systems; using Content.Shared.StatusIcon; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Access.UI @@ -20,16 +21,11 @@ protected override void Open() { base.Open(); - _window?.Dispose(); - _window = new AgentIDCardWindow(this); - if (State != null) - UpdateState(State); + _window = this.CreateWindow(); - _window.OpenCentered(); - - _window.OnClose += Close; _window.OnNameChanged += OnNameChanged; _window.OnJobChanged += OnJobChanged; + _window.OnJobIconChanged += OnJobIconChanged; } private void OnNameChanged(string newName) @@ -61,14 +57,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetCurrentJob(cast.CurrentJob); _window.SetAllowedIcons(cast.Icons, cast.CurrentJobIconId); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); - } } } diff --git a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs index 6d0b2a184f4..071ce41a069 100644 --- a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs +++ b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs @@ -17,19 +17,19 @@ public sealed partial class AgentIDCardWindow : DefaultWindow [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IEntitySystemManager _entitySystem = default!; private readonly SpriteSystem _spriteSystem; - private readonly AgentIDCardBoundUserInterface _bui; private const int JobIconColumnCount = 10; public event Action? OnNameChanged; public event Action? OnJobChanged; - public AgentIDCardWindow(AgentIDCardBoundUserInterface bui) + public event Action>? OnJobIconChanged; + + public AgentIDCardWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); _spriteSystem = _entitySystem.GetEntitySystem(); - _bui = bui; NameLineEdit.OnTextEntered += e => OnNameChanged?.Invoke(e.Text); NameLineEdit.OnFocusExit += e => OnNameChanged?.Invoke(e.Text); @@ -67,7 +67,7 @@ public void SetAllowedIcons(HashSet> icons, string }; // Generate buttons textures - TextureRect jobIconTexture = new TextureRect + var jobIconTexture = new TextureRect { Texture = _spriteSystem.Frame0(jobIcon.Icon), TextureScale = new Vector2(2.5f, 2.5f), @@ -75,7 +75,7 @@ public void SetAllowedIcons(HashSet> icons, string }; jobIconButton.AddChild(jobIconTexture); - jobIconButton.OnPressed += _ => _bui.OnJobIconChanged(jobIconId); + jobIconButton.OnPressed += _ => OnJobIconChanged?.Invoke(jobIcon.ID); IconGrid.AddChild(jobIconButton); if (jobIconId.Equals(currentJobIconId)) diff --git a/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs b/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs index e84cf5d34de..3d65f751899 100644 --- a/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs +++ b/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Ame.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Ame.UI { @@ -16,9 +17,8 @@ protected override void Open() { base.Open(); - _window = new AmeWindow(this); - _window.OnClose += Close; - _window.OpenCentered(); + _window = this.CreateWindow(); + _window.OnAmeButton += ButtonPressed; } /// @@ -40,15 +40,5 @@ public void ButtonPressed(UiButton button) { SendMessage(new UiButtonPressedMessage(button)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } } } diff --git a/Content.Client/Ame/UI/AmeWindow.xaml.cs b/Content.Client/Ame/UI/AmeWindow.xaml.cs index 8b91ec59660..d6d580bcdaf 100644 --- a/Content.Client/Ame/UI/AmeWindow.xaml.cs +++ b/Content.Client/Ame/UI/AmeWindow.xaml.cs @@ -1,3 +1,4 @@ +using System.Linq; using Content.Client.UserInterface; using Content.Shared.Ame.Components; using Robust.Client.AutoGenerated; @@ -9,15 +10,17 @@ namespace Content.Client.Ame.UI [GenerateTypedNameReferences] public sealed partial class AmeWindow : DefaultWindow { - public AmeWindow(AmeControllerBoundUserInterface ui) + public event Action? OnAmeButton; + + public AmeWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - EjectButton.OnPressed += _ => ui.ButtonPressed(UiButton.Eject); - ToggleInjection.OnPressed += _ => ui.ButtonPressed(UiButton.ToggleInjection); - IncreaseFuelButton.OnPressed += _ => ui.ButtonPressed(UiButton.IncreaseFuel); - DecreaseFuelButton.OnPressed += _ => ui.ButtonPressed(UiButton.DecreaseFuel); + EjectButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.Eject); + ToggleInjection.OnPressed += _ => OnAmeButton?.Invoke(UiButton.ToggleInjection); + IncreaseFuelButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.IncreaseFuel); + DecreaseFuelButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.DecreaseFuel); } /// @@ -29,7 +32,7 @@ public void UpdateState(BoundUserInterfaceState state) var castState = (AmeControllerBoundUserInterfaceState) state; // Disable all buttons if not powered - if (Contents.Children != null) + if (Contents.Children.Any()) { ButtonHelpers.SetButtonDisabledRecursive(Contents, !castState.HasPower); EjectButton.Disabled = false; @@ -65,8 +68,8 @@ public void UpdateState(BoundUserInterfaceState state) CoreCount.Text = $"{castState.CoreCount}"; InjectionAmount.Text = $"{castState.InjectionAmount}"; // format power statistics to pretty numbers - CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply.ToString("N1")}"; - TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply.ToString("N1")}"; + CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply:N1}"; + TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply:N1}"; } } } diff --git a/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs b/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs index 5764d0a097d..5d1985485c4 100644 --- a/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs +++ b/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Gravity; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Anomaly.Ui; @@ -18,10 +19,8 @@ protected override void Open() { base.Open(); - _window = new(Owner); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.SetEntity(Owner); _window.OnGenerateButtonPressed += () => { @@ -37,18 +36,5 @@ protected override void UpdateState(BoundUserInterfaceState state) return; _window?.UpdateState(msg); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _window?.Dispose(); - } - - public void SetPowerSwitch(bool on) - { - SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on)); - } } diff --git a/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs b/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs index 08438e2a1b2..82d41192dd0 100644 --- a/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs +++ b/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs @@ -18,17 +18,21 @@ public sealed partial class AnomalyGeneratorWindow : FancyWindow public Action? OnGenerateButtonPressed; - public AnomalyGeneratorWindow(EntityUid gen) + public AnomalyGeneratorWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - EntityView.SetEntity(gen); EntityView.SpriteOffset = false; GenerateButton.OnPressed += _ => OnGenerateButtonPressed?.Invoke(); } + public void SetEntity(EntityUid uid) + { + EntityView.SetEntity(uid); + } + public void UpdateState(AnomalyGeneratorUserInterfaceState state) { _cooldownEnd = state.CooldownEndTime; diff --git a/Content.Client/Arcade/BlockGameMenu.cs b/Content.Client/Arcade/BlockGameMenu.cs index eeda2a31020..4a579fc4bf4 100644 --- a/Content.Client/Arcade/BlockGameMenu.cs +++ b/Content.Client/Arcade/BlockGameMenu.cs @@ -28,8 +28,6 @@ public sealed class BlockGameMenu : DefaultWindow private static readonly Vector2 BlockSize = new(15, 15); - private readonly BlockGameBoundUserInterface _owner; - private readonly PanelContainer _mainPanel; private readonly BoxContainer _gameRootContainer; @@ -58,10 +56,11 @@ public sealed class BlockGameMenu : DefaultWindow private bool _isPlayer = false; private bool _gameOver = false; - public BlockGameMenu(BlockGameBoundUserInterface owner) + public event Action? OnAction; + + public BlockGameMenu() { Title = Loc.GetString("blockgame-menu-title"); - _owner = owner; MinSize = SetSize = new Vector2(410, 490); @@ -176,7 +175,7 @@ public BlockGameMenu(BlockGameBoundUserInterface owner) }; _newGameButton.OnPressed += (e) => { - _owner.SendAction(BlockGamePlayerAction.NewGame); + OnAction?.Invoke(BlockGamePlayerAction.NewGame); }; pauseMenuContainer.AddChild(_newGameButton); pauseMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) }); @@ -186,7 +185,10 @@ public BlockGameMenu(BlockGameBoundUserInterface owner) Text = Loc.GetString("blockgame-menu-button-scoreboard"), TextAlign = Label.AlignMode.Center }; - _scoreBoardButton.OnPressed += (e) => _owner.SendAction(BlockGamePlayerAction.ShowHighscores); + _scoreBoardButton.OnPressed += (e) => + { + OnAction?.Invoke(BlockGamePlayerAction.ShowHighscores); + }; pauseMenuContainer.AddChild(_scoreBoardButton); _unpauseButtonMargin = new Control { MinSize = new Vector2(1, 10), Visible = false }; pauseMenuContainer.AddChild(_unpauseButtonMargin); @@ -199,7 +201,7 @@ public BlockGameMenu(BlockGameBoundUserInterface owner) }; _unpauseButton.OnPressed += (e) => { - _owner.SendAction(BlockGamePlayerAction.Unpause); + OnAction?.Invoke(BlockGamePlayerAction.Unpause); }; pauseMenuContainer.AddChild(_unpauseButton); @@ -257,7 +259,7 @@ public BlockGameMenu(BlockGameBoundUserInterface owner) }; _finalNewGameButton.OnPressed += (e) => { - _owner.SendAction(BlockGamePlayerAction.NewGame); + OnAction?.Invoke(BlockGamePlayerAction.NewGame); }; gameOverMenuContainer.AddChild(_finalNewGameButton); @@ -327,7 +329,10 @@ public BlockGameMenu(BlockGameBoundUserInterface owner) Text = Loc.GetString("blockgame-menu-button-back"), TextAlign = Label.AlignMode.Center }; - _highscoreBackButton.OnPressed += (e) => _owner.SendAction(BlockGamePlayerAction.Pause); + _highscoreBackButton.OnPressed += (e) => + { + OnAction?.Invoke(BlockGamePlayerAction.Pause); + }; menuContainer.AddChild(_highscoreBackButton); menuInnerPanel.AddChild(menuContainer); @@ -473,7 +478,7 @@ protected override void KeyboardFocusExited() private void TryPause() { - _owner.SendAction(BlockGamePlayerAction.Pause); + OnAction?.Invoke(BlockGamePlayerAction.Pause); } public void SetStarted() @@ -576,19 +581,19 @@ protected override void KeyBindDown(GUIBoundKeyEventArgs args) return; else if (args.Function == ContentKeyFunctions.ArcadeLeft) - _owner.SendAction(BlockGamePlayerAction.StartLeft); + OnAction?.Invoke(BlockGamePlayerAction.StartLeft); else if (args.Function == ContentKeyFunctions.ArcadeRight) - _owner.SendAction(BlockGamePlayerAction.StartRight); + OnAction?.Invoke(BlockGamePlayerAction.StartRight); else if (args.Function == ContentKeyFunctions.ArcadeUp) - _owner.SendAction(BlockGamePlayerAction.Rotate); + OnAction?.Invoke(BlockGamePlayerAction.Rotate); else if (args.Function == ContentKeyFunctions.Arcade3) - _owner.SendAction(BlockGamePlayerAction.CounterRotate); + OnAction?.Invoke(BlockGamePlayerAction.CounterRotate); else if (args.Function == ContentKeyFunctions.ArcadeDown) - _owner.SendAction(BlockGamePlayerAction.SoftdropStart); + OnAction?.Invoke(BlockGamePlayerAction.SoftdropStart); else if (args.Function == ContentKeyFunctions.Arcade2) - _owner.SendAction(BlockGamePlayerAction.Hold); + OnAction?.Invoke(BlockGamePlayerAction.Hold); else if (args.Function == ContentKeyFunctions.Arcade1) - _owner.SendAction(BlockGamePlayerAction.Harddrop); + OnAction?.Invoke(BlockGamePlayerAction.Harddrop); } protected override void KeyBindUp(GUIBoundKeyEventArgs args) @@ -599,11 +604,11 @@ protected override void KeyBindUp(GUIBoundKeyEventArgs args) return; else if (args.Function == ContentKeyFunctions.ArcadeLeft) - _owner.SendAction(BlockGamePlayerAction.EndLeft); + OnAction?.Invoke(BlockGamePlayerAction.EndLeft); else if (args.Function == ContentKeyFunctions.ArcadeRight) - _owner.SendAction(BlockGamePlayerAction.EndRight); + OnAction?.Invoke(BlockGamePlayerAction.EndRight); else if (args.Function == ContentKeyFunctions.ArcadeDown) - _owner.SendAction(BlockGamePlayerAction.SoftdropEnd); + OnAction?.Invoke(BlockGamePlayerAction.SoftdropEnd); } public void UpdateNextBlock(BlockGameBlock[] blocks) diff --git a/Content.Client/Arcade/SpaceVillainArcadeMenu.cs b/Content.Client/Arcade/SpaceVillainArcadeMenu.cs index e5542a5848e..1ee4c268184 100644 --- a/Content.Client/Arcade/SpaceVillainArcadeMenu.cs +++ b/Content.Client/Arcade/SpaceVillainArcadeMenu.cs @@ -8,8 +8,6 @@ namespace Content.Client.Arcade { public sealed class SpaceVillainArcadeMenu : DefaultWindow { - public SpaceVillainArcadeBoundUserInterface Owner { get; set; } - private readonly Label _enemyNameLabel; private readonly Label _playerInfoLabel; private readonly Label _enemyInfoLabel; @@ -17,11 +15,13 @@ public sealed class SpaceVillainArcadeMenu : DefaultWindow private readonly Label _enemyActionLabel; private readonly Button[] _gameButtons = new Button[3]; //used to disable/enable all game buttons - public SpaceVillainArcadeMenu(SpaceVillainArcadeBoundUserInterface owner) + + public event Action? OnPlayerAction; + + public SpaceVillainArcadeMenu() { MinSize = SetSize = new Vector2(300, 225); Title = Loc.GetString("spacevillain-menu-title"); - Owner = owner; var grid = new GridContainer { Columns = 1 }; @@ -47,32 +47,43 @@ public SpaceVillainArcadeMenu(SpaceVillainArcadeBoundUserInterface owner) grid.AddChild(_enemyActionLabel); var buttonGrid = new GridContainer { Columns = 3 }; - _gameButtons[0] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Attack) + _gameButtons[0] = new Button() { Text = Loc.GetString("spacevillain-menu-button-attack") }; + + _gameButtons[0].OnPressed += + _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Attack); buttonGrid.AddChild(_gameButtons[0]); - _gameButtons[1] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Heal) + _gameButtons[1] = new Button() { Text = Loc.GetString("spacevillain-menu-button-heal") }; + + _gameButtons[1].OnPressed += + _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Heal); buttonGrid.AddChild(_gameButtons[1]); - _gameButtons[2] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Recharge) + _gameButtons[2] = new Button() { Text = Loc.GetString("spacevillain-menu-button-recharge") }; + + _gameButtons[2].OnPressed += + _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Recharge); buttonGrid.AddChild(_gameButtons[2]); centerContainer = new CenterContainer(); centerContainer.AddChild(buttonGrid); grid.AddChild(centerContainer); - var newGame = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.NewGame) + var newGame = new Button() { Text = Loc.GetString("spacevillain-menu-button-new-game") }; + + newGame.OnPressed += _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.NewGame); grid.AddChild(newGame); Contents.AddChild(grid); @@ -99,23 +110,5 @@ public void UpdateInfo(SharedSpaceVillainArcadeComponent.SpaceVillainArcadeDataU _playerActionLabel.Text = message.PlayerActionMessage; _enemyActionLabel.Text = message.EnemyActionMessage; } - - private sealed class ActionButton : Button - { - private readonly SpaceVillainArcadeBoundUserInterface _owner; - private readonly SharedSpaceVillainArcadeComponent.PlayerAction _playerAction; - - public ActionButton(SpaceVillainArcadeBoundUserInterface owner, SharedSpaceVillainArcadeComponent.PlayerAction playerAction) - { - _owner = owner; - _playerAction = playerAction; - OnPressed += Clicked; - } - - private void Clicked(ButtonEventArgs e) - { - _owner.SendAction(_playerAction); - } - } } } diff --git a/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs b/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs index 1a3422dec0f..8fa8035afd6 100644 --- a/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs +++ b/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Arcade; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Arcade.UI; @@ -15,9 +16,7 @@ protected override void Open() { base.Open(); - _menu = new BlockGameMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); } protected override void ReceiveMessage(BoundUserInterfaceMessage message) diff --git a/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs b/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs index 40bbe8b2d8c..c0704530de2 100644 --- a/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs +++ b/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs @@ -1,4 +1,5 @@ using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.GameObjects; using Robust.Shared.ViewVariables; using static Content.Shared.Arcade.SharedSpaceVillainArcadeComponent; @@ -9,8 +10,6 @@ public sealed class SpaceVillainArcadeBoundUserInterface : BoundUserInterface { [ViewVariables] private SpaceVillainArcadeMenu? _menu; - //public SharedSpaceVillainArcadeComponent SpaceVillainArcade; - public SpaceVillainArcadeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { SendAction(PlayerAction.RequestData); @@ -25,10 +24,7 @@ protected override void Open() { base.Open(); - _menu = new SpaceVillainArcadeMenu(this); - - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); } protected override void ReceiveMessage(BoundUserInterfaceMessage message) @@ -36,12 +32,4 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) if (message is SpaceVillainArcadeDataUpdateMessage msg) _menu?.UpdateInfo(msg); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - _menu?.Dispose(); - } } diff --git a/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs b/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs index 8f3b507c806..2ae15188355 100644 --- a/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs +++ b/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Monitor.Components; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Log; @@ -20,16 +21,9 @@ protected override void Open() { base.Open(); - _window = new AirAlarmWindow(this); + _window = this.CreateWindow(); + _window.SetEntity(Owner); - if (State != null) - { - UpdateState(State); - } - - _window.OpenCentered(); - - _window.OnClose += Close; _window.AtmosDeviceDataChanged += OnDeviceDataChanged; _window.AtmosDeviceDataCopied += OnDeviceDataCopied; _window.AtmosAlarmThresholdChanged += OnThresholdChanged; diff --git a/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs b/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs index 43be67c9d6b..eeec11c7660 100644 --- a/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs +++ b/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs @@ -47,7 +47,7 @@ public sealed partial class AirAlarmWindow : FancyWindow private CheckBox _autoMode => AutoModeCheckBox; - public AirAlarmWindow(BoundUserInterface owner) + public AirAlarmWindow() { RobustXamlLoader.Load(this); @@ -95,8 +95,11 @@ public AirAlarmWindow(BoundUserInterface owner) _sensors.Clear(); ResyncAllRequested!.Invoke(); }; + } - EntityView.SetEntity(owner.Owner); + public void SetEntity(EntityUid uid) + { + EntityView.SetEntity(uid); } public void UpdateState(AirAlarmUIState state) diff --git a/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs b/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs index a5e316a8def..7bf9b396d5e 100644 --- a/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Atmos.Piping.Binary.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -21,14 +22,8 @@ protected override void Open() { base.Open(); - _window = new GasCanisterWindow(); + _window = this.CreateWindow(); - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; _window.ReleaseValveCloseButtonPressed += OnReleaseValveClosePressed; _window.ReleaseValveOpenButtonPressed += OnReleaseValveOpenPressed; _window.ReleasePressureSet += OnReleasePressureSet; diff --git a/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs b/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs index 1904e2b3402..2b8020924cf 100644 --- a/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Atmos.Piping.Trinary.Components; using Content.Shared.Localizations; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -28,14 +29,8 @@ protected override void Open() var atmosSystem = EntMan.System(); - _window = new GasFilterWindow(atmosSystem.Gases); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.PopulateGasList(atmosSystem.Gases); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.FilterTransferRateChanged += OnFilterTransferRatePressed; diff --git a/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs b/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs index 28766c688a0..62748b52592 100644 --- a/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs +++ b/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs @@ -26,10 +26,9 @@ public sealed partial class GasFilterWindow : DefaultWindow public event Action? FilterTransferRateChanged; public event Action? SelectGasPressed; - public GasFilterWindow(IEnumerable gases) + public GasFilterWindow() { RobustXamlLoader.Load(this); - PopulateGasList(gases); ToggleStatusButton.OnPressed += _ => SetFilterStatus(!FilterStatus); ToggleStatusButton.OnPressed += _ => ToggleStatusButtonPressed?.Invoke(); @@ -73,7 +72,7 @@ public void SetGasFiltered(string? id, string name) SelectGasButton.Disabled = true; } - private void PopulateGasList(IEnumerable gases) + public void PopulateGasList(IEnumerable gases) { GasList.Add(new ItemList.Item(GasList) { @@ -81,7 +80,7 @@ private void PopulateGasList(IEnumerable gases) Text = Loc.GetString("comp-gas-filter-ui-filter-gas-none") }); - foreach (GasPrototype gas in gases) + foreach (var gas in gases) { var gasName = Loc.GetString(gas.Name); GasList.Add(GetGasItem(gas.ID, gasName, GasList)); diff --git a/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs b/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs index 709c06517cb..392fbf1cd9a 100644 --- a/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs +++ b/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs @@ -2,7 +2,7 @@ using Content.Shared.Atmos.Piping.Trinary.Components; using Content.Shared.Localizations; using JetBrains.Annotations; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -26,14 +26,7 @@ protected override void Open() { base.Open(); - _window = new GasMixerWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.MixerOutputPressureChanged += OnMixerOutputPressurePressed; @@ -83,12 +76,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetOutputPressure(cast.OutputPressure); _window.SetNodePercentages(cast.NodeOne); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs b/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs index 6eba2e0d215..220fdbe875c 100644 --- a/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Localizations; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -26,14 +27,7 @@ protected override void Open() { base.Open(); - _window = new GasPressurePumpWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.PumpOutputPressureChanged += OnPumpOutputPressurePressed; @@ -67,12 +61,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetPumpStatus(cast.Enabled); _window.SetOutputPressure(cast.OutputPressure); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs b/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs index 1664c8b9d75..d62be8f4bb4 100644 --- a/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Atmos.Piping.Unary.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -31,14 +32,7 @@ protected override void Open() { base.Open(); - _window = new GasThermomachineWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed(); _window.TemperatureSpinbox.OnValueChanged += _ => OnTemperatureChanged(_window.TemperatureSpinbox.Value); @@ -91,12 +85,5 @@ protected override void UpdateState(BoundUserInterfaceState state) true => Loc.GetString("comp-gas-thermomachine-ui-title-heater") }; } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs b/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs index 1b39306181a..642f34c2f92 100644 --- a/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Localizations; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -26,14 +27,7 @@ protected override void Open() { base.Open(); - _window = new GasVolumePumpWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.PumpTransferRateChanged += OnPumpTransferRatePressed; @@ -64,16 +58,9 @@ protected override void UpdateState(BoundUserInterfaceState state) if (_window == null || state is not GasVolumePumpBoundUserInterfaceState cast) return; - _window.Title = (cast.PumpLabel); + _window.Title = cast.PumpLabel; _window.SetPumpStatus(cast.Enabled); _window.SetTransferRate(cast.TransferRate); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs b/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs index 4d8d1191e91..e70426575d4 100644 --- a/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Atmos.Piping.Portable.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.Atmos.UI; @@ -21,14 +22,7 @@ protected override void Open() { base.Open(); - _window = new SpaceHeaterWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed(); _window.IncreaseTempRange.OnPressed += _ => OnTemperatureRangeChanged(_window.TemperatureChangeDelta); diff --git a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs index 60fe339069a..865dfc478d0 100644 --- a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs +++ b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs @@ -1,8 +1,7 @@ using Content.Shared.Audio.Jukebox; using Robust.Client.Audio; -using Robust.Client.Player; +using Robust.Client.UserInterface; using Robust.Shared.Audio.Components; -using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Client.Audio.Jukebox; @@ -23,9 +22,7 @@ protected override void Open() { base.Open(); - _menu = new JukeboxMenu(); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); _menu.OnPlayPressed += args => { @@ -100,19 +97,5 @@ public void SetTime(float time) SendMessage(new JukeboxSetTimeMessage(sentTime)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_menu == null) - return; - - _menu.OnClose -= Close; - _menu.Dispose(); - _menu = null; - } } diff --git a/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs b/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs index ffab1625483..09f3cec8fbf 100644 --- a/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs +++ b/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Bed.Cryostorage; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Bed.Cryostorage; @@ -17,9 +18,7 @@ protected override void Open() { base.Open(); - _menu = new(); - - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.SlotRemoveButtonPressed += (ent, slot) => { @@ -30,8 +29,6 @@ protected override void Open() { SendMessage(new CryostorageRemoveItemBuiMessage(ent, hand, CryostorageRemoveItemBuiMessage.RemovalType.Hand)); }; - - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -45,12 +42,4 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Dispose(); - } } diff --git a/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs index d3365702bcf..44c40143d83 100644 --- a/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Client.Cargo.UI; using Content.Shared.Cargo.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Cargo.BUI; @@ -18,9 +19,7 @@ protected override void Open() { base.Open(); - _menu = new(); - - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.OnLabelButtonPressed += id => { @@ -31,8 +30,6 @@ protected override void Open() { SendMessage(new BountySkipMessage(id)); }; - - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState message) @@ -44,14 +41,4 @@ protected override void UpdateState(BoundUserInterfaceState message) _menu?.UpdateEntries(state.Bounties, state.UntilNextSkip); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (!disposing) - return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs index 20c23a48a0d..2461dafb5f3 100644 --- a/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Cargo.BUI; using Content.Shared.Cargo.Events; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Cargo.BUI; @@ -18,21 +19,9 @@ protected override void Open() { base.Open(); - _menu = new CargoPalletMenu(); + _menu = this.CreateWindow(); _menu.AppraiseRequested += OnAppraisal; _menu.SellRequested += OnSell; - _menu.OnClose += Close; - - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _menu?.Dispose(); - } } private void OnAppraisal() diff --git a/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs index 422d03707a0..02b721b9020 100644 --- a/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Cargo.BUI; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Cargo.BUI; @@ -9,6 +10,8 @@ namespace Content.Client.Cargo.BUI; [UsedImplicitly] public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [ViewVariables] private CargoShuttleMenu? _menu; @@ -19,24 +22,7 @@ public CargoShuttleConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base protected override void Open() { base.Open(); - var collection = IoCManager.Instance; - - if (collection == null) - return; - - _menu = new CargoShuttleMenu(collection.Resolve(), collection.Resolve().GetEntitySystem()); - _menu.OnClose += Close; - - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _menu?.Dispose(); - } + _menu = this.CreateWindow(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -45,6 +31,6 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not CargoShuttleConsoleBoundUserInterfaceState cargoState) return; _menu?.SetAccountName(cargoState.AccountName); _menu?.SetShuttleName(cargoState.ShuttleName); - _menu?.SetOrders(cargoState.Orders); + _menu?.SetOrders(EntMan.System(), _protoManager, cargoState.Orders); } } diff --git a/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs b/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs index c591f917da3..43b00089e16 100644 --- a/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs +++ b/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs @@ -12,14 +12,9 @@ namespace Content.Client.Cargo.UI [GenerateTypedNameReferences] public sealed partial class CargoShuttleMenu : FancyWindow { - private readonly IPrototypeManager _protoManager; - private readonly SpriteSystem _spriteSystem; - - public CargoShuttleMenu(IPrototypeManager protoManager, SpriteSystem spriteSystem) + public CargoShuttleMenu() { RobustXamlLoader.Load(this); - _protoManager = protoManager; - _spriteSystem = spriteSystem; Title = Loc.GetString("cargo-shuttle-console-menu-title"); } @@ -33,19 +28,19 @@ public void SetShuttleName(string name) ShuttleNameLabel.Text = name; } - public void SetOrders(List orders) + public void SetOrders(SpriteSystem sprites, IPrototypeManager protoManager, List orders) { Orders.DisposeAllChildren(); foreach (var order in orders) { - var product = _protoManager.Index(order.ProductId); + var product = protoManager.Index(order.ProductId); var productName = product.Name; var row = new CargoOrderRow { Order = order, - Icon = { Texture = _spriteSystem.Frame0(product) }, + Icon = { Texture = sprites.Frame0(product) }, ProductName = { Text = Loc.GetString( diff --git a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs index 988fea7978b..3ef7f0ae73e 100644 --- a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Containers.ItemSlots; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -27,13 +28,8 @@ protected override void Open() base.Open(); // Setup window layout/elements - _window = new ChemMasterWindow - { - Title = EntMan.GetComponent(Owner).EntityName, - }; - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.Title = EntMan.GetComponent(Owner).EntityName; // Setup static button actions. _window.InputEjectButton.OnPressed += _ => SendMessage( @@ -75,15 +71,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); // Update window state } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } } } diff --git a/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs b/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs index 99e5a3d3953..2ad1b718887 100644 --- a/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Containers.ItemSlots; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -15,9 +16,6 @@ public sealed class ReagentDispenserBoundUserInterface : BoundUserInterface [ViewVariables] private ReagentDispenserWindow? _window; - [ViewVariables] - private ReagentDispenserBoundUserInterfaceState? _lastState; - public ReagentDispenserBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -32,14 +30,9 @@ protected override void Open() base.Open(); // Setup window layout/elements - _window = new() - { - Title = EntMan.GetComponent(Owner).EntityName, - HelpGuidebookIds = EntMan.GetComponent(Owner).Guides - }; - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.Title = EntMan.GetComponent(Owner).EntityName; + _window.HelpGuidebookIds = EntMan.GetComponent(Owner).Guides; // Setup static button actions. _window.EjectButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(SharedReagentDispenser.OutputSlotName)); @@ -63,19 +56,7 @@ protected override void UpdateState(BoundUserInterfaceState state) base.UpdateState(state); var castState = (ReagentDispenserBoundUserInterfaceState) state; - _lastState = castState; - _window?.UpdateState(castState); //Update window state } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } } } diff --git a/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs b/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs index 35df131312d..f1cb27a62a4 100644 --- a/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.FixedPoint; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -18,7 +19,7 @@ public TransferAmountBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = new TransferAmountWindow(); + _window = this.CreateWindow(); _window.ApplyButton.OnPressed += _ => { @@ -28,15 +29,6 @@ protected override void Open() _window.Close(); } }; - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); } } } diff --git a/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs b/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs index 26f0994701e..62a02f37186 100644 --- a/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs +++ b/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; using Content.Shared.Cloning.CloningConsole; +using Robust.Client.UserInterface; namespace Content.Client.CloningConsole.UI { @@ -17,13 +18,11 @@ public CloningConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = new CloningConsoleWindow - { - Title = Loc.GetString("cloning-console-window-title") - }; - _window.OnClose += Close; + + _window = this.CreateWindow(); + _window.Title = Loc.GetString("cloning-console-window-title"); + _window.CloneButton.OnPressed += _ => SendMessage(new UiButtonPressedMessage(UiButton.Clone)); - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -32,19 +31,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.Populate((CloningConsoleBoundUserInterfaceState) state); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_window != null) - { - _window.OnClose -= Close; - _window.CloneButton.OnPressed -= _ => SendMessage(new UiButtonPressedMessage(UiButton.Clone)); - } - _window?.Dispose(); - } } } diff --git a/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs b/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs index 5b0d5fcf21f..83f6ba15662 100644 --- a/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs +++ b/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Clothing.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Clothing.UI; @@ -22,10 +23,8 @@ protected override void Open() { base.Open(); - _menu = new ChameleonMenu(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.OnIdSelected += OnIdSelected; - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -42,15 +41,4 @@ private void OnIdSelected(string selectedId) { SendMessage(new ChameleonPrototypeSelectedMessage(selectedId)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _menu?.Close(); - _menu = null; - } - } } diff --git a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs index 1c94d32bf8d..0310e91eeb0 100644 --- a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs +++ b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.CCVar; using Content.Shared.Chat; using Content.Shared.Communications; +using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Timing; @@ -8,34 +9,11 @@ namespace Content.Client.Communications.UI { public sealed class CommunicationsConsoleBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; [ViewVariables] private CommunicationsConsoleMenu? _menu; - [ViewVariables] - public bool CanAnnounce { get; private set; } - [ViewVariables] - public bool CanBroadcast { get; private set; } - - [ViewVariables] - public bool CanCall { get; private set; } - - [ViewVariables] - public bool CountdownStarted { get; private set; } - - [ViewVariables] - public bool AlertLevelSelectable { get; private set; } - - [ViewVariables] - public string CurrentLevel { get; private set; } = default!; - - [ViewVariables] - private TimeSpan? _expectedCountdownTime; - - public int Countdown => _expectedCountdownTime == null ? 0 : Math.Max((int) _expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0); - public CommunicationsConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -44,23 +22,25 @@ protected override void Open() { base.Open(); - _menu = new CommunicationsConsoleMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnAnnounce += AnnounceButtonPressed; + _menu.OnBroadcast += BroadcastButtonPressed; + _menu.OnAlertLevel += AlertLevelSelected; + _menu.OnEmergencyLevel += EmergencyShuttleButtonPressed; } public void AlertLevelSelected(string level) { - if (AlertLevelSelectable) + if (_menu!.AlertLevelSelectable) { - CurrentLevel = level; + _menu.CurrentLevel = level; SendMessage(new CommunicationsConsoleSelectAlertLevelMessage(level)); } } public void EmergencyShuttleButtonPressed() { - if (CountdownStarted) + if (_menu!.CountdownStarted) RecallShuttle(); else CallShuttle(); @@ -95,31 +75,23 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not CommunicationsConsoleInterfaceState commsState) return; - CanAnnounce = commsState.CanAnnounce; - CanBroadcast = commsState.CanBroadcast; - CanCall = commsState.CanCall; - _expectedCountdownTime = commsState.ExpectedCountdownEnd; - CountdownStarted = commsState.CountdownStarted; - AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0; - CurrentLevel = commsState.CurrentAlert; - if (_menu != null) { + _menu.CanAnnounce = commsState.CanAnnounce; + _menu.CanBroadcast = commsState.CanBroadcast; + _menu.CanCall = commsState.CanCall; + _menu.CountdownStarted = commsState.CountdownStarted; + _menu.AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0; + _menu.CurrentLevel = commsState.CurrentAlert; + _menu.CountdownEnd = commsState.ExpectedCountdownEnd; + _menu.UpdateCountdown(); - _menu.UpdateAlertLevels(commsState.AlertLevels, CurrentLevel); - _menu.AlertLevelButton.Disabled = !AlertLevelSelectable; - _menu.EmergencyShuttleButton.Disabled = !CanCall; - _menu.AnnounceButton.Disabled = !CanAnnounce; - _menu.BroadcastButton.Disabled = !CanBroadcast; + _menu.UpdateAlertLevels(commsState.AlertLevels, _menu.CurrentLevel); + _menu.AlertLevelButton.Disabled = !_menu.AlertLevelSelectable; + _menu.EmergencyShuttleButton.Disabled = !_menu.CanCall; + _menu.AnnounceButton.Disabled = !_menu.CanAnnounce; + _menu.BroadcastButton.Disabled = !_menu.CanBroadcast; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _menu?.Dispose(); - } } } diff --git a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs index bbca06f5194..cef68efd1f3 100644 --- a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs +++ b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs @@ -1,31 +1,40 @@ -using Content.Client.UserInterface.Controls; -using System.Threading; +using System.Globalization; +using Content.Client.UserInterface.Controls; using Content.Shared.CCVar; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.XAML; using Robust.Shared.Configuration; +using Robust.Shared.Timing; using Robust.Shared.Utility; -using Timer = Robust.Shared.Timing.Timer; namespace Content.Client.Communications.UI { [GenerateTypedNameReferences] public sealed partial class CommunicationsConsoleMenu : FancyWindow { - private CommunicationsConsoleBoundUserInterface Owner { get; set; } - private readonly CancellationTokenSource _timerCancelTokenSource = new(); - [Dependency] private readonly IConfigurationManager _cfg = default!; - - public CommunicationsConsoleMenu(CommunicationsConsoleBoundUserInterface owner) + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly ILocalizationManager _loc = default!; + + public bool CanAnnounce; + public bool CanBroadcast; + public bool CanCall; + public bool AlertLevelSelectable; + public bool CountdownStarted; + public string CurrentLevel = string.Empty; + public TimeSpan? CountdownEnd; + + public event Action? OnEmergencyLevel; + public event Action? OnAlertLevel; + public event Action? OnAnnounce; + public event Action? OnBroadcast; + + public CommunicationsConsoleMenu() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - Owner = owner; - - var loc = IoCManager.Resolve(); - MessageInput.Placeholder = new Rope.Leaf(loc.GetString("comms-console-menu-announcement-placeholder")); + MessageInput.Placeholder = new Rope.Leaf(_loc.GetString("comms-console-menu-announcement-placeholder")); var maxAnnounceLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength); MessageInput.OnTextChanged += (args) => @@ -37,33 +46,38 @@ public CommunicationsConsoleMenu(CommunicationsConsoleBoundUserInterface owner) } else { - AnnounceButton.Disabled = !owner.CanAnnounce; + AnnounceButton.Disabled = !CanAnnounce; AnnounceButton.ToolTip = null; } }; - AnnounceButton.OnPressed += (_) => Owner.AnnounceButtonPressed(Rope.Collapse(MessageInput.TextRope)); - AnnounceButton.Disabled = !owner.CanAnnounce; + AnnounceButton.OnPressed += _ => OnAnnounce?.Invoke(Rope.Collapse(MessageInput.TextRope)); + AnnounceButton.Disabled = !CanAnnounce; - BroadcastButton.OnPressed += (_) => Owner.BroadcastButtonPressed(Rope.Collapse(MessageInput.TextRope)); - BroadcastButton.Disabled = !owner.CanBroadcast; + BroadcastButton.OnPressed += _ => OnBroadcast?.Invoke(Rope.Collapse(MessageInput.TextRope)); + BroadcastButton.Disabled = !CanBroadcast; AlertLevelButton.OnItemSelected += args => { var metadata = AlertLevelButton.GetItemMetadata(args.Id); if (metadata != null && metadata is string cast) { - Owner.AlertLevelSelected(cast); + OnAlertLevel?.Invoke(cast); } }; - AlertLevelButton.Disabled = !owner.AlertLevelSelectable; - EmergencyShuttleButton.OnPressed += (_) => Owner.EmergencyShuttleButtonPressed(); - EmergencyShuttleButton.Disabled = !owner.CanCall; + AlertLevelButton.Disabled = !AlertLevelSelectable; + + EmergencyShuttleButton.OnPressed += _ => OnEmergencyLevel?.Invoke(); + EmergencyShuttleButton.Disabled = !CanCall; + } + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); UpdateCountdown(); - Timer.SpawnRepeating(1000, UpdateCountdown, _timerCancelTokenSource.Token); } // The current alert could make levels unselectable, so we need to ensure that the UI reacts properly. @@ -105,32 +119,19 @@ public void UpdateAlertLevels(List? alerts, string currentAlert) public void UpdateCountdown() { - if (!Owner.CountdownStarted) + if (!CountdownStarted) { - CountdownLabel.SetMessage(""); + CountdownLabel.SetMessage(string.Empty); EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-call-shuttle"); return; } + var diff = (CountdownEnd - _timing.CurTime) ?? TimeSpan.Zero; + EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-recall-shuttle"); var infoText = Loc.GetString($"comms-console-menu-time-remaining", - ("time", Owner.Countdown.ToString())); + ("time", diff.TotalSeconds.ToString(CultureInfo.CurrentCulture))); CountdownLabel.SetMessage(infoText); } - - public override void Close() - { - base.Close(); - - _timerCancelTokenSource.Cancel(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - _timerCancelTokenSource.Cancel(); - } } } diff --git a/Content.Client/Computer/ComputerBoundUserInterface.cs b/Content.Client/Computer/ComputerBoundUserInterface.cs index bdbfe03fa10..11c26b252e9 100644 --- a/Content.Client/Computer/ComputerBoundUserInterface.cs +++ b/Content.Client/Computer/ComputerBoundUserInterface.cs @@ -1,4 +1,5 @@ using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; namespace Content.Client.Computer @@ -19,10 +20,8 @@ protected override void Open() { base.Open(); - _window = (TWindow) _dynamicTypeFactory.CreateInstance(typeof(TWindow)); + _window = this.CreateWindow(); _window.SetupComputerWindow(this); - _window.OnClose += Close; - _window.OpenCentered(); } // Alas, this constructor has to be copied to the subclass. :( @@ -42,16 +41,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState((TState) state); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } - protected override void ReceiveMessage(BoundUserInterfaceMessage message) { _window?.ReceiveMessage(message); diff --git a/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs b/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs index 4fea44f2253..e4966f1ec43 100644 --- a/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs +++ b/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs @@ -1,5 +1,6 @@ using System.Text.RegularExpressions; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using static Content.Shared.Configurable.ConfigurationComponent; namespace Content.Client.Configurable.UI @@ -9,9 +10,6 @@ public sealed class ConfigurationBoundUserInterface : BoundUserInterface [ViewVariables] private ConfigurationMenu? _menu; - [ViewVariables] - public Regex? Validation { get; internal set; } - public ConfigurationBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -19,10 +17,8 @@ public ConfigurationBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner protected override void Open() { base.Open(); - _menu = new ConfigurationMenu(this); - - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnConfiguration += SendConfiguration; } protected override void UpdateState(BoundUserInterfaceState state) @@ -30,9 +26,7 @@ protected override void UpdateState(BoundUserInterfaceState state) base.UpdateState(state); if (state is not ConfigurationBoundUserInterfaceState configurationState) - { return; - } _menu?.Populate(configurationState); } @@ -41,9 +35,12 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) { base.ReceiveMessage(message); + if (_menu == null) + return; + if (message is ValidationUpdateMessage msg) { - Validation = new Regex(msg.ValidationString, RegexOptions.Compiled); + _menu.Validation = new Regex(msg.ValidationString, RegexOptions.Compiled); } } @@ -51,16 +48,5 @@ public void SendConfiguration(Dictionary config) { SendMessage(new ConfigurationUpdatedMessage(config)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing && _menu != null) - { - _menu.OnClose -= Close; - _menu.Close(); - } - } } } diff --git a/Content.Client/Configurable/UI/ConfigurationMenu.cs b/Content.Client/Configurable/UI/ConfigurationMenu.cs index cc24af28692..29217eef7be 100644 --- a/Content.Client/Configurable/UI/ConfigurationMenu.cs +++ b/Content.Client/Configurable/UI/ConfigurationMenu.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Numerics; +using System.Text.RegularExpressions; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; @@ -13,23 +14,25 @@ namespace Content.Client.Configurable.UI { public sealed class ConfigurationMenu : DefaultWindow { - public ConfigurationBoundUserInterface Owner { get; } - private readonly BoxContainer _column; private readonly BoxContainer _row; private readonly List<(string name, LineEdit input)> _inputs; - public ConfigurationMenu(ConfigurationBoundUserInterface owner) + [ViewVariables] + public Regex? Validation { get; internal set; } + + public event Action>? OnConfiguration; + + public ConfigurationMenu() { MinSize = SetSize = new Vector2(300, 250); - Owner = owner; _inputs = new List<(string name, LineEdit input)>(); Title = Loc.GetString("configuration-menu-device-title"); - BoxContainer baseContainer = new BoxContainer + var baseContainer = new BoxContainer { Orientation = LayoutOrientation.Vertical, VerticalExpand = true, @@ -116,14 +119,13 @@ public void Populate(ConfigurationBoundUserInterfaceState state) private void OnConfirm(ButtonEventArgs args) { var config = GenerateDictionary(_inputs, "Text"); - - Owner.SendConfiguration(config); + OnConfiguration?.Invoke(config); Close(); } private bool Validate(string value) { - return Owner.Validation == null || Owner.Validation.IsMatch(value); + return Validation?.IsMatch(value) != false; } private Dictionary GenerateDictionary(IEnumerable<(string name, LineEdit input)> inputs, string propertyName) diff --git a/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs b/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs index 86f1b8b83c7..887492955e9 100644 --- a/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs +++ b/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Construction.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Construction.UI { @@ -17,8 +18,8 @@ protected override void Open() { base.Open(); - _menu = new FlatpackCreatorMenu(Owner); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); _menu.PackButtonPressed += () => { @@ -27,14 +28,5 @@ protected override void Open() _menu.OpenCentered(); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } } } diff --git a/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs b/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs index 9f3d5695bb6..269694ebf9e 100644 --- a/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs +++ b/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs @@ -24,7 +24,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow private readonly FlatpackSystem _flatpack; private readonly MaterialStorageSystem _materialStorage; - private readonly EntityUid _owner; + private EntityUid _owner; [ValidatePrototypeId] public const string NoBoardEffectId = "FlatpackerNoBoardEffect"; @@ -33,7 +33,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow public event Action? PackButtonPressed; - public FlatpackCreatorMenu(EntityUid uid) + public FlatpackCreatorMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -42,14 +42,17 @@ public FlatpackCreatorMenu(EntityUid uid) _flatpack = _entityManager.System(); _materialStorage = _entityManager.System(); - _owner = uid; - PackButton.OnPressed += _ => PackButtonPressed?.Invoke(); - MaterialStorageControl.SetOwner(uid); InsertLabel.SetMarkup(Loc.GetString("flatpacker-ui-insert-board")); } + public void SetEntity(EntityUid uid) + { + _owner = uid; + MaterialStorageControl.SetOwner(uid); + } + protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); diff --git a/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs b/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs index e2c4d51ecd1..e5be0b1811f 100644 --- a/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs +++ b/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs @@ -2,12 +2,15 @@ using Content.Shared.Crayon; using Content.Shared.Decals; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Crayon.UI { public sealed class CrayonBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [ViewVariables] private CrayonWindow? _menu; @@ -18,15 +21,29 @@ public CrayonBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey protected override void Open() { base.Open(); - _menu = new CrayonWindow(this); - - _menu.OnClose += Close; - var prototypeManager = IoCManager.Resolve(); - var crayonDecals = prototypeManager.EnumeratePrototypes().Where(x => x.Tags.Contains("crayon")); - _menu.Populate(crayonDecals); + _menu = this.CreateWindow(); + _menu.OnColorSelected += SelectColor; + _menu.OnSelected += Select; + PopulateCrayons(); _menu.OpenCenteredLeft(); } + private void PopulateCrayons() + { + var crayonDecals = _protoManager.EnumeratePrototypes().Where(x => x.Tags.Contains("crayon")); + _menu?.Populate(crayonDecals); + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + + if (!args.WasModified()) + return; + + PopulateCrayons(); + } + protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); @@ -43,16 +60,5 @@ public void SelectColor(Color color) { SendMessage(new CrayonColorMessage(color)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _menu?.Close(); - _menu = null; - } - } } } diff --git a/Content.Client/Crayon/UI/CrayonWindow.xaml.cs b/Content.Client/Crayon/UI/CrayonWindow.xaml.cs index 2a5801ccf2d..b97786cd41a 100644 --- a/Content.Client/Crayon/UI/CrayonWindow.xaml.cs +++ b/Content.Client/Crayon/UI/CrayonWindow.xaml.cs @@ -18,18 +18,17 @@ namespace Content.Client.Crayon.UI [GenerateTypedNameReferences] public sealed partial class CrayonWindow : DefaultWindow { - public CrayonBoundUserInterface Owner { get; } - private Dictionary? _decals; private string? _selected; private Color _color; - public CrayonWindow(CrayonBoundUserInterface owner) + public event Action? OnColorSelected; + public event Action? OnSelected; + + public CrayonWindow() { RobustXamlLoader.Load(this); - Owner = owner; - Search.OnTextChanged += _ => RefreshList(); ColorSelector.OnColorChanged += SelectColor; } @@ -38,16 +37,16 @@ private void SelectColor(Color color) { _color = color; - Owner.SelectColor(color); - + OnColorSelected?.Invoke(color); RefreshList(); } private void RefreshList() { // Clear - Grid.RemoveAllChildren(); - if (_decals == null) return; + Grid.DisposeAllChildren(); + if (_decals == null) + return; var filter = Search.Text; foreach (var (decal, tex) in _decals) @@ -89,7 +88,6 @@ private void ButtonOnPressed(ButtonEventArgs obj) { if (obj.Button.Name == null) return; - Owner.Select(obj.Button.Name); _selected = obj.Button.Name; RefreshList(); } diff --git a/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs b/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs index e8e77217ea5..296e71d3a95 100644 --- a/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs +++ b/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent; namespace Content.Client.Disposal.UI @@ -21,20 +22,16 @@ protected override void Open() { base.Open(); - _window = new DisposalRouterWindow(); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text); _window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text); - } private void ButtonPressed(UiAction action, string tag) { SendMessage(new UiActionMessage(action, tag)); - _window?.Close(); + Close(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -48,18 +45,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } - - } - } diff --git a/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs b/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs index 3aeed8dc802..7fc0eb85401 100644 --- a/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs +++ b/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent; namespace Content.Client.Disposal.UI @@ -21,20 +22,17 @@ protected override void Open() { base.Open(); - _window = new DisposalTaggerWindow(); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text); _window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text); - } private void ButtonPressed(UiAction action, string tag) { + // TODO: This looks copy-pasted with the other mailing stuff... SendMessage(new UiActionMessage(action, tag)); - _window?.Close(); + Close(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -48,18 +46,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } - - } - } diff --git a/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs b/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs index cd7ea717ce3..9b7e23c03aa 100644 --- a/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs +++ b/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Access; using Content.Shared.Doors.Electronics; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Doors.Electronics; @@ -18,6 +19,23 @@ public DoorElectronicsBoundUserInterface(EntityUid owner, Enum uiKey) : base(own protected override void Open() { base.Open(); + _window = this.CreateWindow(); + _window.OnAccessChanged += UpdateConfiguration; + Reset(); + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + + if (!args.WasModified()) + return; + + Reset(); + } + + private void Reset() + { List> accessLevels = new(); foreach (var accessLevel in _prototypeManager.EnumeratePrototypes()) @@ -29,10 +47,7 @@ protected override void Open() } accessLevels.Sort(); - - _window = new DoorElectronicsConfigurationMenu(this, accessLevels, _prototypeManager); - _window.OnClose += Close; - _window.OpenCentered(); + _window?.Reset(_prototypeManager, accessLevels); } protected override void UpdateState(BoundUserInterfaceState state) @@ -44,14 +59,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _window?.Dispose(); - } - public void UpdateConfiguration(List> newAccessList) { SendMessage(new DoorElectronicsUpdateConfigurationMessage(newAccessList)); diff --git a/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs index c01f13a462e..2112a562971 100644 --- a/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs +++ b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs @@ -15,22 +15,23 @@ namespace Content.Client.Doors.Electronics; [GenerateTypedNameReferences] public sealed partial class DoorElectronicsConfigurationMenu : FancyWindow { - private readonly DoorElectronicsBoundUserInterface _owner; - private AccessLevelControl _buttonsList = new(); + private readonly AccessLevelControl _buttonsList = new(); - public DoorElectronicsConfigurationMenu(DoorElectronicsBoundUserInterface ui, List> accessLevels, IPrototypeManager prototypeManager) + public event Action>>? OnAccessChanged; + + public DoorElectronicsConfigurationMenu() { RobustXamlLoader.Load(this); - - _owner = ui; - - _buttonsList.Populate(accessLevels, prototypeManager); AccessLevelControlContainer.AddChild(_buttonsList); + } + + public void Reset(IPrototypeManager protoManager, List> accessLevels) + { + _buttonsList.Populate(accessLevels, protoManager); - foreach (var (id, button) in _buttonsList.ButtonsList) + foreach (var button in _buttonsList.ButtonsList.Values) { - button.OnPressed += _ => _owner.UpdateConfiguration( - _buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); + button.OnPressed += _ => OnAccessChanged?.Invoke(_buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); } } diff --git a/Content.Client/Fax/UI/FaxBoundUi.cs b/Content.Client/Fax/UI/FaxBoundUi.cs index a95066a3b58..ca2e834b4fe 100644 --- a/Content.Client/Fax/UI/FaxBoundUi.cs +++ b/Content.Client/Fax/UI/FaxBoundUi.cs @@ -25,10 +25,7 @@ protected override void Open() { base.Open(); - _window = new FaxWindow(); - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.FileButtonPressed += OnFileButtonPressed; _window.CopyButtonPressed += OnCopyButtonPressed; _window.SendButtonPressed += OnSendButtonPressed; @@ -104,11 +101,4 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - _window?.Dispose(); - } } diff --git a/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs b/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs index ba49f11ea0f..08596b04e6e 100644 --- a/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs +++ b/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs @@ -1,6 +1,7 @@ using Robust.Client.GameObjects; using Robust.Shared.Timing; using Content.Shared.Forensics; +using Robust.Client.UserInterface; namespace Content.Client.Forensics { @@ -21,11 +22,9 @@ public ForensicScannerBoundUserInterface(EntityUid owner, Enum uiKey) : base(own protected override void Open() { base.Open(); - _window = new ForensicScannerMenu(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.Print.OnPressed += _ => Print(); _window.Clear.OnPressed += _ => Clear(); - _window.OpenCentered(); } private void Print() @@ -62,6 +61,7 @@ protected override void UpdateState(BoundUserInterfaceState state) _printCooldown = cast.PrintCooldown; + // TODO: Fix this if (cast.PrintReadyAt > _gameTiming.CurTime) Timer.Spawn(cast.PrintReadyAt - _gameTiming.CurTime, () => { @@ -71,14 +71,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); - } } } diff --git a/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs b/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs index fdb3cdbc010..457b70ca7ca 100644 --- a/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs +++ b/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Gateway; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Gateway.UI; @@ -17,24 +18,13 @@ protected override void Open() { base.Open(); - _window = new GatewayWindow(EntMan.GetNetEntity(Owner)); + _window = this.CreateWindow(); + _window.SetEntity(EntMan.GetNetEntity(Owner)); _window.OpenPortal += destination => { SendMessage(new GatewayOpenPortalMessage(destination)); }; - _window.OnClose += Close; - _window?.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _window?.Dispose(); - _window = null; - } } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Gateway/UI/GatewayWindow.xaml.cs b/Content.Client/Gateway/UI/GatewayWindow.xaml.cs index 889dd6e1759..1c779b2b350 100644 --- a/Content.Client/Gateway/UI/GatewayWindow.xaml.cs +++ b/Content.Client/Gateway/UI/GatewayWindow.xaml.cs @@ -22,7 +22,7 @@ public sealed partial class GatewayWindow : FancyWindow, public event Action? OpenPortal; private List _destinations = new(); - public readonly NetEntity Owner; + public NetEntity Owner; private NetEntity? _current; private TimeSpan _nextReady; @@ -46,16 +46,20 @@ public sealed partial class GatewayWindow : FancyWindow, /// private bool _isCooldownPending = true; - public GatewayWindow(NetEntity netEntity) + public GatewayWindow() { RobustXamlLoader.Load(this); var dependencies = IoCManager.Instance!; _timing = dependencies.Resolve(); - Owner = netEntity; NextUnlockBar.ForegroundStyleBoxOverride = new StyleBoxFlat(Color.FromHex("#C74EBD")); } + public void SetEntity(NetEntity entity) + { + + } + public void UpdateState(GatewayBoundUserInterfaceState state) { _destinations = state.Destinations; diff --git a/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs b/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs index d72da3e8120..32b40747d55 100644 --- a/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs +++ b/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.Gravity; using JetBrains.Annotations; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Gravity.UI { @@ -18,17 +18,8 @@ protected override void Open() { base.Open(); - _window = new GravityGeneratorWindow(this); - - /* - _window.Switch.OnPressed += _ => - { - SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(!IsOn)); - }; - */ - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.SetEntity(Owner); } protected override void UpdateState(BoundUserInterfaceState state) @@ -39,14 +30,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _window?.Dispose(); - } - public void SetPowerSwitch(bool on) { SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on)); diff --git a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs b/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs index 75f8eb479b5..6f04133b594 100644 --- a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs +++ b/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs @@ -12,22 +12,23 @@ public sealed partial class GravityGeneratorWindow : FancyWindow { private readonly ButtonGroup _buttonGroup = new(); - private readonly GravityGeneratorBoundUserInterface _owner; + public event Action? OnPowerSwitch; - public GravityGeneratorWindow(GravityGeneratorBoundUserInterface owner) + public GravityGeneratorWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - _owner = owner; - OnButton.Group = _buttonGroup; OffButton.Group = _buttonGroup; - OnButton.OnPressed += _ => _owner.SetPowerSwitch(true); - OffButton.OnPressed += _ => _owner.SetPowerSwitch(false); + OnButton.OnPressed += _ => OnPowerSwitch?.Invoke(true); + OffButton.OnPressed += _ => OnPowerSwitch?.Invoke(false); + } - EntityView.SetEntity(owner.Owner); + public void SetEntity(EntityUid uid) + { + EntityView.SetEntity(uid); } public void UpdateState(SharedGravityGeneratorComponent.GeneratorState state) diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs index dc0a3e9fccd..38760f4aa3c 100644 --- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs +++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.MedicalScanner; using JetBrains.Annotations; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.HealthAnalyzer.UI { @@ -17,12 +17,9 @@ public HealthAnalyzerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = new HealthAnalyzerWindow - { - Title = EntMan.GetComponent(Owner).EntityName, - }; - _window.OnClose += Close; - _window.OpenCentered(); + _window = this.CreateWindow(); + + _window.Title = EntMan.GetComponent(Owner).EntityName; } protected override void ReceiveMessage(BoundUserInterfaceMessage message) @@ -35,17 +32,5 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) _window.Populate(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_window != null) - _window.OnClose -= Close; - - _window?.Dispose(); - } } } diff --git a/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs b/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs index a8872604a4c..53977eb636b 100644 --- a/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs +++ b/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Humanoid; using Content.Shared.Humanoid.Markings; +using Robust.Client.UserInterface; namespace Content.Client.Humanoid; @@ -20,8 +21,7 @@ protected override void Open() { base.Open(); - _window = new(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.OnMarkingAdded += SendMarkingSet; _window.OnMarkingRemoved += SendMarkingSet; _window.OnMarkingColorChange += SendMarkingSetNoResend; diff --git a/Content.Client/Instruments/UI/BandMenu.xaml.cs b/Content.Client/Instruments/UI/BandMenu.xaml.cs index 5fb293a194d..26cd1369e55 100644 --- a/Content.Client/Instruments/UI/BandMenu.xaml.cs +++ b/Content.Client/Instruments/UI/BandMenu.xaml.cs @@ -11,7 +11,9 @@ public sealed partial class BandMenu : DefaultWindow { private readonly InstrumentBoundUserInterface _owner; - public BandMenu(InstrumentBoundUserInterface owner) : base() + public EntityUid? Master; + + public BandMenu(InstrumentBoundUserInterface owner) { RobustXamlLoader.Load(this); @@ -40,7 +42,7 @@ public void Populate((NetEntity, string)[] nearby, IEntityManager entManager) { var uid = entManager.GetEntity(nent); var item = BandList.AddItem(name, null, true, uid); - item.Selected = _owner.Instrument?.Master == uid; + item.Selected = Master == uid; } } } diff --git a/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs b/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs index 2814d415365..c175e67842f 100644 --- a/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs +++ b/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs @@ -51,7 +51,7 @@ private void OnClearPressed(BaseButton.ButtonEventArgs obj) } } - public void Populate() + public void Populate(InstrumentComponent? instrument) { ChannelList.Clear(); @@ -60,7 +60,8 @@ public void Populate() var item = ChannelList.AddItem(_owner.Loc.GetString("instrument-component-channel-name", ("number", i)), null, true, i); - item.Selected = !_owner.Instrument?.FilteredChannels[i] ?? false; + + item.Selected = !instrument?.FilteredChannels[i] ?? false; } } } diff --git a/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs b/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs index 0f5729f55b1..4816ce8c365 100644 --- a/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs +++ b/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs @@ -24,8 +24,6 @@ public sealed class InstrumentBoundUserInterface : BoundUserInterface [ViewVariables] private BandMenu? _bandMenu; [ViewVariables] private ChannelsMenu? _channelsMenu; - [ViewVariables] public InstrumentComponent? Instrument { get; private set; } - public InstrumentBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { IoCManager.InjectDependencies(this); @@ -43,14 +41,20 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) protected override void Open() { - if (!EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) - return; + _instrumentMenu = this.CreateWindow(); + _instrumentMenu.Title = EntMan.GetComponent(Owner).EntityName; - Instrument = instrument; - _instrumentMenu = new InstrumentMenu(this); - _instrumentMenu.OnClose += Close; + _instrumentMenu.OnOpenBand += OpenBandMenu; + _instrumentMenu.OnOpenChannels += OpenChannelsMenu; + _instrumentMenu.OnCloseChannels += CloseChannelsMenu; + _instrumentMenu.OnCloseBands += CloseBandMenu; - _instrumentMenu.OpenCentered(); + _instrumentMenu.SetMIDI(MidiManager.IsAvailable); + + if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) + { + _instrumentMenu.SetInstrument((Owner, instrument)); + } } protected override void Dispose(bool disposing) @@ -58,7 +62,12 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); if (!disposing) return; - _instrumentMenu?.Dispose(); + + if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) + { + _instrumentMenu?.RemoveInstrument(instrument); + } + _bandMenu?.Dispose(); _channelsMenu?.Dispose(); } @@ -72,6 +81,11 @@ public void OpenBandMenu() { _bandMenu ??= new BandMenu(this); + if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) + { + _bandMenu.Master = instrument.Master; + } + // Refresh cache... RefreshBands(); @@ -87,7 +101,9 @@ public void CloseBandMenu() public void OpenChannelsMenu() { _channelsMenu ??= new ChannelsMenu(this); - _channelsMenu.Populate(); + EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument); + + _channelsMenu.Populate(instrument); _channelsMenu.OpenCenteredRight(); } diff --git a/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs b/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs index da443e3fb5b..fc863648d79 100644 --- a/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs +++ b/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs @@ -1,7 +1,10 @@ using System.IO; using System.Numerics; using System.Threading.Tasks; +using Content.Client.Interactable; +using Content.Shared.ActionBlocker; using Robust.Client.AutoGenerated; +using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; @@ -16,33 +19,23 @@ namespace Content.Client.Instruments.UI [GenerateTypedNameReferences] public sealed partial class InstrumentMenu : DefaultWindow { - private readonly InstrumentBoundUserInterface _owner; + [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private readonly IFileDialogManager _dialogs = default!; + [Dependency] private readonly IPlayerManager _player = default!; private bool _isMidiFileDialogueWindowOpen; - public InstrumentMenu(InstrumentBoundUserInterface owner) - { - RobustXamlLoader.Load(this); - - _owner = owner; + public event Action? OnOpenBand; + public event Action? OnOpenChannels; + public event Action? OnCloseBands; + public event Action? OnCloseChannels; - if (_owner.Instrument != null) - { - _owner.Instrument.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded; - Title = _owner.Entities.GetComponent(_owner.Owner).EntityName; - LoopButton.Disabled = !_owner.Instrument.IsMidiOpen; - LoopButton.Pressed = _owner.Instrument.LoopMidi; - ChannelsButton.Disabled = !_owner.Instrument.IsRendererAlive; - StopButton.Disabled = !_owner.Instrument.IsMidiOpen; - PlaybackSlider.MouseFilter = _owner.Instrument.IsMidiOpen ? MouseFilterMode.Pass : MouseFilterMode.Ignore; - } + public EntityUid Entity; - if (!_owner.MidiManager.IsAvailable) - { - UnavailableOverlay.Visible = true; - // We return early as to not give the buttons behavior. - return; - } + public InstrumentMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); InputButton.OnToggled += MidiInputButtonOnOnToggled; BandButton.OnPressed += BandButtonOnPressed; @@ -57,12 +50,34 @@ public InstrumentMenu(InstrumentBoundUserInterface owner) MinSize = SetSize = new Vector2(400, 150); } + public void SetInstrument(Entity entity) + { + Entity = entity; + var component = entity.Comp; + component.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded; + LoopButton.Disabled = !component.IsMidiOpen; + LoopButton.Pressed = component.LoopMidi; + ChannelsButton.Disabled = !component.IsRendererAlive; + StopButton.Disabled = !component.IsMidiOpen; + PlaybackSlider.MouseFilter = component.IsMidiOpen ? MouseFilterMode.Pass : MouseFilterMode.Ignore; + } + + public void RemoveInstrument(InstrumentComponent component) + { + component.OnMidiPlaybackEnded -= InstrumentOnMidiPlaybackEnded; + } + + public void SetMIDI(bool available) + { + UnavailableOverlay.Visible = !available; + } + private void BandButtonOnPressed(ButtonEventArgs obj) { if (!PlayCheck()) return; - _owner.OpenBandMenu(); + OnOpenBand?.Invoke(); } private void BandButtonOnToggled(ButtonToggledEventArgs obj) @@ -70,12 +85,15 @@ private void BandButtonOnToggled(ButtonToggledEventArgs obj) if (obj.Pressed) return; - _owner.Instruments.SetMaster(_owner.Owner, null); + if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) + { + _entManager.System().SetMaster(Entity, instrument.Master); + } } private void ChannelsButtonOnPressed(ButtonEventArgs obj) { - _owner.OpenChannelsMenu(); + OnOpenChannels?.Invoke(); } private void InstrumentOnMidiPlaybackEnded() @@ -85,8 +103,10 @@ private void InstrumentOnMidiPlaybackEnded() public void MidiPlaybackSetButtonsDisabled(bool disabled) { - if(disabled) - _owner.CloseChannelsMenu(); + if (disabled) + { + OnCloseChannels?.Invoke(); + } LoopButton.Disabled = disabled; StopButton.Disabled = disabled; @@ -100,7 +120,7 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) if (_isMidiFileDialogueWindowOpen) return; - _owner.CloseBandMenu(); + OnCloseBands?.Invoke(); var filters = new FileDialogFilters(new FileDialogFilters.Group("mid", "midi")); @@ -108,7 +128,7 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) // or focus the previously-opened window. _isMidiFileDialogueWindowOpen = true; - await using var file = await _owner.FileDialogManager.OpenFile(filters); + await using var file = await _dialogs.OpenFile(filters); _isMidiFileDialogueWindowOpen = false; @@ -129,9 +149,18 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) await file.CopyToAsync(memStream); - if (_owner.Instrument is not {} instrument - || !_owner.Instruments.OpenMidi(_owner.Owner, memStream.GetBuffer().AsSpan(0, (int) memStream.Length), instrument)) + if (!_entManager.TryGetComponent(Entity, out var instrument)) + { return; + } + + if (!_entManager.System() + .OpenMidi(Entity, + memStream.GetBuffer().AsSpan(0, (int) memStream.Length), + instrument)) + { + return; + } MidiPlaybackSetButtonsDisabled(false); if (InputButton.Pressed) @@ -140,7 +169,7 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) private void MidiInputButtonOnOnToggled(ButtonToggledEventArgs obj) { - _owner.CloseBandMenu(); + OnCloseBands?.Invoke(); if (obj.Pressed) { @@ -148,109 +177,99 @@ private void MidiInputButtonOnOnToggled(ButtonToggledEventArgs obj) return; MidiStopButtonOnPressed(null); - if(_owner.Instrument is {} instrument) - _owner.Instruments.OpenInput(_owner.Owner, instrument); + + if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) + _entManager.System().OpenInput(Entity, instrument); } - else if (_owner.Instrument is { } instrument) + else { - _owner.Instruments.CloseInput(_owner.Owner, false, instrument); - _owner.CloseChannelsMenu(); + _entManager.System().CloseInput(Entity, false); + OnCloseChannels?.Invoke(); } } private bool PlayCheck() { // TODO all of these checks should also be done server-side. - - var instrumentEnt = _owner.Owner; - var instrument = _owner.Instrument; - - if (instrument == null) + if (!_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) return false; - var localEntity = _owner.PlayerManager.LocalEntity; + var localEntity = _player.LocalEntity; // If we don't have a player or controlled entity, we return. if (localEntity == null) return false; // By default, allow an instrument to play itself and skip all other checks - if (localEntity == instrumentEnt) + if (localEntity == Entity) return true; - var container = _owner.Entities.System(); + var container = _entManager.System(); // If we're a handheld instrument, we might be in a container. Get it just in case. - container.TryGetContainingContainer(instrumentEnt, out var conMan); + container.TryGetContainingContainer(Entity, out var conMan); // If the instrument is handheld and we're not holding it, we return. - if ((instrument.Handheld && (conMan == null || conMan.Owner != localEntity))) + if (instrument.Handheld && (conMan == null || conMan.Owner != localEntity)) return false; - if (!_owner.ActionBlocker.CanInteract(localEntity.Value, instrumentEnt)) + if (!_entManager.System().CanInteract(localEntity.Value, Entity)) return false; // We check that we're in range unobstructed just in case. - return _owner.Interactions.InRangeUnobstructed(localEntity.Value, instrumentEnt); + return _entManager.System().InRangeUnobstructed(localEntity.Value, Entity); } private void MidiStopButtonOnPressed(ButtonEventArgs? obj) { MidiPlaybackSetButtonsDisabled(true); - if (_owner.Instrument is not {} instrument) - return; - - _owner.Instruments.CloseMidi(_owner.Owner, false, instrument); - _owner.CloseChannelsMenu(); + _entManager.System().CloseMidi(Entity, false); + OnCloseChannels?.Invoke(); } private void MidiLoopButtonOnOnToggled(ButtonToggledEventArgs obj) { - if (_owner.Instrument == null) - return; + var instrument = _entManager.System(); + + if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrumentComp)) + { + instrumentComp.LoopMidi = obj.Pressed; + } - _owner.Instrument.LoopMidi = obj.Pressed; - _owner.Instruments.UpdateRenderer(_owner.Owner, _owner.Instrument); + instrument.UpdateRenderer(Entity); } private void PlaybackSliderSeek(Range _) { // Do not seek while still grabbing. - if (PlaybackSlider.Grabbed || _owner.Instrument is not {} instrument) + if (PlaybackSlider.Grabbed) return; - _owner.Instruments.SetPlayerTick(_owner.Owner, (int)Math.Ceiling(PlaybackSlider.Value), instrument); + _entManager.System().SetPlayerTick(Entity, (int)Math.Ceiling(PlaybackSlider.Value)); } private void PlaybackSliderKeyUp(GUIBoundKeyEventArgs args) { - if (args.Function != EngineKeyFunctions.UIClick || _owner.Instrument is not {} instrument) + if (args.Function != EngineKeyFunctions.UIClick) return; - _owner.Instruments.SetPlayerTick(_owner.Owner, (int)Math.Ceiling(PlaybackSlider.Value), instrument); - } - - public override void Close() - { - base.Close(); - _owner.CloseBandMenu(); - _owner.CloseChannelsMenu(); + _entManager.System().SetPlayerTick(Entity, (int)Math.Ceiling(PlaybackSlider.Value)); } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - if (_owner.Instrument == null) + if (!_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) return; - var hasMaster = _owner.Instrument.Master != null; + var hasMaster = instrument.Master != null; BandButton.ToggleMode = hasMaster; BandButton.Pressed = hasMaster; - BandButton.Disabled = _owner.Instrument.IsMidiOpen || _owner.Instrument.IsInputOpen; - ChannelsButton.Disabled = !_owner.Instrument.IsRendererAlive; + BandButton.Disabled = instrument.IsMidiOpen || instrument.IsInputOpen; + ChannelsButton.Disabled = !instrument.IsRendererAlive; - if (!_owner.Instrument.IsMidiOpen) + if (!instrument.IsMidiOpen) { PlaybackSlider.MaxValue = 1; PlaybackSlider.SetValueWithoutEvent(0); @@ -260,8 +279,8 @@ protected override void FrameUpdate(FrameEventArgs args) if (PlaybackSlider.Grabbed) return; - PlaybackSlider.MaxValue = _owner.Instrument.PlayerTotalTick; - PlaybackSlider.SetValueWithoutEvent(_owner.Instrument.PlayerTick); + PlaybackSlider.MaxValue = instrument.PlayerTotalTick; + PlaybackSlider.SetValueWithoutEvent(instrument.PlayerTick); } } } diff --git a/Content.Client/Inventory/StrippableBoundUserInterface.cs b/Content.Client/Inventory/StrippableBoundUserInterface.cs index 7e50eb1c68a..132c5ed654c 100644 --- a/Content.Client/Inventory/StrippableBoundUserInterface.cs +++ b/Content.Client/Inventory/StrippableBoundUserInterface.cs @@ -41,7 +41,7 @@ public sealed class StrippableBoundUserInterface : BoundUserInterface public const string HiddenPocketEntityId = "StrippingHiddenEntity"; [ViewVariables] - private readonly StrippingMenu? _strippingMenu; + private StrippingMenu? _strippingMenu; [ViewVariables] private readonly EntityUid _virtualHiddenEntity; @@ -51,33 +51,30 @@ public StrippableBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, u _examine = EntMan.System(); _inv = EntMan.System(); _cuffable = EntMan.System(); - - // TODO update name when identity changes - var title = Loc.GetString("strippable-bound-user-interface-stripping-menu-title", ("ownerName", Identity.Name(Owner, EntMan))); - _strippingMenu = new StrippingMenu(title, this); - _strippingMenu.OnClose += Close; - - // TODO use global entity - // BUIs are opened and closed while applying comp sates, so spawning entities here is probably not the best idea. _virtualHiddenEntity = EntMan.SpawnEntity(HiddenPocketEntityId, MapCoordinates.Nullspace); } protected override void Open() { base.Open(); + + _strippingMenu = this.CreateWindow(); + _strippingMenu.OnDirty += UpdateMenu; + _strippingMenu.Title = Loc.GetString("strippable-bound-user-interface-stripping-menu-title", ("ownerName", Identity.Name(Owner, EntMan))); + _strippingMenu?.OpenCenteredLeft(); } protected override void Dispose(bool disposing) { - base.Dispose(disposing); - - EntMan.DeleteEntity(_virtualHiddenEntity); - if (!disposing) return; - _strippingMenu?.Dispose(); + if (_strippingMenu != null) + _strippingMenu.OnDirty -= UpdateMenu; + + EntMan.DeleteEntity(_virtualHiddenEntity); + base.Dispose(disposing); } public void DirtyMenu() diff --git a/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs b/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs index f97d8a73302..7884268c428 100644 --- a/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs +++ b/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs @@ -12,42 +12,34 @@ namespace Content.Client.Kitchen.UI [GenerateTypedNameReferences] public sealed partial class GrinderMenu : FancyWindow { - private readonly IEntityManager _entityManager; - private readonly IPrototypeManager _prototypeManager; - private readonly ReagentGrinderBoundUserInterface _owner; + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; private readonly Dictionary _chamberVisualContents = new(); - public GrinderMenu(ReagentGrinderBoundUserInterface owner, IEntityManager entityManager, IPrototypeManager prototypeManager) + public event Action? OnToggleAuto; + public event Action? OnGrind; + public event Action? OnJuice; + public event Action? OnEjectAll; + public event Action? OnEjectBeaker; + public event Action? OnEjectChamber; + + public GrinderMenu() { RobustXamlLoader.Load(this); - _entityManager = entityManager; - _prototypeManager = prototypeManager; - _owner = owner; - AutoModeButton.OnPressed += owner.ToggleAutoMode; - GrindButton.OnPressed += owner.StartGrinding; - JuiceButton.OnPressed += owner.StartJuicing; - ChamberContentBox.EjectButton.OnPressed += owner.EjectAll; - BeakerContentBox.EjectButton.OnPressed += owner.EjectBeaker; + IoCManager.InjectDependencies(this); + AutoModeButton.OnPressed += _ => OnToggleAuto?.Invoke(); + GrindButton.OnPressed += _ => OnGrind?.Invoke(); + JuiceButton.OnPressed += _ => OnJuice?.Invoke(); + ChamberContentBox.EjectButton.OnPressed += _ => OnEjectAll?.Invoke(); + BeakerContentBox.EjectButton.OnPressed += _ => OnEjectBeaker?.Invoke(); ChamberContentBox.BoxContents.OnItemSelected += OnChamberBoxContentsItemSelected; BeakerContentBox.BoxContents.SelectMode = ItemList.ItemListSelectMode.None; } private void OnChamberBoxContentsItemSelected(ItemList.ItemListSelectedEventArgs args) { - _owner.EjectChamberContent(_chamberVisualContents[args.ItemIndex]); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _chamberVisualContents.Clear(); - GrindButton.OnPressed -= _owner.StartGrinding; - JuiceButton.OnPressed -= _owner.StartJuicing; - ChamberContentBox.EjectButton.OnPressed -= _owner.EjectAll; - BeakerContentBox.EjectButton.OnPressed -= _owner.EjectBeaker; - ChamberContentBox.BoxContents.OnItemSelected -= OnChamberBoxContentsItemSelected; + OnEjectChamber?.Invoke(_chamberVisualContents[args.ItemIndex]); } public void UpdateState(ReagentGrinderInterfaceState state) diff --git a/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs b/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs index 7e7dd2d6935..643ac47054b 100644 --- a/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs +++ b/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs @@ -3,6 +3,7 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Client.Graphics; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Timing; @@ -19,28 +20,15 @@ public sealed class MicrowaveBoundUserInterface : BoundUserInterface [ViewVariables] private readonly Dictionary _reagents = new(); - [Dependency] private readonly IGameTiming _gameTiming = default!; - - public MicrowaveUpdateUserInterfaceState currentState = default!; - - private IEntityManager _entManager; public MicrowaveBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { - _entManager = IoCManager.Resolve(); - } - - public TimeSpan GetCurrentTime() - { - return _gameTiming.CurTime; } protected override void Open() { base.Open(); - _menu = new MicrowaveMenu(this); - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.StartButton.OnPressed += _ => SendPredictedMessage(new MicrowaveStartCookMessage()); _menu.EjectButton.OnPressed += _ => SendPredictedMessage(new MicrowaveEjectMessage()); _menu.IngredientsList.OnItemSelected += args => @@ -74,38 +62,23 @@ protected override void Open() }; } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (!disposing) - { - return; - } - - _solids.Clear(); - _menu?.Dispose(); - } - protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); - if (state is not MicrowaveUpdateUserInterfaceState cState) + if (state is not MicrowaveUpdateUserInterfaceState cState || _menu == null) { return; } + _menu.IsBusy = cState.IsMicrowaveBusy; + _menu.CurrentCooktimeEnd = cState.CurrentCookTimeEnd; - _menu?.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0); - currentState = cState; - + _menu.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0); // TODO move this to a component state and ensure the net ids. - RefreshContentsDisplay(_entManager.GetEntityArray(cState.ContainedSolids)); - - if (_menu == null) return; + RefreshContentsDisplay(EntMan.GetEntityArray(cState.ContainedSolids)); //Set the cook time info label - var cookTime = cState.ActiveButtonIndex == 0 + var cookTime = cState.ActiveButtonIndex == 0 ? Loc.GetString("microwave-menu-instant-button") : cState.CurrentCookTime.ToString(); diff --git a/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs b/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs index b292e9f1465..7565075f86f 100644 --- a/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs +++ b/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs @@ -9,22 +9,20 @@ namespace Content.Client.Kitchen.UI [GenerateTypedNameReferences] public sealed partial class MicrowaveMenu : FancyWindow { - public sealed class MicrowaveCookTimeButton : Button - { - public uint CookTime; - } + [Dependency] private readonly IGameTiming _timing = default!; public event Action? OnCookTimeSelected; public ButtonGroup CookTimeButtonGroup { get; } - private readonly MicrowaveBoundUserInterface _owner; - public MicrowaveMenu(MicrowaveBoundUserInterface owner) + public bool IsBusy; + public TimeSpan CurrentCooktimeEnd; + + public MicrowaveMenu() { RobustXamlLoader.Load(this); CookTimeButtonGroup = new ButtonGroup(); InstantCookButton.Group = CookTimeButtonGroup; - _owner = owner; InstantCookButton.OnPressed += args => { OnCookTimeSelected?.Invoke(args, 0); @@ -65,14 +63,20 @@ public void ToggleBusyDisableOverlayPanel(bool shouldDisable) protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - if(!_owner.currentState.IsMicrowaveBusy) + + if (!IsBusy) return; - if(_owner.currentState.CurrentCookTimeEnd > _owner.GetCurrentTime()) + if (CurrentCooktimeEnd > _timing.CurTime) { CookTimeInfoLabel.Text = Loc.GetString("microwave-bound-user-interface-cook-time-label", - ("time",_owner.currentState.CurrentCookTimeEnd.Subtract(_owner.GetCurrentTime()).Seconds)); + ("time", CurrentCooktimeEnd.Subtract(_timing.CurTime).Seconds)); } } + + public sealed class MicrowaveCookTimeButton : Button + { + public uint CookTime; + } } } diff --git a/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs b/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs index e6f108b3050..bc4cc75b4d1 100644 --- a/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs +++ b/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Containers.ItemSlots; using Content.Shared.Kitchen; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Prototypes; @@ -8,8 +9,6 @@ namespace Content.Client.Kitchen.UI { public sealed class ReagentGrinderBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [ViewVariables] private GrinderMenu? _menu; @@ -21,20 +20,13 @@ protected override void Open() { base.Open(); - _menu = new GrinderMenu(this, EntMan, _prototypeManager); - _menu.OpenCentered(); - _menu.OnClose += Close; - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - { - return; - } - - _menu?.Dispose(); + _menu = this.CreateWindow(); + _menu.OnToggleAuto += ToggleAutoMode; + _menu.OnGrind += StartGrinding; + _menu.OnJuice += StartJuicing; + _menu.OnEjectAll += EjectAll; + _menu.OnEjectBeaker += EjectBeaker; + _menu.OnEjectChamber += EjectChamberContent; } protected override void UpdateState(BoundUserInterfaceState state) @@ -52,27 +44,27 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) _menu?.HandleMessage(message); } - public void ToggleAutoMode(BaseButton.ButtonEventArgs args) + public void ToggleAutoMode() { SendMessage(new ReagentGrinderToggleAutoModeMessage()); } - public void StartGrinding(BaseButton.ButtonEventArgs? _ = null) + public void StartGrinding() { SendMessage(new ReagentGrinderStartMessage(GrinderProgram.Grind)); } - public void StartJuicing(BaseButton.ButtonEventArgs? _ = null) + public void StartJuicing() { SendMessage(new ReagentGrinderStartMessage(GrinderProgram.Juice)); } - public void EjectAll(BaseButton.ButtonEventArgs? _ = null) + public void EjectAll() { SendMessage(new ReagentGrinderEjectChamberAllMessage()); } - public void EjectBeaker(BaseButton.ButtonEventArgs? _ = null) + public void EjectBeaker() { SendMessage(new ItemSlotButtonPressedEvent(SharedReagentGrinder.BeakerSlotId)); } diff --git a/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs b/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs index 555f1ff09e6..6b656123412 100644 --- a/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs +++ b/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Labels; using Content.Shared.Labels.Components; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Labels.UI { @@ -23,13 +24,8 @@ protected override void Open() { base.Open(); - _window = new HandLabelerWindow(); - if (State != null) - UpdateState(State); + _window = this.CreateWindow(); - _window.OpenCentered(); - - _window.OnClose += Close; _window.OnLabelChanged += OnLabelChanged; Reload(); } @@ -51,13 +47,5 @@ public void Reload() _window.SetCurrentLabel(component.AssignedLabel); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } - } diff --git a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs index 6e6d1b91761..a599f79152e 100644 --- a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs +++ b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Lathe; using Content.Shared.Research.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Lathe.UI { @@ -17,9 +18,9 @@ protected override void Open() { base.Open(); - _menu = new LatheMenu(this); - _menu.OnClose += Close; - + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.OpenCenteredRight(); _menu.OnServerListButtonPressed += _ => { @@ -30,8 +31,6 @@ protected override void Open() { SendMessage(new LatheQueueRecipeMessage(recipe, amount)); }; - - _menu.OpenCenteredRight(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -50,13 +49,5 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Dispose(); - } } } diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml.cs b/Content.Client/Lathe/UI/LatheMenu.xaml.cs index f2f52b67b5b..6f530b76c75 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml.cs +++ b/Content.Client/Lathe/UI/LatheMenu.xaml.cs @@ -1,3 +1,4 @@ +using System.Buffers; using System.Linq; using System.Text; using Content.Client.Materials; @@ -22,7 +23,6 @@ public sealed partial class LatheMenu : DefaultWindow [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - private EntityUid _owner; private readonly SpriteSystem _spriteSystem; private readonly LatheSystem _lathe; private readonly MaterialStorageSystem _materialStorage; @@ -36,9 +36,10 @@ public sealed partial class LatheMenu : DefaultWindow public ProtoId? CurrentCategory; - public LatheMenu(LatheBoundUserInterface owner) + public EntityUid Entity; + + public LatheMenu() { - _owner = owner.Owner; RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -46,8 +47,6 @@ public LatheMenu(LatheBoundUserInterface owner) _lathe = _entityManager.System(); _materialStorage = _entityManager.System(); - Title = _entityManager.GetComponent(owner.Owner).EntityName; - SearchBar.OnTextChanged += _ => { PopulateRecipes(); @@ -60,8 +59,13 @@ public LatheMenu(LatheBoundUserInterface owner) FilterOption.OnItemSelected += OnItemSelected; ServerListButton.OnPressed += a => OnServerListButtonPressed?.Invoke(a); + } - if (_entityManager.TryGetComponent(owner.Owner, out var latheComponent)) + public void SetEntity(EntityUid uid) + { + Entity = uid; + + if (_entityManager.TryGetComponent(Entity, out var latheComponent)) { if (!latheComponent.DynamicRecipes.Any()) { @@ -69,7 +73,7 @@ public LatheMenu(LatheBoundUserInterface owner) } } - MaterialsList.SetOwner(owner.Owner); + MaterialsList.SetOwner(Entity); } /// @@ -102,13 +106,15 @@ public void PopulateRecipes() var sortedRecipesToShow = recipesToShow.OrderBy(p => p.Name); RecipeList.Children.Clear(); + _entityManager.TryGetComponent(Entity, out LatheComponent? lathe); + foreach (var prototype in sortedRecipesToShow) { EntityPrototype? recipeProto = null; - if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto) && entityProto != null) + if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto)) recipeProto = entityProto; - var canProduce = _lathe.CanProduce(_owner, prototype, quantity); + var canProduce = _lathe.CanProduce(Entity, prototype, quantity, component: lathe); var control = new RecipeControl(prototype, () => GenerateTooltipText(prototype), canProduce, recipeProto); control.OnButtonPressed += s => @@ -124,19 +130,20 @@ public void PopulateRecipes() private string GenerateTooltipText(LatheRecipePrototype prototype) { StringBuilder sb = new(); + var multiplier = _entityManager.GetComponent(Entity).MaterialUseMultiplier; foreach (var (id, amount) in prototype.RequiredMaterials) { if (!_prototypeManager.TryIndex(id, out var proto)) continue; - var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, _entityManager.GetComponent(_owner).MaterialUseMultiplier); + var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, multiplier); var sheetVolume = _materialStorage.GetSheetVolume(proto); var unit = Loc.GetString(proto.Unit); var sheets = adjustedAmount / (float) sheetVolume; - var availableAmount = _materialStorage.GetMaterialAmount(_owner, id); + var availableAmount = _materialStorage.GetMaterialAmount(Entity, id); var missingAmount = Math.Max(0, adjustedAmount - availableAmount); var missingSheets = missingAmount / (float) sheetVolume; diff --git a/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs b/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs index 09bdedfd94c..11abe8c2451 100644 --- a/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs +++ b/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.MachineLinking; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Timing; namespace Content.Client.MachineLinking.UI; @@ -19,19 +20,14 @@ protected override void Open() { base.Open(); - _window = new SignalTimerWindow(this); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.OnStartTimer += StartTimer; _window.OnCurrentTextChanged += OnTextChanged; _window.OnCurrentDelayMinutesChanged += OnDelayChanged; _window.OnCurrentDelaySecondsChanged += OnDelayChanged; } - public void OnStartTimer() + public void StartTimer() { SendMessage(new SignalTimerStartMessage()); } @@ -48,11 +44,6 @@ private void OnDelayChanged(string newDelay) SendMessage(new SignalTimerDelayChangedMessage(_window.GetDelay())); } - public TimeSpan GetCurrentTime() - { - return _gameTiming.CurTime; - } - /// /// Update the UI state based on server-sent info /// @@ -72,11 +63,4 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetTimerStarted(cast.TimerStarted); _window.SetHasAccess(cast.HasAccess); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } diff --git a/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs b/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs index b62595595e5..6133abfcb70 100644 --- a/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs +++ b/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs @@ -9,42 +9,44 @@ namespace Content.Client.MachineLinking.UI; [GenerateTypedNameReferences] public sealed partial class SignalTimerWindow : DefaultWindow { + [Dependency] private readonly IGameTiming _timing = default!; + private const int MaxTextLength = 5; public event Action? OnCurrentTextChanged; public event Action? OnCurrentDelayMinutesChanged; public event Action? OnCurrentDelaySecondsChanged; - private readonly SignalTimerBoundUserInterface _owner; - private TimeSpan? _triggerTime; private bool _timerStarted; - public SignalTimerWindow(SignalTimerBoundUserInterface owner) + public event Action? OnStartTimer; + + public SignalTimerWindow() { RobustXamlLoader.Load(this); - - _owner = owner; + IoCManager.InjectDependencies(this); CurrentTextEdit.OnTextChanged += e => OnCurrentTextChange(e.Text); CurrentDelayEditMinutes.OnTextChanged += e => OnCurrentDelayMinutesChange(e.Text); CurrentDelayEditSeconds.OnTextChanged += e => OnCurrentDelaySecondsChange(e.Text); - StartTimer.OnPressed += _ => OnStartTimer(); + StartTimer.OnPressed += _ => StartTimerWeh(); } - public void OnStartTimer() + private void StartTimerWeh() { if (!_timerStarted) { _timerStarted = true; - _triggerTime = _owner.GetCurrentTime() + GetDelay(); + _triggerTime = _timing.CurTime + GetDelay(); } else { SetTimerStarted(false); } - _owner.OnStartTimer(); + + OnStartTimer?.Invoke(); } protected override void FrameUpdate(FrameEventArgs args) @@ -54,9 +56,9 @@ protected override void FrameUpdate(FrameEventArgs args) if (!_timerStarted || _triggerTime == null) return; - if (_owner.GetCurrentTime() < _triggerTime.Value) + if (_timing.CurTime < _triggerTime.Value) { - StartTimer.Text = TextScreenSystem.TimeToString(_triggerTime.Value - _owner.GetCurrentTime()); + StartTimer.Text = TextScreenSystem.TimeToString(_triggerTime.Value - _timing.CurTime); } else { diff --git a/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs b/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs index f6979bf8d7b..0a87948ff62 100644 --- a/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs +++ b/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Humanoid.Markings; using Content.Shared.MagicMirror; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.MagicMirror; @@ -17,7 +18,7 @@ protected override void Open() { base.Open(); - _window = new(); + _window = this.CreateWindow(); _window.OnHairSelected += tuple => SelectHair(MagicMirrorCategory.Hair, tuple.id, tuple.slot); _window.OnHairColorChanged += args => ChangeColor(MagicMirrorCategory.Hair, args.marking, args.slot); @@ -29,9 +30,6 @@ protected override void Open() args => ChangeColor(MagicMirrorCategory.FacialHair, args.marking, args.slot); _window.OnFacialHairSlotAdded += delegate () { AddSlot(MagicMirrorCategory.FacialHair); }; _window.OnFacialHairSlotRemoved += args => RemoveSlot(MagicMirrorCategory.FacialHair, args); - - _window.OnClose += Close; - _window.OpenCentered(); } private void SelectHair(MagicMirrorCategory category, string marking, int slot) @@ -65,14 +63,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState(data); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); - } } diff --git a/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs b/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs index 80eca82e324..22e5bc452a0 100644 --- a/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs +++ b/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs @@ -1,6 +1,7 @@ using JetBrains.Annotations; using Content.Shared.MassMedia.Systems; using Content.Shared.MassMedia.Components; +using Robust.Client.UserInterface; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -9,8 +10,6 @@ namespace Content.Client.MassMedia.Ui; [UsedImplicitly] public sealed class NewsWriterBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IGameTiming _gameTiming = default!; - [ViewVariables] private NewsWriterMenu? _menu; @@ -21,10 +20,7 @@ public NewsWriterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, u protected override void Open() { - _menu = new NewsWriterMenu(_gameTiming); - - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.ArticleEditorPanel.PublishButtonPressed += OnPublishButtonPressed; _menu.DeleteButtonPressed += OnDeleteButtonPressed; @@ -32,16 +28,6 @@ protected override void Open() SendMessage(new NewsWriterArticlesRequestMessage()); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Close(); - _menu?.Dispose(); - } - protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); diff --git a/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs b/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs index e2d57935e3a..c059ce785af 100644 --- a/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs +++ b/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs @@ -10,17 +10,17 @@ namespace Content.Client.MassMedia.Ui; [GenerateTypedNameReferences] public sealed partial class NewsWriterMenu : FancyWindow { - private readonly IGameTiming _gameTiming; + [Dependency] private readonly IGameTiming _gameTiming = default!; private TimeSpan? _nextPublish; public event Action? DeleteButtonPressed; - public NewsWriterMenu(IGameTiming gameTiming) + public NewsWriterMenu() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); - _gameTiming = gameTiming; ContentsContainer.RectClipContent = false; // Customize scrollbar width and margin. This is not possible in xaml diff --git a/Content.Client/Mech/Ui/MechBoundUserInterface.cs b/Content.Client/Mech/Ui/MechBoundUserInterface.cs index 4172bdc90f1..2130a8c6099 100644 --- a/Content.Client/Mech/Ui/MechBoundUserInterface.cs +++ b/Content.Client/Mech/Ui/MechBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Mech.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Mech.Ui; @@ -20,9 +21,8 @@ protected override void Open() { base.Open(); - _menu = new(Owner); - - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); _menu.OpenCenteredLeft(); _menu.OnRemoveButtonPressed += uid => @@ -60,16 +60,6 @@ public void UpdateEquipmentControls(MechBoundUiState state) } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (!disposing) - return; - - _menu?.Close(); - } - public UIFragment? GetEquipmentUi(EntityUid? uid) { var component = EntMan.GetComponentOrNull(uid); diff --git a/Content.Client/Mech/Ui/MechMenu.xaml.cs b/Content.Client/Mech/Ui/MechMenu.xaml.cs index fad76488086..6f39bc386ee 100644 --- a/Content.Client/Mech/Ui/MechMenu.xaml.cs +++ b/Content.Client/Mech/Ui/MechMenu.xaml.cs @@ -16,14 +16,15 @@ public sealed partial class MechMenu : FancyWindow public event Action? OnRemoveButtonPressed; - public MechMenu(EntityUid mech) + public MechMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); + } - _mech = mech; - - MechView.SetEntity(mech); + public void SetEntity(EntityUid uid) + { + MechView.SetEntity(uid); } public void UpdateMechStats() diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs index 39788809871..b1f239cd78e 100644 --- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs @@ -1,4 +1,5 @@ using Content.Shared.Medical.CrewMonitoring; +using Robust.Client.UserInterface; namespace Content.Client.Medical.CrewMonitoring; @@ -14,7 +15,7 @@ public CrewMonitoringBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { EntityUid? gridUid = null; - string stationName = string.Empty; + var stationName = string.Empty; if (EntMan.TryGetComponent(Owner, out var xform)) { @@ -26,10 +27,8 @@ protected override void Open() } } - _menu = new CrewMonitoringWindow(stationName, gridUid); - - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.Set(stationName, gridUid); } protected override void UpdateState(BoundUserInterfaceState state) @@ -44,13 +43,4 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs index 863412e5532..e861864c144 100644 --- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs @@ -23,22 +23,27 @@ namespace Content.Client.Medical.CrewMonitoring; [GenerateTypedNameReferences] public sealed partial class CrewMonitoringWindow : FancyWindow { - private readonly IEntityManager _entManager; - private readonly IPrototypeManager _prototypeManager; + [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; private readonly SpriteSystem _spriteSystem; private NetEntity? _trackedEntity; private bool _tryToScrollToListFocus; private Texture? _blipTexture; - public CrewMonitoringWindow(string stationName, EntityUid? mapUid) + public CrewMonitoringWindow() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); - _entManager = IoCManager.Resolve(); - _prototypeManager = IoCManager.Resolve(); _spriteSystem = _entManager.System(); + NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; + + } + + public void Set(string stationName, EntityUid? mapUid) + { _blipTexture = _spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png"))); if (_entManager.TryGetComponent(mapUid, out var xform)) @@ -49,8 +54,6 @@ public CrewMonitoringWindow(string stationName, EntityUid? mapUid) StationName.AddStyleClass("LabelBig"); StationName.Text = stationName; - - NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; NavMap.ForceNavMapUpdate(); } diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs index 80c98f143b9..f85220a9266 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Client.NetworkConfigurator.Systems; using Content.Shared.DeviceNetwork; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.NetworkConfigurator; @@ -35,14 +36,12 @@ protected override void Open() switch (UiKey) { case NetworkConfiguratorUiKey.List: - _listMenu = new NetworkConfiguratorListMenu(this); - _listMenu.OnClose += Close; + _listMenu = this.CreateWindow(); _listMenu.ClearButton.OnPressed += _ => OnClearButtonPressed(); - _listMenu.OpenCenteredRight(); + _listMenu.OnRemoveAddress += OnRemoveButtonPressed; break; case NetworkConfiguratorUiKey.Configure: - _configurationMenu = new NetworkConfiguratorConfigurationMenu(); - _configurationMenu.OnClose += Close; + _configurationMenu = this.CreateWindow(); _configurationMenu.Set.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Set); _configurationMenu.Add.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Add); //_configurationMenu.Edit.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Edit); @@ -50,12 +49,24 @@ protected override void Open() _configurationMenu.Copy.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Copy); _configurationMenu.Show.OnPressed += OnShowPressed; _configurationMenu.Show.Pressed = _netConfig.ConfiguredListIsTracked(Owner); - _configurationMenu.OpenCentered(); + _configurationMenu.OnRemoveAddress += OnRemoveButtonPressed; break; case NetworkConfiguratorUiKey.Link: - _linkMenu = new NetworkConfiguratorLinkMenu(this); - _linkMenu.OnClose += Close; - _linkMenu.OpenCentered(); + _linkMenu = this.CreateWindow(); + _linkMenu.OnLinkDefaults += args => + { + SendMessage(new NetworkConfiguratorLinksSaveMessage(args)); + }; + + _linkMenu.OnToggleLink += (left, right) => + { + SendMessage(new NetworkConfiguratorToggleLinkMessage(left, right)); + }; + + _linkMenu.OnClearLinks += () => + { + SendMessage(new NetworkConfiguratorClearLinksMessage()); + }; break; } } @@ -83,16 +94,6 @@ protected override void UpdateState(BoundUserInterfaceState state) } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _linkMenu?.Dispose(); - _listMenu?.Dispose(); - _configurationMenu?.Dispose(); - } - private void OnClearButtonPressed() { SendMessage(new NetworkConfiguratorClearDevicesMessage()); diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs index 19d04cd3464..fcd2f759187 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs @@ -9,17 +9,23 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorConfigurationMenu : FancyWindow { + public event Action? OnRemoveAddress; + public NetworkConfiguratorConfigurationMenu() { RobustXamlLoader.Load(this); Clear.StyleClasses.Add(StyleBase.ButtonOpenLeft); Clear.StyleClasses.Add(StyleNano.StyleClassButtonColorRed); + DeviceList.OnRemoveAddress += args => + { + OnRemoveAddress?.Invoke(args); + }; } public void UpdateState(DeviceListUserInterfaceState state) { - DeviceList.UpdateState(null, state.DeviceList); + DeviceList.UpdateState(state.DeviceList, false); Count.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count)); } diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs index 8cfa97dc6c2..e75c60058cb 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs @@ -7,17 +7,19 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorDeviceList : ScrollContainer { - public void UpdateState(NetworkConfiguratorBoundUserInterface? ui, HashSet<(string address, string name)> devices) + public event Action? OnRemoveAddress; + + public void UpdateState(HashSet<(string address, string name)> devices, bool ui) { DeviceList.RemoveAllChildren(); foreach (var device in devices) { - DeviceList.AddChild(BuildDeviceListRow(ui, device)); + DeviceList.AddChild(BuildDeviceListRow(device, ui)); } } - private static BoxContainer BuildDeviceListRow(NetworkConfiguratorBoundUserInterface? ui, (string address, string name) savedDevice) + private BoxContainer BuildDeviceListRow((string address, string name) savedDevice, bool ui) { var row = new BoxContainer() { @@ -48,10 +50,10 @@ private static BoxContainer BuildDeviceListRow(NetworkConfiguratorBoundUserInter row.AddChild(name); row.AddChild(address); - if (ui != null) + if (ui) { row.AddChild(removeButton); - removeButton.OnPressed += _ => ui.OnRemoveButtonPressed(savedDevice.address); + removeButton.OnPressed += _ => OnRemoveAddress?.Invoke(savedDevice.address); } return row; diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs index c04b42f249b..8cdffd16af6 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs @@ -18,20 +18,20 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow private readonly LinksRender _links; - private readonly List _sources = new(); private readonly List _sinks = new(); - private readonly NetworkConfiguratorBoundUserInterface _userInterface; - private (ButtonPosition position, string id, int index)? _selectedButton; private List<(string left, string right)>? _defaults; - public NetworkConfiguratorLinkMenu(NetworkConfiguratorBoundUserInterface userInterface) + public event Action? OnClearLinks; + public event Action? OnToggleLink; + public event Action>? OnLinkDefaults; + + public NetworkConfiguratorLinkMenu() { - _userInterface = userInterface; RobustXamlLoader.Load(this); var footerStyleBox = new StyleBoxFlat() @@ -52,7 +52,7 @@ public NetworkConfiguratorLinkMenu(NetworkConfiguratorBoundUserInterface userInt ButtonOk.OnPressed += _ => Close(); ButtonLinkDefault.OnPressed += _ => LinkDefaults(); - ButtonClear.OnPressed += _ => _userInterface.SendMessage(new NetworkConfiguratorClearLinksMessage()); + ButtonClear.OnPressed += _ => OnClearLinks?.Invoke(); } public void UpdateState(DeviceLinkUserInterfaceState linkState) @@ -98,7 +98,7 @@ private void LinkDefaults() if (_defaults == default) return; - _userInterface.SendMessage(new NetworkConfiguratorLinksSaveMessage(_defaults)); + OnLinkDefaults?.Invoke(_defaults); } private Button CreateButton(ButtonPosition position, string name, string description, string id, int index) @@ -138,7 +138,7 @@ private void OnButtonPressed(BaseButton.ButtonEventArgs args, ButtonPosition pos var left = _selectedButton.Value.position == ButtonPosition.Left ? _selectedButton.Value.id : id; var right = _selectedButton.Value.position == ButtonPosition.Left ? id : _selectedButton.Value.id; - _userInterface.SendMessage(new NetworkConfiguratorToggleLinkMessage(left, right)); + OnToggleLink?.Invoke(left, right); args.Button.Pressed = false; diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs index fb4aec1974b..6294facaeed 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs @@ -9,17 +9,20 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorListMenu : FancyWindow { - private readonly NetworkConfiguratorBoundUserInterface _ui; - public NetworkConfiguratorListMenu(NetworkConfiguratorBoundUserInterface ui) + public event Action? OnRemoveAddress; + + public NetworkConfiguratorListMenu() { RobustXamlLoader.Load(this); - - _ui = ui; + DeviceList.OnRemoveAddress += args => + { + OnRemoveAddress?.Invoke(args); + }; } public void UpdateState(NetworkConfiguratorUserInterfaceState state) { DeviceCountLabel.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count)); - DeviceList.UpdateState(_ui, state.DeviceList); + DeviceList.UpdateState(state.DeviceList, true); } } diff --git a/Content.Client/Nuke/NukeBoundUserInterface.cs b/Content.Client/Nuke/NukeBoundUserInterface.cs index 59fbc5b319b..2e150423734 100644 --- a/Content.Client/Nuke/NukeBoundUserInterface.cs +++ b/Content.Client/Nuke/NukeBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Nuke; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Nuke { @@ -11,15 +12,13 @@ public sealed class NukeBoundUserInterface : BoundUserInterface [ViewVariables] private NukeMenu? _menu; - public NukeBoundUserInterface([NotNull] EntityUid owner, [NotNull] Enum uiKey) : base(owner, uiKey) + public NukeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } protected override void Open() { - _menu = new NukeMenu(); - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.OnKeypadButtonPressed += i => { @@ -62,15 +61,5 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Close(); - _menu?.Dispose(); - } } } diff --git a/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs b/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs index ec055b3240c..ad4f1a75d47 100644 --- a/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs +++ b/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Chat; using Content.Shared.NukeOps; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Timing; @@ -11,8 +12,6 @@ namespace Content.Client.NukeOps; public sealed class WarDeclaratorBoundUserInterface : BoundUserInterface { [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly ILocalizationManager _localizationManager = default!; [ViewVariables] private WarDeclaratorWindow? _window; @@ -23,13 +22,7 @@ protected override void Open() { base.Open(); - _window = new WarDeclaratorWindow(_gameTiming, _localizationManager); - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.OnActivated += OnWarDeclaratorActivated; } @@ -42,13 +35,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - _window?.Dispose(); - } - private void OnWarDeclaratorActivated(string message) { var maxLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength); diff --git a/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs b/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs index b4a3f1c7fa5..aeceae13275 100644 --- a/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs +++ b/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs @@ -11,7 +11,8 @@ namespace Content.Client.NukeOps; [GenerateTypedNameReferences] public sealed partial class WarDeclaratorWindow : FancyWindow { - private readonly IGameTiming _gameTiming; + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly ILocalizationManager _localizationManager = default!; public event Action? OnActivated; @@ -19,15 +20,13 @@ public sealed partial class WarDeclaratorWindow : FancyWindow private TimeSpan _shuttleDisabledTime; private WarConditionStatus _status; - public WarDeclaratorWindow(IGameTiming gameTiming, ILocalizationManager localizationManager) + public WarDeclaratorWindow() { RobustXamlLoader.Load(this); - _gameTiming = gameTiming; - WarButton.OnPressed += (_) => OnActivated?.Invoke(Rope.Collapse(MessageEdit.TextRope)); - MessageEdit.Placeholder = new Rope.Leaf(localizationManager.GetString("war-declarator-message-placeholder")); + MessageEdit.Placeholder = new Rope.Leaf(_localizationManager.GetString("war-declarator-message-placeholder")); } protected override void FrameUpdate(FrameEventArgs args) diff --git a/Content.Client/PDA/PdaBoundUserInterface.cs b/Content.Client/PDA/PdaBoundUserInterface.cs index f8f4c67076c..37ce9c4280f 100644 --- a/Content.Client/PDA/PdaBoundUserInterface.cs +++ b/Content.Client/PDA/PdaBoundUserInterface.cs @@ -24,14 +24,13 @@ protected override void Open() if (_menu == null) CreateMenu(); - - _menu?.OpenCenteredLeft(); } private void CreateMenu() { - _menu = new PdaMenu(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.OpenCenteredLeft(); + _menu.FlashLightToggleButton.OnToggled += _ => { SendMessage(new PdaToggleFlashlightMessage()); @@ -96,7 +95,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _menu?.UpdateState(updateState); } - protected override void AttachCartridgeUI(Control cartridgeUIFragment, string? title) { _menu?.ProgramView.AddChild(cartridgeUIFragment); @@ -118,15 +116,6 @@ protected override void UpdateAvailablePrograms(List<(EntityUid, CartridgeCompon _menu?.UpdateAvailablePrograms(programs); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } - private PdaBorderColorComponent? GetBorderColorComponent() { return EntMan.GetComponentOrNull(Owner); diff --git a/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs b/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs index a0688523f1e..170a296ac2e 100644 --- a/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs +++ b/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.PDA; using Content.Shared.PDA.Ringer; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Shared.Timing; namespace Content.Client.PDA.Ringer @@ -18,9 +19,8 @@ public RingerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey protected override void Open() { base.Open(); - _menu = new RingtoneMenu(); + _menu = this.CreateWindow(); _menu.OpenToLeft(); - _menu.OnClose += Close; _menu.TestRingerButton.OnPressed += _ => { diff --git a/Content.Client/Paper/UI/PaperBoundUserInterface.cs b/Content.Client/Paper/UI/PaperBoundUserInterface.cs index 4b0ac868f01..f3ad1e347e7 100644 --- a/Content.Client/Paper/UI/PaperBoundUserInterface.cs +++ b/Content.Client/Paper/UI/PaperBoundUserInterface.cs @@ -1,4 +1,5 @@ using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Utility; using static Content.Shared.Paper.SharedPaperComponent; @@ -19,16 +20,13 @@ protected override void Open() { base.Open(); - _window = new PaperWindow(); - _window.OnClose += Close; - _window.OnSaved += Input_OnTextEntered; + _window = this.CreateWindow(); + _window.OnSaved += InputOnTextEntered; if (EntMan.TryGetComponent(Owner, out var visuals)) { _window.InitVisuals(Owner, visuals); } - - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -37,7 +35,7 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.Populate((PaperBoundUserInterfaceState) state); } - private void Input_OnTextEntered(string text) + private void InputOnTextEntered(string text) { SendMessage(new PaperInputTextMessage(text)); @@ -47,11 +45,4 @@ private void Input_OnTextEntered(string text) _window.Input.CursorPosition = new TextEdit.CursorPos(0, TextEdit.LineBreakBias.Top); } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } diff --git a/Content.Client/Paper/UI/PaperWindow.xaml.cs b/Content.Client/Paper/UI/PaperWindow.xaml.cs index 7a5fd652643..f7cace642ce 100644 --- a/Content.Client/Paper/UI/PaperWindow.xaml.cs +++ b/Content.Client/Paper/UI/PaperWindow.xaml.cs @@ -17,6 +17,7 @@ namespace Content.Client.Paper.UI public sealed partial class PaperWindow : BaseWindow { [Dependency] private readonly IInputManager _inputManager = default!; + [Dependency] private readonly IResourceCache _resCache = default!; private static Color DefaultTextColor = new(25, 25, 25); @@ -85,11 +86,10 @@ public void InitVisuals(EntityUid entity, PaperVisualsComponent visuals) // Randomize the placement of any stamps based on the entity UID // so that there's some variety in different papers. StampDisplay.PlacementSeed = (int)entity; - var resCache = IoCManager.Resolve(); // Initialize the background: PaperBackground.ModulateSelfOverride = visuals.BackgroundModulate; - var backgroundImage = visuals.BackgroundImagePath != null? resCache.GetResource(visuals.BackgroundImagePath) : null; + var backgroundImage = visuals.BackgroundImagePath != null? _resCache.GetResource(visuals.BackgroundImagePath) : null; if (backgroundImage != null) { var backgroundImageMode = visuals.BackgroundImageTile ? StyleBoxTexture.StretchMode.Tile : StyleBoxTexture.StretchMode.Stretch; @@ -127,7 +127,7 @@ public void InitVisuals(EntityUid entity, PaperVisualsComponent visuals) PaperContent.ModulateSelfOverride = visuals.ContentImageModulate; WrittenTextLabel.ModulateSelfOverride = visuals.FontAccentColor; - var contentImage = visuals.ContentImagePath != null ? resCache.GetResource(visuals.ContentImagePath) : null; + var contentImage = visuals.ContentImagePath != null ? _resCache.GetResource(visuals.ContentImagePath) : null; if (contentImage != null) { // Setup the paper content texture, but keep a reference to it, as we can't set diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs index cde5ba9ef79..ff1eae36f55 100644 --- a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs +++ b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Singularity.Components; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.ParticleAccelerator.UI { @@ -16,9 +17,10 @@ protected override void Open() { base.Open(); - _menu = new ParticleAcceleratorControlMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnOverallState += SendEnableMessage; + _menu.OnPowerState += SendPowerStateMessage; + _menu.OnScanPartsRequested += SendScanPartsMessage; } public void SendEnableMessage(bool enable) @@ -40,13 +42,5 @@ protected override void UpdateState(BoundUserInterfaceState state) { _menu?.DataUpdate((ParticleAcceleratorUIState) state); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _menu?.Dispose(); - _menu = null; - } } } diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs index c69e0271372..85a5f476293 100644 --- a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs +++ b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs @@ -18,9 +18,10 @@ namespace Content.Client.ParticleAccelerator.UI { public sealed class ParticleAcceleratorControlMenu : BaseWindow { - private readonly ShaderInstance _greyScaleShader; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly IResourceCache _cache = default!; - private readonly ParticleAcceleratorBoundUserInterface _owner; + private readonly ShaderInstance _greyScaleShader; private readonly Label _drawLabel; private readonly FastNoiseLite _drawNoiseGenerator; @@ -50,19 +51,21 @@ public sealed class ParticleAcceleratorControlMenu : BaseWindow private bool _shouldContinueAnimating; private int _maxStrength = 3; - public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owner) + public event Action? OnOverallState; + public event Action? OnPowerState; + public event Action? OnScanPartsRequested; + + public ParticleAcceleratorControlMenu() { SetSize = new Vector2(400, 320); - _greyScaleShader = IoCManager.Resolve().Index("Greyscale").Instance(); + _greyScaleShader = _protoManager.Index("Greyscale").Instance(); - _owner = owner; _drawNoiseGenerator = new(); _drawNoiseGenerator.SetFractalType(FastNoiseLite.FractalType.FBm); _drawNoiseGenerator.SetFrequency(0.5f); - var resourceCache = IoCManager.Resolve(); - var font = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); - var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); + var font = _cache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); + var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); MouseFilter = MouseFilterMode.Stop; @@ -112,7 +115,8 @@ public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owne Text = Loc.GetString("particle-accelerator-control-menu-off-button"), StyleClasses = { StyleBase.ButtonOpenRight }, }; - _offButton.OnPressed += args => owner.SendEnableMessage(false); + + _offButton.OnPressed += args => OnOverallState?.Invoke(false); _onButton = new Button { @@ -120,7 +124,7 @@ public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owne Text = Loc.GetString("particle-accelerator-control-menu-on-button"), StyleClasses = { StyleBase.ButtonOpenLeft }, }; - _onButton.OnPressed += args => owner.SendEnableMessage(true); + _onButton.OnPressed += args => OnOverallState?.Invoke(true); var closeButton = new TextureButton { @@ -316,7 +320,7 @@ public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owne } }); - _scanButton.OnPressed += args => _owner.SendScanPartsMessage(); + _scanButton.OnPressed += args => OnScanPartsRequested?.Invoke(); _alarmControl.AnimationCompleted += s => { @@ -332,7 +336,7 @@ public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owne PASegmentControl Segment(string name) { - return new(this, resourceCache, name); + return new(this, _cache, name); } UpdateUI(false, false, false, false); @@ -368,7 +372,7 @@ private void PowerStateChanged(ValueChangedEventArgs e) } _stateSpinBox.SetButtonDisabled(true); - _owner.SendPowerStateMessage(newState); + OnPowerState?.Invoke(newState); } protected override DragMode GetDragModeFor(Vector2 relativeMousePos) diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs b/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs index 3ebcf7cbced..0df6787170a 100644 --- a/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Pinpointer; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Pinpointer.UI; @@ -16,19 +17,16 @@ public NavMapBeaconBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, protected override void Open() { base.Open(); - _window = new NavMapBeaconWindow(Owner); - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + + if (EntMan.TryGetComponent(Owner, out NavMapBeaconComponent? beacon)) + { + _window.SetEntity(Owner, beacon); + } _window.OnApplyButtonPressed += (label, enabled, color) => { SendMessage(new NavMapBeaconConfigureBuiMessage(label, enabled, color)); }; } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); - } } diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs b/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs index 968fe188f75..b77f1af0472 100644 --- a/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs +++ b/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs @@ -10,38 +10,37 @@ namespace Content.Client.Pinpointer.UI; [GenerateTypedNameReferences] public sealed partial class NavMapBeaconWindow : FancyWindow { - [Dependency] private readonly IEntityManager _entityManager = default!; - private string? _defaultLabel; private bool _defaultEnabled; private Color _defaultColor; public event Action? OnApplyButtonPressed; - public NavMapBeaconWindow(EntityUid beaconEntity) + public NavMapBeaconWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - if (!_entityManager.TryGetComponent(beaconEntity, out var navMap)) - return; - _defaultLabel = navMap.Text; - _defaultEnabled = navMap.Enabled; - _defaultColor = navMap.Color; - UpdateVisibleButton(navMap.Enabled); VisibleButton.OnPressed += args => UpdateVisibleButton(args.Button.Pressed); - - LabelLineEdit.Text = navMap.Text ?? string.Empty; LabelLineEdit.OnTextChanged += OnTextChanged; - - ColorSelector.Color = navMap.Color; ColorSelector.OnColorChanged += _ => TryEnableApplyButton(); TryEnableApplyButton(); ApplyButton.OnPressed += OnApplyPressed; } + public void SetEntity(EntityUid uid, NavMapBeaconComponent navMap) + { + _defaultLabel = navMap.Text; + _defaultEnabled = navMap.Enabled; + _defaultColor = navMap.Color; + + UpdateVisibleButton(navMap.Enabled); + LabelLineEdit.Text = navMap.Text ?? string.Empty; + ColorSelector.Color = navMap.Color; + } + private void UpdateVisibleButton(bool value) { VisibleButton.Pressed = value; diff --git a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs index 1483e75e732..7417fafede5 100644 --- a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs @@ -1,4 +1,4 @@ -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Pinpointer.UI; @@ -14,7 +14,6 @@ public StationMapBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, u protected override void Open() { base.Open(); - _window?.Close(); EntityUid? gridUid = null; if (EntMan.TryGetComponent(Owner, out var xform)) @@ -22,14 +21,8 @@ protected override void Open() gridUid = xform.GridUid; } - _window = new StationMapWindow(gridUid, Owner); - _window.OpenCentered(); - _window.OnClose += Close; - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); + _window = this.CreateWindow(); + _window.Title = EntMan.GetComponent(Owner).EntityName; + _window.Set(gridUid, Owner); } } diff --git a/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs b/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs index 1b01fe4e304..7cbb8b7d0db 100644 --- a/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs +++ b/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs @@ -9,19 +9,18 @@ namespace Content.Client.Pinpointer.UI; [GenerateTypedNameReferences] public sealed partial class StationMapWindow : FancyWindow { - public StationMapWindow(EntityUid? mapUid, EntityUid? trackedEntity) + public StationMapWindow() { RobustXamlLoader.Load(this); + } + + public void Set(EntityUid? mapUid, EntityUid? trackedEntity) + { NavMapScreen.MapUid = mapUid; if (trackedEntity != null) NavMapScreen.TrackedCoordinates.Add(new EntityCoordinates(trackedEntity.Value, Vector2.Zero), (true, Color.Cyan)); - if (IoCManager.Resolve().TryGetComponent(mapUid, out var metadata)) - { - Title = metadata.EntityName; - } - NavMapScreen.ForceNavMapUpdate(); } } diff --git a/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs b/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs index 57965b030a2..a3ca6f65da2 100644 --- a/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs @@ -1,4 +1,4 @@ -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Pinpointer.UI; @@ -14,22 +14,15 @@ public UntrackedStationMapBoundUserInterface(EntityUid owner, Enum uiKey) : base protected override void Open() { base.Open(); - _window?.Close(); EntityUid? gridUid = null; + // TODO: What this just looks like it's been copy-pasted wholesale from StationMapBoundUserInterface? if (EntMan.TryGetComponent(Owner, out var xform)) { gridUid = xform.GridUid; } - _window = new StationMapWindow(gridUid, null); - _window.OpenCentered(); - _window.OnClose += Close; - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); + _window = this.CreateWindow(); + _window.Set(gridUid, Owner); } } diff --git a/Content.Client/Power/APC/ApcBoundUserInterface.cs b/Content.Client/Power/APC/ApcBoundUserInterface.cs index fbcbf011569..759a5949ba6 100644 --- a/Content.Client/Power/APC/ApcBoundUserInterface.cs +++ b/Content.Client/Power/APC/ApcBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.APC; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Power.APC { @@ -19,9 +20,8 @@ protected override void Open() { base.Open(); - _menu = new ApcMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnBreaker += BreakerPressed; } protected override void UpdateState(BoundUserInterfaceState state) @@ -36,15 +36,5 @@ public void BreakerPressed() { SendMessage(new ApcToggleMainBreakerMessage()); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _menu?.Dispose(); - } - } } } diff --git a/Content.Client/Power/APC/UI/ApcMenu.xaml.cs b/Content.Client/Power/APC/UI/ApcMenu.xaml.cs index dbf68ea07b0..2f61ea63a86 100644 --- a/Content.Client/Power/APC/UI/ApcMenu.xaml.cs +++ b/Content.Client/Power/APC/UI/ApcMenu.xaml.cs @@ -17,13 +17,19 @@ namespace Content.Client.Power.APC.UI [GenerateTypedNameReferences] public sealed partial class ApcMenu : FancyWindow { - public ApcMenu(ApcBoundUserInterface owner) + public event Action? OnBreaker; + + public ApcMenu() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - EntityView.SetEntity(owner.Owner); - BreakerButton.OnPressed += _ => owner.BreakerPressed(); + BreakerButton.OnPressed += _ => OnBreaker?.Invoke(); + } + + public void SetEntity(EntityUid entity) + { + EntityView.SetEntity(entity); } public void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Power/Generator/GeneratorWindow.xaml.cs b/Content.Client/Power/Generator/GeneratorWindow.xaml.cs index bd5b75de1da..e975e5d466e 100644 --- a/Content.Client/Power/Generator/GeneratorWindow.xaml.cs +++ b/Content.Client/Power/Generator/GeneratorWindow.xaml.cs @@ -9,35 +9,39 @@ namespace Content.Client.Power.Generator; [GenerateTypedNameReferences] public sealed partial class GeneratorWindow : FancyWindow { - private readonly EntityUid _entity; - [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly ILocalizationManager _loc = default!; - private readonly SharedPowerSwitchableSystem _switchable; - private readonly FuelGeneratorComponent? _component; - private PortableGeneratorComponentBuiState? _lastState; + private EntityUid _entity; + + public float? MaximumPower; + + public event Action? OnPower; + public event Action? OnState; + public event Action? OnSwitchOutput; + public event Action? OnEjectFuel; - public GeneratorWindow(PortableGeneratorBoundUserInterface bui, EntityUid entity) + public GeneratorWindow() { - _entity = entity; RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - _entityManager.TryGetComponent(entity, out _component); - _switchable = _entityManager.System(); - - EntityView.SetEntity(entity); TargetPower.IsValid += IsValid; TargetPower.ValueChanged += (args) => { - bui.SetTargetPower(args.Value); + OnPower?.Invoke(args.Value); }; - StartButton.OnPressed += _ => bui.Start(); - StopButton.OnPressed += _ => bui.Stop(); - OutputSwitchButton.OnPressed += _ => bui.SwitchOutput(); - FuelEject.OnPressed += _ => bui.EjectFuel(); + StartButton.OnPressed += _ => OnState?.Invoke(true); + StopButton.OnPressed += _ => OnState?.Invoke(false); + OutputSwitchButton.OnPressed += _ => OnSwitchOutput?.Invoke(); + FuelEject.OnPressed += _ => OnEjectFuel?.Invoke(); + } + + public void SetEntity(EntityUid entity) + { + _entity = entity; + EntityView.SetEntity(entity); } private bool IsValid(int arg) @@ -45,7 +49,7 @@ private bool IsValid(int arg) if (arg < 0) return false; - if (arg > (_lastState?.MaximumPower / 1000.0f ?? 0)) + if (arg > (MaximumPower / 1000.0f ?? 0)) return false; return true; @@ -53,16 +57,17 @@ private bool IsValid(int arg) public void Update(PortableGeneratorComponentBuiState state) { - if (_component == null) + MaximumPower = state.MaximumPower; + + if (!_entityManager.TryGetComponent(_entity, out FuelGeneratorComponent? component)) return; - _lastState = state; if (!TargetPower.LineEditControl.HasKeyboardFocus()) TargetPower.OverrideValue((int)(state.TargetPower / 1000.0f)); - var efficiency = SharedGeneratorSystem.CalcFuelEfficiency(state.TargetPower, state.OptimalPower, _component); + var efficiency = SharedGeneratorSystem.CalcFuelEfficiency(state.TargetPower, state.OptimalPower, component); Efficiency.Text = efficiency.ToString("P1"); - var burnRate = _component.OptimalBurnRate / efficiency; + var burnRate = component.OptimalBurnRate / efficiency; var left = state.RemainingFuel / burnRate; Eta.Text = Loc.GetString( @@ -102,14 +107,15 @@ public void Update(PortableGeneratorComponentBuiState state) } var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableComponent? switchable); + var switcher = _entityManager.System(); OutputSwitchLabel.Visible = canSwitch; OutputSwitchButton.Visible = canSwitch; if (switchable != null) { - var voltage = _switchable.VoltageString(_switchable.GetVoltage(_entity, switchable)); + var voltage = switcher.VoltageString(switcher.GetVoltage(_entity, switchable)); OutputSwitchLabel.Text = Loc.GetString("portable-generator-ui-current-output", ("voltage", voltage)); - var nextVoltage = _switchable.VoltageString(_switchable.GetNextVoltage(_entity, switchable)); + var nextVoltage = switcher.VoltageString(switcher.GetNextVoltage(_entity, switchable)); OutputSwitchButton.Text = Loc.GetString("power-switchable-switch-voltage", ("voltage", nextVoltage)); OutputSwitchButton.Disabled = state.On; } diff --git a/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs b/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs index 30679d71fd6..550e1041b62 100644 --- a/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs +++ b/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Power.Generator; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Power.Generator; @@ -16,10 +17,25 @@ public PortableGeneratorBoundUserInterface(EntityUid owner, Enum uiKey) : base(o protected override void Open() { base.Open(); - _window = new GeneratorWindow(this, Owner); + _window = this.CreateWindow(); + _window.SetEntity(Owner); + _window.OnState += args => + { + if (args) + { + Start(); + } + else + { + Stop(); + } + }; + + _window.OnPower += SetTargetPower; + _window.OnEjectFuel += EjectFuel; + _window.OnSwitchOutput += SwitchOutput; _window.OpenCenteredLeft(); - _window.OnClose += Close; } protected override void UpdateState(BoundUserInterfaceState state) @@ -30,11 +46,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.Update(msg); } - protected override void Dispose(bool disposing) - { - _window?.Dispose(); - } - public void SetTargetPower(int target) { SendMessage(new PortableGeneratorSetTargetPowerMessage(target)); diff --git a/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs b/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs index dc1dcd03ef1..cbc343c06c6 100644 --- a/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs +++ b/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs @@ -1,4 +1,5 @@ using Content.Shared.Power; +using Robust.Client.UserInterface; namespace Content.Client.Power; @@ -11,9 +12,9 @@ public PowerMonitoringConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : b protected override void Open() { - _menu = new PowerMonitoringWindow(this, Owner); - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.SendPowerMonitoringConsoleMessageAction += SendPowerMonitoringConsoleMessage; } protected override void UpdateState(BoundUserInterfaceState state) @@ -22,9 +23,6 @@ protected override void UpdateState(BoundUserInterfaceState state) var castState = (PowerMonitoringConsoleBoundInterfaceState) state; - if (castState == null) - return; - EntMan.TryGetComponent(Owner, out var xform); _menu?.ShowEntites (castState.TotalSources, @@ -40,13 +38,4 @@ public void SendPowerMonitoringConsoleMessage(NetEntity? netEntity, PowerMonitor { SendMessage(new PowerMonitoringConsoleMessage(netEntity, group)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs b/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs index 74752ddc534..d9952992070 100644 --- a/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs +++ b/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs @@ -32,7 +32,7 @@ private void UpdateWindowConsoleEntry if (windowEntry == null) return; - // Update sources and loads + // Update sources and loads UpdateEntrySourcesOrLoads(masterContainer, windowEntry.SourcesContainer, focusSources, _sourceIcon); UpdateEntrySourcesOrLoads(masterContainer, windowEntry.LoadsContainer, focusLoads, _loadIconPath); @@ -134,7 +134,7 @@ private void UpdateEntrySourcesOrLoads(BoxContainer masterContainer, BoxContaine subEntry.Button.OnButtonUp += args => { ButtonAction(subEntry, masterContainer); }; } - if (!_entManager.TryGetComponent(_owner, out var console)) + if (!_entManager.TryGetComponent(Entity, out var console)) return; // Update all children @@ -379,7 +379,7 @@ public PowerMonitoringWindowEntry(PowerMonitoringConsoleEntry entry) : base(entr AddChild(MainContainer); - // Grid container to hold the list of sources when selected + // Grid container to hold the list of sources when selected SourcesContainer = new BoxContainer() { Orientation = LayoutOrientation.Vertical, diff --git a/Content.Client/Power/PowerMonitoringWindow.xaml.cs b/Content.Client/Power/PowerMonitoringWindow.xaml.cs index 81fe1f4d047..e3043252486 100644 --- a/Content.Client/Power/PowerMonitoringWindow.xaml.cs +++ b/Content.Client/Power/PowerMonitoringWindow.xaml.cs @@ -15,13 +15,12 @@ namespace Content.Client.Power; [GenerateTypedNameReferences] public sealed partial class PowerMonitoringWindow : FancyWindow { - private readonly IEntityManager _entManager; + [Dependency] private IEntityManager _entManager = default!; private readonly SpriteSystem _spriteSystem; - private readonly IGameTiming _gameTiming; + [Dependency] private IGameTiming _gameTiming = default!; private const float BlinkFrequency = 1f; - private EntityUid? _owner; private NetEntity? _focusEntity; public event Action? SendPowerMonitoringConsoleMessageAction; @@ -34,31 +33,56 @@ public sealed partial class PowerMonitoringWindow : FancyWindow { PowerMonitoringConsoleGroup.APC, (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_triangle.png")), Color.LimeGreen) }, }; - public PowerMonitoringWindow(PowerMonitoringConsoleBoundUserInterface userInterface, EntityUid? owner) + public EntityUid Entity; + + public PowerMonitoringWindow() { RobustXamlLoader.Load(this); - _entManager = IoCManager.Resolve(); - _gameTiming = IoCManager.Resolve(); + IoCManager.InjectDependencies(this); _spriteSystem = _entManager.System(); - _owner = owner; + + // Set trackable entity selected action + NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; + + // Update nav map + NavMap.ForceNavMapUpdate(); + + // Set UI tab titles + MasterTabContainer.SetTabTitle(0, Loc.GetString("power-monitoring-window-label-sources")); + MasterTabContainer.SetTabTitle(1, Loc.GetString("power-monitoring-window-label-smes")); + MasterTabContainer.SetTabTitle(2, Loc.GetString("power-monitoring-window-label-substation")); + MasterTabContainer.SetTabTitle(3, Loc.GetString("power-monitoring-window-label-apc")); + + // Track when the MasterTabContainer changes its tab + MasterTabContainer.OnTabChanged += OnTabChanged; + + // Set UI toggles + ShowHVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.HighVoltage); + ShowMVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.MediumVoltage); + ShowLVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.Apc); + } + + public void SetEntity(EntityUid uid) + { + Entity = uid; // Pass owner to nav map - NavMap.Owner = _owner; + NavMap.Owner = uid; // Set nav map grid uid var stationName = Loc.GetString("power-monitoring-window-unknown-location"); - if (_entManager.TryGetComponent(owner, out var xform)) + if (_entManager.TryGetComponent(uid, out var xform)) { NavMap.MapUid = xform.GridUid; - // Assign station name + // Assign station name if (_entManager.TryGetComponent(xform.GridUid, out var stationMetaData)) stationName = stationMetaData.EntityName; var msg = new FormattedMessage(); - msg.AddMarkup(Loc.GetString("power-monitoring-window-station-name", ("stationName", stationName))); + msg.AddMarkupOrThrow(Loc.GetString("power-monitoring-window-station-name", ("stationName", stationName))); StationName.SetMessage(msg); } @@ -68,29 +92,6 @@ public PowerMonitoringWindow(PowerMonitoringConsoleBoundUserInterface userInterf StationName.SetMessage(stationName); NavMap.Visible = false; } - - // Set trackable entity selected action - NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; - - // Update nav map - NavMap.ForceNavMapUpdate(); - - // Set UI tab titles - MasterTabContainer.SetTabTitle(0, Loc.GetString("power-monitoring-window-label-sources")); - MasterTabContainer.SetTabTitle(1, Loc.GetString("power-monitoring-window-label-smes")); - MasterTabContainer.SetTabTitle(2, Loc.GetString("power-monitoring-window-label-substation")); - MasterTabContainer.SetTabTitle(3, Loc.GetString("power-monitoring-window-label-apc")); - - // Track when the MasterTabContainer changes its tab - MasterTabContainer.OnTabChanged += OnTabChanged; - - // Set UI toggles - ShowHVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.HighVoltage); - ShowMVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.MediumVoltage); - ShowLVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.Apc); - - // Set power monitoring message action - SendPowerMonitoringConsoleMessageAction += userInterface.SendPowerMonitoringConsoleMessage; } private void OnTabChanged(int tab) @@ -113,10 +114,7 @@ public void ShowEntites PowerMonitoringConsoleEntry[] focusLoads, EntityCoordinates? monitorCoords) { - if (_owner == null) - return; - - if (!_entManager.TryGetComponent(_owner.Value, out var console)) + if (!_entManager.TryGetComponent(Entity, out var console)) return; // Update power status text @@ -161,13 +159,13 @@ public void ShowEntites } // Show monitor location - var mon = _entManager.GetNetEntity(_owner); + var mon = _entManager.GetNetEntity(Entity); - if (monitorCoords != null && mon != null) + if (monitorCoords != null && mon.IsValid()) { var texture = _spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png"))); var blip = new NavMapBlip(monitorCoords.Value, texture, Color.Cyan, true, false); - NavMap.TrackedEntities[mon.Value] = blip; + NavMap.TrackedEntities[mon] = blip; } // If the entry group doesn't match the current tab, the data is out dated, do not use it @@ -239,7 +237,7 @@ private void SetTrackedEntityFromNavMap(NetEntity? netEntity) if (netEntity == null) return; - if (!_entManager.TryGetComponent(_owner, out var console)) + if (!_entManager.TryGetComponent(Entity, out var console)) return; if (!console.PowerMonitoringDeviceMetaData.TryGetValue(netEntity.Value, out var metaData)) @@ -266,7 +264,7 @@ protected override void FrameUpdate(FrameEventArgs args) { AutoScrollToFocus(); - // Warning sign pulse + // Warning sign pulse var lit = _gameTiming.RealTime.TotalSeconds % BlinkFrequency > BlinkFrequency / 2f; SystemWarningPanel.Modulate = lit ? Color.White : new Color(178, 178, 178); } diff --git a/Content.Client/RCD/RCDMenu.xaml.cs b/Content.Client/RCD/RCDMenu.xaml.cs index 3eb0397a690..aefb3191812 100644 --- a/Content.Client/RCD/RCDMenu.xaml.cs +++ b/Content.Client/RCD/RCDMenu.xaml.cs @@ -20,31 +20,36 @@ public sealed partial class RCDMenu : RadialMenu [Dependency] private readonly IPrototypeManager _protoManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; - private readonly SpriteSystem _spriteSystem; - private readonly SharedPopupSystem _popup; + private SharedPopupSystem _popup; + private SpriteSystem _sprites; public event Action>? SendRCDSystemMessageAction; private EntityUid _owner; - public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) + public RCDMenu() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - _spriteSystem = _entManager.System(); _popup = _entManager.System(); + _sprites = _entManager.System(); - _owner = owner; + OnChildAdded += AddRCDMenuButtonOnClickActions; + } + + public void SetEntity(EntityUid uid) + { + _owner = uid; + } + public void Refresh() + { // Find the main radial container var main = FindControl("Main"); - if (main == null) - return; - // Populate secondary radial containers - if (!_entManager.TryGetComponent(owner, out var rcd)) + if (!_entManager.TryGetComponent(_owner, out var rcd)) return; foreach (var protoId in rcd.AvailablePrototypes) @@ -56,10 +61,6 @@ public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) continue; var parent = FindControl(proto.Category); - - if (parent == null) - continue; - var tooltip = Loc.GetString(proto.SetName); if ((proto.Mode == RcdMode.ConstructTile || proto.Mode == RcdMode.ConstructObject) && @@ -84,7 +85,7 @@ public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) { VerticalAlignment = VAlignment.Center, HorizontalAlignment = HAlignment.Center, - Texture = _spriteSystem.Frame0(proto.Sprite), + Texture = _sprites.Frame0(proto.Sprite), TextureScale = new Vector2(2f, 2f), }; @@ -112,11 +113,9 @@ public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) // Set up menu actions foreach (var child in Children) + { AddRCDMenuButtonOnClickActions(child); - - OnChildAdded += AddRCDMenuButtonOnClickActions; - - SendRCDSystemMessageAction += bui.SendRCDSystemMessage; + } } private static string OopsConcat(string a, string b) diff --git a/Content.Client/RCD/RCDMenuBoundUserInterface.cs b/Content.Client/RCD/RCDMenuBoundUserInterface.cs index a37dbcecf8c..1dd03626ae6 100644 --- a/Content.Client/RCD/RCDMenuBoundUserInterface.cs +++ b/Content.Client/RCD/RCDMenuBoundUserInterface.cs @@ -3,6 +3,7 @@ using JetBrains.Annotations; using Robust.Client.Graphics; using Robust.Client.Input; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.RCD; @@ -24,8 +25,9 @@ protected override void Open() { base.Open(); - _menu = new(Owner, this); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.SendRCDSystemMessageAction += SendRCDSystemMessage; // Open the menu, centered on the mouse var vpSize = _displayManager.ScreenSize; @@ -34,16 +36,8 @@ protected override void Open() public void SendRCDSystemMessage(ProtoId protoId) { - // A predicted message cannot be used here as the RCD UI is closed immediately + // A predicted message cannot be used here as the RCD UI is closed immediately // after this message is sent, which will stop the server from receiving it SendMessage(new RCDSystemMessage(protoId)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs b/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs index 7b3e39aa084..401e7edd44a 100644 --- a/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs +++ b/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs @@ -1,6 +1,8 @@ using Content.Shared.Radio; using Content.Shared.Radio.Components; using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Radio.Ui; @@ -19,9 +21,12 @@ protected override void Open() { base.Open(); - var comp = EntMan.GetComponent(Owner); + _menu = this.CreateWindow(); - _menu = new((Owner, comp)); + if (EntMan.TryGetComponent(Owner, out IntercomComponent? intercom)) + { + _menu.Update((Owner, intercom)); + } _menu.OnMicPressed += enabled => { @@ -35,17 +40,6 @@ protected override void Open() { SendMessage(new SelectIntercomChannelMessage(channel)); }; - - _menu.OnClose += Close; - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); } public void Update(Entity ent) diff --git a/Content.Client/Radio/Ui/IntercomMenu.xaml.cs b/Content.Client/Radio/Ui/IntercomMenu.xaml.cs index 2e08913051c..20d2e4a3e54 100644 --- a/Content.Client/Radio/Ui/IntercomMenu.xaml.cs +++ b/Content.Client/Radio/Ui/IntercomMenu.xaml.cs @@ -18,15 +18,13 @@ public sealed partial class IntercomMenu : FancyWindow private readonly List _channels = new(); - public IntercomMenu(Entity entity) + public IntercomMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); MicButton.OnPressed += args => OnMicPressed?.Invoke(args.Button.Pressed); SpeakerButton.OnPressed += args => OnSpeakerPressed?.Invoke(args.Button.Pressed); - - Update(entity); } public void Update(Entity entity) diff --git a/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs b/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs index c14a8c5bd05..9641adb5b2d 100644 --- a/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs +++ b/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs @@ -1,5 +1,7 @@ using Content.Shared.Research; using Content.Shared.Research.Components; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Research.UI { @@ -16,10 +18,7 @@ protected override void Open() { base.Open(); - _menu = new(); - - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); _menu.OnServerButtonPressed += () => { @@ -31,14 +30,6 @@ protected override void Open() }; } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); - } - protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); diff --git a/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs b/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs index a0a2b58e889..288445e4dea 100644 --- a/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs +++ b/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs @@ -1,4 +1,6 @@ using Content.Shared.Research.Components; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Research.UI { @@ -15,10 +17,9 @@ public ResearchClientBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - - _menu = new ResearchClientServerSelectionMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnServerSelected += SelectServer; + _menu.OnServerDeselected += DeselectServer; } public void SelectServer(int serverId) @@ -37,12 +38,5 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not ResearchClientBoundInterfaceState rState) return; _menu?.Populate(rState.ServerCount, rState.ServerNames, rState.ServerIds, rState.SelectedServerId); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _menu?.Dispose(); - } } } diff --git a/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs b/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs index ceaa965e59f..d10f8b39f48 100644 --- a/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs +++ b/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs @@ -13,27 +13,26 @@ public sealed partial class ResearchClientServerSelectionMenu : DefaultWindow private int[] _serverIds = Array.Empty(); private int _selectedServerId = -1; - private ResearchClientBoundUserInterface Owner { get; } + public event Action? OnServerSelected; + public event Action? OnServerDeselected; - public ResearchClientServerSelectionMenu(ResearchClientBoundUserInterface owner) + public ResearchClientServerSelectionMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - Owner = owner; - Servers.OnItemSelected += OnItemSelected; Servers.OnItemDeselected += OnItemDeselected; } public void OnItemSelected(ItemList.ItemListSelectedEventArgs itemListSelectedEventArgs) { - Owner.SelectServer(_serverIds[itemListSelectedEventArgs.ItemIndex]); + OnServerSelected?.Invoke(_serverIds[itemListSelectedEventArgs.ItemIndex]); } public void OnItemDeselected(ItemList.ItemListDeselectedEventArgs itemListDeselectedEventArgs) { - Owner.DeselectServer(); + OnServerDeselected?.Invoke(); } public void Populate(int serverCount, string[] serverNames, int[] serverIds, int selectedServerId) diff --git a/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs b/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs index 2a9782045b8..2895ada61fb 100644 --- a/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs +++ b/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs @@ -1,5 +1,8 @@ using Content.Shared.Research.Components; +using Content.Shared.Research.Prototypes; using JetBrains.Annotations; +using Robust.Client.UserInterface; +using Robust.Shared.Prototypes; namespace Content.Client.Research.UI; @@ -19,7 +22,8 @@ protected override void Open() var owner = Owner; - _consoleMenu = new ResearchConsoleMenu(owner); + _consoleMenu = this.CreateWindow(); + _consoleMenu.SetEntity(owner); _consoleMenu.OnTechnologyCardPressed += id => { @@ -30,10 +34,20 @@ protected override void Open() { SendMessage(new ConsoleServerSelectionMessage()); }; + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + + if (!args.WasModified()) + return; - _consoleMenu.OnClose += Close; + if (State is not ResearchConsoleBoundInterfaceState rState) + return; - _consoleMenu.OpenCentered(); + _consoleMenu?.UpdatePanels(rState); + _consoleMenu?.UpdateInformationPanel(rState); } protected override void UpdateState(BoundUserInterfaceState state) @@ -45,12 +59,4 @@ protected override void UpdateState(BoundUserInterfaceState state) _consoleMenu?.UpdatePanels(castState); _consoleMenu?.UpdateInformationPanel(castState); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _consoleMenu?.Dispose(); - } } diff --git a/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs b/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs index 77ebe6740c5..eafbe75fbb9 100644 --- a/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs +++ b/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs @@ -25,14 +25,13 @@ public sealed partial class ResearchConsoleMenu : FancyWindow [Dependency] private readonly IEntityManager _entity = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IPlayerManager _player = default!; - private readonly TechnologyDatabaseComponent? _technologyDatabase; private readonly ResearchSystem _research; private readonly SpriteSystem _sprite; private readonly AccessReaderSystem _accessReader; - public readonly EntityUid Entity; + public EntityUid Entity; - public ResearchConsoleMenu(EntityUid entity) + public ResearchConsoleMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -40,21 +39,23 @@ public ResearchConsoleMenu(EntityUid entity) _research = _entity.System(); _sprite = _entity.System(); _accessReader = _entity.System(); - Entity = entity; ServerButton.OnPressed += _ => OnServerButtonPressed?.Invoke(); + } - _entity.TryGetComponent(entity, out _technologyDatabase); + public void SetEntity(EntityUid entity) + { + Entity = entity; } - public void UpdatePanels(ResearchConsoleBoundInterfaceState state) + public void UpdatePanels(ResearchConsoleBoundInterfaceState state) { TechnologyCardsContainer.Children.Clear(); var availableTech = _research.GetAvailableTechnologies(Entity); SyncTechnologyList(AvailableCardsContainer, availableTech); - if (_technologyDatabase == null) + if (!_entity.TryGetComponent(Entity, out TechnologyDatabaseComponent? database)) return; // i can't figure out the spacing so here you go @@ -66,7 +67,7 @@ public void UpdatePanels(ResearchConsoleBoundInterfaceState state) var hasAccess = _player.LocalEntity is not { } local || !_entity.TryGetComponent(Entity, out var access) || _accessReader.IsAllowed(local, Entity, access); - foreach (var techId in _technologyDatabase.CurrentTechnologyCards) + foreach (var techId in database.CurrentTechnologyCards) { var tech = _prototype.Index(techId); var cardControl = new TechnologyCardControl(tech, _prototype, _sprite, _research.GetTechnologyDescription(tech, includeTier: false), state.Points, hasAccess); @@ -74,7 +75,7 @@ public void UpdatePanels(ResearchConsoleBoundInterfaceState state) TechnologyCardsContainer.AddChild(cardControl); } - var unlockedTech = _technologyDatabase.UnlockedTechnologies.Select(x => _prototype.Index(x)); + var unlockedTech = database.UnlockedTechnologies.Select(x => _prototype.Index(x)); SyncTechnologyList(UnlockedCardsContainer, unlockedTech); } @@ -85,14 +86,14 @@ public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state) ("points", state.Points))); ResearchAmountLabel.SetMessage(amountMsg); - if (_technologyDatabase == null) + if (!_entity.TryGetComponent(Entity, out TechnologyDatabaseComponent? database)) return; var disciplineText = Loc.GetString("research-discipline-none"); var disciplineColor = Color.Gray; - if (_technologyDatabase.MainDiscipline != null) + if (database.MainDiscipline != null) { - var discipline = _prototype.Index(_technologyDatabase.MainDiscipline); + var discipline = _prototype.Index(database.MainDiscipline); disciplineText = Loc.GetString(discipline.Name); disciplineColor = discipline.Color; } @@ -103,10 +104,10 @@ public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state) MainDisciplineLabel.SetMessage(msg); TierDisplayContainer.Children.Clear(); - foreach (var disciplineId in _technologyDatabase.SupportedDisciplines) + foreach (var disciplineId in database.SupportedDisciplines) { var discipline = _prototype.Index(disciplineId); - var tier = _research.GetHighestDisciplineTier(_technologyDatabase, discipline); + var tier = _research.GetHighestDisciplineTier(database, discipline); // don't show tiers with no available tech if (tier == 0) diff --git a/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs b/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs index 6185979eee6..9a5159880f9 100644 --- a/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs +++ b/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Robotics; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Robotics.UI; @@ -16,7 +17,9 @@ protected override void Open() { base.Open(); - _window = new RoboticsConsoleWindow(Owner); + _window = this.CreateWindow(); + _window.SetEntity(Owner); + _window.OnDisablePressed += address => { SendMessage(new RoboticsConsoleDisableMessage(address)); @@ -25,9 +28,6 @@ protected override void Open() { SendMessage(new RoboticsConsoleDestroyMessage(address)); }; - _window.OnClose += Close; - - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -37,14 +37,6 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not RoboticsConsoleState cast) return; - _window?.UpdateState(cast); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - _window?.Dispose(); + _window.UpdateState(cast); } } diff --git a/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs b/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs index fc7b234bccc..87d7e62c392 100644 --- a/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs +++ b/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs @@ -23,11 +23,12 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow public Action? OnDisablePressed; public Action? OnDestroyPressed; - private Entity _console; private string? _selected; private Dictionary _cyborgs = new(); - public RoboticsConsoleWindow(EntityUid console) + public EntityUid Entity; + + public RoboticsConsoleWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -35,9 +36,6 @@ public RoboticsConsoleWindow(EntityUid console) _lock = _entMan.System(); _sprite = _entMan.System(); - _console = (console, _entMan.GetComponent(console), null); - _entMan.TryGetComponent(_console, out _console.Comp2); - Cyborgs.OnItemSelected += args => { if (Cyborgs[args.ItemIndex].Metadata is not string address) @@ -66,6 +64,11 @@ public RoboticsConsoleWindow(EntityUid console) DestroyButton.StyleClasses.Add(StyleBase.ButtonCaution); } + public void SetEntity(EntityUid uid) + { + Entity = uid; + } + public void UpdateState(RoboticsConsoleState state) { _cyborgs = state.Cyborgs; @@ -81,7 +84,7 @@ public void UpdateState(RoboticsConsoleState state) PopulateData(); - var locked = _lock.IsLocked((_console, _console.Comp2)); + var locked = _lock.IsLocked(Entity); DangerZone.Visible = !locked; LockedMessage.Visible = locked; } @@ -135,13 +138,19 @@ private void PopulateData() // how the turntables DisableButton.Disabled = !(data.HasBrain && data.CanDisable); - DestroyButton.Disabled = _timing.CurTime < _console.Comp1.NextDestroy; } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - DestroyButton.Disabled = _timing.CurTime < _console.Comp1.NextDestroy; + if (_entMan.TryGetComponent(Entity, out RoboticsConsoleComponent? console)) + { + DestroyButton.Disabled = _timing.CurTime < console.NextDestroy; + } + else + { + DestroyButton.Disabled = true; + } } } diff --git a/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs b/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs index 8f1723d1f22..663bde15b0d 100644 --- a/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs +++ b/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs @@ -30,17 +30,9 @@ public SalvageExpeditionConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : protected override void Open() { base.Open(); - _window = new OfferingWindow(); + _window = this.CreateWindow(); _window.Title = Loc.GetString("salvage-expedition-window-title"); - _window.OnClose += Close; - _window?.OpenCenteredLeft(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); - _window = null; + _window.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs b/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs index eafb692733f..a248126a855 100644 --- a/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs +++ b/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs @@ -21,13 +21,9 @@ protected override void Open() { base.Open(); - if (_window is null) - { - _window = new OfferingWindow(); - _window.Title = Loc.GetString("salvage-magnet-window-title"); - _window.OnClose += Close; - _window.OpenCenteredLeft(); - } + _window = this.CreateWindow(); + _window.Title = Loc.GetString("salvage-magnet-window-title"); + _window.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -112,15 +108,4 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.AddOption(option); } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Close(); - _window?.Dispose(); - } - } } diff --git a/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs index 086369aa264..b8b4fb8a746 100644 --- a/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Shuttles.Events; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Shuttles.BUI; @@ -20,8 +21,7 @@ protected override void Open() { base.Open(); - _window = new IFFConsoleWindow(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ShowIFF += SendIFFMessage; _window.ShowVessel += SendVesselMessage; _window.OpenCenteredLeft(); diff --git a/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs index 4bd44a47a8e..f75759b042f 100644 --- a/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Shuttles.BUIStates; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using RadarConsoleWindow = Content.Client.Shuttles.UI.RadarConsoleWindow; namespace Content.Client.Shuttles.BUI; @@ -20,18 +21,7 @@ protected override void Open() { base.Open(); - _window = new RadarConsoleWindow(); - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _window?.Dispose(); - } + _window = this.CreateWindow(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs index af7b6055c80..e677181419e 100644 --- a/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Events; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Shared.Map; namespace Content.Client.Shuttles.BUI; @@ -19,9 +20,7 @@ public ShuttleConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = new ShuttleConsoleWindow(); - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.RequestFTL += OnFTLRequest; _window.RequestBeaconFTL += OnFTLBeaconRequest; diff --git a/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs b/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs index 3cc2a35d795..ed9bf40a481 100644 --- a/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs +++ b/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Silicons.Borgs; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Silicons.Borgs; @@ -18,9 +19,8 @@ protected override void Open() { base.Open(); - var owner = Owner; - - _menu = new BorgMenu(owner); + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); _menu.BrainButtonPressed += () => { @@ -41,10 +41,6 @@ protected override void Open() { SendMessage(new BorgRemoveModuleBuiMessage(EntMan.GetNetEntity(module))); }; - - _menu.OnClose += Close; - - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -55,12 +51,4 @@ protected override void UpdateState(BoundUserInterfaceState state) return; _menu?.UpdateState(msg); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Dispose(); - } } diff --git a/Content.Client/Silicons/Borgs/BorgMenu.xaml b/Content.Client/Silicons/Borgs/BorgMenu.xaml index 7d8fd9fe57d..4cc2e41a8fb 100644 --- a/Content.Client/Silicons/Borgs/BorgMenu.xaml +++ b/Content.Client/Silicons/Borgs/BorgMenu.xaml @@ -10,7 +10,7 @@ VerticalExpand="True"> - + diff --git a/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs b/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs index 474a83b4530..f6a861aa057 100644 --- a/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs +++ b/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs @@ -21,25 +21,33 @@ public sealed partial class BorgMenu : FancyWindow public Action? NameChanged; public Action? RemoveModuleButtonPressed; - private readonly BorgChassisComponent? _chassis; - public readonly EntityUid Entity; public float AccumulatedTime; private string _lastValidName; private List _modules = new(); - public BorgMenu(EntityUid entity) + public EntityUid Entity; + + public BorgMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - Entity = entity; + _lastValidName = NameLineEdit.Text; - if (_entity.TryGetComponent(Entity, out var chassis)) - _chassis = chassis; + EjectBatteryButton.OnPressed += _ => EjectBatteryButtonPressed?.Invoke(); + BrainButton.OnPressed += _ => BrainButtonPressed?.Invoke(); + NameLineEdit.OnTextChanged += OnNameChanged; + NameLineEdit.OnTextEntered += OnNameEntered; + NameLineEdit.OnFocusExit += OnNameFocusExit; + + UpdateBrainButton(); + } + + public void SetEntity(EntityUid entity) + { + Entity = entity; BorgSprite.SetEntity(entity); - ChargeBar.MaxValue = 1f; - ChargeBar.Value = 1f; if (_entity.TryGetComponent(Entity, out var nameIdentifierComponent)) { @@ -55,17 +63,6 @@ public BorgMenu(EntityUid entity) NameIdentifierLabel.Visible = false; NameLineEdit.Text = _entity.GetComponent(Entity).EntityName; } - - _lastValidName = NameLineEdit.Text; - - EjectBatteryButton.OnPressed += _ => EjectBatteryButtonPressed?.Invoke(); - BrainButton.OnPressed += _ => BrainButtonPressed?.Invoke(); - - NameLineEdit.OnTextChanged += OnNameChanged; - NameLineEdit.OnTextEntered += OnNameEntered; - NameLineEdit.OnFocusExit += OnNameFocusExit; - - UpdateBrainButton(); } protected override void FrameUpdate(FrameEventArgs args) @@ -89,7 +86,7 @@ public void UpdateState(BorgBuiState state) private void UpdateBrainButton() { - if (_chassis?.BrainEntity is { } brain) + if (_entity.TryGetComponent(Entity, out BorgChassisComponent? chassis) && chassis.BrainEntity is { } brain) { BrainButton.Text = _entity.GetComponent(brain).EntityName; BrainView.Visible = true; @@ -108,17 +105,17 @@ private void UpdateBrainButton() private void UpdateModulePanel() { - if (_chassis == null) + if (!_entity.TryGetComponent(Entity, out BorgChassisComponent? chassis)) return; ModuleCounter.Text = Loc.GetString("borg-ui-module-counter", - ("actual", _chassis.ModuleCount), - ("max", _chassis.MaxModules)); + ("actual", chassis.ModuleCount), + ("max", chassis.MaxModules)); - if (_chassis.ModuleContainer.Count == _modules.Count) + if (chassis.ModuleContainer.Count == _modules.Count) { var isSame = true; - foreach (var module in _chassis.ModuleContainer.ContainedEntities) + foreach (var module in chassis.ModuleContainer.ContainedEntities) { if (_modules.Contains(module)) continue; @@ -132,7 +129,7 @@ private void UpdateModulePanel() ModuleContainer.Children.Clear(); _modules.Clear(); - foreach (var module in _chassis.ModuleContainer.ContainedEntities) + foreach (var module in chassis.ModuleContainer.ContainedEntities) { var control = new BorgModuleControl(module, _entity); control.RemoveButtonPressed += () => diff --git a/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs b/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs index d150735fa11..56216b91847 100644 --- a/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs +++ b/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Silicons.Laws; using Content.Shared.Silicons.Laws.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Silicons.Laws.Ui; @@ -22,18 +23,7 @@ protected override void Open() { base.Open(); - _menu = new(); - - _menu.OnClose += Close; - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); + _menu = this.CreateWindow(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs b/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs index e8442d23908..7d6a6cf2a5a 100644 --- a/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs +++ b/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.SprayPainter; using Content.Shared.SprayPainter.Components; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.SprayPainter.UI; @@ -10,9 +10,6 @@ public sealed class SprayPainterBoundUserInterface : BoundUserInterface [ViewVariables] private SprayPainterWindow? _window; - [ViewVariables] - private SprayPainterSystem? _painter; - public SprayPainterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -21,27 +18,15 @@ protected override void Open() { base.Open(); - if (!EntMan.TryGetComponent(Owner, out var comp)) - return; - - _window = new SprayPainterWindow(); + _window = this.CreateWindow(); - _painter = EntMan.System(); - - _window.OnClose += Close; _window.OnSpritePicked = OnSpritePicked; _window.OnColorPicked = OnColorPicked; - _window.Populate(_painter.Entries, comp.Index, comp.PickedColor, comp.ColorPalette); - - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _window?.Dispose(); + if (EntMan.TryGetComponent(Owner, out SprayPainterComponent? comp)) + { + _window.Populate(EntMan.System().Entries, comp.Index, comp.PickedColor, comp.ColorPalette); + } } private void OnSpritePicked(ItemList.ItemListSelectedEventArgs args) diff --git a/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs b/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs index 720a2efb9dd..e7bab71e38e 100644 --- a/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs +++ b/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs @@ -1,4 +1,5 @@ using Content.Shared.StationRecords; +using Robust.Client.UserInterface; namespace Content.Client.StationRecords; @@ -15,15 +16,12 @@ protected override void Open() { base.Open(); - _window = new(); + _window = this.CreateWindow(); _window.OnKeySelected += key => SendMessage(new SelectStationRecord(key)); _window.OnFiltersChanged += (type, filterValue) => SendMessage(new SetStationRecordFilter(type, filterValue)); _window.OnDeleted += id => SendMessage(new DeleteStationRecord(id)); - _window.OnClose += Close; - - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -35,11 +33,4 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _window?.Close(); - } } diff --git a/Content.Client/Store/Ui/StoreBoundUserInterface.cs b/Content.Client/Store/Ui/StoreBoundUserInterface.cs index 0010aedd964..7ed67f7b5dd 100644 --- a/Content.Client/Store/Ui/StoreBoundUserInterface.cs +++ b/Content.Client/Store/Ui/StoreBoundUserInterface.cs @@ -2,6 +2,7 @@ using JetBrains.Annotations; using System.Linq; using Content.Shared.Store.Components; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Store.Ui; @@ -26,13 +27,10 @@ public StoreBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) protected override void Open() { - _menu = new StoreMenu(); + _menu = this.CreateWindow(); if (EntMan.TryGetComponent(Owner, out var store)) _menu.Title = Loc.GetString(store.Name); - _menu.OpenCentered(); - _menu.OnClose += Close; - _menu.OnListingButtonPressed += (_, listing) => { SendMessage(new StoreBuyListingMessage(listing)); @@ -77,15 +75,6 @@ protected override void UpdateState(BoundUserInterfaceState state) } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); - _menu?.Dispose(); - } - private void UpdateListingsWithSearchFilter() { if (_menu == null) diff --git a/Content.Client/Strip/StrippingMenu.cs b/Content.Client/Strip/StrippingMenu.cs index eea867b7948..1c46b4be35c 100644 --- a/Content.Client/Strip/StrippingMenu.cs +++ b/Content.Client/Strip/StrippingMenu.cs @@ -1,4 +1,3 @@ -using Content.Client.Inventory; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Timing; @@ -11,14 +10,12 @@ public sealed class StrippingMenu : DefaultWindow public LayoutContainer InventoryContainer = new(); public BoxContainer HandsContainer = new() { Orientation = LayoutOrientation.Horizontal }; public BoxContainer SnareContainer = new(); - private StrippableBoundUserInterface _bui; public bool Dirty = true; - public StrippingMenu(string title, StrippableBoundUserInterface bui) - { - Title = title; - _bui = bui; + public event Action? OnDirty; + public StrippingMenu() + { var box = new BoxContainer() { Orientation = LayoutOrientation.Vertical, Margin = new Thickness(0, 8) }; Contents.AddChild(box); box.AddChild(SnareContainer); @@ -39,7 +36,7 @@ protected override void FrameUpdate(FrameEventArgs args) return; Dirty = false; - _bui.UpdateMenu(); + OnDirty?.Invoke(); } } } diff --git a/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs b/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs index 9132dd6ed5f..e3646c00cc3 100644 --- a/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs +++ b/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs @@ -1,6 +1,7 @@ using Content.Client.Eye; using Content.Shared.SurveillanceCamera; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.SurveillanceCamera.UI; @@ -25,20 +26,12 @@ protected override void Open() { base.Open(); - _window = new SurveillanceCameraMonitorWindow(); - - if (State != null) - { - UpdateState(State); - } - - _window.OpenCentered(); + _window = this.CreateWindow(); _window.CameraSelected += OnCameraSelected; _window.SubnetOpened += OnSubnetRequest; _window.CameraRefresh += OnCameraRefresh; _window.SubnetRefresh += OnSubnetRefresh; - _window.OnClose += Close; _window.CameraSwitchTimer += OnCameraSwitchTimer; _window.CameraDisconnect += OnCameraDisconnect; } diff --git a/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs b/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs index 37384daafef..0631d98993a 100644 --- a/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs +++ b/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Thief; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Thief; @@ -15,21 +16,9 @@ protected override void Open() { base.Open(); - _window = new ThiefBackpackMenu(this); - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_window != null) - _window.OnClose -= Close; - - _window?.Dispose(); + _window = this.CreateWindow(); + _window.OnApprove += SendApprove; + _window.OnSetChange += SendChangeSelected; } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Thief/ThiefBackpackMenu.xaml.cs b/Content.Client/Thief/ThiefBackpackMenu.xaml.cs index 543772c704c..aaee3576174 100644 --- a/Content.Client/Thief/ThiefBackpackMenu.xaml.cs +++ b/Content.Client/Thief/ThiefBackpackMenu.xaml.cs @@ -12,46 +12,42 @@ public sealed partial class ThiefBackpackMenu : FancyWindow [Dependency] private readonly IEntitySystemManager _sysMan = default!; private readonly SpriteSystem _spriteSystem; - private readonly ThiefBackpackBoundUserInterface _owner; + public event Action? OnApprove; + public event Action? OnSetChange; - public ThiefBackpackMenu(ThiefBackpackBoundUserInterface owner) + public ThiefBackpackMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); _spriteSystem = _sysMan.GetEntitySystem(); - _owner = owner; - - ApproveButton.OnButtonDown += (args) => + ApproveButton.OnPressed += args => { - _owner.SendApprove(); + OnApprove?.Invoke(); }; } public void UpdateState(ThiefBackpackBoundUserInterfaceState state) { - SetsGrid.RemoveAllChildren(); - int count = 0; - int selectedNumber = 0; - foreach (var set in state.Sets) + SetsGrid.DisposeAllChildren(); + var selectedNumber = 0; + foreach (var (set, info) in state.Sets) { - var child = new ThiefBackpackSet(set.Value, _spriteSystem); + var child = new ThiefBackpackSet(info, _spriteSystem); child.SetButton.OnButtonDown += (args) => { - _owner.SendChangeSelected(set.Key); + OnSetChange?.Invoke(set); }; SetsGrid.AddChild(child); - count++; - - if (set.Value.Selected) + if (info.Selected) selectedNumber++; } Description.Text = Loc.GetString("thief-backpack-window-description", ("maxCount", state.MaxSelectedSets)); SelectedSets.Text = Loc.GetString("thief-backpack-window-selected", ("selectedCount", selectedNumber), ("maxCount", state.MaxSelectedSets)); - ApproveButton.Disabled = selectedNumber == state.MaxSelectedSets ? false : true; + ApproveButton.Disabled = selectedNumber != state.MaxSelectedSets; } } diff --git a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs index 4702f8f3659..4ae74a5d65e 100644 --- a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs +++ b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs @@ -1,5 +1,7 @@ using Content.Shared.Atmos.Components; using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.UserInterface.Systems.Atmos.GasTank { @@ -13,7 +15,7 @@ public GasTankBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKe { } - public void SetOutputPressure(in float value) + public void SetOutputPressure(float value) { SendMessage(new GasTankSetPressureMessage { @@ -29,9 +31,10 @@ public void ToggleInternals() protected override void Open() { base.Open(); - _window = new GasTankWindow(this, EntMan.GetComponent(Owner).EntityName); - _window.OnClose += Close; - _window.OpenCentered(); + _window = this.CreateWindow(); + _window.SetTitle(EntMan.GetComponent(Owner).EntityName); + _window.OnOutputPressure += SetOutputPressure; + _window.OnToggleInternals += ToggleInternals; } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs index c23850a6503..12eeaa55de9 100644 --- a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs +++ b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs @@ -15,23 +15,28 @@ namespace Content.Client.UserInterface.Systems.Atmos.GasTank; public sealed class GasTankWindow : BaseWindow { + [Dependency] private readonly IResourceCache _cache = default!; + private readonly RichTextLabel _lblPressure; private readonly FloatSpinBox _spbPressure; private readonly RichTextLabel _lblInternals; private readonly Button _btnInternals; + private readonly Label _topLabel; + + public event Action? OnOutputPressure; + public event Action? OnToggleInternals; - public GasTankWindow(GasTankBoundUserInterface owner, string uidName) + public GasTankWindow() { Control contentContainer; BoxContainer topContainer; TextureButton btnClose; - var resourceCache = IoCManager.Resolve(); var rootContainer = new LayoutContainer { Name = "GasTankRoot" }; AddChild(rootContainer); MouseFilter = MouseFilterMode.Stop; - var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); + var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); var back = new StyleBoxTexture { Texture = panelTex, @@ -78,7 +83,17 @@ public GasTankWindow(GasTankBoundUserInterface owner, string uidName) LayoutContainer.SetAnchorPreset(topContainerWrap, LayoutContainer.LayoutPreset.Wide); - var font = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); + var font = _cache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); + + _topLabel = new Label + { + FontOverride = font, + FontColorOverride = StyleNano.NanoGold, + VerticalAlignment = VAlignment.Center, + HorizontalExpand = true, + HorizontalAlignment = HAlignment.Left, + Margin = new Thickness(0, 0, 20, 0), + }; var topRow = new BoxContainer { @@ -86,16 +101,7 @@ public GasTankWindow(GasTankBoundUserInterface owner, string uidName) Margin = new Thickness(4, 2, 12, 2), Children = { - (new Label - { - Text = uidName, - FontOverride = font, - FontColorOverride = StyleNano.NanoGold, - VerticalAlignment = VAlignment.Center, - HorizontalExpand = true, - HorizontalAlignment = HAlignment.Left, - Margin = new Thickness(0, 0, 20, 0), - }), + _topLabel, (btnClose = new TextureButton { StyleClasses = {DefaultWindow.StyleClassWindowCloseButton}, @@ -168,17 +174,22 @@ public GasTankWindow(GasTankBoundUserInterface owner, string uidName) // Handlers _spbPressure.OnValueChanged += args => { - owner.SetOutputPressure(args.Value); + OnOutputPressure?.Invoke(args.Value); }; _btnInternals.OnPressed += args => { - owner.ToggleInternals(); + OnToggleInternals?.Invoke(); }; btnClose.OnPressed += _ => Close(); } + public void SetTitle(string name) + { + _topLabel.Text = name; + } + public void UpdateState(GasTankBoundUserInterfaceState state) { _lblPressure.SetMarkup(Loc.GetString("gas-tank-window-tank-pressure-text", ("tankPressure", $"{state.TankPressure:0.##}"))); diff --git a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs index 17ddba77ffc..eafab84ed63 100644 --- a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs +++ b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.VendingMachines; using Robust.Client.UserInterface.Controls; using System.Linq; +using Robust.Client.UserInterface; namespace Content.Client.VendingMachines { @@ -28,15 +29,14 @@ protected override void Open() _cachedInventory = vendingMachineSys.GetAllInventory(Owner); - _menu = new VendingMachineMenu { Title = EntMan.GetComponent(Owner).EntityName }; + _menu = this.CreateWindow(); + _menu.OpenCenteredLeft(); + _menu.Title = EntMan.GetComponent(Owner).EntityName; - _menu.OnClose += Close; _menu.OnItemSelected += OnItemSelected; _menu.OnSearchChanged += OnSearchChanged; _menu.Populate(_cachedInventory, out _cachedFilteredIndex); - - _menu.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs b/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs index f700c6663b9..891804674d3 100644 --- a/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs +++ b/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs @@ -1,12 +1,13 @@ using Content.Shared.VoiceMask; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.VoiceMask; public sealed class VoiceMaskBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly IPrototypeManager _protomanager = default!; [ViewVariables] private VoiceMaskNameChangeWindow? _window; @@ -19,12 +20,11 @@ protected override void Open() { base.Open(); - _window = new(_proto); + _window = this.CreateWindow(); + _window.ReloadVerbs(_protomanager); - _window.OpenCentered(); _window.OnNameChange += OnNameSelected; _window.OnVerbChange += verb => SendMessage(new VoiceMaskChangeVerbMessage(verb)); - _window.OnClose += Close; } private void OnNameSelected(string name) diff --git a/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs b/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs index 16a28f9d9b3..0dc41f807ab 100644 --- a/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs +++ b/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs @@ -17,7 +17,7 @@ public sealed partial class VoiceMaskNameChangeWindow : FancyWindow private string? _verb; - public VoiceMaskNameChangeWindow(IPrototypeManager proto) + public VoiceMaskNameChangeWindow() { RobustXamlLoader.Load(this); @@ -32,12 +32,10 @@ public VoiceMaskNameChangeWindow(IPrototypeManager proto) SpeechVerbSelector.SelectId(args.Id); }; - ReloadVerbs(proto); - AddVerbs(); } - private void ReloadVerbs(IPrototypeManager proto) + public void ReloadVerbs(IPrototypeManager proto) { foreach (var verb in proto.EnumeratePrototypes()) { diff --git a/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs b/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs index f3e0c0a539a..3f01808c422 100644 --- a/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs +++ b/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs @@ -1,5 +1,6 @@ using Robust.Client.GameObjects; using Content.Shared.Speech.Components; +using Robust.Client.UserInterface; namespace Content.Client.Weapons.Melee.UI; @@ -19,17 +20,10 @@ protected override void Open() { base.Open(); - _window = new MeleeSpeechWindow(); - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.OnBattlecryEntered += OnBattlecryChanged; } - private void OnBattlecryChanged(string newBattlecry) { SendMessage(new MeleeSpeechBattlecryChangedMessage(newBattlecry)); diff --git a/Content.Client/Wires/UI/WiresBoundUserInterface.cs b/Content.Client/Wires/UI/WiresBoundUserInterface.cs index 5a8869a204e..edf1a2d3770 100644 --- a/Content.Client/Wires/UI/WiresBoundUserInterface.cs +++ b/Content.Client/Wires/UI/WiresBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Wires; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Wires.UI { @@ -15,10 +16,8 @@ public WiresBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) protected override void Open() { base.Open(); - - _menu = new WiresMenu(this); - _menu.OnClose += Close; - _menu.OpenCenteredLeft(); + _menu = this.CreateWindow(); + _menu.OnAction += PerformAction; } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Wires/UI/WiresMenu.cs b/Content.Client/Wires/UI/WiresMenu.cs index 7bccc208616..eccc548297c 100644 --- a/Content.Client/Wires/UI/WiresMenu.cs +++ b/Content.Client/Wires/UI/WiresMenu.cs @@ -1,4 +1,3 @@ -using System; using System.Numerics; using Content.Client.Examine; using Content.Client.Resources; @@ -12,10 +11,6 @@ using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Animations; using Robust.Shared.Input; -using Robust.Shared.IoC; -using Robust.Shared.Localization; -using Robust.Shared.Maths; -using Robust.Shared.Random; using static Robust.Client.UserInterface.Controls.BoxContainer; namespace Content.Client.Wires.UI @@ -24,8 +19,6 @@ public sealed class WiresMenu : BaseWindow { [Dependency] private readonly IResourceCache _resourceCache = default!; - public WiresBoundUserInterface Owner { get; } - private readonly Control _wiresHBox; private readonly Control _topContainer; private readonly Control _statusContainer; @@ -35,11 +28,12 @@ public sealed class WiresMenu : BaseWindow public TextureButton CloseButton { get; set; } - public WiresMenu(WiresBoundUserInterface owner) + public event Action? OnAction; + + public WiresMenu() { IoCManager.InjectDependencies(this); - Owner = owner; var rootContainer = new LayoutContainer {Name = "WireRoot"}; AddChild(rootContainer); @@ -257,12 +251,12 @@ public void Populate(WiresBoundUserInterfaceState state) control.WireClicked += () => { - Owner.PerformAction(wire.Id, wire.IsCut ? WiresAction.Mend : WiresAction.Cut); + OnAction?.Invoke(wire.Id, wire.IsCut ? WiresAction.Mend : WiresAction.Cut); }; control.ContactsClicked += () => { - Owner.PerformAction(wire.Id, WiresAction.Pulse); + OnAction?.Invoke(wire.Id, WiresAction.Pulse); }; } diff --git a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs index 2538caf6eb8..c7a74815b6b 100644 --- a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs +++ b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Xenoarchaeology.Equipment; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Xenoarchaeology.Ui; @@ -18,10 +19,7 @@ protected override void Open() { base.Open(); - _consoleMenu = new AnalysisConsoleMenu(); - - _consoleMenu.OnClose += Close; - _consoleMenu.OpenCentered(); + _consoleMenu = this.CreateWindow(); _consoleMenu.OnServerSelectionButtonPressed += () => { From 4997f92e189e1d21eadfdff46d9301db4545fc3d Mon Sep 17 00:00:00 2001 From: Aiden Date: Sat, 20 Jul 2024 00:53:57 -0500 Subject: [PATCH 083/134] MassHallucinationsRule Minor Refactor (#28748) * Update MassHallucinationsRule. * Update Content.Server/StationEvents/Events/MassHallucinationsRule.cs Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> * Update Content.Server/StationEvents/Events/MassHallucinationsRule.cs Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> * Update Content.Server/StationEvents/Events/MassHallucinationsRule.cs Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> * MGS Change * Update Content.Server/StationEvents/Events/MassHallucinationsRule.cs Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Update Content.Server/StationEvents/Events/MassHallucinationsRule.cs Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Move affectedentities to component, remove masshallucinationscomponent as its no longer needed to track entities. * Apply suggested changes. * No double checks --------- Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> --- .../Components/MassHallucinationsComponent.cs | 11 ----------- .../MassHallucinationsRuleComponent.cs | 4 ++++ .../Events/MassHallucinationsRule.cs | 19 ++++++++++++------- 3 files changed, 16 insertions(+), 18 deletions(-) delete mode 100644 Content.Server/StationEvents/Components/MassHallucinationsComponent.cs diff --git a/Content.Server/StationEvents/Components/MassHallucinationsComponent.cs b/Content.Server/StationEvents/Components/MassHallucinationsComponent.cs deleted file mode 100644 index 99b893cad51..00000000000 --- a/Content.Server/StationEvents/Components/MassHallucinationsComponent.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Content.Server.StationEvents.Events; - -namespace Content.Server.StationEvents.Components; - -/// -/// This is used to keep track of hallucinated entities to remove effects when event ends -/// -[RegisterComponent, Access(typeof(MassHallucinationsRule))] -public sealed partial class MassHallucinationsComponent : Component -{ -} diff --git a/Content.Server/StationEvents/Components/MassHallucinationsRuleComponent.cs b/Content.Server/StationEvents/Components/MassHallucinationsRuleComponent.cs index 63a1f872513..a5268f97a62 100644 --- a/Content.Server/StationEvents/Components/MassHallucinationsRuleComponent.cs +++ b/Content.Server/StationEvents/Components/MassHallucinationsRuleComponent.cs @@ -1,5 +1,6 @@ using Content.Server.StationEvents.Events; using Robust.Shared.Audio; +using Robust.Shared.Collections; namespace Content.Server.StationEvents.Components; @@ -23,4 +24,7 @@ public sealed partial class MassHallucinationsRuleComponent : Component [DataField("sounds", required: true)] public SoundSpecifier Sounds = default!; + + [DataField, ViewVariables(VVAccess.ReadOnly)] + public List AffectedEntities = new(); } diff --git a/Content.Server/StationEvents/Events/MassHallucinationsRule.cs b/Content.Server/StationEvents/Events/MassHallucinationsRule.cs index bfb7699e9d6..b03231b5bcd 100644 --- a/Content.Server/StationEvents/Events/MassHallucinationsRule.cs +++ b/Content.Server/StationEvents/Events/MassHallucinationsRule.cs @@ -2,9 +2,11 @@ using Content.Server.StationEvents.Components; using Content.Server.Traits.Assorted; using Content.Shared.GameTicking.Components; +using Content.Shared.Humanoid; using Content.Shared.Mind.Components; using Content.Shared.Traits.Assorted; + namespace Content.Server.StationEvents.Events; public sealed class MassHallucinationsRule : StationEventSystem @@ -14,16 +16,17 @@ public sealed class MassHallucinationsRule : StationEventSystem(); - while (query.MoveNext(out var ent, out _)) + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var ent, out _, out _)) { - if (!HasComp(ent)) + if (!EnsureComp(ent, out var paracusia)) { - EnsureComp(ent); - var paracusia = EnsureComp(ent); _paracusia.SetSounds(ent, component.Sounds, paracusia); _paracusia.SetTime(ent, component.MinTimeBetweenIncidents, component.MaxTimeBetweenIncidents, paracusia); _paracusia.SetDistance(ent, component.MaxSoundDistance); + + component.AffectedEntities.Add(ent); } } } @@ -31,10 +34,12 @@ protected override void Started(EntityUid uid, MassHallucinationsRuleComponent c protected override void Ended(EntityUid uid, MassHallucinationsRuleComponent component, GameRuleComponent gameRule, GameRuleEndedEvent args) { base.Ended(uid, component, gameRule, args); - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var ent, out _)) + + foreach (var ent in component.AffectedEntities) { RemComp(ent); } + + component.AffectedEntities.Clear(); } } From 0cbc2e8d4312cc5cc2ea611f091368c6312284fe Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 20 Jul 2024 05:55:05 +0000 Subject: [PATCH 084/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 09ab407edd9..ed8f51b7865 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Boaz1111 - changes: - - message: Refactored Cluster's medbay, including cryo in the bottom left room - type: Tweak - id: 6442 - time: '2024-04-26T08:01:21.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27293 - author: metalgearsloth changes: - message: Add predicted UI opening for storage and PDAs. @@ -3798,3 +3791,10 @@ id: 6941 time: '2024-07-20T03:00:28.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30156 +- author: Aidenkrz + changes: + - message: The mass hallucinations event no longer affects non-humanoids. + type: Fix + id: 6942 + time: '2024-07-20T05:53:58.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28748 From 8d5792efd700e8e5544ff8eaf75c64ba26230a7f Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sat, 20 Jul 2024 07:56:21 +0200 Subject: [PATCH 085/134] Remove HighImpassable from TableTopLayer (#29455) * uhmm * Update CollisionGroup.cs --- Content.Shared/Physics/CollisionGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Shared/Physics/CollisionGroup.cs b/Content.Shared/Physics/CollisionGroup.cs index 775ccb7c446..9f8c5ad9bef 100644 --- a/Content.Shared/Physics/CollisionGroup.cs +++ b/Content.Shared/Physics/CollisionGroup.cs @@ -58,7 +58,7 @@ public enum CollisionGroup // Tabletop machines, windoors, firelocks TabletopMachineMask = Impassable | HighImpassable, // Tabletop machines - TabletopMachineLayer = Opaque | HighImpassable | BulletImpassable, + TabletopMachineLayer = Opaque | BulletImpassable, // Airlocks, windoors, firelocks GlassAirlockLayer = HighImpassable | MidImpassable | BulletImpassable | InteractImpassable, From 53eb9421c23d4c60dab47f9073bdb27aa6a38f9a Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 20 Jul 2024 15:56:34 +1000 Subject: [PATCH 086/134] Update submodule to 229.0.0 (#30186) --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index fc1cca4f48f..2e4275a7f3b 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit fc1cca4f48f2f2d3fbf41aa42b80b4e43b1095a4 +Subproject commit 2e4275a7f3b2800e7fbe1da1e1909e8e349033bf From 3a30eea64003e4d70290980f673eea92542d9f81 Mon Sep 17 00:00:00 2001 From: IProduceWidgets <107586145+IProduceWidgets@users.noreply.github.com> Date: Sat, 20 Jul 2024 02:22:47 -0400 Subject: [PATCH 087/134] Update oasis (#30182) * Update oasis * unpause map. We really need a test for that. * lv cables * magic or gate airlock --- Resources/Maps/oasis.yml | 9413 ++++++++++++++++++++------------------ 1 file changed, 5028 insertions(+), 4385 deletions(-) diff --git a/Resources/Maps/oasis.yml b/Resources/Maps/oasis.yml index d9d9018051a..7353864af19 100644 --- a/Resources/Maps/oasis.yml +++ b/Resources/Maps/oasis.yml @@ -123,7 +123,7 @@ entities: version: 6 1,1: ind: 1,1 - tiles: DAAAAAABDAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADKQAAAAACKQAAAAABKQAAAAADKQAAAAACKQAAAAABgQAAAAAAgQAAAAAAKQAAAAAAKQAAAAABKQAAAAAADAAAAAAADAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAAAKQAAAAACKQAAAAAAKQAAAAADKQAAAAADKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAAAKQAAAAACgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAABKQAAAAABKQAAAAAAKQAAAAADKQAAAAADKQAAAAACgQAAAAAAfwAAAAACfwAAAAABfwAAAAABfwAAAAABgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfwAAAAADfQAAAAADfQAAAAADfQAAAAADgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAARAAAAAAARAAAAAAARAAAAAAARAAAAAAAIAAAAAABIAAAAAADgQAAAAAAfwAAAAACfQAAAAACfQAAAAACfQAAAAADgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAARAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAIAAAAAADgQAAAAAAfwAAAAADfQAAAAADfQAAAAAAfQAAAAABgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAARAAAAAAAgQAAAAAAgQAAAAAARAAAAAAAIAAAAAAAIAAAAAACgQAAAAAAfwAAAAADfwAAAAABfwAAAAADfwAAAAABgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAARAAAAAAARAAAAAAARAAAAAAARAAAAAAAIAAAAAACIAAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAIQAAAAADgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAADYAAAAAADYAAAAAADYAAAAAAAYAAAAAABYAAAAAADbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAYAAAAAADYAAAAAABYAAAAAACYAAAAAABYAAAAAADYAAAAAACgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAACYAAAAAADYAAAAAACYAAAAAABYAAAAAADYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAYAAAAAACYAAAAAABYAAAAAADYAAAAAAAYAAAAAABYAAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAZQAAAAACZQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfQAAAAAAfQAAAAADgQAAAAAAbwAAAAAAgQAAAAAAYAAAAAACYAAAAAABYAAAAAABYAAAAAAAYAAAAAAAYAAAAAABYAAAAAADYAAAAAADYAAAAAAAgQAAAAAAcAAAAAAAYAAAAAAAYAAAAAADYAAAAAACYAAAAAABgQAAAAAAYAAAAAADYAAAAAABYAAAAAAAYAAAAAADYAAAAAADYAAAAAAAYAAAAAACYAAAAAADYAAAAAABgQAAAAAAcAAAAAAA + tiles: DAAAAAABDAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADKQAAAAACKQAAAAABKQAAAAADKQAAAAACKQAAAAABgQAAAAAAgQAAAAAAKQAAAAAAKQAAAAABKQAAAAAADAAAAAAADAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAAAKQAAAAACKQAAAAAAKQAAAAADKQAAAAADKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfwAAAAAAfwAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAABKQAAAAABKQAAAAAAKQAAAAADKQAAAAADKQAAAAACgQAAAAAAfwAAAAACfwAAAAABfwAAAAABfwAAAAABgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfwAAAAADfQAAAAADfQAAAAADfQAAAAADgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAARAAAAAAARAAAAAAARAAAAAAARAAAAAAAIAAAAAABIAAAAAADgQAAAAAAfwAAAAACfQAAAAACfQAAAAACfQAAAAADgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAARAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAIAAAAAADgQAAAAAAfwAAAAADfQAAAAADfQAAAAAAfQAAAAABgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAARAAAAAAAgQAAAAAAgQAAAAAARAAAAAAAIAAAAAAAIAAAAAACgQAAAAAAfwAAAAADfwAAAAABfwAAAAADfwAAAAABgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAARAAAAAAARAAAAAAARAAAAAAARAAAAAAAIAAAAAACIAAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAIQAAAAADgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAADYAAAAAADYAAAAAADYAAAAAAAYAAAAAABYAAAAAADbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAYAAAAAADYAAAAAABYAAAAAACYAAAAAABYAAAAAADYAAAAAACgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAACYAAAAAADYAAAAAACYAAAAAABYAAAAAADYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAYAAAAAACYAAAAAABYAAAAAADYAAAAAAAYAAAAAABYAAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAZQAAAAACZQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfQAAAAAAfQAAAAADgQAAAAAAbwAAAAAAgQAAAAAAYAAAAAACYAAAAAABYAAAAAABYAAAAAAAYAAAAAAAYAAAAAABYAAAAAADYAAAAAADYAAAAAAAgQAAAAAAcAAAAAAAYAAAAAAAYAAAAAADYAAAAAACYAAAAAABgQAAAAAAYAAAAAADYAAAAAABYAAAAAAAYAAAAAADYAAAAAADYAAAAAAAYAAAAAACYAAAAAADYAAAAAABgQAAAAAAcAAAAAAA version: 6 1,0: ind: 1,0 @@ -171,7 +171,7 @@ entities: version: 6 2,-3: ind: 2,-3 - tiles: gQAAAAAAbwAAAAAAKQAAAAADKQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAKQAAAAABbwAAAAAAKQAAAAABKQAAAAAAbwAAAAAAKQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAbwAAAAAAgQAAAAAABwAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAABYAAAAAACYAAAAAABgQAAAAAAKQAAAAADKQAAAAAAgQAAAAAAKQAAAAACKQAAAAADKQAAAAADKQAAAAACKQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAABYAAAAAACYAAAAAADgQAAAAAAKQAAAAACKQAAAAAAIQAAAAACKQAAAAAAKQAAAAAAKQAAAAAAKQAAAAABKQAAAAACgQAAAAAAgQAAAAAAJAAAAAAAgQAAAAAAdwAAAAAAYAAAAAACYAAAAAABgQAAAAAAKQAAAAABKQAAAAABgQAAAAAAKQAAAAADJgAAAAAAJgAAAAAAJgAAAAAAKQAAAAADgQAAAAAAKQAAAAABKQAAAAAAKQAAAAACdwAAAAADYAAAAAACYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADKQAAAAABKQAAAAAAKQAAAAABKQAAAAACgQAAAAAAKQAAAAACKQAAAAAAKQAAAAAAdwAAAAABYAAAAAAAYAAAAAADYAAAAAABYAAAAAADYAAAAAABgQAAAAAAgQAAAAAAgQAAAAAAIQAAAAACgQAAAAAAgQAAAAAAKQAAAAADKQAAAAAAKQAAAAADKQAAAAABYAAAAAAAYAAAAAADYAAAAAACYAAAAAACYAAAAAAAYAAAAAADgQAAAAAAKQAAAAABKQAAAAAAKQAAAAADKQAAAAACKQAAAAADIQAAAAAAKQAAAAAAKQAAAAACKQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAAAKQAAAAAAKQAAAAABKQAAAAAAgQAAAAAAKQAAAAABKQAAAAAAKQAAAAABKQAAAAADKQAAAAACKQAAAAADKQAAAAACKQAAAAABKQAAAAADKQAAAAAAgQAAAAAAKQAAAAABKQAAAAAAKQAAAAADKQAAAAAAgQAAAAAAgQAAAAAAJAAAAAABgQAAAAAAKQAAAAADKQAAAAAAKQAAAAABKQAAAAABKQAAAAABKQAAAAAAKQAAAAACIQAAAAABKQAAAAADKQAAAAAAKQAAAAADKQAAAAADKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAABKQAAAAACKQAAAAACKQAAAAAAKQAAAAABKQAAAAACKQAAAAACKQAAAAADKQAAAAAAKQAAAAAAKQAAAAABKQAAAAAAKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAA + tiles: gQAAAAAAbwAAAAAAKQAAAAADKQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAKQAAAAABbwAAAAAAKQAAAAABKQAAAAAAbwAAAAAAKQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAbwAAAAAAgQAAAAAABwAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAABYAAAAAACYAAAAAABgQAAAAAAKQAAAAADKQAAAAAAgQAAAAAAKQAAAAACKQAAAAADKQAAAAADKQAAAAACKQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAABYAAAAAACYAAAAAADgQAAAAAAKQAAAAACKQAAAAAAIQAAAAACKQAAAAAAKQAAAAAAKQAAAAAAKQAAAAABKQAAAAACgQAAAAAAgQAAAAAAJAAAAAAAgQAAAAAAdwAAAAAAYAAAAAACYAAAAAABgQAAAAAAKQAAAAABKQAAAAABgQAAAAAAKQAAAAADJgAAAAAAJgAAAAAAJgAAAAAAKQAAAAADgQAAAAAAKQAAAAABKQAAAAAAKQAAAAACdwAAAAADYAAAAAACYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADKQAAAAABKQAAAAAAKQAAAAABKQAAAAACgQAAAAAAKQAAAAACKQAAAAAAKQAAAAAAdwAAAAABYAAAAAAAYAAAAAADYAAAAAABYAAAAAADYAAAAAABgQAAAAAAgQAAAAAAgQAAAAAAIQAAAAACgQAAAAAAgQAAAAAAKQAAAAADKQAAAAAAKQAAAAADKQAAAAABYAAAAAAAYAAAAAADYAAAAAACYAAAAAACYAAAAAAAYAAAAAADgQAAAAAAKQAAAAABKQAAAAAAKQAAAAADKQAAAAACKQAAAAADIQAAAAAAKQAAAAAAKQAAAAACKQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAAAKQAAAAAAKQAAAAABKQAAAAAAgQAAAAAAKQAAAAABKQAAAAAAKQAAAAABKQAAAAADKQAAAAACKQAAAAADKQAAAAACKQAAAAABKQAAAAADKQAAAAAAgQAAAAAAKQAAAAABKQAAAAAAKQAAAAADKQAAAAAAgQAAAAAAgQAAAAAAJAAAAAABgQAAAAAAKQAAAAADKQAAAAAAKQAAAAABKQAAAAABKQAAAAABKQAAAAAAKQAAAAACIQAAAAABKQAAAAADKQAAAAAAKQAAAAADKQAAAAADKQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAKQAAAAABKQAAAAACKQAAAAACKQAAAAAAKQAAAAABKQAAAAACKQAAAAACKQAAAAADKQAAAAAAKQAAAAAAKQAAAAABKQAAAAAAKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAA version: 6 2,-1: ind: 2,-1 @@ -179,7 +179,7 @@ entities: version: 6 2,0: ind: 2,0 - tiles: YAAAAAAAYAAAAAABYAAAAAAAYAAAAAABYAAAAAACYAAAAAACYAAAAAABYAAAAAACYAAAAAADYAAAAAABYAAAAAADYAAAAAAAYAAAAAABYAAAAAADYAAAAAACYAAAAAABYAAAAAACYAAAAAABYAAAAAAAYAAAAAADYAAAAAACYAAAAAADYAAAAAABYAAAAAACYAAAAAAAYAAAAAABYAAAAAABYAAAAAADYAAAAAACYAAAAAABYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAYAAAAAABYAAAAAAAYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAYAAAAAAAYAAAAAADYAAAAAADYAAAAAABYAAAAAACgQAAAAAALwAAAAAAYAAAAAAAYAAAAAAALwAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAYAAAAAAAYAAAAAADYAAAAAADYAAAAAADYAAAAAADgQAAAAAALwAAAAAAYAAAAAACYAAAAAABLwAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAABYAAAAAACYAAAAAACYAAAAAADYAAAAAACgQAAAAAALwAAAAAAYAAAAAACYAAAAAAAYAAAAAACgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAADYAAAAAADYAAAAAAAYAAAAAABYAAAAAADgQAAAAAALwAAAAAAYAAAAAABLwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfQAAAAADfQAAAAACfQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAABKQAAAAACgQAAAAAAfQAAAAADfQAAAAACfwAAAAAAfQAAAAABfQAAAAAAfQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAABKQAAAAACKQAAAAAAfQAAAAAAfQAAAAAAfwAAAAACfQAAAAACfQAAAAABfQAAAAACgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADKQAAAAADKQAAAAACfQAAAAAAfQAAAAADfwAAAAADfQAAAAABfQAAAAADfQAAAAADgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAAAKQAAAAADgQAAAAAAfQAAAAABfQAAAAABfwAAAAAAfQAAAAADfQAAAAAAfQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAA + tiles: YAAAAAAAYAAAAAABYAAAAAAAYAAAAAABYAAAAAACYAAAAAACYAAAAAABYAAAAAACYAAAAAADYAAAAAABYAAAAAADYAAAAAAAYAAAAAABYAAAAAADYAAAAAACYAAAAAABYAAAAAACYAAAAAABYAAAAAAAYAAAAAADYAAAAAACYAAAAAADYAAAAAABYAAAAAACYAAAAAAAYAAAAAABYAAAAAABYAAAAAADYAAAAAACYAAAAAABYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAYAAAAAABYAAAAAAAYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAYAAAAAAAYAAAAAADYAAAAAADYAAAAAABYAAAAAACgQAAAAAALwAAAAAAYAAAAAAAYAAAAAAALwAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAYAAAAAAAYAAAAAADYAAAAAADYAAAAAADYAAAAAADgQAAAAAALwAAAAAAYAAAAAACYAAAAAABLwAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAABYAAAAAACYAAAAAACYAAAAAADYAAAAAACgQAAAAAALwAAAAAAYAAAAAACYAAAAAAAYAAAAAACgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAADYAAAAAADYAAAAAAAYAAAAAABYAAAAAADgQAAAAAALwAAAAAAYAAAAAABLwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfQAAAAADfQAAAAACfQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAABKQAAAAACgQAAAAAAfQAAAAADfQAAAAACfwAAAAAAfQAAAAABfQAAAAAAfQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAABKQAAAAACfwAAAAAAfQAAAAAAfQAAAAAAfwAAAAACfQAAAAACfQAAAAABfQAAAAACgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADKQAAAAADfwAAAAAAfQAAAAAAfQAAAAADfwAAAAADfQAAAAABfQAAAAADfQAAAAADgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAAAKQAAAAADgQAAAAAAfQAAAAABfQAAAAABfwAAAAAAfQAAAAADfQAAAAAAfQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAA version: 6 2,1: ind: 2,1 @@ -187,11 +187,11 @@ entities: version: 6 -3,-3: ind: -3,-3 - tiles: bwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAgQAAAAAAEQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAEQAAAAAAEQAAAAAAEQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAEQAAAAAAEQAAAAAAEQAAAAAAgQAAAAAAgQAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAfQAAAAACfQAAAAACfQAAAAACfQAAAAADbwAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAgQAAAAAAgQAAAAAAEQAAAAAAgQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAfwAAAAACfQAAAAAAfQAAAAAAfQAAAAAAfQAAAAADgQAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAgQAAAAAAEQAAAAAAEQAAAAAAEQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAfQAAAAAAfQAAAAADfQAAAAADfQAAAAAAgQAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAgQAAAAAAEQAAAAAAEQAAAAAAEQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAfQAAAAACfQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAEQAAAAAAgQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAfQAAAAACfQAAAAADgQAAAAAAfQAAAAACLwAAAAAALwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAFwAAAAAAgQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAfwAAAAACgQAAAAAAgQAAAAAAfQAAAAADLwAAAAAALwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAFwAAAAAAFwAAAAAAgQAAAAAAgQAAAAAAcwAAAAABcwAAAAAAcwAAAAABcwAAAAACcwAAAAACgQAAAAAAfQAAAAACLwAAAAAALwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAFwAAAAAAFwAAAAAAgQAAAAAAgQAAAAAAcwAAAAAAcwAAAAADcwAAAAAAcwAAAAADcwAAAAACgQAAAAAAgQAAAAAALwAAAAAALwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAACcwAAAAAAcwAAAAACcwAAAAAAcwAAAAABcwAAAAABcwAAAAAB + tiles: bwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAgQAAAAAAEQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAEQAAAAAAEQAAAAAAEQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAEQAAAAAAEQAAAAAAEQAAAAAAgQAAAAAAgQAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAfQAAAAACfQAAAAACfQAAAAACfQAAAAADbwAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAgQAAAAAAgQAAAAAAEQAAAAAAgQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAfwAAAAACfQAAAAAAfQAAAAAAfQAAAAAAfQAAAAADgQAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAgQAAAAAAEQAAAAAAEQAAAAAAEQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAfQAAAAAAfQAAAAADfQAAAAADfQAAAAAAgQAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAgQAAAAAAEQAAAAAAEQAAAAAAEQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAfQAAAAACfQAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAEQAAAAAAgQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAfQAAAAACfQAAAAADgQAAAAAAfQAAAAACLwAAAAAALwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAFwAAAAAAgQAAAAAAgQAAAAAAQgAAAAAAQgAAAAAAgQAAAAAAfwAAAAACgQAAAAAAgQAAAAAAfQAAAAADLwAAAAAALwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAFwAAAAAAFwAAAAAAgQAAAAAAgQAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAgQAAAAAAfQAAAAACLwAAAAAALwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAFwAAAAAAFwAAAAAAgQAAAAAAgQAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAgQAAAAAAgQAAAAAALwAAAAAALwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAcwAAAAABcwAAAAAB version: 6 -3,-2: ind: -3,-2 - tiles: LwAAAAAALwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAACcwAAAAACcwAAAAABcwAAAAABcwAAAAADcwAAAAABcwAAAAAAIAAAAAADIAAAAAADIAAAAAADYAAAAAAAYAAAAAACYAAAAAABYAAAAAAAYAAAAAABgQAAAAAAcwAAAAAAcwAAAAADcwAAAAAAcwAAAAADcwAAAAACgQAAAAAAgQAAAAAAIAAAAAADIAAAAAABIAAAAAACYAAAAAABYAAAAAADYAAAAAAAYAAAAAABYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAAAYAAAAAADgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAABKQAAAAABKQAAAAACYAAAAAAAYAAAAAADgQAAAAAAYAAAAAAAYAAAAAABYAAAAAACgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAAAKQAAAAADKQAAAAAAYAAAAAACYAAAAAAAgQAAAAAAYAAAAAABYAAAAAADYAAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAADKQAAAAABKQAAAAAAYAAAAAAAYAAAAAACKQAAAAAAYAAAAAAAYAAAAAABYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAABYAAAAAACYAAAAAADYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAUwAAAAAAUwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAYAAAAAAAYAAAAAAAYAAAAAACgQAAAAAAYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfAAAAAAAUwAAAAAAUwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAADYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfAAAAAADUwAAAAAAUwAAAAAAUwAAAAAAUwAAAAAAUwAAAAAAYAAAAAABYAAAAAAAYAAAAAACgQAAAAAAYAAAAAABYAAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAUwAAAAAAUwAAAAAAUwAAAAAAUwAAAAAAUwAAAAAAYAAAAAABYAAAAAACYAAAAAABgQAAAAAAYAAAAAADYAAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfAAAAAABUwAAAAAAUwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAAAYAAAAAACYAAAAAADYAAAAAACYAAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAfAAAAAAAUwAAAAAAUwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAYAAAAAADYAAAAAAAYAAAAAACgQAAAAAAYAAAAAADYAAAAAADgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAfAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAACYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAfAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAACYAAAAAACYAAAAAABgQAAAAAAYAAAAAACYAAAAAADgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAfAAAAAAA + tiles: LwAAAAAALwAAAAAALwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAcwAAAAABcwAAAAAAIAAAAAADIAAAAAADIAAAAAADYAAAAAAAYAAAAAACYAAAAAABYAAAAAAAYAAAAAABgQAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAfAAAAAAAgQAAAAAAgQAAAAAAIAAAAAADIAAAAAABIAAAAAACYAAAAAABYAAAAAADYAAAAAAAYAAAAAABYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAAAYAAAAAADgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAABKQAAAAABKQAAAAACYAAAAAAAYAAAAAADgQAAAAAAYAAAAAAAYAAAAAABYAAAAAACgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAAAKQAAAAADKQAAAAAAYAAAAAACYAAAAAAAgQAAAAAAYAAAAAABYAAAAAADYAAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAADKQAAAAABKQAAAAAAYAAAAAAAYAAAAAACKQAAAAAAYAAAAAAAYAAAAAABYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcwAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAABYAAAAAACYAAAAAADYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAUwAAAAAAUwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAYAAAAAAAYAAAAAAAYAAAAAACgQAAAAAAYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfAAAAAAAUwAAAAAAUwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAADYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfAAAAAADUwAAAAAAUwAAAAAAUwAAAAAAUwAAAAAAUwAAAAAAYAAAAAABYAAAAAAAYAAAAAACgQAAAAAAYAAAAAABYAAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAUwAAAAAAUwAAAAAAUwAAAAAAUwAAAAAAUwAAAAAAYAAAAAABYAAAAAACYAAAAAABgQAAAAAAYAAAAAADYAAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAfAAAAAABUwAAAAAAUwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAAAYAAAAAACYAAAAAADYAAAAAACYAAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAfAAAAAAAUwAAAAAAUwAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAYAAAAAADYAAAAAAAYAAAAAACgQAAAAAAYAAAAAADYAAAAAADgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAfAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAACYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAfAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAACYAAAAAACYAAAAAABgQAAAAAAYAAAAAACYAAAAAADgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAfAAAAAAA version: 6 -3,-1: ind: -3,-1 @@ -203,7 +203,7 @@ entities: version: 6 -3,1: ind: -3,1 - tiles: AAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAA + tiles: AAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAA version: 6 0,-4: ind: 0,-4 @@ -251,15 +251,15 @@ entities: version: 6 3,-2: ind: 3,-2 - tiles: gQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAJwAAAAABJwAAAAAAJwAAAAAAgQAAAAAAJwAAAAADJwAAAAACJwAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAJwAAAAACJwAAAAACJwAAAAADgQAAAAAAJwAAAAABJwAAAAACJwAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAKQAAAAACKQAAAAADKQAAAAAAKQAAAAADKQAAAAAAKQAAAAACKQAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAKQAAAAAAKQAAAAADKQAAAAABKQAAAAABKQAAAAADKQAAAAACKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAKQAAAAABKQAAAAACKQAAAAADKQAAAAAAKQAAAAADKQAAAAACKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgAAAAAAA + tiles: gQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAJwAAAAABJwAAAAAAJwAAAAAAgQAAAAAAJwAAAAADJwAAAAACJwAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAJwAAAAACJwAAAAACJwAAAAADgQAAAAAAJwAAAAABJwAAAAACJwAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAKQAAAAACKQAAAAADKQAAAAAAKQAAAAADKQAAAAAAKQAAAAACKQAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAKQAAAAAAKQAAAAADKQAAAAABKQAAAAABKQAAAAADKQAAAAACKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAKQAAAAABKQAAAAACKQAAAAADKQAAAAAAKQAAAAADKQAAAAACKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAAAAAAAAAgAAAAAAA version: 6 3,-3: ind: 3,-3 - tiles: AAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAABwAAAAABBwAAAAAEBwAAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAHBwAAAAAFBwAAAAALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAABwAAAAAABwAAAAAABwAAAAAKBwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAAAAAAAAAAAAAAAAAAgQAAAAAABwAAAAAABwAAAAAABwAAAAABBwAAAAAGBwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAAgQAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAACBwAAAAAABwAAAAALBwAAAAAABwAAAAADBwAAAAAABwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAABwAAAAAABwAAAAAEBwAAAAAABwAAAAAAKQAAAAACgQAAAAAAKQAAAAACKQAAAAAAKQAAAAABKQAAAAABKQAAAAAAKQAAAAABKQAAAAADKQAAAAADKQAAAAABgQAAAAAAgQAAAAAABwAAAAAABwAAAAAABwAAAAAAKQAAAAAAKQAAAAADKQAAAAAAKQAAAAADKQAAAAADKQAAAAADKQAAAAADKQAAAAACKQAAAAAAKQAAAAADKQAAAAADKQAAAAADgQAAAAAAgQAAAAAABwAAAAAABwAAAAAAKQAAAAADKQAAAAACKQAAAAABKQAAAAACKQAAAAABKQAAAAACKQAAAAABKQAAAAACKQAAAAABKQAAAAABKQAAAAADKQAAAAADKQAAAAAAgQAAAAAABwAAAAAABwAAAAAAKQAAAAABgQAAAAAAKQAAAAADKQAAAAAAKQAAAAAAKQAAAAABKQAAAAAAKQAAAAADKQAAAAADKQAAAAABKQAAAAAAKQAAAAABKQAAAAACgQAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAA + tiles: AAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAABwAAAAABBwAAAAAEBwAAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAHBwAAAAAFBwAAAAALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAABwAAAAAABwAAAAAABwAAAAAKBwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAAAAAAAAAAAAAAAAAAgQAAAAAABwAAAAAABwAAAAAABwAAAAABBwAAAAAGBwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAAgQAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAAABwAAAAACBwAAAAAABwAAAAALBwAAAAAABwAAAAADBwAAAAAABwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAABwAAAAAABwAAAAAEBwAAAAAABwAAAAAAKQAAAAACgQAAAAAAKQAAAAACKQAAAAAAKQAAAAABKQAAAAABKQAAAAAAKQAAAAABKQAAAAADKQAAAAADKQAAAAABgQAAAAAAgQAAAAAABwAAAAAABwAAAAAABwAAAAAAKQAAAAAAKQAAAAADKQAAAAAAKQAAAAADKQAAAAADKQAAAAADKQAAAAADKQAAAAACKQAAAAAAKQAAAAADKQAAAAADKQAAAAADgQAAAAAAgQAAAAAABwAAAAAABwAAAAAAKQAAAAADKQAAAAACKQAAAAABKQAAAAACKQAAAAABKQAAAAACKQAAAAABKQAAAAACKQAAAAABKQAAAAABKQAAAAADKQAAAAADKQAAAAAAgQAAAAAABwAAAAAABwAAAAAAKQAAAAABgQAAAAAAKQAAAAADKQAAAAAAKQAAAAAAKQAAAAABKQAAAAAAKQAAAAADKQAAAAADKQAAAAABKQAAAAAAKQAAAAABKQAAAAACgQAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAA version: 6 -1,2: ind: -1,2 - tiles: fQAAAAAAfwAAAAAAfQAAAAADfQAAAAADfQAAAAAAgQAAAAAAfQAAAAABfQAAAAADfQAAAAADfQAAAAADfQAAAAAAfQAAAAAAfQAAAAABgQAAAAAAYAAAAAADYAAAAAABgQAAAAAAgQAAAAAAfQAAAAAAfQAAAAACfQAAAAABgQAAAAAAfQAAAAABfQAAAAABfQAAAAAAfQAAAAAAfQAAAAAAfQAAAAADfQAAAAADgQAAAAAAYAAAAAADYAAAAAADbwAAAAAAgQAAAAAAgQAAAAAAfwAAAAADgQAAAAAAgQAAAAAAfQAAAAABfQAAAAAAfQAAAAAAfQAAAAAAfQAAAAAAfQAAAAACfQAAAAAAgQAAAAAAYAAAAAABYAAAAAACbwAAAAAAgQAAAAAAfQAAAAAAfQAAAAAAfQAAAAACfQAAAAAAfQAAAAACfQAAAAADfQAAAAAAfQAAAAACfQAAAAAAfQAAAAADfQAAAAACgQAAAAAAYAAAAAABYAAAAAABbwAAAAAAgQAAAAAAfQAAAAAAfQAAAAACfQAAAAABfQAAAAACfQAAAAADfQAAAAAAfQAAAAABfQAAAAAAfQAAAAACfQAAAAACfQAAAAABgQAAAAAAYAAAAAABYAAAAAACbwAAAAAAbwAAAAAAfQAAAAAAfQAAAAACfQAAAAABfQAAAAACfQAAAAACfQAAAAACfQAAAAADfQAAAAABfQAAAAACfQAAAAABfQAAAAACYAAAAAAAYAAAAAADYAAAAAABgQAAAAAAgQAAAAAAfQAAAAABfQAAAAACfQAAAAABfQAAAAADfQAAAAACfQAAAAABfQAAAAACfQAAAAABfQAAAAADfQAAAAADfQAAAAADYAAAAAAAYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAADYAAAAAACYAAAAAACYAAAAAADYAAAAAABYAAAAAADYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcAAAAAAAYAAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAYAAAAAADYAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcAAAAAAAYAAAAAACJgAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAYAAAAAABYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAADYAAAAAADYAAAAAABYAAAAAACYAAAAAAAYAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAABKQAAAAACKQAAAAABKQAAAAABKQAAAAADKQAAAAAAgQAAAAAA + tiles: fQAAAAAAfwAAAAAAfQAAAAADfQAAAAADfQAAAAAAgQAAAAAAfQAAAAABfQAAAAADfQAAAAADfQAAAAADfQAAAAAAfQAAAAAAfQAAAAABgQAAAAAAYAAAAAADYAAAAAABgQAAAAAAgQAAAAAAfQAAAAAAfQAAAAACfQAAAAABgQAAAAAAfQAAAAABfQAAAAABfQAAAAAAfQAAAAAAfQAAAAAAfQAAAAADfQAAAAADgQAAAAAAYAAAAAADYAAAAAADbwAAAAAAgQAAAAAAgQAAAAAAfwAAAAADgQAAAAAAgQAAAAAAfQAAAAABfQAAAAAAfQAAAAAAfQAAAAAAfQAAAAAAfQAAAAACfQAAAAAAgQAAAAAAYAAAAAABYAAAAAACbwAAAAAAgQAAAAAAfQAAAAAAfQAAAAAAfQAAAAACfQAAAAAAfQAAAAACfQAAAAADfQAAAAAAfQAAAAACfQAAAAAAfQAAAAADfQAAAAACgQAAAAAAYAAAAAABYAAAAAABbwAAAAAAgQAAAAAAfQAAAAAAfQAAAAACfQAAAAABfQAAAAACfQAAAAADfQAAAAAAfQAAAAABfQAAAAAAfQAAAAACfQAAAAACfQAAAAABYAAAAAAAYAAAAAABYAAAAAACbwAAAAAAbwAAAAAAfQAAAAAAfQAAAAACfQAAAAABfQAAAAACfQAAAAACfQAAAAACfQAAAAADfQAAAAABfQAAAAACfQAAAAABfQAAAAACYAAAAAAAYAAAAAADYAAAAAABgQAAAAAAgQAAAAAAfQAAAAABfQAAAAACfQAAAAABfQAAAAADfQAAAAACfQAAAAABfQAAAAACfQAAAAABfQAAAAADfQAAAAADfQAAAAADgQAAAAAAYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAADYAAAAAACYAAAAAACYAAAAAADYAAAAAABYAAAAAADYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcAAAAAAAYAAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAYAAAAAADYAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAcAAAAAAAYAAAAAACJgAAAAAAJgAAAAAAJgAAAAAAJgAAAAAAYAAAAAABYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAADYAAAAAADYAAAAAABYAAAAAACYAAAAAAAYAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAKQAAAAABKQAAAAACKQAAAAABKQAAAAABKQAAAAADKQAAAAAAgQAAAAAA version: 6 -2,2: ind: -2,2 @@ -267,7 +267,7 @@ entities: version: 6 -3,2: ind: -3,2 - tiles: AAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAYAAAAAABYAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgQAAAAAAYAAAAAABJgAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgQAAAAAAYAAAAAABJgAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgQAAAAAAYAAAAAAAJgAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgQAAAAAAYAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAA + tiles: AAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAYAAAAAABYAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgQAAAAAAYAAAAAABJgAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgQAAAAAAYAAAAAABJgAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgQAAAAAAYAAAAAAAJgAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgQAAAAAAYAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAA version: 6 2,-4: ind: 2,-4 @@ -291,7 +291,7 @@ entities: version: 6 1,3: ind: 1,3 - tiles: gQAAAAAAYAAAAAADYAAAAAACYAAAAAADRAAAAAAAKQAAAAABKQAAAAACKQAAAAABKQAAAAADKQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAKQAAAAABYAAAAAABYAAAAAADYAAAAAAARAAAAAAAKQAAAAAAKQAAAAADKQAAAAADKQAAAAADKQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAYAAAAAACYAAAAAACYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAYAAAAAAAYAAAAAABYAAAAAADgQAAAAAAgQAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAARAAAAAAARAAAAAAARAAAAAAAgQAAAAAAgQAAAAAABwAAAAAABwAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAABwAAAAAABwAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAABwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + tiles: gQAAAAAAYAAAAAADYAAAAAACYAAAAAADRAAAAAAAKQAAAAABKQAAAAACKQAAAAABKQAAAAADKQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAKQAAAAABYAAAAAABYAAAAAADYAAAAAAARAAAAAAAKQAAAAAAKQAAAAADKQAAAAADKQAAAAADKQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAYAAAAAACYAAAAAACYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAYAAAAAAAYAAAAAABYAAAAAADgQAAAAAAgQAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAARAAAAAAARAAAAAAARAAAAAAAgQAAAAAAgQAAAAAABwAAAAAABwAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAABwAAAAAABwAAAAAAgQAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAABwAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA version: 6 2,3: ind: 2,3 @@ -363,7 +363,7 @@ entities: version: 6 -4,-1: ind: -4,-1 - tiles: AAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAACYAAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAYAAAAAABYAAAAAACYAAAAAAAYAAAAAAAYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAYAAAAAAAYAAAAAABYAAAAAACYAAAAAAAYAAAAAADYAAAAAABbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAYAAAAAADYAAAAAADYAAAAAADYAAAAAAAYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAYAAAAAADJQAAAAACJQAAAAABJQAAAAACYAAAAAADYAAAAAABgQAAAAAAgQAAAAAAUwAAAAAAUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAYAAAAAADJQAAAAACJQAAAAAAJQAAAAACYAAAAAAAYAAAAAAAYAAAAAAAgQAAAAAAOQAAAAAAUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAYAAAAAAAJQAAAAAAJQAAAAADJQAAAAADYAAAAAABYAAAAAACYAAAAAADUwAAAAAAOQAAAAAAUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAYAAAAAACJQAAAAAAJQAAAAAAJQAAAAADYAAAAAABYAAAAAADYAAAAAAAgQAAAAAAOQAAAAAAUwAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAYAAAAAACYAAAAAABYAAAAAADYAAAAAACYAAAAAACYAAAAAADgQAAAAAAgQAAAAAAUwAAAAAAUwAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAACYAAAAAADYAAAAAACYAAAAAAAYAAAAAAAYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAABYAAAAAACYAAAAAABYAAAAAABYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAagAAAAADZQAAAAACZQAAAAACYAAAAAADYAAAAAADYAAAAAACYAAAAAABgQAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAZQAAAAAAZQAAAAADYAAAAAAAYAAAAAABYAAAAAACYAAAAAABgQAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAagAAAAABZQAAAAAAZQAAAAACYAAAAAACYAAAAAABYAAAAAAAYAAAAAACgQAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAACYAAAAAABYAAAAAACYAAAAAABYAAAAAAAYAAAAAAAgQAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAACYAAAAAACYAAAAAAAYAAAAAABYAAAAAADYAAAAAADYAAAAAAAbAAAAAAAbAAAAAAA + tiles: AAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAbwAAAAAAgQAAAAAAYAAAAAACYAAAAAABgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAYAAAAAABYAAAAAACYAAAAAAAYAAAAAAAYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAYAAAAAAAYAAAAAABYAAAAAACYAAAAAAAYAAAAAADYAAAAAABbwAAAAAAbwAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAYAAAAAADYAAAAAADYAAAAAADYAAAAAAAYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAYAAAAAADJQAAAAACJQAAAAABJQAAAAACYAAAAAADYAAAAAABgQAAAAAAgQAAAAAAUwAAAAAAUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAYAAAAAADJQAAAAACJQAAAAAAJQAAAAACYAAAAAAAYAAAAAAAYAAAAAAAgQAAAAAAOQAAAAAAUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgQAAAAAAYAAAAAAAJQAAAAAAJQAAAAADJQAAAAADYAAAAAABYAAAAAACYAAAAAADUwAAAAAAOQAAAAAAUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAYAAAAAACJQAAAAAAJQAAAAAAJQAAAAADYAAAAAABYAAAAAADYAAAAAAAgQAAAAAAOQAAAAAAUwAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAgAAAAAAAgAAAAAAAgQAAAAAAYAAAAAACYAAAAAABYAAAAAADYAAAAAACYAAAAAACYAAAAAADgQAAAAAAgQAAAAAAUwAAAAAAUwAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAACYAAAAAADYAAAAAACYAAAAAAAYAAAAAAAYAAAAAACgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAABYAAAAAACYAAAAAABYAAAAAABYAAAAAAAYAAAAAADgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAagAAAAADZQAAAAACZQAAAAACYAAAAAADYAAAAAADYAAAAAACYAAAAAABgQAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAZQAAAAAAZQAAAAADYAAAAAAAYAAAAAABYAAAAAACYAAAAAABgQAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAagAAAAABZQAAAAAAZQAAAAACYAAAAAACYAAAAAABYAAAAAAAYAAAAAACgQAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAACYAAAAAABYAAAAAACYAAAAAABYAAAAAAAYAAAAAAAgQAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAAAAAAAAAAAAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAgQAAAAAAYAAAAAAAYAAAAAACYAAAAAACYAAAAAAAYAAAAAABYAAAAAADYAAAAAADYAAAAAAAbAAAAAAAbAAAAAAA version: 6 4,1: ind: 4,1 @@ -445,445 +445,445 @@ entities: color: '#FFFFFFFF' id: Arrows decals: - 709: 42.99683,-1.538444 + 707: 42.99683,-1.538444 - node: angle: 3.141592653589793 rad color: '#FFFFFFFF' id: Arrows decals: - 710: 39.96558,-1.975944 + 708: 39.96558,-1.975944 - node: color: '#FFFFFFFF' id: Bot decals: - 963: -57,-9 - 964: -56,-9 - 965: -55,-9 - 966: -55,-10 - 967: -56,-10 - 968: -57,-10 - 969: -57,-11 - 970: -56,-11 - 971: -55,-11 - 972: -55,-12 - 973: -56,-12 - 974: -57,-12 - 3491: -3,-31 + 961: -57,-9 + 962: -56,-9 + 963: -55,-9 + 964: -55,-10 + 965: -56,-10 + 966: -57,-10 + 967: -57,-11 + 968: -56,-11 + 969: -55,-11 + 970: -55,-12 + 971: -56,-12 + 972: -57,-12 + 3489: -3,-31 - node: angle: 3.141592653589793 rad color: '#FFFFFFFF' id: Bot decals: - 714: 40,-3 + 712: 40,-3 - node: color: '#FFFFFFFF' id: BotGreyscale decals: - 2721: 35,-25 - 2722: 35,-26 - 2723: 32,-25 - 2724: 32,-24 - 2725: 32,-22 - 2836: 7,-38 - 2967: 15,-40 - 2968: 15,-41 + 2719: 35,-25 + 2720: 35,-26 + 2721: 32,-25 + 2722: 32,-24 + 2723: 32,-22 + 2834: 7,-38 + 2965: 15,-40 + 2966: 15,-41 - node: angle: 3.141592653589793 rad color: '#FFFFFFFF' id: BotLeft decals: - 711: 43,-3 - 712: 42,-3 - 713: 41,-3 + 709: 43,-3 + 710: 42,-3 + 711: 41,-3 - node: color: '#FFFFFFFF' id: BotLeftGreyscale decals: - 2837: 7,-38 + 2835: 7,-38 - node: color: '#FFFFFFFF' id: BotRightGreyscale decals: - 2838: 7,-38 + 2836: 7,-38 - node: color: '#FFFFFFFF' id: Box decals: - 1734: 49,-37 - 1735: 49,-38 - 2341: -7,-51 - 2342: -5,-53 + 1732: 49,-37 + 1733: 49,-38 + 2339: -7,-51 + 2340: -5,-53 - node: color: '#C74EBDB2' id: BrickCornerOverlayNE decals: - 2933: -18,-25 + 2931: -18,-25 - node: color: '#EFB34196' id: BrickCornerOverlayNE decals: - 2484: 5,51 - 3098: -3,42 + 2482: 5,51 + 3096: -3,42 - node: color: '#F9801DB2' id: BrickCornerOverlayNE decals: - 2946: -22,-25 + 2944: -22,-25 - node: color: '#FED83DB2' id: BrickCornerOverlayNE decals: - 2939: -15,-25 + 2937: -15,-25 - node: color: '#C74EBDB2' id: BrickCornerOverlayNW decals: - 2934: -20,-25 + 2932: -20,-25 - node: color: '#EFB34196' id: BrickCornerOverlayNW decals: - 2485: 3,51 - 3097: -6,42 + 2483: 3,51 + 3095: -6,42 - node: color: '#F9801DB2' id: BrickCornerOverlayNW decals: - 2945: -23,-25 + 2943: -23,-25 - node: color: '#FED83DB2' id: BrickCornerOverlayNW decals: - 2940: -16,-25 + 2938: -16,-25 - node: color: '#C74EBDB2' id: BrickCornerOverlaySE decals: - 2936: -18,-26 + 2934: -18,-26 - node: color: '#EFB34196' id: BrickCornerOverlaySE decals: - 2486: 5,49 - 3095: -3,41 + 2484: 5,49 + 3093: -3,41 - node: color: '#F9801DB2' id: BrickCornerOverlaySE decals: - 2943: -22,-26 + 2941: -22,-26 - node: color: '#FED83DB2' id: BrickCornerOverlaySE decals: - 2941: -15,-26 + 2939: -15,-26 - node: color: '#C74EBDB2' id: BrickCornerOverlaySW decals: - 2935: -20,-26 + 2933: -20,-26 - node: color: '#EFB34196' id: BrickCornerOverlaySW decals: - 2438: 7,40 - 2487: 3,49 - 3096: -6,41 + 2436: 7,40 + 2485: 3,49 + 3094: -6,41 - node: color: '#F9801DB2' id: BrickCornerOverlaySW decals: - 2944: -23,-26 + 2942: -23,-26 - node: color: '#FED83DB2' id: BrickCornerOverlaySW decals: - 2942: -16,-26 + 2940: -16,-26 - node: color: '#EFB34196' id: BrickLineOverlayE decals: - 2449: 9,50 - 2450: 9,48 - 2451: 9,47 - 2459: 19,50 - 2470: 19,51 - 2471: 9,51 - 2490: 5,50 - 2492: 3,50 + 2447: 9,50 + 2448: 9,48 + 2449: 9,47 + 2457: 19,50 + 2468: 19,51 + 2469: 9,51 + 2488: 5,50 + 2490: 3,50 - node: color: '#C74EBDB2' id: BrickLineOverlayN decals: - 2937: -19,-25 - 2948: -20,-27 - 2949: -18,-27 - 2955: -19,-27 + 2935: -19,-25 + 2946: -20,-27 + 2947: -18,-27 + 2953: -19,-27 - node: color: '#EFB34196' id: BrickLineOverlayN decals: - 2452: 10,46 - 2453: 11,46 - 2454: 15,46 - 2455: 16,46 - 2489: 4,51 - 2495: 4,49 - 3099: -4,42 - 3100: -5,42 + 2450: 10,46 + 2451: 11,46 + 2452: 15,46 + 2453: 16,46 + 2487: 4,51 + 2493: 4,49 + 3097: -4,42 + 3098: -5,42 - node: color: '#F9801DB2' id: BrickLineOverlayN decals: - 2947: -23,-27 - 2956: -22,-27 + 2945: -23,-27 + 2954: -22,-27 - node: color: '#FED83DB2' id: BrickLineOverlayN decals: - 2950: -15,-27 - 2954: -16,-27 + 2948: -15,-27 + 2952: -16,-27 - node: color: '#C74EBDB2' id: BrickLineOverlayS decals: - 2938: -19,-26 + 2936: -19,-26 - node: color: '#EFB34196' id: BrickLineOverlayS decals: - 2491: 4,49 - 2493: 4,51 - 3101: -5,41 - 3102: -4,41 + 2489: 4,49 + 2491: 4,51 + 3099: -5,41 + 3100: -4,41 - node: color: '#EFB34196' id: BrickLineOverlayW decals: - 2439: 7,41 - 2440: 7,42 - 2441: 7,43 - 2442: 7,44 - 2443: 7,45 - 2444: 7,46 - 2445: 7,47 - 2446: 7,48 - 2447: 7,49 - 2448: 7,50 - 2456: 17,47 - 2457: 17,48 - 2458: 17,50 - 2469: 17,51 - 2472: 7,51 - 2488: 3,50 - 2494: 5,50 + 2437: 7,41 + 2438: 7,42 + 2439: 7,43 + 2440: 7,44 + 2441: 7,45 + 2442: 7,46 + 2443: 7,47 + 2444: 7,48 + 2445: 7,49 + 2446: 7,50 + 2454: 17,47 + 2455: 17,48 + 2456: 17,50 + 2467: 17,51 + 2470: 7,51 + 2486: 3,50 + 2492: 5,50 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerNe decals: - 874: -53,8 - 875: -52,7 - 1727: 42,-40 + 872: -53,8 + 873: -52,7 + 1725: 42,-40 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerNw decals: - 872: -55,8 - 876: -57,7 - 1726: 40,-40 + 870: -55,8 + 874: -57,7 + 1724: 40,-40 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerSe decals: - 877: -52,5 + 875: -52,5 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerSw decals: - 878: -57,5 + 876: -57,5 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerNe decals: - 620: 22,4 - 885: -53,7 + 618: 22,4 + 883: -53,7 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerNw decals: - 886: -55,7 + 884: -55,7 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerSe decals: - 621: 22,9 + 619: 22,9 - node: color: '#FFFFFFFF' id: BrickTileDarkLineE decals: - 616: 22,8 - 617: 22,7 - 618: 22,6 - 619: 22,5 - 887: -52,6 - 2519: 27,42 - 2520: 27,43 - 2521: 30,42 - 2522: 30,43 + 614: 22,8 + 615: 22,7 + 616: 22,6 + 617: 22,5 + 885: -52,6 + 2517: 27,42 + 2518: 27,43 + 2519: 30,42 + 2520: 30,43 - node: color: '#FFFFFFFF' id: BrickTileDarkLineN decals: - 873: -54,8 - 884: -56,7 - 1728: 41,-40 - 3509: -8,-24 + 871: -54,8 + 882: -56,7 + 1726: 41,-40 + 3507: -8,-24 - node: color: '#FFFFFFFF' id: BrickTileDarkLineS decals: - 879: -56,5 - 880: -55,5 - 881: -54,5 - 882: -53,5 + 877: -56,5 + 878: -55,5 + 879: -54,5 + 880: -53,5 - node: color: '#FFFFFFFF' id: BrickTileDarkLineW decals: - 883: -57,6 - 2523: 31,42 - 2524: 31,43 + 881: -57,6 + 2521: 31,42 + 2522: 31,43 - node: color: '#FFFFFFFF' id: BrickTileSteelCornerNe decals: - 724: -1,-34 - 2325: -4,-50 - 2389: 32,-38 - 3081: -28,42 + 722: -1,-34 + 2323: -4,-50 + 2387: 32,-38 + 3079: -28,42 - node: color: '#FFFFFFFF' id: BrickTileSteelCornerNw decals: - 2326: -8,-50 - 2388: 29,-38 - 3082: -33,42 - 3427: 19,-18 - 3428: 18,-19 + 2324: -8,-50 + 2386: 29,-38 + 3080: -33,42 + 3425: 19,-18 + 3426: 18,-19 - node: color: '#FFFFFFFF' id: BrickTileSteelCornerSe decals: - 723: -1,-39 - 2327: -4,-54 - 2397: 32,-40 - 3083: -28,40 + 721: -1,-39 + 2325: -4,-54 + 2395: 32,-40 + 3081: -28,40 - node: color: '#FFFFFFFF' id: BrickTileSteelCornerSw decals: - 2328: -8,-54 - 2393: 29,-40 - 3084: -33,40 + 2326: -8,-54 + 2391: 29,-40 + 3082: -33,40 - node: color: '#FFFFFFFF' id: BrickTileSteelEndN decals: - 2317: -8,-44 + 2315: -8,-44 - node: color: '#FFFFFFFF' id: BrickTileSteelEndS decals: - 2318: -8,-48 + 2316: -8,-48 - node: color: '#FFFFFFFF' id: BrickTileSteelInnerNe decals: - 721: -2,-34 + 719: -2,-34 - node: color: '#FFFFFFFF' id: BrickTileSteelInnerNw decals: - 3433: 19,-19 + 3431: 19,-19 - node: color: '#FFFFFFFF' id: BrickTileSteelInnerSe decals: - 720: -2,-39 + 718: -2,-39 - node: color: '#FFFFFFFF' id: BrickTileSteelLineE decals: - 715: -2,-40 - 716: -1,-38 - 717: -1,-37 - 718: -1,-36 - 719: -1,-35 - 722: -2,-33 - 1815: 17,30 - 2319: -8,-47 - 2320: -8,-46 - 2321: -8,-45 - 2329: -4,-53 - 2330: -4,-52 - 2331: -4,-51 - 2396: 32,-39 - 3085: -28,41 + 713: -2,-40 + 714: -1,-38 + 715: -1,-37 + 716: -1,-36 + 717: -1,-35 + 720: -2,-33 + 1813: 17,30 + 2317: -8,-47 + 2318: -8,-46 + 2319: -8,-45 + 2327: -4,-53 + 2328: -4,-52 + 2329: -4,-51 + 2394: 32,-39 + 3083: -28,41 - node: color: '#FFFFFFFF' id: BrickTileSteelLineN decals: - 2332: -5,-50 - 2333: -6,-50 - 2334: -7,-50 - 2390: 30,-38 - 2394: 31,-38 - 3091: -32,42 - 3092: -31,42 - 3093: -30,42 - 3094: -29,42 - 3431: 20,-18 - 3432: 21,-18 + 2330: -5,-50 + 2331: -6,-50 + 2332: -7,-50 + 2388: 30,-38 + 2392: 31,-38 + 3089: -32,42 + 3090: -31,42 + 3091: -30,42 + 3092: -29,42 + 3429: 20,-18 + 3430: 21,-18 - node: color: '#FFFFFFFF' id: BrickTileSteelLineS decals: - 2335: -5,-54 - 2336: -6,-54 - 2337: -7,-54 - 2391: 30,-40 - 2392: 31,-40 - 3087: -32,40 - 3088: -31,40 - 3089: -30,40 - 3090: -29,40 + 2333: -5,-54 + 2334: -6,-54 + 2335: -7,-54 + 2389: 30,-40 + 2390: 31,-40 + 3085: -32,40 + 3086: -31,40 + 3087: -30,40 + 3088: -29,40 - node: color: '#FFFFFFFF' id: BrickTileSteelLineW decals: - 1816: 12,30 - 2322: -8,-47 - 2323: -8,-46 - 2324: -8,-45 - 2338: -8,-53 - 2339: -8,-52 - 2340: -8,-51 - 2395: 29,-39 - 3086: -33,41 - 3429: 18,-21 - 3430: 18,-20 + 1814: 12,30 + 2320: -8,-47 + 2321: -8,-46 + 2322: -8,-45 + 2336: -8,-53 + 2337: -8,-52 + 2338: -8,-51 + 2393: 29,-39 + 3084: -33,41 + 3427: 18,-21 + 3428: 18,-20 - node: color: '#00BEBE7F' id: BrickTileWhiteCornerNe decals: - 3169: -27,43 - 3179: -36,4 - 3181: -42,5 + 3167: -27,43 + 3177: -36,4 + 3179: -42,5 - node: color: '#334E6DC8' id: BrickTileWhiteCornerNe decals: - 609: 24,9 - 612: 24,8 + 607: 24,9 + 610: 24,8 - node: color: '#4B709CFF' id: BrickTileWhiteCornerNe @@ -897,63 +897,63 @@ entities: 231: -5,-38 494: -25,-26 505: -29,-26 - 557: -24,-39 - 2361: 28,-35 - 2383: 37,-37 + 555: -24,-39 + 2359: 28,-35 + 2381: 37,-37 - node: color: '#765428FF' id: BrickTileWhiteCornerNe decals: - 3333: -53,-17 + 3331: -53,-17 - node: color: '#9FED58B3' id: BrickTileWhiteCornerNe decals: - 2534: -46,-30 + 2532: -46,-30 - node: color: '#BC863FFF' id: BrickTileWhiteCornerNe decals: - 3222: -49,3 + 3220: -49,3 - node: color: '#D381C996' id: BrickTileWhiteCornerNe decals: - 837: -11,-47 - 2189: 16,-35 - 2190: 12,-43 + 835: -11,-47 + 2187: 16,-35 + 2188: 12,-43 - node: color: '#DE3A3A96' id: BrickTileWhiteCornerNe decals: - 1551: 51,-3 - 1715: 42,-41 - 1729: 42,-40 + 1549: 51,-3 + 1713: 42,-41 + 1727: 42,-40 - node: color: '#EFB34196' id: BrickTileWhiteCornerNe decals: - 3103: -2,43 + 3101: -2,43 - node: color: '#FFFFFFFF' id: BrickTileWhiteCornerNe decals: - 574: -30,-27 + 572: -30,-27 - node: color: '#00BEBE7F' id: BrickTileWhiteCornerNw decals: - 3170: -34,43 - 3180: -44,5 + 3168: -34,43 + 3178: -44,5 - node: color: '#334E6DC8' id: BrickTileWhiteCornerNw decals: - 599: 21,8 - 604: 20,8 - 610: 23,9 - 611: 23,8 - 3211: -44,-9 + 597: 21,8 + 602: 20,8 + 608: 23,9 + 609: 23,8 + 3209: -44,-9 - node: color: '#4B709CFF' id: BrickTileWhiteCornerNw @@ -967,62 +967,62 @@ entities: 225: -10,-33 493: -27,-26 504: -33,-26 - 558: -28,-39 - 727: -2,-39 - 2360: 27,-35 + 556: -28,-39 + 725: -2,-39 + 2358: 27,-35 - node: color: '#765428FF' id: BrickTileWhiteCornerNw decals: - 3332: -58,-17 + 3330: -58,-17 - node: color: '#9FED58B3' id: BrickTileWhiteCornerNw decals: - 2535: -48,-30 + 2533: -48,-30 - node: color: '#BC863FFF' id: BrickTileWhiteCornerNw decals: - 3221: -51,3 - 3358: -51,-2 + 3219: -51,3 + 3356: -51,-2 - node: color: '#D381C996' id: BrickTileWhiteCornerNw decals: - 838: -14,-47 - 2183: 6,-43 - 2184: 14,-35 + 836: -14,-47 + 2181: 6,-43 + 2182: 14,-35 - node: color: '#DE3A3A96' id: BrickTileWhiteCornerNw decals: - 1550: 49,-3 - 1730: 40,-40 + 1548: 49,-3 + 1728: 40,-40 - node: color: '#EFB34196' id: BrickTileWhiteCornerNw decals: - 3114: -7,43 + 3112: -7,43 - node: color: '#FFFFFFFF' id: BrickTileWhiteCornerNw decals: - 572: -32,-27 - 573: -32,-27 + 570: -32,-27 + 571: -32,-27 - node: color: '#00BEBE7F' id: BrickTileWhiteCornerSe decals: - 3171: -27,39 - 3183: -36,3 + 3169: -27,39 + 3181: -36,3 - node: color: '#334E6DC8' id: BrickTileWhiteCornerSe decals: - 608: 24,4 - 613: 24,5 - 614: 24,5 + 606: 24,4 + 611: 24,5 + 612: 24,5 - node: color: '#4B709CFF' id: BrickTileWhiteCornerSe @@ -1036,63 +1036,63 @@ entities: 227: -5,-40 491: -25,-30 503: -29,-30 - 555: -24,-42 - 2381: 34,-42 - 2382: 37,-38 + 553: -24,-42 + 2379: 34,-42 + 2380: 37,-38 - node: color: '#765428FF' id: BrickTileWhiteCornerSe decals: - 3335: -53,-24 + 3333: -53,-24 - node: color: '#9FED58B3' id: BrickTileWhiteCornerSe decals: - 2532: -46,-31 + 2530: -46,-31 - node: color: '#BC863FFF' id: BrickTileWhiteCornerSe decals: - 3230: -49,-5 + 3228: -49,-5 - node: color: '#D381C996' id: BrickTileWhiteCornerSe decals: - 836: -11,-51 - 2185: 12,-45 - 2186: 16,-44 + 834: -11,-51 + 2183: 12,-45 + 2184: 16,-44 - node: color: '#DE3A3A96' id: BrickTileWhiteCornerSe decals: - 1552: 51,-4 + 1550: 51,-4 - node: color: '#EFB34196' id: BrickTileWhiteCornerSe decals: - 3104: -2,40 - 3119: 10,40 - 3124: 19,39 + 3102: -2,40 + 3117: 10,40 + 3122: 19,39 - node: color: '#FFFFFFFF' id: BrickTileWhiteCornerSe decals: - 571: -30,-29 + 569: -30,-29 - node: color: '#00BEBE7F' id: BrickTileWhiteCornerSw decals: - 3172: -34,39 - 3182: -44,3 + 3170: -34,39 + 3180: -44,3 - node: color: '#334E6DC8' id: BrickTileWhiteCornerSw decals: - 600: 21,5 - 603: 20,5 - 607: 23,4 - 615: 23,5 - 3210: -44,-11 + 598: 21,5 + 601: 20,5 + 605: 23,4 + 613: 23,5 + 3208: -44,-11 - node: color: '#4B709CFF' id: BrickTileWhiteCornerSw @@ -1106,48 +1106,48 @@ entities: 229: -10,-35 492: -27,-30 506: -33,-30 - 556: -28,-42 - 726: -2,-34 - 2384: 27,-42 + 554: -28,-42 + 724: -2,-34 + 2382: 27,-42 - node: color: '#765428FF' id: BrickTileWhiteCornerSw decals: - 3334: -58,-24 + 3332: -58,-24 - node: color: '#9FED58B3' id: BrickTileWhiteCornerSw decals: - 2533: -48,-31 + 2531: -48,-31 - node: color: '#BC863FFF' id: BrickTileWhiteCornerSw decals: - 3231: -51,-5 - 3357: -51,1 + 3229: -51,-5 + 3355: -51,1 - node: color: '#D381C996' id: BrickTileWhiteCornerSw decals: - 839: -14,-51 - 2187: 6,-45 - 2188: 14,-44 + 837: -14,-51 + 2185: 6,-45 + 2186: 14,-44 - node: color: '#DE3A3A96' id: BrickTileWhiteCornerSw decals: - 1553: 49,-4 + 1551: 49,-4 - node: color: '#EFB34196' id: BrickTileWhiteCornerSw decals: - 3112: -7,40 - 3123: 17,39 + 3110: -7,40 + 3121: 17,39 - node: color: '#FFFFFFFF' id: BrickTileWhiteCornerSw decals: - 575: -32,-29 + 573: -32,-29 - node: color: '#169C9CFF' id: BrickTileWhiteEndE @@ -1167,22 +1167,22 @@ entities: color: '#80C71F80' id: BrickTileWhiteEndS decals: - 3451: 53,-20 + 3449: 53,-20 - node: color: '#8932B87F' id: BrickTileWhiteEndS decals: - 3448: 49,-20 + 3446: 49,-20 - node: color: '#DE3A3A96' id: BrickTileWhiteEndS decals: - 1716: 42,-42 + 1714: 42,-42 - node: color: '#F9801D7F' id: BrickTileWhiteEndS decals: - 3447: 45,-20 + 3445: 45,-20 - node: color: '#169C9CFF' id: BrickTileWhiteEndW @@ -1197,7 +1197,7 @@ entities: color: '#DE3A3A96' id: BrickTileWhiteEndW decals: - 1714: 40,-41 + 1712: 40,-41 - node: color: '#F38BAAFF' id: BrickTileWhiteEndW @@ -1207,13 +1207,13 @@ entities: color: '#00BEBE7F' id: BrickTileWhiteInnerNe decals: - 3200: -44,1 - 3208: -42,4 + 3198: -44,1 + 3206: -42,4 - node: color: '#334E6DC8' id: BrickTileWhiteInnerNe decals: - 1357: 33,-8 + 1355: 33,-8 - node: color: '#4B709CFF' id: BrickTileWhiteInnerNe @@ -1223,219 +1223,219 @@ entities: color: '#52B4E996' id: BrickTileWhiteInnerNe decals: - 2387: 28,-37 + 2385: 28,-37 - node: color: '#9FED58B3' id: BrickTileWhiteInnerNe decals: - 2542: -48,-31 + 2540: -48,-31 - node: color: '#BC863FFF' id: BrickTileWhiteInnerNe decals: - 3239: -53,-2 - 3240: -53,3 - 3277: -53,1 - 3278: -53,2 - 3279: -53,3 - 3280: -53,-3 - 3281: -53,-4 - 3282: -53,-5 - 3283: -53,-6 - 3284: -53,-7 - 3285: -53,-8 - 3286: -53,-9 - 3287: -53,-10 - 3288: -53,-11 - 3289: -53,-12 - 3290: -53,-13 - 3291: -53,-15 - 3309: -58,3 - 3310: -57,3 - 3311: -56,3 - 3312: -55,3 + 3237: -53,-2 + 3238: -53,3 + 3275: -53,1 + 3276: -53,2 + 3277: -53,3 + 3278: -53,-3 + 3279: -53,-4 + 3280: -53,-5 + 3281: -53,-6 + 3282: -53,-7 + 3283: -53,-8 + 3284: -53,-9 + 3285: -53,-10 + 3286: -53,-11 + 3287: -53,-12 + 3288: -53,-13 + 3289: -53,-15 + 3307: -58,3 + 3308: -57,3 + 3309: -56,3 + 3310: -55,3 - node: color: '#D381C996' id: BrickTileWhiteInnerNe decals: - 2074: 3,-48 - 2077: 3,-45 - 2104: 17,-37 - 2105: 17,-36 - 2106: 17,-35 - 2107: 17,-34 - 2108: 15,-34 - 2109: 14,-34 - 2110: 13,-34 - 2118: 12,-42 - 2119: 11,-42 - 2120: 10,-42 - 2121: 9,-42 - 2122: 8,-42 - 2123: 7,-42 - 2124: 6,-42 - 2125: 5,-42 - 2133: 4,-34 - 2134: 8,-34 - 2135: 11,-40 - 2167: 8,-47 - 2168: 21,-44 - 2173: 13,-46 - 2182: 18,-45 - 2234: 5,-39 - 2287: -9,-42 - 2288: -8,-42 - 2289: -7,-42 - 2290: -7,-43 - 2296: -7,-46 - 2297: -7,-45 - 2300: -7,-49 - 2301: -6,-49 - 2302: -5,-49 - 2303: -5,-49 - 2304: -4,-49 - 2305: -3,-49 - 2306: -3,-50 - 2307: -3,-51 - 2308: -3,-52 - 2309: -3,-53 - 2310: -3,-54 - 2311: -3,-55 - 2861: 17,-42 - 2863: 17,-38 - 2864: 17,-39 - 2865: 17,-40 - 2866: 17,-43 - 2871: 20,-43 - 2872: 19,-43 - 2873: 18,-43 - 2963: 14,-42 + 2072: 3,-48 + 2075: 3,-45 + 2102: 17,-37 + 2103: 17,-36 + 2104: 17,-35 + 2105: 17,-34 + 2106: 15,-34 + 2107: 14,-34 + 2108: 13,-34 + 2116: 12,-42 + 2117: 11,-42 + 2118: 10,-42 + 2119: 9,-42 + 2120: 8,-42 + 2121: 7,-42 + 2122: 6,-42 + 2123: 5,-42 + 2131: 4,-34 + 2132: 8,-34 + 2133: 11,-40 + 2165: 8,-47 + 2166: 21,-44 + 2171: 13,-46 + 2180: 18,-45 + 2232: 5,-39 + 2285: -9,-42 + 2286: -8,-42 + 2287: -7,-42 + 2288: -7,-43 + 2294: -7,-46 + 2295: -7,-45 + 2298: -7,-49 + 2299: -6,-49 + 2300: -5,-49 + 2301: -5,-49 + 2302: -4,-49 + 2303: -3,-49 + 2304: -3,-50 + 2305: -3,-51 + 2306: -3,-52 + 2307: -3,-53 + 2308: -3,-54 + 2309: -3,-55 + 2859: 17,-42 + 2861: 17,-38 + 2862: 17,-39 + 2863: 17,-40 + 2864: 17,-43 + 2869: 20,-43 + 2870: 19,-43 + 2871: 18,-43 + 2961: 14,-42 - node: color: '#D4D4D428' id: BrickTileWhiteInnerNe decals: - 1364: 30,-3 + 1362: 30,-3 - node: color: '#DE3A3A96' id: BrickTileWhiteInnerNe decals: - 1384: 52,-6 - 1385: 52,-7 - 1386: 53,-8 - 1387: 54,-8 - 1388: 54,-9 - 1389: 54,-14 - 1390: 54,-16 - 1391: 54,-18 - 1392: 54,-17 - 1393: 52,-8 - 1394: 54,-15 - 1395: 54,-13 - 1396: 50,-6 - 1397: 48,-6 - 1420: 47,-8 - 1421: 46,-8 - 1440: 40,-15 - 1441: 40,-14 - 1442: 40,-13 - 1443: 40,-12 - 1444: 39,-11 - 1445: 37,-11 - 1446: 36,-11 - 1447: 35,-11 - 1448: 34,-11 - 1449: 33,-11 - 1450: 31,-11 - 1451: 30,-11 - 1502: 42,-21 - 1503: 42,-20 - 1524: 52,-16 - 1525: 51,-16 - 1526: 49,-16 - 1527: 48,-16 - 1528: 47,-16 - 1540: 47,-15 - 1541: 47,-14 - 1542: 47,-13 - 1543: 47,-12 - 1544: 47,-11 - 1545: 47,-10 - 1570: 40,-24 - 1572: 42,-24 - 1589: 39,-25 - 1590: 42,-25 - 1591: 42,-26 - 1592: 42,-28 - 1593: 42,-29 - 1594: 42,-30 - 1624: 38,-35 - 1646: 38,-31 - 1647: 37,-31 - 1648: 36,-31 - 1649: 35,-31 - 1650: 34,-31 - 1651: 33,-31 - 1652: 32,-31 - 1653: 31,-31 - 1654: 30,-31 - 1664: 40,-32 - 1677: 44,-32 - 1678: 43,-32 - 1679: 42,-32 - 1680: 44,-33 - 1681: 44,-34 - 1682: 43,-35 - 1683: 43,-36 - 1692: 39,-37 - 1700: 43,-39 - 1701: 43,-40 - 1702: 43,-41 - 1703: 43,-42 - 1721: 40,-39 - 1724: 39,-39 - 1732: 37,-42 - 2726: 54,-10 - 2842: 40,-25 - 2848: 42,-23 - 2850: 42,-22 - 3458: 54,-19 + 1382: 52,-6 + 1383: 52,-7 + 1384: 53,-8 + 1385: 54,-8 + 1386: 54,-9 + 1387: 54,-14 + 1388: 54,-16 + 1389: 54,-18 + 1390: 54,-17 + 1391: 52,-8 + 1392: 54,-15 + 1393: 54,-13 + 1394: 50,-6 + 1395: 48,-6 + 1418: 47,-8 + 1419: 46,-8 + 1438: 40,-15 + 1439: 40,-14 + 1440: 40,-13 + 1441: 40,-12 + 1442: 39,-11 + 1443: 37,-11 + 1444: 36,-11 + 1445: 35,-11 + 1446: 34,-11 + 1447: 33,-11 + 1448: 31,-11 + 1449: 30,-11 + 1500: 42,-21 + 1501: 42,-20 + 1522: 52,-16 + 1523: 51,-16 + 1524: 49,-16 + 1525: 48,-16 + 1526: 47,-16 + 1538: 47,-15 + 1539: 47,-14 + 1540: 47,-13 + 1541: 47,-12 + 1542: 47,-11 + 1543: 47,-10 + 1568: 40,-24 + 1570: 42,-24 + 1587: 39,-25 + 1588: 42,-25 + 1589: 42,-26 + 1590: 42,-28 + 1591: 42,-29 + 1592: 42,-30 + 1622: 38,-35 + 1644: 38,-31 + 1645: 37,-31 + 1646: 36,-31 + 1647: 35,-31 + 1648: 34,-31 + 1649: 33,-31 + 1650: 32,-31 + 1651: 31,-31 + 1652: 30,-31 + 1662: 40,-32 + 1675: 44,-32 + 1676: 43,-32 + 1677: 42,-32 + 1678: 44,-33 + 1679: 44,-34 + 1680: 43,-35 + 1681: 43,-36 + 1690: 39,-37 + 1698: 43,-39 + 1699: 43,-40 + 1700: 43,-41 + 1701: 43,-42 + 1719: 40,-39 + 1722: 39,-39 + 1730: 37,-42 + 2724: 54,-10 + 2840: 40,-25 + 2846: 42,-23 + 2848: 42,-22 + 3456: 54,-19 - node: color: '#EFB34196' id: BrickTileWhiteInnerNe decals: - 1757: 6,38 - 1758: 5,38 - 1759: 4,38 - 1760: 8,38 - 1761: 8,37 - 1762: 8,36 - 1763: 8,35 - 1764: 8,34 - 1765: 8,31 - 1766: 8,30 - 1811: 5,31 - 1832: 19,31 - 1847: 25,23 - 1848: 22,28 - 1849: 23,34 - 1850: 25,34 - 1851: 25,40 - 1852: 23,40 - 1866: 22,31 - 2496: 3,49 - 2500: 19,43 - 2513: 9,46 - 3062: 11,31 + 1755: 6,38 + 1756: 5,38 + 1757: 4,38 + 1758: 8,38 + 1759: 8,37 + 1760: 8,36 + 1761: 8,35 + 1762: 8,34 + 1763: 8,31 + 1764: 8,30 + 1809: 5,31 + 1830: 19,31 + 1845: 25,23 + 1846: 22,28 + 1847: 23,34 + 1848: 25,34 + 1849: 25,40 + 1850: 23,40 + 1864: 22,31 + 2494: 3,49 + 2498: 19,43 + 2511: 9,46 + 3060: 11,31 - node: color: '#FFFFFFFF' id: BrickTileWhiteInnerNe decals: - 3488: -6,-29 + 3486: -6,-29 - node: color: '#00BEBE7F' id: BrickTileWhiteInnerNw decals: - 3199: -35,1 + 3197: -35,1 - node: color: '#4B709CFF' id: BrickTileWhiteInnerNw @@ -1445,209 +1445,209 @@ entities: color: '#52B4E996' id: BrickTileWhiteInnerNw decals: - 734: -1,-39 + 732: -1,-39 - node: color: '#9FED58B3' id: BrickTileWhiteInnerNw decals: - 2539: -46,-31 + 2537: -46,-31 - node: color: '#A4610696' id: BrickTileWhiteInnerNw decals: - 1014: -48,-5 - 1015: -48,-5 + 1012: -48,-5 + 1013: -48,-5 - node: color: '#BC863FFF' id: BrickTileWhiteInnerNw decals: - 3241: -53,3 - 3242: -55,3 - 3243: -56,3 - 3244: -57,3 - 3245: -58,3 - 3246: -58,2 - 3247: -58,1 - 3248: -58,0 - 3249: -58,-1 - 3250: -58,-8 - 3251: -58,-9 - 3252: -58,-10 - 3253: -58,-11 - 3254: -58,-12 - 3255: -58,-13 - 3256: -58,-14 - 3257: -58,-15 - 3345: -47,-5 - 3353: -47,-2 - 3362: -50,-2 + 3239: -53,3 + 3240: -55,3 + 3241: -56,3 + 3242: -57,3 + 3243: -58,3 + 3244: -58,2 + 3245: -58,1 + 3246: -58,0 + 3247: -58,-1 + 3248: -58,-8 + 3249: -58,-9 + 3250: -58,-10 + 3251: -58,-11 + 3252: -58,-12 + 3253: -58,-13 + 3254: -58,-14 + 3255: -58,-15 + 3343: -47,-5 + 3351: -47,-2 + 3360: -50,-2 - node: color: '#D381C996' id: BrickTileWhiteInnerNw decals: - 2080: 5,-45 - 2085: 5,-42 - 2086: 6,-42 - 2087: 7,-42 - 2088: 8,-42 - 2089: 9,-42 - 2090: 10,-42 - 2091: 11,-42 - 2092: 12,-42 - 2093: 13,-42 - 2094: 13,-41 - 2095: 13,-40 - 2096: 13,-38 - 2097: 13,-37 - 2098: 13,-36 - 2099: 13,-35 - 2100: 13,-34 - 2101: 14,-34 - 2102: 15,-34 - 2103: 17,-34 - 2137: 6,-34 - 2138: 10,-34 - 2235: 9,-39 - 2274: -9,-55 - 2275: -9,-53 - 2276: -9,-52 - 2277: -9,-51 - 2278: -9,-50 - 2279: -9,-48 - 2280: -9,-47 - 2281: -9,-46 - 2282: -9,-44 - 2283: -9,-43 - 2284: -9,-42 - 2285: -8,-42 - 2286: -7,-42 - 2312: -3,-49 - 2313: -4,-49 - 2314: -5,-49 - 2315: -6,-49 - 2353: -1,-48 - 2867: 18,-43 - 2868: 19,-43 - 2869: 20,-43 - 2870: 21,-43 - 2964: 16,-42 + 2078: 5,-45 + 2083: 5,-42 + 2084: 6,-42 + 2085: 7,-42 + 2086: 8,-42 + 2087: 9,-42 + 2088: 10,-42 + 2089: 11,-42 + 2090: 12,-42 + 2091: 13,-42 + 2092: 13,-41 + 2093: 13,-40 + 2094: 13,-38 + 2095: 13,-37 + 2096: 13,-36 + 2097: 13,-35 + 2098: 13,-34 + 2099: 14,-34 + 2100: 15,-34 + 2101: 17,-34 + 2135: 6,-34 + 2136: 10,-34 + 2233: 9,-39 + 2272: -9,-55 + 2273: -9,-53 + 2274: -9,-52 + 2275: -9,-51 + 2276: -9,-50 + 2277: -9,-48 + 2278: -9,-47 + 2279: -9,-46 + 2280: -9,-44 + 2281: -9,-43 + 2282: -9,-42 + 2283: -8,-42 + 2284: -7,-42 + 2310: -3,-49 + 2311: -4,-49 + 2312: -5,-49 + 2313: -6,-49 + 2351: -1,-48 + 2865: 18,-43 + 2866: 19,-43 + 2867: 20,-43 + 2868: 21,-43 + 2962: 16,-42 - node: color: '#D4D4D428' id: BrickTileWhiteInnerNw decals: - 1365: 33,-3 + 1363: 33,-3 - node: color: '#DE3A3A96' id: BrickTileWhiteInnerNw decals: - 1398: 48,-6 - 1399: 48,-7 - 1400: 48,-8 - 1401: 47,-8 - 1402: 46,-8 - 1403: 46,-9 - 1404: 46,-10 - 1405: 46,-11 - 1406: 46,-12 - 1407: 46,-13 - 1408: 46,-14 - 1409: 46,-15 - 1418: 54,-8 - 1419: 53,-8 - 1422: 50,-6 - 1434: 52,-6 - 1452: 30,-11 - 1453: 30,-12 - 1454: 30,-13 - 1472: 39,-19 - 1475: 37,-18 - 1476: 37,-17 - 1477: 37,-16 - 1478: 37,-15 - 1479: 37,-14 - 1488: 31,-11 - 1489: 33,-11 - 1491: 34,-11 - 1492: 35,-11 - 1493: 36,-11 - 1494: 37,-11 - 1495: 39,-11 - 1529: 48,-16 - 1530: 49,-16 - 1531: 51,-16 - 1532: 52,-16 - 1533: 53,-15 - 1534: 53,-14 - 1535: 53,-13 - 1536: 53,-12 - 1537: 53,-11 - 1538: 53,-10 - 1539: 53,-16 - 1571: 42,-24 - 1573: 40,-24 - 1574: 40,-25 - 1575: 39,-25 - 1576: 39,-26 - 1577: 39,-27 - 1578: 39,-28 - 1579: 39,-29 - 1580: 40,-30 - 1622: 30,-34 - 1625: 40,-35 - 1637: 30,-35 - 1655: 30,-31 - 1656: 31,-31 - 1657: 32,-31 - 1658: 33,-31 - 1659: 34,-31 - 1660: 35,-31 - 1661: 36,-31 - 1662: 37,-31 - 1663: 38,-31 - 1665: 42,-32 - 1666: 43,-32 - 1667: 44,-32 - 1668: 40,-36 - 1669: 40,-37 - 1670: 39,-37 - 1711: 39,-42 - 1712: 39,-40 - 1713: 43,-39 - 1722: 40,-39 - 1723: 39,-39 - 2841: 42,-25 - 2846: 40,-23 - 2856: 40,-19 - 2857: 40,-20 + 1396: 48,-6 + 1397: 48,-7 + 1398: 48,-8 + 1399: 47,-8 + 1400: 46,-8 + 1401: 46,-9 + 1402: 46,-10 + 1403: 46,-11 + 1404: 46,-12 + 1405: 46,-13 + 1406: 46,-14 + 1407: 46,-15 + 1416: 54,-8 + 1417: 53,-8 + 1420: 50,-6 + 1432: 52,-6 + 1450: 30,-11 + 1451: 30,-12 + 1452: 30,-13 + 1470: 39,-19 + 1473: 37,-18 + 1474: 37,-17 + 1475: 37,-16 + 1476: 37,-15 + 1477: 37,-14 + 1486: 31,-11 + 1487: 33,-11 + 1489: 34,-11 + 1490: 35,-11 + 1491: 36,-11 + 1492: 37,-11 + 1493: 39,-11 + 1527: 48,-16 + 1528: 49,-16 + 1529: 51,-16 + 1530: 52,-16 + 1531: 53,-15 + 1532: 53,-14 + 1533: 53,-13 + 1534: 53,-12 + 1535: 53,-11 + 1536: 53,-10 + 1537: 53,-16 + 1569: 42,-24 + 1571: 40,-24 + 1572: 40,-25 + 1573: 39,-25 + 1574: 39,-26 + 1575: 39,-27 + 1576: 39,-28 + 1577: 39,-29 + 1578: 40,-30 + 1620: 30,-34 + 1623: 40,-35 + 1635: 30,-35 + 1653: 30,-31 + 1654: 31,-31 + 1655: 32,-31 + 1656: 33,-31 + 1657: 34,-31 + 1658: 35,-31 + 1659: 36,-31 + 1660: 37,-31 + 1661: 38,-31 + 1663: 42,-32 + 1664: 43,-32 + 1665: 44,-32 + 1666: 40,-36 + 1667: 40,-37 + 1668: 39,-37 + 1709: 39,-42 + 1710: 39,-40 + 1711: 43,-39 + 1720: 40,-39 + 1721: 39,-39 + 2839: 42,-25 + 2844: 40,-23 + 2854: 40,-19 + 2855: 40,-20 - node: color: '#EFB34196' id: BrickTileWhiteInnerNw decals: - 1778: 8,38 - 1779: 6,38 - 1780: 5,38 - 1781: 4,38 - 1782: 4,37 - 1783: 4,34 - 1784: 4,31 - 1785: 4,30 - 1812: 7,31 - 1833: 21,31 - 1853: 25,40 - 1854: 27,40 - 1855: 27,34 - 1856: 25,28 - 1857: 25,34 - 1867: 28,31 - 2497: 5,49 - 2502: 20,43 - 2514: 17,46 - 3063: 18,31 + 1776: 8,38 + 1777: 6,38 + 1778: 5,38 + 1779: 4,38 + 1780: 4,37 + 1781: 4,34 + 1782: 4,31 + 1783: 4,30 + 1810: 7,31 + 1831: 21,31 + 1851: 25,40 + 1852: 27,40 + 1853: 27,34 + 1854: 25,28 + 1855: 25,34 + 1865: 28,31 + 2495: 5,49 + 2500: 20,43 + 2512: 17,46 + 3061: 18,31 - node: color: '#334E6DC8' id: BrickTileWhiteInnerSe decals: - 1358: 33,-4 + 1356: 33,-4 - node: color: '#4B709CFF' id: BrickTileWhiteInnerSe @@ -1658,221 +1658,221 @@ entities: id: BrickTileWhiteInnerSe decals: 416: -18,-29 - 2385: 34,-38 + 2383: 34,-38 - node: color: '#80C71F80' id: BrickTileWhiteInnerSe decals: - 3452: 53,-19 + 3450: 53,-19 - node: color: '#8932B87F' id: BrickTileWhiteInnerSe decals: - 3450: 49,-19 + 3448: 49,-19 - node: color: '#9FED58B3' id: BrickTileWhiteInnerSe decals: - 2540: -48,-30 + 2538: -48,-30 - node: color: '#BC863FFF' id: BrickTileWhiteInnerSe decals: - 3258: -58,-15 - 3259: -57,-15 - 3260: -54,-15 - 3261: -53,-15 - 3262: -53,-13 - 3263: -53,-12 - 3264: -53,-11 - 3265: -53,-10 - 3266: -53,-9 - 3267: -53,-8 - 3268: -53,-7 - 3269: -53,-6 - 3270: -53,-4 - 3271: -53,-5 - 3272: -53,-3 - 3273: -53,-2 - 3274: -53,1 - 3275: -53,2 - 3276: -53,3 - 3292: -53,-15 + 3256: -58,-15 + 3257: -57,-15 + 3258: -54,-15 + 3259: -53,-15 + 3260: -53,-13 + 3261: -53,-12 + 3262: -53,-11 + 3263: -53,-10 + 3264: -53,-9 + 3265: -53,-8 + 3266: -53,-7 + 3267: -53,-6 + 3268: -53,-4 + 3269: -53,-5 + 3270: -53,-3 + 3271: -53,-2 + 3272: -53,1 + 3273: -53,2 + 3274: -53,3 + 3290: -53,-15 - node: color: '#D381C996' id: BrickTileWhiteInnerSe decals: - 2075: 3,-45 - 2076: 3,-42 - 2136: 11,-38 - 2139: 21,-42 - 2140: 17,-36 - 2141: 17,-35 - 2142: 17,-34 - 2143: 21,-44 - 2144: 20,-44 - 2145: 19,-44 - 2146: 18,-44 - 2147: 18,-45 - 2148: 17,-45 - 2149: 16,-45 - 2150: 15,-45 - 2151: 14,-45 - 2152: 13,-45 - 2153: 13,-46 - 2154: 12,-46 - 2155: 11,-46 - 2156: 10,-46 - 2157: 9,-46 - 2158: 8,-46 - 2159: 8,-47 - 2160: 5,-47 - 2161: 6,-47 - 2162: 7,-47 - 2236: 5,-35 - 2261: -3,-55 - 2262: -3,-54 - 2263: -3,-53 - 2264: -3,-52 - 2265: -3,-51 - 2266: -3,-50 - 2267: -3,-49 - 2268: -4,-55 - 2269: -5,-55 - 2270: -6,-55 - 2271: -7,-55 - 2272: -8,-55 - 2273: -9,-55 - 2291: -7,-43 - 2292: -7,-42 - 2293: -7,-45 - 2294: -7,-46 - 2295: -7,-48 - 2862: 17,-40 - 2874: 17,-42 - 2875: 17,-39 - 2876: 17,-38 - 2877: 17,-37 - 2965: 14,-39 + 2073: 3,-45 + 2074: 3,-42 + 2134: 11,-38 + 2137: 21,-42 + 2138: 17,-36 + 2139: 17,-35 + 2140: 17,-34 + 2141: 21,-44 + 2142: 20,-44 + 2143: 19,-44 + 2144: 18,-44 + 2145: 18,-45 + 2146: 17,-45 + 2147: 16,-45 + 2148: 15,-45 + 2149: 14,-45 + 2150: 13,-45 + 2151: 13,-46 + 2152: 12,-46 + 2153: 11,-46 + 2154: 10,-46 + 2155: 9,-46 + 2156: 8,-46 + 2157: 8,-47 + 2158: 5,-47 + 2159: 6,-47 + 2160: 7,-47 + 2234: 5,-35 + 2259: -3,-55 + 2260: -3,-54 + 2261: -3,-53 + 2262: -3,-52 + 2263: -3,-51 + 2264: -3,-50 + 2265: -3,-49 + 2266: -4,-55 + 2267: -5,-55 + 2268: -6,-55 + 2269: -7,-55 + 2270: -8,-55 + 2271: -9,-55 + 2289: -7,-43 + 2290: -7,-42 + 2291: -7,-45 + 2292: -7,-46 + 2293: -7,-48 + 2860: 17,-40 + 2872: 17,-42 + 2873: 17,-39 + 2874: 17,-38 + 2875: 17,-37 + 2963: 14,-39 - node: color: '#DE3A3A96' id: BrickTileWhiteInnerSe decals: - 1361: 31,-9 - 1410: 54,-8 - 1411: 54,-9 - 1412: 54,-13 - 1413: 54,-14 - 1414: 54,-15 - 1415: 54,-16 - 1416: 54,-17 - 1417: 54,-18 - 1469: 42,-21 - 1470: 42,-20 - 1471: 42,-19 - 1473: 38,-18 - 1474: 37,-18 - 1482: 34,-13 - 1483: 33,-13 - 1484: 32,-13 - 1485: 30,-13 - 1498: 40,-11 - 1499: 40,-12 - 1500: 40,-13 - 1501: 40,-14 - 1513: 47,-15 - 1514: 47,-14 - 1515: 47,-13 - 1516: 47,-12 - 1517: 47,-11 - 1518: 47,-10 - 1519: 47,-9 - 1520: 48,-9 - 1521: 49,-9 - 1548: 51,-9 - 1549: 52,-9 - 1587: 39,-29 - 1597: 40,-30 - 1598: 42,-30 - 1599: 42,-29 - 1600: 42,-28 - 1601: 42,-26 - 1602: 42,-25 - 1603: 42,-24 - 1620: 28,-31 - 1623: 38,-31 - 1626: 38,-35 - 1638: 30,-35 - 1639: 31,-35 - 1640: 32,-35 - 1641: 33,-35 - 1642: 34,-35 - 1643: 35,-35 - 1644: 36,-35 - 1645: 37,-35 - 1671: 43,-36 - 1672: 43,-35 - 1673: 43,-34 - 1674: 44,-34 - 1675: 44,-33 - 1676: 44,-32 - 1689: 40,-37 - 1690: 39,-37 - 1691: 42,-37 - 1704: 39,-42 - 1705: 40,-42 - 1706: 41,-42 - 1707: 43,-42 - 1708: 43,-41 - 1709: 43,-40 - 1710: 43,-39 - 1733: 37,-40 - 2727: 54,-12 - 2844: 40,-23 - 2847: 42,-23 - 2849: 42,-22 - 2855: 39,-18 - 3456: 52,-7 - 3457: 52,-6 + 1359: 31,-9 + 1408: 54,-8 + 1409: 54,-9 + 1410: 54,-13 + 1411: 54,-14 + 1412: 54,-15 + 1413: 54,-16 + 1414: 54,-17 + 1415: 54,-18 + 1467: 42,-21 + 1468: 42,-20 + 1469: 42,-19 + 1471: 38,-18 + 1472: 37,-18 + 1480: 34,-13 + 1481: 33,-13 + 1482: 32,-13 + 1483: 30,-13 + 1496: 40,-11 + 1497: 40,-12 + 1498: 40,-13 + 1499: 40,-14 + 1511: 47,-15 + 1512: 47,-14 + 1513: 47,-13 + 1514: 47,-12 + 1515: 47,-11 + 1516: 47,-10 + 1517: 47,-9 + 1518: 48,-9 + 1519: 49,-9 + 1546: 51,-9 + 1547: 52,-9 + 1585: 39,-29 + 1595: 40,-30 + 1596: 42,-30 + 1597: 42,-29 + 1598: 42,-28 + 1599: 42,-26 + 1600: 42,-25 + 1601: 42,-24 + 1618: 28,-31 + 1621: 38,-31 + 1624: 38,-35 + 1636: 30,-35 + 1637: 31,-35 + 1638: 32,-35 + 1639: 33,-35 + 1640: 34,-35 + 1641: 35,-35 + 1642: 36,-35 + 1643: 37,-35 + 1669: 43,-36 + 1670: 43,-35 + 1671: 43,-34 + 1672: 44,-34 + 1673: 44,-33 + 1674: 44,-32 + 1687: 40,-37 + 1688: 39,-37 + 1689: 42,-37 + 1702: 39,-42 + 1703: 40,-42 + 1704: 41,-42 + 1705: 43,-42 + 1706: 43,-41 + 1707: 43,-40 + 1708: 43,-39 + 1731: 37,-40 + 2725: 54,-12 + 2842: 40,-23 + 2845: 42,-23 + 2847: 42,-22 + 2853: 39,-18 + 3454: 52,-7 + 3455: 52,-6 - node: color: '#EFB34196' id: BrickTileWhiteInnerSe decals: - 1767: 8,30 - 1768: 7,30 - 1769: 6,30 - 1770: 5,30 - 1771: 4,30 - 1772: 8,31 - 1773: 8,34 - 1774: 8,35 - 1775: 8,36 - 1776: 8,37 - 1777: 8,38 - 1814: 5,37 - 1831: 19,34 - 1858: 22,30 - 1859: 23,36 - 1860: 25,36 - 1861: 25,25 - 1869: 22,33 - 2498: 3,51 - 2501: 19,42 - 2512: 10,45 - 2526: 32,42 - 2527: 25,42 - 2529: 23,42 - 3064: 11,33 + 1765: 8,30 + 1766: 7,30 + 1767: 6,30 + 1768: 5,30 + 1769: 4,30 + 1770: 8,31 + 1771: 8,34 + 1772: 8,35 + 1773: 8,36 + 1774: 8,37 + 1775: 8,38 + 1812: 5,37 + 1829: 19,34 + 1856: 22,30 + 1857: 23,36 + 1858: 25,36 + 1859: 25,25 + 1867: 22,33 + 2496: 3,51 + 2499: 19,42 + 2510: 10,45 + 2524: 32,42 + 2525: 25,42 + 2527: 23,42 + 3062: 11,33 - node: color: '#F9801D7F' id: BrickTileWhiteInnerSe decals: - 3455: 45,-19 + 3453: 45,-19 - node: color: '#FFFFFFFF' id: BrickTileWhiteInnerSe decals: - 3487: -6,-26 + 3485: -6,-26 - node: color: '#4B709CFF' id: BrickTileWhiteInnerSw @@ -1883,227 +1883,231 @@ entities: id: BrickTileWhiteInnerSw decals: 415: -20,-29 - 733: -1,-34 + 731: -1,-34 - node: color: '#80C71F80' id: BrickTileWhiteInnerSw decals: - 3453: 53,-19 + 3451: 53,-19 - node: color: '#8932B87F' id: BrickTileWhiteInnerSw decals: - 3449: 49,-19 + 3447: 49,-19 - node: color: '#9FED58B3' id: BrickTileWhiteInnerSw decals: - 2541: -46,-30 + 2539: -46,-30 - node: color: '#A4610696' id: BrickTileWhiteInnerSw decals: - 1016: -48,-2 - 1017: -48,-2 + 1014: -48,-2 + 1015: -48,-2 - node: color: '#BC863FFF' id: BrickTileWhiteInnerSw decals: - 3293: -53,-15 - 3294: -54,-15 - 3295: -57,-15 - 3296: -58,-15 - 3297: -58,-14 - 3298: -58,-13 - 3299: -58,-12 - 3300: -58,-11 - 3301: -58,-10 - 3302: -58,-9 - 3303: -58,-8 - 3304: -58,-7 - 3305: -58,0 - 3306: -58,1 - 3307: -58,2 - 3308: -58,3 - 3348: -47,2 - 3354: -47,-2 - 3361: -50,1 + 3291: -53,-15 + 3292: -54,-15 + 3293: -57,-15 + 3294: -58,-15 + 3295: -58,-14 + 3296: -58,-13 + 3297: -58,-12 + 3298: -58,-11 + 3299: -58,-10 + 3300: -58,-9 + 3301: -58,-8 + 3302: -58,-7 + 3303: -58,0 + 3304: -58,1 + 3305: -58,2 + 3306: -58,3 + 3346: -47,2 + 3352: -47,-2 + 3359: -50,1 - node: color: '#D381C996' id: BrickTileWhiteInnerSw decals: - 2078: 5,-42 - 2079: 5,-45 - 2111: 13,-34 - 2112: 13,-35 - 2113: 13,-36 - 2114: 13,-37 - 2115: 13,-38 - 2116: 13,-40 - 2117: 13,-41 - 2163: 6,-47 - 2164: 7,-47 - 2165: 8,-47 - 2166: 9,-46 - 2169: 10,-46 - 2170: 11,-46 - 2171: 12,-46 - 2172: 13,-46 - 2174: 14,-45 - 2175: 16,-45 - 2176: 15,-45 - 2177: 17,-45 - 2178: 18,-45 - 2179: 19,-44 - 2180: 20,-44 - 2181: 21,-44 - 2233: 9,-35 - 2242: -9,-48 - 2243: -5,-46 - 2244: -9,-47 - 2245: -9,-46 - 2246: -9,-44 - 2247: -9,-43 - 2248: -9,-42 - 2249: -9,-50 - 2250: -9,-51 - 2251: -9,-52 - 2252: -9,-53 - 2254: -9,-55 - 2255: -8,-55 - 2256: -7,-55 - 2257: -6,-55 - 2258: -5,-55 - 2259: -4,-55 - 2260: -3,-55 - 2349: -1,-42 - 2966: 16,-39 + 2076: 5,-42 + 2077: 5,-45 + 2109: 13,-34 + 2110: 13,-35 + 2111: 13,-36 + 2112: 13,-37 + 2113: 13,-38 + 2114: 13,-40 + 2115: 13,-41 + 2161: 6,-47 + 2162: 7,-47 + 2163: 8,-47 + 2164: 9,-46 + 2167: 10,-46 + 2168: 11,-46 + 2169: 12,-46 + 2170: 13,-46 + 2172: 14,-45 + 2173: 16,-45 + 2174: 15,-45 + 2175: 17,-45 + 2176: 18,-45 + 2177: 19,-44 + 2178: 20,-44 + 2179: 21,-44 + 2231: 9,-35 + 2240: -9,-48 + 2241: -5,-46 + 2242: -9,-47 + 2243: -9,-46 + 2244: -9,-44 + 2245: -9,-43 + 2246: -9,-42 + 2247: -9,-50 + 2248: -9,-51 + 2249: -9,-52 + 2250: -9,-53 + 2252: -9,-55 + 2253: -8,-55 + 2254: -7,-55 + 2255: -6,-55 + 2256: -5,-55 + 2257: -4,-55 + 2258: -3,-55 + 2347: -1,-42 + 2964: 16,-39 - node: color: '#DE3A3A96' id: BrickTileWhiteInnerSw decals: - 1360: 33,-9 - 1423: 48,-7 - 1424: 48,-6 - 1425: 46,-8 - 1426: 46,-9 - 1427: 46,-10 - 1428: 46,-11 - 1429: 46,-12 - 1430: 46,-13 - 1431: 46,-14 - 1455: 30,-13 - 1456: 32,-13 - 1457: 33,-13 - 1458: 34,-13 - 1459: 36,-13 - 1460: 37,-13 - 1461: 37,-14 - 1462: 37,-15 - 1463: 37,-16 - 1464: 37,-17 - 1465: 37,-18 - 1466: 38,-18 - 1467: 39,-18 - 1468: 39,-19 - 1486: 30,-12 - 1487: 30,-11 - 1504: 51,-9 - 1505: 52,-9 - 1506: 53,-9 - 1507: 53,-10 - 1508: 53,-11 - 1509: 53,-12 - 1510: 53,-13 - 1511: 53,-14 - 1512: 53,-15 - 1546: 48,-9 - 1547: 49,-9 - 1581: 40,-24 - 1582: 39,-25 - 1583: 39,-26 - 1584: 39,-27 - 1585: 39,-28 - 1586: 39,-29 - 1588: 40,-29 - 1595: 42,-30 - 1596: 40,-30 - 1621: 30,-31 - 1627: 38,-35 - 1628: 37,-35 - 1629: 36,-35 - 1630: 35,-35 - 1631: 34,-35 - 1632: 33,-35 - 1633: 32,-35 - 1634: 31,-35 - 1635: 30,-35 - 1636: 30,-34 - 1684: 44,-34 - 1685: 43,-37 - 1686: 42,-37 - 1687: 40,-37 - 1688: 39,-37 - 1693: 40,-35 - 1694: 40,-36 - 1695: 43,-42 - 1696: 41,-42 - 1697: 40,-42 - 1698: 39,-42 - 1699: 39,-40 - 1719: 42,-41 - 1725: 39,-39 - 2843: 42,-23 - 2845: 40,-23 - 2852: 40,-20 - 2853: 40,-19 - 2854: 40,-18 + 1358: 33,-9 + 1421: 48,-7 + 1422: 48,-6 + 1423: 46,-8 + 1424: 46,-9 + 1425: 46,-10 + 1426: 46,-11 + 1427: 46,-12 + 1428: 46,-13 + 1429: 46,-14 + 1453: 30,-13 + 1454: 32,-13 + 1455: 33,-13 + 1456: 34,-13 + 1457: 36,-13 + 1458: 37,-13 + 1459: 37,-14 + 1460: 37,-15 + 1461: 37,-16 + 1462: 37,-17 + 1463: 37,-18 + 1464: 38,-18 + 1465: 39,-18 + 1466: 39,-19 + 1484: 30,-12 + 1485: 30,-11 + 1502: 51,-9 + 1503: 52,-9 + 1504: 53,-9 + 1505: 53,-10 + 1506: 53,-11 + 1507: 53,-12 + 1508: 53,-13 + 1509: 53,-14 + 1510: 53,-15 + 1544: 48,-9 + 1545: 49,-9 + 1579: 40,-24 + 1580: 39,-25 + 1581: 39,-26 + 1582: 39,-27 + 1583: 39,-28 + 1584: 39,-29 + 1586: 40,-29 + 1593: 42,-30 + 1594: 40,-30 + 1619: 30,-31 + 1625: 38,-35 + 1626: 37,-35 + 1627: 36,-35 + 1628: 35,-35 + 1629: 34,-35 + 1630: 33,-35 + 1631: 32,-35 + 1632: 31,-35 + 1633: 30,-35 + 1634: 30,-34 + 1682: 44,-34 + 1683: 43,-37 + 1684: 42,-37 + 1685: 40,-37 + 1686: 39,-37 + 1691: 40,-35 + 1692: 40,-36 + 1693: 43,-42 + 1694: 41,-42 + 1695: 40,-42 + 1696: 39,-42 + 1697: 39,-40 + 1717: 42,-41 + 1723: 39,-39 + 2841: 42,-23 + 2843: 40,-23 + 2850: 40,-20 + 2851: 40,-19 + 2852: 40,-18 - node: color: '#EFB34196' id: BrickTileWhiteInnerSw decals: - 1790: 4,37 - 1791: 4,34 - 1792: 4,30 - 1793: 5,30 - 1794: 6,30 - 1795: 7,30 - 1796: 8,30 - 1797: 4,31 - 1798: 4,38 - 1813: 7,37 - 1821: 10,34 - 1830: 21,34 - 1862: 25,30 - 1863: 25,36 - 1864: 27,36 - 1865: 27,42 - 1868: 28,33 - 1883: 35,42 - 2499: 5,51 - 2503: 20,42 - 2528: 25,42 - 3065: 18,33 - 3134: 17,45 + 1788: 4,37 + 1789: 4,34 + 1790: 4,30 + 1791: 5,30 + 1792: 6,30 + 1793: 7,30 + 1794: 8,30 + 1795: 4,31 + 1796: 4,38 + 1811: 7,37 + 1819: 10,34 + 1828: 21,34 + 1860: 25,30 + 1861: 25,36 + 1862: 27,36 + 1863: 27,42 + 1866: 28,33 + 1881: 35,42 + 2497: 5,51 + 2501: 20,42 + 2526: 25,42 + 3063: 18,33 + 3132: 17,45 - node: color: '#F9801D7F' id: BrickTileWhiteInnerSw decals: - 3454: 45,-19 + 3452: 45,-19 - node: color: '#00BEBE7F' id: BrickTileWhiteLineE decals: - 3157: -27,40 - 3158: -27,41 - 3159: -27,42 + 3155: -27,40 + 3156: -27,41 + 3157: -27,42 - node: color: '#334E6DC8' id: BrickTileWhiteLineE decals: - 1354: 33,-5 - 1355: 33,-7 - 1356: 33,-6 + 1352: 33,-5 + 1353: 33,-7 + 1354: 33,-6 + 3594: 26,13 + 3595: 26,14 + 3608: 33,13 + 3609: 33,14 - node: color: '#4B709CFF' id: BrickTileWhiteLineE @@ -2124,153 +2128,159 @@ entities: 507: -29,-29 508: -29,-28 509: -29,-27 - 562: -24,-40 - 563: -24,-41 - 2372: 34,-39 - 2373: 34,-40 - 2374: 34,-41 - 2386: 28,-36 + 560: -24,-40 + 561: -24,-41 + 2370: 34,-39 + 2371: 34,-40 + 2372: 34,-41 + 2384: 28,-36 - node: color: '#765428FF' id: BrickTileWhiteLineE decals: - 3319: -53,-18 - 3320: -53,-19 - 3321: -53,-20 - 3322: -53,-21 - 3323: -53,-22 - 3324: -53,-23 + 3317: -53,-18 + 3318: -53,-19 + 3319: -53,-20 + 3320: -53,-21 + 3321: -53,-22 + 3322: -53,-23 - node: color: '#9FED58B3' id: BrickTileWhiteLineE decals: - 2543: -45,-31 - 2544: -45,-30 + 2541: -45,-31 + 2542: -45,-30 - node: color: '#BC863FFF' id: BrickTileWhiteLineE decals: - 3216: -53,-14 - 3217: -53,-1 - 3218: -53,0 - 3224: -49,2 - 3225: -49,1 - 3226: -49,0 - 3227: -49,-1 - 3228: -49,-2 - 3229: -49,-4 - 3356: -49,-3 + 3214: -53,-14 + 3215: -53,-1 + 3216: -53,0 + 3222: -49,2 + 3223: -49,1 + 3224: -49,0 + 3225: -49,-1 + 3226: -49,-2 + 3227: -49,-4 + 3354: -49,-3 - node: color: '#D381C996' id: BrickTileWhiteLineE decals: - 843: -11,-50 - 844: -11,-49 - 845: -11,-48 - 2070: 3,-43 - 2071: 3,-44 - 2072: 3,-46 - 2073: 3,-47 - 2127: 17,-41 - 2128: 21,-43 - 2129: 11,-39 - 2197: 12,-44 - 2198: 16,-43 - 2199: 16,-42 - 2200: 16,-41 - 2201: 16,-40 - 2202: 16,-39 - 2203: 16,-38 - 2204: 16,-37 - 2205: 16,-36 - 2227: 5,-38 - 2228: 5,-37 - 2229: 5,-36 - 2237: -7,-47 - 2239: -7,-44 - 2299: -11,-45 - 2343: -3,-47 - 2344: -3,-46 - 2959: 14,-41 - 2960: 14,-40 + 841: -11,-50 + 842: -11,-49 + 843: -11,-48 + 2068: 3,-43 + 2069: 3,-44 + 2070: 3,-46 + 2071: 3,-47 + 2125: 17,-41 + 2126: 21,-43 + 2127: 11,-39 + 2195: 12,-44 + 2196: 16,-43 + 2197: 16,-42 + 2198: 16,-41 + 2199: 16,-40 + 2200: 16,-39 + 2201: 16,-38 + 2202: 16,-37 + 2203: 16,-36 + 2225: 5,-38 + 2226: 5,-37 + 2227: 5,-36 + 2235: -7,-47 + 2237: -7,-44 + 2297: -11,-45 + 2341: -3,-47 + 2342: -3,-46 + 2957: 14,-41 + 2958: 14,-40 - node: color: '#DE3A3A96' id: BrickTileWhiteLineE decals: - 1604: 42,-27 - 1605: 43,-37 - 1608: 37,-41 - 1609: 38,-34 - 1610: 38,-33 - 1611: 38,-32 - 1617: 27,-27 - 1618: 28,-32 - 1619: 28,-33 + 1602: 42,-27 + 1603: 43,-37 + 1606: 37,-41 + 1607: 38,-34 + 1608: 38,-33 + 1609: 38,-32 + 1615: 27,-27 + 1616: 28,-32 + 1617: 28,-33 - node: color: '#EFB34196' id: BrickTileWhiteLineE decals: - 1755: 8,32 - 1756: 8,33 - 1799: 5,32 - 1800: 5,33 - 1801: 5,34 - 1802: 5,35 - 1803: 5,36 - 1817: 17,30 - 1826: 19,32 - 1827: 19,33 - 1880: 22,32 - 2509: 10,44 - 2510: 10,43 - 2511: 10,42 - 2515: 19,44 - 2516: 19,45 - 2517: 20,42 - 2518: 20,43 - 3053: 11,32 - 3080: 17,34 - 3105: -2,41 - 3106: -2,42 - 3120: 10,41 - 3125: 19,40 - 3126: 19,41 + 1753: 8,32 + 1754: 8,33 + 1797: 5,32 + 1798: 5,33 + 1799: 5,34 + 1800: 5,35 + 1801: 5,36 + 1815: 17,30 + 1824: 19,32 + 1825: 19,33 + 1878: 22,32 + 2507: 10,44 + 2508: 10,43 + 2509: 10,42 + 2513: 19,44 + 2514: 19,45 + 2515: 20,42 + 2516: 20,43 + 3051: 11,32 + 3078: 17,34 + 3103: -2,41 + 3104: -2,42 + 3118: 10,41 + 3123: 19,40 + 3124: 19,41 - node: color: '#FFFFFFFF' id: BrickTileWhiteLineE decals: - 577: -30,-28 - 3489: -6,-28 - 3490: -6,-27 + 575: -30,-28 + 3487: -6,-28 + 3488: -6,-27 - node: color: '#00BEBE7F' id: BrickTileWhiteLineN decals: - 3160: -28,43 - 3161: -29,43 - 3162: -30,43 - 3163: -31,43 - 3164: -32,43 - 3165: -33,43 - 3191: -43,1 - 3192: -42,1 - 3193: -41,1 - 3194: -40,1 - 3195: -39,1 - 3196: -38,1 - 3197: -37,1 - 3198: -36,1 - 3202: -43,5 - 3203: -41,4 - 3204: -40,4 - 3205: -39,4 - 3206: -38,4 - 3207: -37,4 + 3158: -28,43 + 3159: -29,43 + 3160: -30,43 + 3161: -31,43 + 3162: -32,43 + 3163: -33,43 + 3189: -43,1 + 3190: -42,1 + 3191: -41,1 + 3192: -40,1 + 3193: -39,1 + 3194: -38,1 + 3195: -37,1 + 3196: -36,1 + 3200: -43,5 + 3201: -41,4 + 3202: -40,4 + 3203: -39,4 + 3204: -38,4 + 3205: -37,4 - node: color: '#169C9CFF' id: BrickTileWhiteLineN decals: 402: -16,-30 + - node: + color: '#334E6DC8' + id: BrickTileWhiteLineN + decals: + 3610: 30,16 + 3611: 31,16 - node: color: '#4B709CFF' id: BrickTileWhiteLineN @@ -2298,111 +2308,111 @@ entities: 510: -30,-26 511: -31,-26 512: -32,-26 - 559: -27,-39 - 560: -26,-39 - 561: -25,-39 - 2362: 29,-37 - 2363: 30,-37 - 2364: 31,-37 - 2365: 32,-37 - 2366: 33,-37 - 2367: 34,-37 - 2368: 35,-37 - 2369: 36,-37 + 557: -27,-39 + 558: -26,-39 + 559: -25,-39 + 2360: 29,-37 + 2361: 30,-37 + 2362: 31,-37 + 2363: 32,-37 + 2364: 33,-37 + 2365: 34,-37 + 2366: 35,-37 + 2367: 36,-37 - node: color: '#765428FF' id: BrickTileWhiteLineN decals: - 3313: -55,-17 - 3314: -56,-17 - 3315: -57,-17 - 3316: -54,-17 + 3311: -55,-17 + 3312: -56,-17 + 3313: -57,-17 + 3314: -54,-17 - node: color: '#9FED58B3' id: BrickTileWhiteLineN decals: - 2531: -47,-31 - 2537: -47,-30 + 2529: -47,-31 + 2535: -47,-30 - node: color: '#BC863FFF' id: BrickTileWhiteLineN decals: - 3213: -54,3 - 3223: -50,3 + 3211: -54,3 + 3221: -50,3 - node: color: '#D381C996' id: BrickTileWhiteLineN decals: - 834: -13,-47 - 835: -12,-47 - 2130: 16,-34 - 2131: 9,-34 - 2132: 5,-34 - 2191: 7,-43 - 2192: 8,-43 - 2193: 9,-43 - 2194: 10,-43 - 2195: 11,-43 - 2196: 15,-35 - 2224: 6,-39 - 2225: 7,-39 - 2226: 8,-39 + 832: -13,-47 + 833: -12,-47 + 2128: 16,-34 + 2129: 9,-34 + 2130: 5,-34 + 2189: 7,-43 + 2190: 8,-43 + 2191: 9,-43 + 2192: 10,-43 + 2193: 11,-43 + 2194: 15,-35 + 2222: 6,-39 + 2223: 7,-39 + 2224: 8,-39 - node: color: '#D4D4D428' id: BrickTileWhiteLineN decals: - 1362: 31,-3 - 1363: 32,-3 + 1360: 31,-3 + 1361: 32,-3 - node: color: '#DE3A3A96' id: BrickTileWhiteLineN decals: - 1432: 49,-6 - 1433: 51,-6 - 1490: 32,-11 - 1496: 38,-11 - 1497: 40,-11 - 1523: 50,-16 - 1554: 50,-3 - 1568: 41,-32 - 1717: 41,-41 - 1720: 41,-39 - 1731: 41,-40 - 2840: 41,-25 + 1430: 49,-6 + 1431: 51,-6 + 1488: 32,-11 + 1494: 38,-11 + 1495: 40,-11 + 1521: 50,-16 + 1552: 50,-3 + 1566: 41,-32 + 1715: 41,-41 + 1718: 41,-39 + 1729: 41,-40 + 2838: 41,-25 - node: color: '#EFB34196' id: BrickTileWhiteLineN decals: - 1754: 7,38 - 1804: 6,31 - 1834: 23,28 - 1835: 24,28 - 1842: 24,40 - 1843: 26,40 - 1844: 24,34 - 1845: 26,34 - 1846: 26,23 - 1870: 23,31 - 1871: 24,31 - 1872: 25,31 - 1873: 26,31 - 1874: 27,31 - 3041: 17,31 - 3042: 16,31 - 3043: 15,31 - 3044: 14,31 - 3045: 13,31 - 3046: 12,31 - 3056: 12,33 - 3057: 13,33 - 3058: 14,33 - 3059: 15,33 - 3060: 16,33 - 3061: 17,33 - 3115: -6,43 - 3116: -5,43 - 3117: -4,43 - 3118: -3,43 + 1752: 7,38 + 1802: 6,31 + 1832: 23,28 + 1833: 24,28 + 1840: 24,40 + 1841: 26,40 + 1842: 24,34 + 1843: 26,34 + 1844: 26,23 + 1868: 23,31 + 1869: 24,31 + 1870: 25,31 + 1871: 26,31 + 1872: 27,31 + 3039: 17,31 + 3040: 16,31 + 3041: 15,31 + 3042: 14,31 + 3043: 13,31 + 3044: 12,31 + 3054: 12,33 + 3055: 13,33 + 3056: 14,33 + 3057: 15,33 + 3058: 16,33 + 3059: 17,33 + 3113: -6,43 + 3114: -5,43 + 3115: -4,43 + 3116: -3,43 - node: color: '#F38BAAFF' id: BrickTileWhiteLineN @@ -2412,27 +2422,27 @@ entities: color: '#FFFFFFFF' id: BrickTileWhiteLineN decals: - 576: -31,-27 - 3481: -5,-29 - 3482: -4,-29 - 3483: -3,-29 + 574: -31,-27 + 3479: -5,-29 + 3480: -4,-29 + 3481: -3,-29 - node: color: '#00BEBE7F' id: BrickTileWhiteLineS decals: - 3151: -33,39 - 3152: -32,39 - 3153: -31,39 - 3154: -30,39 - 3155: -29,39 - 3156: -28,39 - 3184: -37,3 - 3185: -38,3 - 3186: -39,3 - 3187: -40,3 - 3188: -41,3 - 3189: -42,3 - 3190: -43,3 + 3149: -33,39 + 3150: -32,39 + 3151: -31,39 + 3152: -30,39 + 3153: -29,39 + 3154: -28,39 + 3182: -37,3 + 3183: -38,3 + 3184: -39,3 + 3185: -40,3 + 3186: -41,3 + 3187: -42,3 + 3188: -43,3 - node: color: '#169C9CFF' id: BrickTileWhiteLineS @@ -2469,120 +2479,119 @@ entities: 496: -26,-30 516: -32,-30 517: -31,-30 - 518: -30,-30 - 519: -30,-30 - 564: -25,-42 - 565: -26,-42 - 566: -27,-42 - 2370: 36,-38 - 2371: 35,-38 - 2375: 33,-42 - 2376: 32,-42 - 2377: 31,-42 - 2378: 30,-42 - 2379: 29,-42 - 2380: 28,-42 + 562: -25,-42 + 563: -26,-42 + 564: -27,-42 + 2368: 36,-38 + 2369: 35,-38 + 2373: 33,-42 + 2374: 32,-42 + 2375: 31,-42 + 2376: 30,-42 + 2377: 29,-42 + 2378: 28,-42 + 3624: -30,-30 - node: color: '#765428FF' id: BrickTileWhiteLineS decals: - 3325: -54,-24 - 3326: -55,-24 - 3327: -56,-24 - 3328: -57,-24 + 3323: -54,-24 + 3324: -55,-24 + 3325: -56,-24 + 3326: -57,-24 - node: color: '#80C71F7F' id: BrickTileWhiteLineS decals: - 3438: 54,-19 - 3439: 52,-19 - 3440: 51,-19 + 3436: 54,-19 + 3437: 52,-19 + 3438: 51,-19 - node: color: '#8932B87F' id: BrickTileWhiteLineS decals: - 3441: 50,-19 - 3442: 48,-19 - 3443: 47,-19 + 3439: 50,-19 + 3440: 48,-19 + 3441: 47,-19 - node: color: '#9FED58B3' id: BrickTileWhiteLineS decals: - 2536: -47,-30 - 2538: -47,-31 + 2534: -47,-30 + 2536: -47,-31 - node: color: '#BC863FFF' id: BrickTileWhiteLineS decals: - 3214: -56,-15 - 3215: -55,-15 - 3232: -50,-5 + 3212: -56,-15 + 3213: -55,-15 + 3230: -50,-5 - node: color: '#D381C996' id: BrickTileWhiteLineS decals: - 846: -12,-51 - 847: -13,-51 - 2215: 7,-45 - 2216: 8,-45 - 2217: 9,-45 - 2218: 10,-45 - 2219: 11,-45 - 2220: 15,-44 - 2221: 6,-35 - 2222: 7,-35 - 2223: 8,-35 + 844: -12,-51 + 845: -13,-51 + 2213: 7,-45 + 2214: 8,-45 + 2215: 9,-45 + 2216: 10,-45 + 2217: 11,-45 + 2218: 15,-44 + 2219: 6,-35 + 2220: 7,-35 + 2221: 8,-35 - node: color: '#DE3A3A96' id: BrickTileWhiteLineS decals: - 1359: 32,-9 - 1480: 35,-13 - 1481: 31,-13 - 1522: 50,-9 - 1555: 50,-4 - 1569: 41,-30 - 1606: 41,-37 - 1718: 41,-41 - 2839: 41,-23 + 1357: 32,-9 + 1478: 35,-13 + 1479: 31,-13 + 1520: 50,-9 + 1553: 50,-4 + 1567: 41,-30 + 1604: 41,-37 + 1716: 41,-41 + 2837: 41,-23 - node: color: '#EFB34196' id: BrickTileWhiteLineS decals: - 1810: 6,37 - 1836: 23,30 - 1837: 24,30 - 1838: 26,25 - 1839: 26,36 - 1840: 24,36 - 1841: 26,42 - 1875: 23,33 - 1876: 24,33 - 1877: 25,33 - 1878: 26,33 - 1879: 27,33 - 1882: 34,42 - 2504: 15,45 - 2505: 14,45 - 2506: 13,45 - 2507: 12,45 - 2508: 11,45 - 2525: 33,42 - 2530: 24,42 - 3047: 12,33 - 3048: 13,33 - 3049: 14,33 - 3050: 15,33 - 3051: 16,33 - 3052: 17,33 - 3107: -3,40 - 3108: -4,40 - 3109: -5,40 - 3113: -6,40 - 3121: 9,40 - 3122: 8,40 - 3127: 18,39 - 3133: 16,45 + 1808: 6,37 + 1834: 23,30 + 1835: 24,30 + 1836: 26,25 + 1837: 26,36 + 1838: 24,36 + 1839: 26,42 + 1873: 23,33 + 1874: 24,33 + 1875: 25,33 + 1876: 26,33 + 1877: 27,33 + 1880: 34,42 + 2502: 15,45 + 2503: 14,45 + 2504: 13,45 + 2505: 12,45 + 2506: 11,45 + 2523: 33,42 + 2528: 24,42 + 3045: 12,33 + 3046: 13,33 + 3047: 14,33 + 3048: 15,33 + 3049: 16,33 + 3050: 17,33 + 3105: -3,40 + 3106: -4,40 + 3107: -5,40 + 3111: -6,40 + 3119: 9,40 + 3120: 8,40 + 3125: 18,39 + 3131: 16,45 - node: color: '#F38BAAFF' id: BrickTileWhiteLineS @@ -2592,34 +2601,36 @@ entities: color: '#F9801D7F' id: BrickTileWhiteLineS decals: - 3444: 46,-19 - 3445: 44,-19 - 3446: 43,-19 + 3442: 46,-19 + 3443: 44,-19 + 3444: 43,-19 - node: color: '#FFFFFFFF' id: BrickTileWhiteLineS decals: - 578: -31,-29 - 3484: -5,-26 - 3485: -4,-26 - 3486: -3,-26 + 576: -31,-29 + 3482: -5,-26 + 3483: -4,-26 + 3484: -3,-26 - node: color: '#00BEBE7F' id: BrickTileWhiteLineW decals: - 3166: -34,42 - 3167: -34,41 - 3168: -34,40 - 3201: -44,4 + 3164: -34,42 + 3165: -34,41 + 3166: -34,40 + 3199: -44,4 - node: color: '#334E6DC8' id: BrickTileWhiteLineW decals: - 601: 21,6 - 602: 21,7 - 605: 20,6 - 606: 20,7 - 3212: -44,-10 + 599: 21,6 + 600: 21,7 + 603: 20,6 + 604: 20,7 + 3210: -44,-10 + 3596: 28,13 + 3597: 28,14 - node: color: '#4B709CFF' id: BrickTileWhiteLineW @@ -2640,517 +2651,517 @@ entities: 513: -33,-29 514: -33,-28 515: -33,-27 - 567: -28,-41 - 568: -28,-40 - 725: -2,-33 - 728: -2,-40 - 729: -1,-35 - 730: -1,-36 - 731: -1,-37 - 732: -1,-38 - 2354: 27,-41 - 2355: 27,-40 - 2356: 27,-39 - 2357: 27,-38 - 2358: 27,-37 - 2359: 27,-36 + 565: -28,-41 + 566: -28,-40 + 723: -2,-33 + 726: -2,-40 + 727: -1,-35 + 728: -1,-36 + 729: -1,-37 + 730: -1,-38 + 2352: 27,-41 + 2353: 27,-40 + 2354: 27,-39 + 2355: 27,-38 + 2356: 27,-37 + 2357: 27,-36 - node: color: '#765428FF' id: BrickTileWhiteLineW decals: - 3329: -58,-23 - 3330: -58,-22 - 3331: -58,-21 + 3327: -58,-23 + 3328: -58,-22 + 3329: -58,-21 - node: color: '#9FED58B3' id: BrickTileWhiteLineW decals: - 2545: -45,-31 - 2546: -45,-30 + 2543: -45,-31 + 2544: -45,-30 - node: color: '#BC863FFF' id: BrickTileWhiteLineW decals: - 3219: -51,-4 - 3220: -51,-3 - 3233: -47,-4 - 3234: -47,-3 - 3346: -47,0 - 3347: -47,1 - 3352: -47,-1 - 3355: -51,2 - 3359: -50,-1 - 3360: -50,0 + 3217: -51,-4 + 3218: -51,-3 + 3231: -47,-4 + 3232: -47,-3 + 3344: -47,0 + 3345: -47,1 + 3350: -47,-1 + 3353: -51,2 + 3357: -50,-1 + 3358: -50,0 - node: color: '#D381C996' id: BrickTileWhiteLineW decals: - 840: -14,-50 - 841: -14,-49 - 842: -14,-48 - 2081: 5,-43 - 2082: 5,-44 - 2083: 5,-46 - 2084: 5,-47 - 2126: 13,-39 - 2206: 6,-44 - 2207: 14,-43 - 2208: 14,-42 - 2209: 14,-41 - 2210: 14,-39 - 2211: 14,-40 - 2212: 14,-38 - 2213: 14,-37 - 2214: 14,-36 - 2230: 9,-38 - 2231: 9,-37 - 2232: 9,-36 - 2238: -5,-47 - 2241: -9,-49 - 2253: -9,-54 - 2298: -9,-45 - 2345: -1,-46 - 2346: -1,-45 - 2347: -1,-44 - 2348: -1,-43 - 2352: -1,-47 - 2961: 16,-41 - 2962: 16,-40 + 838: -14,-50 + 839: -14,-49 + 840: -14,-48 + 2079: 5,-43 + 2080: 5,-44 + 2081: 5,-46 + 2082: 5,-47 + 2124: 13,-39 + 2204: 6,-44 + 2205: 14,-43 + 2206: 14,-42 + 2207: 14,-41 + 2208: 14,-39 + 2209: 14,-40 + 2210: 14,-38 + 2211: 14,-37 + 2212: 14,-36 + 2228: 9,-38 + 2229: 9,-37 + 2230: 9,-36 + 2236: -5,-47 + 2239: -9,-49 + 2251: -9,-54 + 2296: -9,-45 + 2343: -1,-46 + 2344: -1,-45 + 2345: -1,-44 + 2346: -1,-43 + 2350: -1,-47 + 2959: 16,-41 + 2960: 16,-40 - node: color: '#DE3A3A96' id: BrickTileWhiteLineW decals: - 1607: 39,-41 - 1612: 40,-34 - 1613: 40,-33 - 1614: 40,-32 - 1615: 30,-33 - 1616: 30,-32 - 2858: 40,-22 - 2859: 40,-21 + 1605: 39,-41 + 1610: 40,-34 + 1611: 40,-33 + 1612: 40,-32 + 1613: 30,-33 + 1614: 30,-32 + 2856: 40,-22 + 2857: 40,-21 - node: color: '#EFB34196' id: BrickTileWhiteLineW decals: - 1786: 4,32 - 1787: 4,33 - 1788: 4,35 - 1789: 4,36 - 1805: 7,32 - 1806: 7,33 - 1807: 7,34 - 1808: 7,35 - 1809: 7,36 - 1818: 12,30 - 1819: 10,33 - 1820: 10,32 - 1828: 21,32 - 1829: 21,33 - 1881: 28,32 - 3054: 18,32 - 3055: 12,34 - 3110: -7,41 - 3111: -7,42 - 3128: 17,40 - 3129: 17,41 - 3130: 17,42 - 3131: 17,43 - 3132: 17,44 + 1784: 4,32 + 1785: 4,33 + 1786: 4,35 + 1787: 4,36 + 1803: 7,32 + 1804: 7,33 + 1805: 7,34 + 1806: 7,35 + 1807: 7,36 + 1816: 12,30 + 1817: 10,33 + 1818: 10,32 + 1826: 21,32 + 1827: 21,33 + 1879: 28,32 + 3052: 18,32 + 3053: 12,34 + 3108: -7,41 + 3109: -7,42 + 3126: 17,40 + 3127: 17,41 + 3128: 17,42 + 3129: 17,43 + 3130: 17,44 - node: color: '#FFFFFFFF' id: BrickTileWhiteLineW decals: - 579: -32,-28 - 580: -32,-28 + 577: -32,-28 + 578: -32,-28 - node: color: '#FFFFFFFF' id: BushAOne decals: - 2647: -12.173578,-13.16537 + 2645: -12.173578,-13.16537 - node: color: '#FFFFFFFF' id: BushAThree decals: - 2604: 7.063609,-17.083809 - 2648: -12.954828,-13.13412 - 2980: -13.009358,7.995878 - 2985: -15.09027,11.031727 + 2602: 7.063609,-17.083809 + 2646: -12.954828,-13.13412 + 2978: -13.009358,7.995878 + 2983: -15.09027,11.031727 - node: color: '#FFFFFFFF' id: BushATwo decals: - 2649: -12.996495,-12.238287 - 2650: -6.0969057,-13.717453 + 2647: -12.996495,-12.238287 + 2648: -6.0969057,-13.717453 - node: color: '#FFFFFFFF' id: BushCOne decals: - 2973: -11.007082,13.412277 + 2971: -11.007082,13.412277 - node: color: '#FFFFFFFF' id: BushCThree decals: - 2598: 17.014423,-8.300894 - 2634: -4.785802,3.4705331 + 2596: 17.014423,-8.300894 + 2632: -4.785802,3.4705331 - node: color: '#FFFFFFFF' id: BushCTwo decals: - 2653: -5.148989,-12.144537 + 2651: -5.148989,-12.144537 - node: color: '#FFFFFFFF' id: BushDTwo decals: - 2590: 17.163681,15.561111 - 2591: 3.516313,17.119299 + 2588: 17.163681,15.561111 + 2589: 3.516313,17.119299 - node: color: '#FFFFFFFF' id: Busha1 decals: - 2592: 4.90173,16.900549 - 2977: -13.092692,9.881294 + 2590: 4.90173,16.900549 + 2975: -13.092692,9.881294 - node: color: '#FFFFFFFF' id: Busha2 decals: - 2982: -13.96527,9.885894 - 2984: -14.642353,10.979644 + 2980: -13.96527,9.885894 + 2982: -14.642353,10.979644 - node: color: '#FFFFFFFF' id: Bushb1 decals: - 2974: -10.975832,14.18311 - 2978: -13.092692,9.006294 + 2972: -10.975832,14.18311 + 2976: -13.092692,9.006294 - node: color: '#FFFFFFFF' id: Bushb2 decals: - 2646: -12.183994,-14.061203 - 2975: -10.996666,15.02686 + 2644: -12.183994,-14.061203 + 2973: -10.996666,15.02686 - node: color: '#FFFFFFFF' id: Bushb3 decals: - 2979: -13.009358,8.402128 - 2983: -14.017353,10.354644 + 2977: -13.009358,8.402128 + 2981: -14.017353,10.354644 - node: color: '#FFFFFFFF' id: Bushc1 decals: - 2651: -5.1698227,-12.957037 - 2981: -14.02777,11.062977 + 2649: -5.1698227,-12.957037 + 2979: -14.02777,11.062977 - node: color: '#FFFFFFFF' id: Bushc3 decals: - 2589: 17.194931,12.9986105 - 2652: -8.055239,-11.332037 - 2976: -11.044625,12.930744 + 2587: 17.194931,12.9986105 + 2650: -8.055239,-11.332037 + 2974: -11.044625,12.930744 - node: color: '#FFFFFFFF' id: Bushe1 decals: - 2580: 6.2998166,3.7755318 - 2595: 17.076923,-7.467561 - 2596: 16.566507,-7.988394 - 2602: 7.2406926,-16.500475 - 2617: 3.5204434,-9.447139 - 2618: 3.2912767,-9.686723 - 2654: -8.044823,-11.092453 + 2578: 6.2998166,3.7755318 + 2593: 17.076923,-7.467561 + 2594: 16.566507,-7.988394 + 2600: 7.2406926,-16.500475 + 2615: 3.5204434,-9.447139 + 2616: 3.2912767,-9.686723 + 2652: -8.044823,-11.092453 - node: color: '#FFFFFFFF' id: Bushe2 decals: - 2581: 6.6984973,3.4174294 - 2597: 17.014423,-8.030061 - 2611: 7.441076,6.766222 - 2971: -17.569584,14.99561 - 2994: -4.0134697,4.9046235 - 3476: 63.771957,-1.9947927 - 3480: 64.23029,-2.0052094 + 2579: 6.6984973,3.4174294 + 2595: 17.014423,-8.030061 + 2609: 7.441076,6.766222 + 2969: -17.569584,14.99561 + 2992: -4.0134697,4.9046235 + 3474: 63.771957,-1.9947927 + 3478: 64.23029,-2.0052094 - node: color: '#FFFFFFFF' id: Bushe3 decals: - 2603: 6.6990256,-16.510893 - 3375: 58.245747,-2.973395 - 3376: 57.818665,-3.0463119 - 3377: 58.308247,-2.1817284 - 3475: 64.15737,-0.19270933 + 2601: 6.6990256,-16.510893 + 3373: 58.245747,-2.973395 + 3374: 57.818665,-3.0463119 + 3375: 58.308247,-2.1817284 + 3473: 64.15737,-0.19270933 - node: color: '#FFFFFFFF' id: Bushe4 decals: - 1304: 57.84424,1.1426643 - 1305: 58.21924,0.9864143 - 1306: 57.885906,-2.0552526 - 1307: 58.15674,-1.5865024 - 1308: 57.90674,0.18433094 - 2628: 6.6556993,14.650438 - 2635: -4.7441354,3.6892834 - 2660: -12.329075,-5.2076516 - 2661: -11.683241,-5.540985 - 2995: -4.2530527,4.29004 - 3474: 63.792793,0.09895742 + 1302: 57.84424,1.1426643 + 1303: 58.21924,0.9864143 + 1304: 57.885906,-2.0552526 + 1305: 58.15674,-1.5865024 + 1306: 57.90674,0.18433094 + 2626: 6.6556993,14.650438 + 2633: -4.7441354,3.6892834 + 2658: -12.329075,-5.2076516 + 2659: -11.683241,-5.540985 + 2993: -4.2530527,4.29004 + 3472: 63.792793,0.09895742 - node: color: '#FFFFFFFF' id: Bushf1 decals: - 1311: 58.167156,-0.24275243 - 3008: -4.922404,-3.8768375 + 1309: 58.167156,-0.24275243 + 3006: -4.922404,-3.8768375 - node: color: '#FFFFFFFF' id: Bushf2 decals: - 1312: 57.833824,-0.37816906 - 3010: -4.4328203,-4.7726707 - 3011: -4.3255215,-5.3247385 + 1310: 57.833824,-0.37816906 + 3008: -4.4328203,-4.7726707 + 3009: -4.3255215,-5.3247385 - node: color: '#FFFFFFFF' id: Bushf3 decals: - 2970: -17.132084,16.266443 - 3009: -4.3703203,-4.199754 - 3374: 57.943665,-2.723395 + 2968: -17.132084,16.266443 + 3007: -4.3703203,-4.199754 + 3372: 57.943665,-2.723395 - node: color: '#FFFFFFFF' id: Bushg1 decals: - 2599: 17.14984,-5.092561 - 2605: 8.53236,-17.187975 - 2639: 3.404969,-4.7533755 - 2986: -9.359586,2.9312673 + 2597: 17.14984,-5.092561 + 2603: 8.53236,-17.187975 + 2637: 3.404969,-4.7533755 + 2984: -9.359586,2.9312673 - node: color: '#FFFFFFFF' id: Bushg2 decals: - 2640: 4.175802,-4.0346255 - 2972: -16.8925,15.828943 + 2638: 4.175802,-4.0346255 + 2970: -16.8925,15.828943 - node: color: '#FFFFFFFF' id: Bushg3 decals: - 2559: -2.1416075,5.8916445 - 2560: -2.162441,14.072103 - 2561: 17.866562,15.155413 - 2562: 18.231146,11.999163 - 2563: 3.059716,-17.07088 - 2564: -4.1298733,-14.029394 - 2565: -2.3702574,-5.9809127 - 2566: -8.961391,-10.053829 - 2567: -17.146135,-6.1901164 + 2557: -2.1416075,5.8916445 + 2558: -2.162441,14.072103 + 2559: 17.866562,15.155413 + 2560: 18.231146,11.999163 + 2561: 3.059716,-17.07088 + 2562: -4.1298733,-14.029394 + 2563: -2.3702574,-5.9809127 + 2564: -8.961391,-10.053829 + 2565: -17.146135,-6.1901164 - node: color: '#FFFFFFFF' id: Bushg4 decals: - 2600: 17.160257,-5.6342273 - 2629: 7.2077823,13.712938 + 2598: 17.160257,-5.6342273 + 2627: 7.2077823,13.712938 - node: color: '#FFFFFFFF' id: Bushh1 decals: - 2577: 5.9211392,3.1419072 - 2582: 8.507914,15.796663 - 2583: 9.528748,15.46333 - 2993: -3.4732609,5.2424126 + 2575: 5.9211392,3.1419072 + 2580: 8.507914,15.796663 + 2581: 9.528748,15.46333 + 2991: -3.4732609,5.2424126 - node: color: '#FFFFFFFF' id: Bushh2 decals: - 2578: 5.087806,3.9127407 - 2584: 8.528747,14.473747 - 2662: -13.162408,-5.0826516 - 2663: -14.037408,-5.988902 + 2576: 5.087806,3.9127407 + 2582: 8.528747,14.473747 + 2660: -13.162408,-5.0826516 + 2661: -14.037408,-5.988902 - node: color: '#FFFFFFFF' id: Bushh3 decals: - 2579: 7.181556,4.0273237 - 2588: 17.465765,12.071527 - 2664: -13.756159,-5.822237 - 2665: -13.901991,-8.228487 - 2990: -9.230458,4.9216795 + 2577: 7.181556,4.0273237 + 2586: 17.465765,12.071527 + 2662: -13.756159,-5.822237 + 2663: -13.901991,-8.228487 + 2988: -9.230458,4.9216795 - node: color: '#FFFFFFFF' id: Bushi1 decals: - 2568: -17.677385,-15.149096 - 2569: -6.0205603,-17.117607 - 2570: -9.970078,-14.052947 - 2571: -9.887934,2.4137444 - 2572: -18.05108,15.0529785 - 2601: 6.2927756,-17.073393 - 2612: 15.850491,-4.61609 - 2614: 9.772904,-4.483665 - 2626: 13.70388,8.66825 - 2627: 7.1036158,14.358771 - 2630: -5.465275,9.849015 - 2631: -6.746525,10.213598 - 2644: 3.4466357,-5.461709 - 2679: -20.130556,-17.838984 - 2680: -16.849306,-19.984818 - 2681: -17.307638,-19.6619 - 2682: -19.265972,-20.13065 - 2998: -14.051299,-2.1793242 - 3001: -17.143507,-2.1316965 - 3002: -14.734559,-9.289597 - 3004: -14.390809,-9.633347 - 3005: -10.377625,-9.233512 - 3013: -3.5338547,-5.210155 - 3014: -4.8467765,-14.670914 - 3370: -2.6337829,9.646117 + 2566: -17.677385,-15.149096 + 2567: -6.0205603,-17.117607 + 2568: -9.970078,-14.052947 + 2569: -9.887934,2.4137444 + 2570: -18.05108,15.0529785 + 2599: 6.2927756,-17.073393 + 2610: 15.850491,-4.61609 + 2612: 9.772904,-4.483665 + 2624: 13.70388,8.66825 + 2625: 7.1036158,14.358771 + 2628: -5.465275,9.849015 + 2629: -6.746525,10.213598 + 2642: 3.4466357,-5.461709 + 2677: -20.130556,-17.838984 + 2678: -16.849306,-19.984818 + 2679: -17.307638,-19.6619 + 2680: -19.265972,-20.13065 + 2996: -14.051299,-2.1793242 + 2999: -17.143507,-2.1316965 + 3000: -14.734559,-9.289597 + 3002: -14.390809,-9.633347 + 3003: -10.377625,-9.233512 + 3011: -3.5338547,-5.210155 + 3012: -4.8467765,-14.670914 + 3368: -2.6337829,9.646117 - node: color: '#FFFFFFFF' id: Bushi2 decals: - 2573: -17.025719,17.03245 - 2574: 18.117056,13.867498 - 2619: 3.580893,-8.535644 - 2620: 8.918044,-3.98356 - 2621: 15.266736,-5.8692675 - 2622: 16.209822,-5.8538113 - 2623: 7.318463,5.66825 - 2624: 6.4642963,5.85575 - 2625: 14.620547,8.230751 - 2636: 6.318049,2.225238 - 2655: -8.044823,-13.97787 - 2656: -8.878156,-13.144537 - 2657: -5.867739,-11.154953 - 2658: -13.026991,-9.009735 - 2659: -11.860325,-5.124318 - 2683: -16.859722,-18.94315 - 2987: -8.75542,2.9208503 - 2992: -13.95071,2.256745 - 2999: -14.165881,-2.439741 - 3003: -14.713725,-9.602097 - 3006: -9.76849,-14.395954 - 3015: -4.450943,-14.608414 - 3371: -2.8004496,9.333617 + 2571: -17.025719,17.03245 + 2572: 18.117056,13.867498 + 2617: 3.580893,-8.535644 + 2618: 8.918044,-3.98356 + 2619: 15.266736,-5.8692675 + 2620: 16.209822,-5.8538113 + 2621: 7.318463,5.66825 + 2622: 6.4642963,5.85575 + 2623: 14.620547,8.230751 + 2634: 6.318049,2.225238 + 2653: -8.044823,-13.97787 + 2654: -8.878156,-13.144537 + 2655: -5.867739,-11.154953 + 2656: -13.026991,-9.009735 + 2657: -11.860325,-5.124318 + 2681: -16.859722,-18.94315 + 2985: -8.75542,2.9208503 + 2990: -13.95071,2.256745 + 2997: -14.165881,-2.439741 + 3001: -14.713725,-9.602097 + 3004: -9.76849,-14.395954 + 3013: -4.450943,-14.608414 + 3369: -2.8004496,9.333617 - node: color: '#FFFFFFFF' id: Bushi3 decals: - 2575: 17.117056,10.211248 - 2576: 9.26489,2.9960737 - 2606: 14.499886,6.958212 - 2607: 13.541552,7.447795 - 2608: 6.0254874,14.498462 - 2613: 16.579659,-3.9598398 - 2637: 7.224299,2.3710713 - 2638: 4.0082765,6.5204124 - 2645: 5.713353,-3.1926599 - 2969: -14.413333,18.172693 - 2989: -9.557503,5.8271008 - 2991: -14.0402975,2.506745 - 3372: -2.8212829,8.989867 + 2573: 17.117056,10.211248 + 2574: 9.26489,2.9960737 + 2604: 14.499886,6.958212 + 2605: 13.541552,7.447795 + 2606: 6.0254874,14.498462 + 2611: 16.579659,-3.9598398 + 2635: 7.224299,2.3710713 + 2636: 4.0082765,6.5204124 + 2643: 5.713353,-3.1926599 + 2967: -14.413333,18.172693 + 2987: -9.557503,5.8271008 + 2989: -14.0402975,2.506745 + 3370: -2.8212829,8.989867 - node: color: '#FFFFFFFF' id: Bushi4 decals: - 2547: -15.13607,-18.199955 - 2548: -18.14605,-11.80234 - 2549: -13.963279,-4.177868 - 2550: -5.8667884,-5.4799514 - 2551: 8.061129,-4.427868 - 2552: 15.901968,-2.2820346 - 2553: 17.151968,2.9988291 - 2554: 9.610178,17.11985 - 2555: 4.0546904,17.078184 - 2556: 3.480264,5.210905 - 2557: -15.017622,18.057854 - 2558: -5.5270247,2.9853945 - 2593: 5.777904,17.049623 - 2594: 9.139725,14.0701685 - 2609: 6.567154,13.456795 - 2610: 6.441076,6.7870555 - 2615: 9.397904,-5.046165 - 2616: 4.3850265,-9.488806 - 2632: -6.2881913,9.494848 - 2633: -5.402775,10.869849 - 2641: 3.8528857,-4.5242085 - 2666: -11.037408,-8.100949 - 2996: -3.7009702,4.4983735 - 2997: -5.697132,-3.1168242 - 3007: -9.425084,-14.560988 - 3012: -3.5442712,-4.7830715 + 2545: -15.13607,-18.199955 + 2546: -18.14605,-11.80234 + 2547: -13.963279,-4.177868 + 2548: -5.8667884,-5.4799514 + 2549: 8.061129,-4.427868 + 2550: 15.901968,-2.2820346 + 2551: 17.151968,2.9988291 + 2552: 9.610178,17.11985 + 2553: 4.0546904,17.078184 + 2554: 3.480264,5.210905 + 2555: -15.017622,18.057854 + 2556: -5.5270247,2.9853945 + 2591: 5.777904,17.049623 + 2592: 9.139725,14.0701685 + 2607: 6.567154,13.456795 + 2608: 6.441076,6.7870555 + 2613: 9.397904,-5.046165 + 2614: 4.3850265,-9.488806 + 2630: -6.2881913,9.494848 + 2631: -5.402775,10.869849 + 2639: 3.8528857,-4.5242085 + 2664: -11.037408,-8.100949 + 2994: -3.7009702,4.4983735 + 2995: -5.697132,-3.1168242 + 3005: -9.425084,-14.560988 + 3010: -3.5442712,-4.7830715 - node: color: '#FFFFFFFF' id: Bushj1 decals: - 2585: 8.789164,15.109163 - 2671: -19.824345,-10.10782 - 2672: -20.11601,-9.63907 - 2674: -20.011845,-8.243237 - 2675: -18.730595,-8.79532 - 2676: -18.873224,-10.013859 - 2677: -19.654474,-7.0659423 - 3388: -18.860361,-7.807997 + 2583: 8.789164,15.109163 + 2669: -19.824345,-10.10782 + 2670: -20.11601,-9.63907 + 2672: -20.011845,-8.243237 + 2673: -18.730595,-8.79532 + 2674: -18.873224,-10.013859 + 2675: -19.654474,-7.0659423 + 3386: -18.860361,-7.807997 - node: color: '#FFFFFFFF' id: Bushj2 decals: - 2673: -18.793095,-6.868236 - 2678: -19.94614,-7.7117753 - 3386: -20.016611,-7.2975807 - 3387: -18.902029,-9.370498 - 3389: -19.318695,-8.485081 + 2671: -18.793095,-6.868236 + 2676: -19.94614,-7.7117753 + 3384: -20.016611,-7.2975807 + 3385: -18.902029,-9.370498 + 3387: -19.318695,-8.485081 - node: color: '#FFFFFFFF' id: Bushj3 decals: - 3373: -4.6337833,10.114867 + 3371: -4.6337833,10.114867 - node: color: '#FFFFFFFF' id: Bushk1 decals: - 2643: 3.0091357,-5.795042 - 2988: -10.00542,5.191684 + 2641: 3.0091357,-5.795042 + 2986: -10.00542,5.191684 - node: color: '#FFFFFFFF' id: Bushk3 decals: - 2586: 15.903748,17.02583 - 2587: 18.067644,12.942497 - 2642: 4.8112187,-3.7846253 + 2584: 15.903748,17.02583 + 2585: 18.067644,12.942497 + 2640: 4.8112187,-3.7846253 - node: color: '#FFFFFFFF' id: Bushm1 decals: - 3477: 63.81363,-0.83854264 + 3475: 63.81363,-0.83854264 - node: color: '#FFFFFFFF' id: Bushm3 decals: - 3478: 64.29279,-0.73437595 + 3476: 64.29279,-0.73437595 - node: color: '#FFFFFFFF' id: Bushm4 decals: - 2667: -10.9586735,-6.0094166 - 2668: -11.224603,-5.736016 - 2669: -13.307937,-8.381849 - 2670: -14.067469,-7.593817 - 3479: 64.12612,-1.2864593 + 2665: -10.9586735,-6.0094166 + 2666: -11.224603,-5.736016 + 2667: -13.307937,-8.381849 + 2668: -14.067469,-7.593817 + 3477: 64.12612,-1.2864593 - node: color: '#FFFFFFFF' id: Bushn1 decals: - 1309: 58.021324,0.5489143 - 1310: 57.96924,-1.1594192 - 3378: 57.99387,-2.411529 + 1307: 58.021324,0.5489143 + 1308: 57.96924,-1.1594192 + 3376: 57.99387,-2.411529 - node: angle: 1.5707963267948966 rad color: '#FFFFFFFF' id: Caution decals: - 3546: 56.20735,16.017925 + 3544: 56.20735,16.017925 - node: color: '#52B4E996' id: CheckerNWSE decals: - 2951: -19,-27 - 2952: -16,-27 - 2953: -22,-27 + 2949: -19,-27 + 2950: -16,-27 + 2951: -22,-27 - node: color: '#FFFFFFFF' id: ConcreteTrimCornerNe @@ -3181,33 +3192,33 @@ entities: decals: 30: -2,-2 31: -2,-2 - 3413: 2,4 - 3414: 3,3 - 3415: 4,2 + 3411: 2,4 + 3412: 3,3 + 3413: 4,2 - node: color: '#FFFFFFFF' id: ConcreteTrimInnerNw decals: 33: 2,-2 - 3410: -4,2 - 3411: -3,3 - 3412: -2,4 + 3408: -4,2 + 3409: -3,3 + 3410: -2,4 - node: color: '#FFFFFFFF' id: ConcreteTrimInnerSe decals: 29: -2,2 - 3407: 2,-4 - 3408: 3,-3 - 3409: 4,-2 + 3405: 2,-4 + 3406: 3,-3 + 3407: 4,-2 - node: color: '#FFFFFFFF' id: ConcreteTrimInnerSw decals: 32: 2,2 - 3404: -2,-4 - 3405: -3,-3 - 3406: -4,-2 + 3402: -2,-4 + 3403: -3,-3 + 3404: -4,-2 - node: color: '#FFFFFFFF' id: ConcreteTrimLineE @@ -3271,7 +3282,7 @@ entities: 95: -13,-2 96: -16,-2 97: -17,-2 - 3000: -14,-2 + 2998: -14,-2 - node: color: '#FFFFFFFF' id: ConcreteTrimLineS @@ -3302,8 +3313,8 @@ entities: 105: -8,2 106: -7,2 107: -6,2 - 3396: 11,2 - 3397: 14,2 + 3394: 11,2 + 3395: 14,2 - node: color: '#FFFFFFFF' id: ConcreteTrimLineW @@ -3333,348 +3344,350 @@ entities: 76: 2,-14 77: 2,-16 78: 2,-17 - 3402: 2,10 - 3403: 2,13 + 3400: 2,10 + 3401: 2,13 - node: color: '#FFFFFFFF' id: Delivery decals: - 1736: 50,-39 - 1737: 50,-38 - 1738: 50,-37 - 1739: 50,-36 + 1734: 50,-39 + 1735: 50,-38 + 1736: 50,-37 + 1737: 50,-36 - node: color: '#3EB38896' id: DiagonalCheckerAOverlay decals: - 3523: 12,23 - 3524: 13,22 - 3525: 13,23 - 3526: 14,23 - 3527: 15,23 - 3528: 15,22 - 3529: 14,22 - 3530: 14,21 - 3531: 13,21 - 3532: 12,20 - 3533: 13,20 - 3534: 14,20 - 3535: 15,20 - 3536: 15,21 - 3538: 12,21 - 3539: 12,22 + 3521: 12,23 + 3522: 13,22 + 3523: 13,23 + 3524: 14,23 + 3525: 15,23 + 3526: 15,22 + 3527: 14,22 + 3528: 14,21 + 3529: 13,21 + 3530: 12,20 + 3531: 13,20 + 3532: 14,20 + 3533: 15,20 + 3534: 15,21 + 3536: 12,21 + 3537: 12,22 - node: color: '#639137FF' id: DiagonalCheckerBOverlay decals: - 3510: 12,20 - 3511: 13,20 - 3512: 13,21 - 3513: 13,22 - 3514: 13,23 - 3515: 14,23 - 3516: 14,22 - 3517: 14,21 - 3518: 14,20 - 3519: 15,20 - 3520: 15,21 - 3521: 15,22 - 3522: 15,23 - 3537: 12,23 - 3540: 12,21 - 3541: 12,22 + 3508: 12,20 + 3509: 13,20 + 3510: 13,21 + 3511: 13,22 + 3512: 13,23 + 3513: 14,23 + 3514: 14,22 + 3515: 14,21 + 3516: 14,20 + 3517: 15,20 + 3518: 15,21 + 3519: 15,22 + 3520: 15,23 + 3535: 12,23 + 3538: 12,21 + 3539: 12,22 - node: color: '#D381C996' id: DiagonalOverlay decals: - 2240: -10,-49 - 2316: -10,-45 - 3381: 4,-47 - 3382: 4,-46 - 3383: -2,-47 - 3384: -6,-47 + 2238: -10,-49 + 2314: -10,-45 + 3379: 4,-47 + 3380: 4,-46 + 3381: -2,-47 + 3382: -6,-47 - node: color: '#DE3A3A96' id: DiagonalOverlay decals: - 1556: 51,-2 - 1557: 49,-2 - 1558: 49,-5 - 1559: 51,-5 - 1560: 29,-33 - 1561: 29,-32 - 1562: 39,-34 - 1563: 39,-32 - 1564: 41,-31 - 1565: 44,-37 - 1566: 41,-38 - 1567: 38,-41 - 2851: 41,-24 + 1554: 51,-2 + 1555: 49,-2 + 1556: 49,-5 + 1557: 51,-5 + 1558: 29,-33 + 1559: 29,-32 + 1560: 39,-34 + 1561: 39,-32 + 1562: 41,-31 + 1563: 44,-37 + 1564: 41,-38 + 1565: 38,-41 + 2849: 41,-24 - node: color: '#EFB34196' id: DiagonalOverlay decals: - 1822: 9,33 - 1823: 9,32 - 1824: 20,33 - 1825: 20,32 + 1820: 9,33 + 1821: 9,32 + 1822: 20,33 + 1823: 20,32 - node: color: '#FFFFFFFF' id: FlowersBROne decals: - 2749: 16.070688,16.03927 - 2780: 9.361443,4.4135666 - 2781: 8.71561,5.3614836 + 2747: 16.070688,16.03927 + 2778: 9.361443,4.4135666 + 2779: 8.71561,5.3614836 - node: color: '#FFFFFFFF' id: FlowersBRThree decals: - 2750: 17.062426,11.239492 - 2751: 10.321154,17.060677 - 2784: 7.6635256,6.1948166 - 2785: 8.538526,6.2989836 - 2820: 9.51524,6.327868 + 2748: 17.062426,11.239492 + 2749: 10.321154,17.060677 + 2782: 7.6635256,6.1948166 + 2783: 8.538526,6.2989836 + 2818: 9.51524,6.327868 - node: color: '#FFFFFFFF' id: FlowersBRTwo decals: - 2777: 10.111443,4.4344 - 2778: 8.663526,4.5594 - 2779: 8.05936,5.5073166 - 2821: 9.79649,6.7862015 + 2775: 10.111443,4.4344 + 2776: 8.663526,4.5594 + 2777: 8.05936,5.5073166 + 2819: 9.79649,6.7862015 - node: color: '#FFFFFFFF' id: Flowersbr1 decals: - 2746: 3.1090877,15.838451 - 2747: 15.10194,16.174686 + 2744: 3.1090877,15.838451 + 2745: 15.10194,16.174686 - node: color: '#FFFFFFFF' id: Flowersbr2 decals: - 2748: 15.393607,16.737186 - 2782: 9.49686,5.1010666 - 2783: 9.080193,5.7260666 - 2786: 10.324566,5.2335067 - 2808: 16.988474,10.508276 - 2809: 16.363474,10.747859 - 2810: 11.000941,16.992361 - 2811: 11.6309395,17.170504 - 2827: 7.8013525,4.69695 - 2828: 9.145103,3.603201 - 2829: 9.15132,6.0905905 + 2746: 15.393607,16.737186 + 2780: 9.49686,5.1010666 + 2781: 9.080193,5.7260666 + 2784: 10.324566,5.2335067 + 2806: 16.988474,10.508276 + 2807: 16.363474,10.747859 + 2808: 11.000941,16.992361 + 2809: 11.6309395,17.170504 + 2825: 7.8013525,4.69695 + 2826: 9.145103,3.603201 + 2827: 9.15132,6.0905905 - node: color: '#FFFFFFFF' id: Flowersbr3 decals: - 2819: 8.806907,6.8799515 + 2817: 8.806907,6.8799515 - node: color: '#FFFFFFFF' id: Flowerspv1 decals: - 2787: 15.255633,6.9409747 - 2788: 14.661882,7.545141 + 2785: 15.255633,6.9409747 + 2786: 14.661882,7.545141 - node: color: '#FFFFFFFF' id: Flowerspv2 decals: - 2789: 15.463966,7.690975 - 2791: 14.5844555,8.774308 - 2795: 14.978545,6.1768036 - 2796: 15.728544,6.3643036 - 2822: 14.814111,5.0989227 - 2823: 15.56411,4.4947557 - 2826: 12.9190645,9.799427 + 2787: 15.463966,7.690975 + 2789: 14.5844555,8.774308 + 2793: 14.978545,6.1768036 + 2794: 15.728544,6.3643036 + 2820: 14.814111,5.0989227 + 2821: 15.56411,4.4947557 + 2824: 12.9190645,9.799427 - node: color: '#FFFFFFFF' id: Flowerspv3 decals: - 2740: 8.013186,3.1140726 - 2741: 10.378889,-5.012858 - 2742: 10.274722,-4.383773 - 2790: 15.219872,8.347224 - 2792: 13.9177885,8.774308 - 2793: 13.252036,8.115639 - 2794: 13.134795,8.926804 - 2797: 16.103544,7.1143036 - 2798: 16.42646,6.1143036 - 2799: 15.748611,5.544657 - 2824: 14.501611,4.234339 - 2825: 13.6690645,9.570259 + 2738: 8.013186,3.1140726 + 2739: 10.378889,-5.012858 + 2740: 10.274722,-4.383773 + 2788: 15.219872,8.347224 + 2790: 13.9177885,8.774308 + 2791: 13.252036,8.115639 + 2792: 13.134795,8.926804 + 2795: 16.103544,7.1143036 + 2796: 16.42646,6.1143036 + 2797: 15.748611,5.544657 + 2822: 14.501611,4.234339 + 2823: 13.6690645,9.570259 - node: color: '#FFFFFFFF' id: Flowersy1 decals: - 2738: 7.160172,13.449887 - 2739: 5.483089,13.918637 - 2752: 12.341987,18.164845 - 2759: 4.084557,12.876521 - 2760: 6.313724,11.689021 - 2761: 9.0012245,11.564021 - 2767: 8.3553915,12.168188 - 2768: 6.730391,12.855688 - 2769: 5.105391,14.376521 - 2770: 2.9283073,14.741104 - 2772: 4.719974,13.105688 - 2773: 4.355391,14.585857 - 2774: 3.473161,14.394393 - 2775: 4.3585773,13.821476 - 2801: 2.299132,6.662748 - 2806: 4.7337813,6.6002483 - 2807: 4.5150313,6.0064983 + 2736: 7.160172,13.449887 + 2737: 5.483089,13.918637 + 2750: 12.341987,18.164845 + 2757: 4.084557,12.876521 + 2758: 6.313724,11.689021 + 2759: 9.0012245,11.564021 + 2765: 8.3553915,12.168188 + 2766: 6.730391,12.855688 + 2767: 5.105391,14.376521 + 2768: 2.9283073,14.741104 + 2770: 4.719974,13.105688 + 2771: 4.355391,14.585857 + 2772: 3.473161,14.394393 + 2773: 4.3585773,13.821476 + 2799: 2.299132,6.662748 + 2804: 4.7337813,6.6002483 + 2805: 4.5150313,6.0064983 - node: color: '#FFFFFFFF' id: Flowersy2 decals: - 2753: 14.633654,18.154427 - 2762: 7.6991415,11.939021 - 2763: 7.0533075,11.282771 - 2764: 8.1783085,11.241104 - 2802: 3.0178826,5.8710814 + 2751: 14.633654,18.154427 + 2760: 7.6991415,11.939021 + 2761: 7.0533075,11.282771 + 2762: 8.1783085,11.241104 + 2800: 3.0178826,5.8710814 - node: color: '#FFFFFFFF' id: Flowersy3 decals: - 2754: 13.227404,18.091927 - 2756: 11.914904,18.11276 - 2757: 11.914904,18.11276 - 2765: 6.938724,12.168188 - 2766: 7.6158075,12.918188 - 2776: 3.4939945,13.592309 - 2803: 3.1637156,6.5481644 - 2804: 3.7887158,5.704415 - 2805: 3.9108648,7.0273314 + 2752: 13.227404,18.091927 + 2754: 11.914904,18.11276 + 2755: 11.914904,18.11276 + 2763: 6.938724,12.168188 + 2764: 7.6158075,12.918188 + 2774: 3.4939945,13.592309 + 2801: 3.1637156,6.5481644 + 2802: 3.7887158,5.704415 + 2803: 3.9108648,7.0273314 - node: color: '#FFFFFFFF' id: Flowersy4 decals: - 2743: 3.8501334,-9.470912 - 2744: 4.3709664,-9.908412 - 2745: 3.6209664,-9.960495 - 2755: 13.966987,18.133595 - 2758: 15.123237,18.071095 - 2771: 5.136641,13.511938 - 2800: 2.2574656,5.8294144 - 2812: 9.849766,11.338729 - 2813: 9.047683,10.619978 - 2814: 4.7809443,7.692894 - 2815: 5.676778,7.797061 - 2816: 5.4059443,8.505394 - 2817: 5.8902392,6.890369 - 2818: 6.223573,8.400785 + 2741: 3.8501334,-9.470912 + 2742: 4.3709664,-9.908412 + 2743: 3.6209664,-9.960495 + 2753: 13.966987,18.133595 + 2756: 15.123237,18.071095 + 2769: 5.136641,13.511938 + 2798: 2.2574656,5.8294144 + 2810: 9.849766,11.338729 + 2811: 9.047683,10.619978 + 2812: 4.7809443,7.692894 + 2813: 5.676778,7.797061 + 2814: 5.4059443,8.505394 + 2815: 5.8902392,6.890369 + 2816: 6.223573,8.400785 - node: color: '#00BEBE7F' id: FullTileOverlayGreyscale decals: - 3173: -26,40 - 3174: -26,42 - 3175: -43,2 - 3176: -42,2 - 3177: -37,2 - 3178: -36,2 + 3171: -26,40 + 3172: -26,42 + 3173: -43,2 + 3174: -42,2 + 3175: -37,2 + 3176: -36,2 - node: color: '#334E6DC8' id: FullTileOverlayGreyscale decals: - 706: 21,3 - 707: 23,3 - 708: 25,3 - 808: -33,-9 - 809: -29,-9 - 2860: -23,-36 + 704: 21,3 + 705: 23,3 + 706: 25,3 + 806: -33,-9 + 807: -29,-9 + 2858: -23,-36 + 3612: 27,13 + 3613: 27,14 - node: color: '#373737FF' id: FullTileOverlayGreyscale decals: - 3416: 21,-19 - 3417: 20,-19 - 3418: 19,-19 - 3419: 19,-18 - 3420: 18,-19 - 3421: 18,-20 - 3422: 19,-20 - 3423: 19,-21 - 3424: 18,-21 - 3425: 21,-18 - 3426: 20,-18 - 3434: 17,-18 - 3435: 18,-17 - 3436: 21,-22 - 3437: 22,-21 + 3414: 21,-19 + 3415: 20,-19 + 3416: 19,-19 + 3417: 19,-18 + 3418: 18,-19 + 3419: 18,-20 + 3420: 19,-20 + 3421: 19,-21 + 3422: 18,-21 + 3423: 21,-18 + 3424: 20,-18 + 3432: 17,-18 + 3433: 18,-17 + 3434: 21,-22 + 3435: 22,-21 - node: color: '#4A35194C' id: FullTileOverlayGreyscale decals: - 2689: -22,3 - 2690: -21,3 - 2691: -20,3 - 2692: -19,3 - 2693: -19,4 - 2694: -19,5 - 2695: -19,6 - 2696: -19,7 - 2697: -19,8 - 2698: -19,9 - 2699: -19,10 - 2700: -20,10 - 2701: -20,9 - 2702: -20,8 - 2703: -20,7 - 2704: -20,6 - 2705: -20,5 - 2706: -20,4 - 2707: -21,4 - 2708: -22,4 - 2709: -22,5 - 2710: -21,5 - 2711: -21,6 - 2712: -22,6 - 2713: -22,7 - 2714: -21,7 - 2715: -21,8 - 2716: -22,8 - 2717: -22,9 - 2718: -21,9 - 2719: -21,10 - 2720: -22,10 + 2687: -22,3 + 2688: -21,3 + 2689: -20,3 + 2690: -19,3 + 2691: -19,4 + 2692: -19,5 + 2693: -19,6 + 2694: -19,7 + 2695: -19,8 + 2696: -19,9 + 2697: -19,10 + 2698: -20,10 + 2699: -20,9 + 2700: -20,8 + 2701: -20,7 + 2702: -20,6 + 2703: -20,5 + 2704: -20,4 + 2705: -21,4 + 2706: -22,4 + 2707: -22,5 + 2708: -21,5 + 2709: -21,6 + 2710: -22,6 + 2711: -22,7 + 2712: -21,7 + 2713: -21,8 + 2714: -22,8 + 2715: -22,9 + 2716: -21,9 + 2717: -21,10 + 2718: -22,10 - node: color: '#52B4E996' id: FullTileOverlayGreyscale decals: 244: -8,-39 245: -7,-39 - 530: -26,-27 - 531: -26,-28 - 532: -26,-29 - 533: -12,-30 - 534: -12,-29 - 535: -11,-29 - 550: -26,-41 - 735: -3,-37 - 736: -3,-36 - 818: -29,-6 - 819: -33,-6 - 927: -28,-29 - 928: -28,-28 - 929: -24,-29 - 930: -24,-28 + 528: -26,-27 + 529: -26,-28 + 530: -26,-29 + 531: -12,-30 + 532: -12,-29 + 533: -11,-29 + 548: -26,-41 + 733: -3,-37 + 734: -3,-36 + 816: -29,-6 + 817: -33,-6 + 925: -28,-29 + 926: -28,-28 + 927: -24,-29 + 928: -24,-28 - node: color: '#765428FF' id: FullTileOverlayGreyscale decals: - 3317: -55,-16 - 3318: -56,-16 + 3315: -55,-16 + 3316: -56,-16 - node: color: '#951710FF' id: FullTileOverlayGreyscale decals: - 2398: 43,37 - 2399: 43,38 - 2400: 43,39 - 2401: 43,40 - 2402: 43,41 - 2403: 43,36 - 2404: 43,42 + 2396: 43,37 + 2397: 43,38 + 2398: 43,39 + 2399: 43,40 + 2400: 43,41 + 2401: 43,36 + 2402: 43,42 - node: color: '#9FED5896' id: FullTileOverlayGreyscale @@ -3687,102 +3700,106 @@ entities: 193: -31,-17 263: -26,-14 474: -30,-22 - 814: -31,-9 - 815: -31,-4 + 812: -31,-9 + 813: -31,-4 - node: color: '#A4610696' id: FullTileOverlayGreyscale decals: - 812: -31,-8 - 813: -31,-5 + 810: -31,-8 + 811: -31,-5 - node: color: '#BC863FFF' id: FullTileOverlayGreyscale decals: - 3235: -48,-3 - 3236: -48,-4 - 3237: -52,-1 - 3238: -52,0 - 3349: -48,0 - 3350: -48,1 - 3351: -48,-1 - 3363: -51,-1 - 3364: -51,0 + 3233: -48,-3 + 3234: -48,-4 + 3235: -52,-1 + 3236: -52,0 + 3347: -48,0 + 3348: -48,1 + 3349: -48,-1 + 3361: -51,-1 + 3362: -51,0 - node: color: '#C6FF91FF' id: FullTileOverlayGreyscale decals: - 3018: -37,-35 - 3019: -37,-34 - 3020: -36,-34 - 3021: -35,-34 + 3016: -37,-35 + 3017: -37,-34 + 3018: -36,-34 + 3019: -35,-34 - node: color: '#D381C996' id: FullTileOverlayGreyscale decals: - 822: -29,-4 - 823: -33,-4 + 820: -29,-4 + 821: -33,-4 - node: color: '#D4D4D496' id: FullTileOverlayGreyscale decals: - 816: -29,-7 - 817: -33,-7 + 814: -29,-7 + 815: -33,-7 - node: color: '#DE3A3A96' id: FullTileOverlayGreyscale decals: - 820: -29,-5 - 821: -33,-5 - 2735: 56,-10 - 2736: 56,-11 - 2737: 56,-12 - 3390: 32,-10 - 3391: 38,-10 - 3392: 40,-10 + 818: -29,-5 + 819: -33,-5 + 2733: 56,-10 + 2734: 56,-11 + 2735: 56,-12 + 3388: 32,-10 + 3389: 38,-10 + 3390: 40,-10 - node: color: '#EFB34196' id: FullTileOverlayGreyscale decals: - 810: -29,-8 - 811: -33,-8 - 2886: -11,-39 - 2887: -19,-40 - 2932: -16,-38 + 808: -29,-8 + 809: -33,-8 + 2884: -11,-39 + 2885: -19,-40 + 2930: -16,-38 - node: color: '#FFFFFFFF' id: GrayConcreteTrimLineE decals: - 3393: 11,2 + 3391: 11,2 - node: color: '#FFFFFFFF' id: GrayConcreteTrimLineN decals: - 3400: 2,10 + 3398: 2,10 - node: color: '#FFFFFFFF' id: GrayConcreteTrimLineS decals: - 3395: 12.501469,3.9993005 - 3398: 2,13 - 3399: 2,13 + 3393: 12.501469,3.9993005 + 3396: 2,13 + 3397: 2,13 - node: color: '#FFFFFFFF' id: GrayConcreteTrimLineW decals: - 3394: 14,2 - 3401: 4.001555,11.500919 + 3392: 14,2 + 3399: 4.001555,11.500919 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale decals: - 593: 20,9 - 594: 21,9 - 595: 21,9 - 596: 22,9 - 597: 22,9 - 598: 25,9 - 622: 26,9 + 591: 20,9 + 592: 21,9 + 593: 21,9 + 594: 22,9 + 595: 22,9 + 596: 25,9 + 620: 26,9 + 3585: 22,18 + 3586: 23,18 + 3587: 24,18 + 3588: 25,18 - node: color: '#52B4E996' id: HalfTileOverlayGreyscale @@ -3795,18 +3812,18 @@ entities: 332: -17,-33 333: -16,-33 334: -15,-33 - 537: -13,-29 - 549: -26,-42 + 535: -13,-29 + 547: -26,-42 - node: color: '#639137FF' id: HalfTileOverlayGreyscale decals: - 640: 4,24 - 641: 5,24 - 642: 6,24 - 643: 7,24 - 644: 8,24 - 645: 9,24 + 638: 4,24 + 639: 5,24 + 640: 6,24 + 641: 7,24 + 642: 8,24 + 643: 9,24 - node: color: '#9FED5896' id: HalfTileOverlayGreyscale @@ -3825,35 +3842,37 @@ entities: color: '#C6FF91FF' id: HalfTileOverlayGreyscale decals: - 3022: -36,-31 - 3023: -37,-31 - 3024: -38,-31 + 3020: -36,-31 + 3021: -37,-31 + 3022: -38,-31 - node: color: '#D381C996' id: HalfTileOverlayGreyscale decals: - 830: -13,-50 - 831: -12,-50 - 2957: 15,-42 + 828: -13,-50 + 829: -12,-50 + 2955: 15,-42 - node: color: '#DE3A3A96' id: HalfTileOverlayGreyscale decals: - 1435: 45,-15 - 1436: 44,-15 - 1437: 43,-15 - 1438: 42,-15 - 1439: 41,-15 + 1433: 45,-15 + 1434: 44,-15 + 1435: 43,-15 + 1436: 42,-15 + 1437: 41,-15 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale180 decals: - 588: 20,4 - 589: 20,4 - 590: 21,4 - 591: 22,4 - 592: 25,4 - 623: 26,4 + 586: 20,4 + 587: 20,4 + 588: 21,4 + 589: 22,4 + 590: 25,4 + 621: 26,4 + 3589: 23,11 + 3590: 24,11 - node: color: '#52B4E996' id: HalfTileOverlayGreyscale180 @@ -3864,26 +3883,26 @@ entities: 340: -18,-36 341: -20,-36 342: -19,-36 - 536: -13,-28 - 548: -26,-40 + 534: -13,-28 + 546: -26,-40 - node: color: '#639137FF' id: HalfTileOverlayGreyscale180 decals: - 632: 8,22 - 633: 7,22 - 634: 7,22 - 635: 6,22 - 636: 5,22 - 646: 4,19 - 647: 5,19 - 648: 6,19 - 649: 7,19 - 650: 7,19 - 651: 8,19 - 652: 9,19 - 665: 5,23 - 666: 8,23 + 630: 8,22 + 631: 7,22 + 632: 7,22 + 633: 6,22 + 634: 5,22 + 644: 4,19 + 645: 5,19 + 646: 6,19 + 647: 7,19 + 648: 7,19 + 649: 8,19 + 650: 9,19 + 663: 5,23 + 664: 8,23 - node: color: '#9FED5896' id: HalfTileOverlayGreyscale180 @@ -3901,33 +3920,38 @@ entities: color: '#C6FF91FF' id: HalfTileOverlayGreyscale180 decals: - 3017: -38,-35 + 3015: -38,-35 - node: color: '#D381C996' id: HalfTileOverlayGreyscale180 decals: - 824: -13,-48 - 825: -12,-48 - 2958: 15,-39 + 822: -13,-48 + 823: -12,-48 + 2956: 15,-39 - node: color: '#1E5026FF' id: HalfTileOverlayGreyscale270 decals: - 2412: 42,36 - 2413: 42,37 - 2414: 42,38 - 2415: 42,39 - 2416: 42,40 - 2417: 42,41 - 2418: 42,42 + 2410: 42,36 + 2411: 42,37 + 2412: 42,38 + 2413: 42,39 + 2414: 42,40 + 2415: 42,41 + 2416: 42,42 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale270 decals: - 584: 19,5 - 585: 19,6 - 586: 19,7 - 587: 19,8 + 582: 19,5 + 583: 19,6 + 584: 19,7 + 585: 19,8 + 3580: 21,13 + 3581: 21,14 + 3582: 21,15 + 3583: 21,16 + 3584: 21,17 - node: color: '#52B4E996' id: HalfTileOverlayGreyscale270 @@ -3944,32 +3968,32 @@ entities: 257: -8,-34 327: -21,-34 328: -21,-35 - 541: -11,-28 - 542: -11,-27 - 543: -11,-26 - 547: -11,-25 + 539: -11,-28 + 540: -11,-27 + 541: -11,-26 + 545: -11,-25 - node: color: '#639137FF' id: HalfTileOverlayGreyscale270 decals: - 631: 9,21 - 653: 3,20 - 654: 3,21 - 655: 3,22 - 656: 3,23 - 667: 7,20 - 670: 7,21 + 629: 9,21 + 651: 3,20 + 652: 3,21 + 653: 3,22 + 654: 3,23 + 665: 7,20 + 668: 7,21 - node: color: '#951710FF' id: HalfTileOverlayGreyscale270 decals: - 2426: 44,36 - 2427: 44,37 - 2428: 44,38 - 2429: 44,39 - 2430: 44,40 - 2431: 44,41 - 2432: 44,42 + 2424: 44,36 + 2425: 44,37 + 2426: 44,38 + 2427: 44,39 + 2428: 44,40 + 2429: 44,41 + 2430: 44,42 - node: color: '#9FED5896' id: HalfTileOverlayGreyscale270 @@ -3985,32 +4009,39 @@ entities: color: '#C6FF91FF' id: HalfTileOverlayGreyscale270 decals: - 3026: -39,-32 - 3027: -39,-33 - 3028: -39,-34 + 3024: -39,-32 + 3025: -39,-33 + 3026: -39,-34 - node: color: '#D381C996' id: HalfTileOverlayGreyscale270 decals: - 829: -13,-49 + 827: -13,-49 - node: color: '#DE3A3A96' id: HalfTileOverlayGreyscale270 decals: - 2730: 57,-12 - 2731: 57,-11 - 2732: 57,-10 + 2728: 57,-12 + 2729: 57,-11 + 2730: 57,-10 - node: color: '#1E5026FF' id: HalfTileOverlayGreyscale90 decals: - 2405: 44,36 - 2406: 44,37 - 2407: 44,38 - 2408: 44,39 - 2409: 44,40 - 2410: 44,41 - 2411: 44,42 + 2403: 44,36 + 2404: 44,37 + 2405: 44,38 + 2406: 44,39 + 2407: 44,40 + 2408: 44,41 + 2409: 44,42 + - node: + color: '#334E6DC8' + id: HalfTileOverlayGreyscale90 + decals: + 3591: 26,15 + 3592: 26,16 + 3593: 26,17 - node: color: '#52B4E996' id: HalfTileOverlayGreyscale90 @@ -4021,31 +4052,31 @@ entities: 255: -10,-34 335: -14,-34 336: -14,-35 - 544: -12,-27 - 545: -12,-26 - 546: -12,-25 + 542: -12,-27 + 543: -12,-26 + 544: -12,-25 - node: color: '#639137FF' id: HalfTileOverlayGreyscale90 decals: - 637: 4,21 - 657: 10,20 - 658: 10,21 - 659: 10,22 - 660: 10,23 - 668: 6,20 - 669: 6,21 + 635: 4,21 + 655: 10,20 + 656: 10,21 + 657: 10,22 + 658: 10,23 + 666: 6,20 + 667: 6,21 - node: color: '#951710FF' id: HalfTileOverlayGreyscale90 decals: - 2419: 42,36 - 2420: 42,37 - 2421: 42,38 - 2422: 42,39 - 2423: 42,40 - 2424: 42,41 - 2425: 42,42 + 2417: 42,36 + 2418: 42,37 + 2419: 42,38 + 2420: 42,39 + 2421: 42,40 + 2422: 42,41 + 2423: 42,42 - node: color: '#9FED5896' id: HalfTileOverlayGreyscale90 @@ -4059,238 +4090,238 @@ entities: color: '#D381C996' id: HalfTileOverlayGreyscale90 decals: - 828: -12,-49 + 826: -12,-49 - node: color: '#EFB34196' id: MiniTileCornerOverlayNE decals: - 2881: -14,-40 + 2879: -14,-40 - node: color: '#EFB34196' id: MiniTileCornerOverlayNW decals: - 2878: -16,-40 + 2876: -16,-40 - node: color: '#EFB34196' id: MiniTileCornerOverlaySE decals: - 2879: -14,-42 + 2877: -14,-42 - node: color: '#EFB34196' id: MiniTileCornerOverlaySW decals: - 2880: -16,-42 + 2878: -16,-42 - node: color: '#DE3A3A96' id: MiniTileInnerOverlaySE decals: - 2830: 36,-13 + 2828: 36,-13 - node: color: '#EFB34196' id: MiniTileLineOverlayE decals: - 2883: -14,-41 + 2881: -14,-41 - node: color: '#DE3A3A96' id: MiniTileLineOverlayN decals: - 2729: 55,-10 + 2727: 55,-10 - node: color: '#EFB34196' id: MiniTileLineOverlayN decals: - 2882: -15,-40 + 2880: -15,-40 - node: color: '#DE3A3A96' id: MiniTileLineOverlayS decals: - 2728: 55,-12 + 2726: 55,-12 - node: color: '#EFB34196' id: MiniTileLineOverlayS decals: - 2885: -15,-42 + 2883: -15,-42 - node: color: '#EFB34196' id: MiniTileLineOverlayW decals: - 2884: -16,-41 + 2882: -16,-41 - node: color: '#D4D4D496' id: MiniTileOverlay decals: - 1751: 46,-35 - 1752: 46,-41 + 1749: 46,-35 + 1750: 46,-41 - node: color: '#FFFFFFFF' id: MiniTileOverlay decals: - 1753: 6,39 + 1751: 6,39 - node: color: '#FFFFFFFF' id: MiniTileSteelCornerNe decals: - 1741: 48,-36 + 1739: 48,-36 - node: color: '#FFFFFFFF' id: MiniTileSteelCornerNw decals: - 1742: 45,-36 + 1740: 45,-36 - node: color: '#FFFFFFFF' id: MiniTileSteelCornerSe decals: - 1740: 48,-39 - 1744: 47,-40 + 1738: 48,-39 + 1742: 47,-40 - node: color: '#FFFFFFFF' id: MiniTileSteelCornerSw decals: - 1743: 45,-40 + 1741: 45,-40 - node: color: '#FFFFFFFF' id: MiniTileSteelLineN decals: - 1745: 46,-36 - 1746: 47,-36 + 1743: 46,-36 + 1744: 47,-36 - node: color: '#FFFFFFFF' id: MiniTileSteelLineS decals: - 1747: 46,-40 + 1745: 46,-40 - node: color: '#FFFFFFFF' id: MiniTileSteelLineW decals: - 1748: 45,-39 - 1749: 45,-38 - 1750: 45,-37 + 1746: 45,-39 + 1747: 45,-38 + 1748: 45,-37 - node: color: '#334E6DC8' id: MiniTileWhiteCornerNe decals: - 989: -52,-9 + 987: -52,-9 - node: color: '#A4610696' id: MiniTileWhiteCornerNe decals: - 1004: -57,-3 - 1007: -57,-3 + 1002: -57,-3 + 1005: -57,-3 - node: color: '#BC863FBF' id: MiniTileWhiteCornerNe decals: - 960: -57,-18 + 958: -57,-18 - node: color: '#EFB34196' id: MiniTileWhiteCornerNe decals: - 2923: -11,-42 - 2924: -12,-39 + 2921: -11,-42 + 2922: -12,-39 - node: color: '#FFFFFFFF' id: MiniTileWhiteCornerNe decals: 441: -15,-34 - 2891: -12,-39 - 2892: -11,-42 + 2889: -12,-39 + 2890: -11,-42 - node: color: '#A4610696' id: MiniTileWhiteCornerNw decals: - 1005: -58,-3 - 1006: -58,-3 + 1003: -58,-3 + 1004: -58,-3 - node: color: '#BC863FBF' id: MiniTileWhiteCornerNw decals: - 959: -58,-18 + 957: -58,-18 - node: color: '#EFB34196' id: MiniTileWhiteCornerNw decals: - 2925: -18,-39 + 2923: -18,-39 - node: color: '#FFFFFFFF' id: MiniTileWhiteCornerNw decals: 440: -20,-34 - 2890: -18,-39 + 2888: -18,-39 - node: color: '#334E6DC8' id: MiniTileWhiteCornerSe decals: - 988: -52,-11 + 986: -52,-11 - node: color: '#A4610696' id: MiniTileWhiteCornerSe decals: - 1002: -57,-5 - 1008: -57,-5 + 1000: -57,-5 + 1006: -57,-5 - node: color: '#BC863FBF' id: MiniTileWhiteCornerSe decals: - 957: -57,-20 + 955: -57,-20 - node: color: '#EFB34196' id: MiniTileWhiteCornerSe decals: - 2922: -11,-43 + 2920: -11,-43 - node: color: '#FFFFFFFF' id: MiniTileWhiteCornerSe decals: 438: -15,-35 - 2888: -11,-43 + 2886: -11,-43 - node: color: '#A4610696' id: MiniTileWhiteCornerSw decals: - 1003: -58,-5 - 1009: -58,-5 + 1001: -58,-5 + 1007: -58,-5 - node: color: '#BC863FBF' id: MiniTileWhiteCornerSw decals: - 958: -58,-20 + 956: -58,-20 - node: color: '#EFB34196' id: MiniTileWhiteCornerSw decals: - 2921: -18,-43 + 2919: -18,-43 - node: color: '#FFFFFFFF' id: MiniTileWhiteCornerSw decals: 439: -20,-35 - 2889: -18,-43 + 2887: -18,-43 - node: color: '#D381C996' id: MiniTileWhiteInnerNe decals: - 3385: -7,-48 + 3383: -7,-48 - node: color: '#DE3A3A96' id: MiniTileWhiteInnerNe decals: - 3380: 42,-39 + 3378: 42,-39 - node: color: '#EFB34196' id: MiniTileWhiteInnerNe decals: - 2931: -12,-42 + 2929: -12,-42 - node: color: '#FFFFFFFF' id: MiniTileWhiteInnerNe decals: 434: -21,-36 - 2909: -12,-42 + 2907: -12,-42 - node: color: '#DE3A3A96' id: MiniTileWhiteInnerNw decals: - 3379: 42,-39 + 3377: 42,-39 - node: color: '#FFFFFFFF' id: MiniTileWhiteInnerNw @@ -4311,24 +4342,24 @@ entities: color: '#334E6DC8' id: MiniTileWhiteLineE decals: - 987: -52,-10 + 985: -52,-10 - node: color: '#A4610696' id: MiniTileWhiteLineE decals: - 1012: -57,-4 - 1013: -57,-4 + 1010: -57,-4 + 1011: -57,-4 - node: color: '#BC863FBF' id: MiniTileWhiteLineE decals: - 962: -57,-19 + 960: -57,-19 - node: color: '#EFB34196' id: MiniTileWhiteLineE decals: - 2929: -12,-41 - 2930: -12,-40 + 2927: -12,-41 + 2928: -12,-40 - node: color: '#FFFFFFFF' id: MiniTileWhiteLineE @@ -4336,17 +4367,17 @@ entities: 425: -21,-34 426: -21,-34 427: -21,-35 - 2898: -12,-40 - 2899: -12,-41 + 2896: -12,-40 + 2897: -12,-41 - node: color: '#EFB34196' id: MiniTileWhiteLineN decals: - 2910: -17,-39 - 2911: -16,-39 - 2912: -15,-39 - 2913: -14,-39 - 2914: -13,-39 + 2908: -17,-39 + 2909: -16,-39 + 2910: -15,-39 + 2911: -14,-39 + 2912: -13,-39 - node: color: '#FFFFFFFF' id: MiniTileWhiteLineN @@ -4361,21 +4392,21 @@ entities: 443: -18,-34 444: -17,-34 445: -16,-34 - 2893: -17,-39 - 2894: -16,-39 - 2895: -15,-39 - 2896: -14,-39 - 2897: -13,-39 + 2891: -17,-39 + 2892: -16,-39 + 2893: -15,-39 + 2894: -14,-39 + 2895: -13,-39 - node: color: '#EFB34196' id: MiniTileWhiteLineS decals: - 2915: -12,-43 - 2916: -13,-43 - 2917: -14,-43 - 2918: -15,-43 - 2919: -16,-43 - 2920: -17,-43 + 2913: -12,-43 + 2914: -13,-43 + 2915: -14,-43 + 2916: -15,-43 + 2917: -16,-43 + 2918: -17,-43 - node: color: '#FFFFFFFF' id: MiniTileWhiteLineS @@ -4390,39 +4421,39 @@ entities: 447: -17,-35 448: -18,-35 449: -19,-35 - 2900: -12,-43 - 2901: -13,-43 - 2902: -14,-43 - 2903: -15,-43 - 2904: -16,-43 - 2905: -17,-43 + 2898: -12,-43 + 2899: -13,-43 + 2900: -14,-43 + 2901: -15,-43 + 2902: -16,-43 + 2903: -17,-43 - node: color: '#A4610696' id: MiniTileWhiteLineW decals: - 1010: -58,-4 - 1011: -58,-4 + 1008: -58,-4 + 1009: -58,-4 - node: color: '#BC863FBF' id: MiniTileWhiteLineW decals: - 961: -58,-19 + 959: -58,-19 - node: color: '#EFB34196' id: MiniTileWhiteLineW decals: - 2926: -18,-40 - 2927: -18,-41 - 2928: -18,-42 + 2924: -18,-40 + 2925: -18,-41 + 2926: -18,-42 - node: color: '#FFFFFFFF' id: MiniTileWhiteLineW decals: 417: -14,-35 418: -14,-34 - 2906: -18,-42 - 2907: -18,-41 - 2908: -18,-40 + 2904: -18,-42 + 2905: -18,-41 + 2906: -18,-40 - node: color: '#FFFFFFFF' id: OldConcreteTrimInnerNe @@ -4486,53 +4517,53 @@ entities: color: '#D4D4D428' id: PavementOverlay decals: - 1366: 44,-21 - 1367: 45,-21 - 1368: 46,-21 - 1369: 46,-22 - 1370: 45,-22 - 1371: 44,-22 - 1372: 48,-21 - 1373: 49,-21 - 1374: 50,-21 - 1375: 50,-22 - 1376: 49,-22 - 1377: 48,-22 - 1378: 52,-21 - 1379: 53,-21 - 1380: 54,-21 - 1381: 54,-22 - 1382: 53,-22 - 1383: 52,-22 - 3459: 42,-12 - 3460: 44,-12 - 3461: 44,-13 - 3462: 43,-13 - 3463: 41,-12 - 3464: 41,-14 - 3465: 42,-13 - 3466: 41,-13 - 3467: 42,-14 - 3468: 43,-14 - 3469: 44,-14 - 3470: 45,-14 - 3471: 45,-13 - 3472: 45,-12 - 3473: 43,-12 + 1364: 44,-21 + 1365: 45,-21 + 1366: 46,-21 + 1367: 46,-22 + 1368: 45,-22 + 1369: 44,-22 + 1370: 48,-21 + 1371: 49,-21 + 1372: 50,-21 + 1373: 50,-22 + 1374: 49,-22 + 1375: 48,-22 + 1376: 52,-21 + 1377: 53,-21 + 1378: 54,-21 + 1379: 54,-22 + 1380: 53,-22 + 1381: 52,-22 + 3457: 42,-12 + 3458: 44,-12 + 3459: 44,-13 + 3460: 43,-13 + 3461: 41,-12 + 3462: 41,-14 + 3463: 42,-13 + 3464: 41,-13 + 3465: 42,-14 + 3466: 43,-14 + 3467: 44,-14 + 3468: 45,-14 + 3469: 45,-13 + 3470: 45,-12 + 3471: 43,-12 - node: color: '#1D1D21FF' id: QuarterTileOverlayGreyscale decals: - 2433: 43,37 - 2436: 44,41 + 2431: 43,37 + 2434: 44,41 - node: color: '#334E6DC8' id: QuarterTileOverlayGreyscale decals: - 1344: 30,-3 - 1348: 30,-8 - 1351: 30,-5 - 1352: 30,-6 + 1342: 30,-3 + 1346: 30,-8 + 1349: 30,-5 + 1350: 30,-6 - node: color: '#52B4E996' id: QuarterTileOverlayGreyscale @@ -4586,19 +4617,19 @@ entities: 394: -22,-28 395: -19,-28 396: -16,-28 - 520: -31,-32 - 521: -31,-31 - 524: -31,-33 - 525: -22,-36 - 529: -24,-29 - 538: -14,-29 - 554: -25,-42 - 570: -12,-31 - 737: -2,-37 - 3029: -36,-33 - 3033: -37,-33 - 3037: -35,-33 - 3039: -34,-33 + 518: -31,-32 + 519: -31,-31 + 522: -31,-33 + 523: -22,-36 + 527: -24,-29 + 536: -14,-29 + 552: -25,-42 + 568: -12,-31 + 735: -2,-37 + 3027: -36,-33 + 3031: -37,-33 + 3035: -35,-33 + 3037: -34,-33 - node: color: '#9FED5896' id: QuarterTileOverlayGreyscale @@ -4608,168 +4639,169 @@ entities: color: '#D381C996' id: QuarterTileOverlayGreyscale decals: - 832: -11,-50 + 830: -11,-50 - node: color: '#D4D4D428' id: QuarterTileOverlayGreyscale decals: - 1018: -48,-2 - 1020: -48,3 - 1055: -33,-2 - 1120: -1,18 - 1121: -1,19 - 1122: -1,20 - 1123: -1,21 - 1124: -1,22 - 1125: -1,23 - 1126: -1,24 - 1127: -1,25 - 1128: -1,29 - 1129: -1,30 - 1130: -2,31 - 1131: -2,32 - 1132: -2,33 - 1133: -2,34 - 1134: -2,35 - 1135: -2,36 - 1136: -2,37 - 1137: -2,38 - 1152: -13,53 - 1154: -12,53 - 1155: -11,53 - 1156: -10,53 - 1157: -9,53 - 1162: -8,50 - 1163: -7,50 - 1164: -6,50 - 1165: -5,50 - 1166: -5,50 - 1167: -4,50 - 1168: -3,50 - 1169: -3,51 - 1170: -3,52 - 1171: -3,53 - 1172: -2,53 - 1173: -1,53 - 1174: 0,53 - 1176: 1,53 - 1218: -2,26 - 1219: -2,27 - 1220: -2,27 - 1221: -2,28 - 1257: 53,1 - 1258: 53,2 - 1259: 54,3 - 1260: 55,4 - 1261: 56,5 - 1302: 45,-3 - 1303: 45,-2 - 1315: 59,-3 - 1329: 57,5 - 1330: 58,5 - 1331: 59,5 - 1332: 60,5 - 1333: 61,5 - 1339: 62,0 - 1933: 3,-83 - 1934: 3,-82 - 1935: 3,-81 - 1936: 3,-80 - 1937: 3,-79 - 1938: 3,-78 - 1939: 3,-77 - 1940: 3,-76 - 1941: 3,-75 - 1942: 3,-74 - 1943: 3,-73 - 1944: 3,-72 - 1945: 3,-71 - 1946: 3,-70 - 1947: 3,-69 - 1948: 3,-68 - 1949: 3,-67 - 1950: 3,-66 - 1951: 3,-65 - 1952: 3,-64 - 1987: -10,-81 - 1988: -10,-80 - 1989: -10,-79 - 1990: -10,-78 - 1991: -11,-77 - 1992: -11,-76 - 1993: -11,-75 - 1994: -11,-75 - 1995: -10,-75 - 1996: -10,-74 - 1997: -10,-73 - 1998: -10,-72 - 1999: -10,-71 - 2000: -11,-70 - 2001: -11,-69 - 2002: -11,-68 - 2003: -10,-68 - 2004: -10,-67 - 2005: -10,-66 - 2006: -10,-65 - 2007: -10,-64 - 2008: -10,-63 - 2009: -10,-62 - 2010: -10,-61 - 2011: -10,-60 - 2012: -10,-59 - 2013: -10,-58 - 2014: -10,-57 - 2015: -9,-57 - 2016: -1,-57 - 2017: -1,-56 - 2018: -1,-55 - 2019: -1,-54 - 2020: -1,-53 - 2021: -1,-52 - 2022: -1,-51 - 2023: -1,-50 - 2024: -1,-49 - 2025: -1,-46 - 2026: -1,-45 - 2027: -1,-44 - 2028: -1,-43 - 2029: -1,-42 - 2030: -1,-41 - 2350: -1,-47 - 2351: -1,-48 + 1016: -48,-2 + 1018: -48,3 + 1053: -33,-2 + 1118: -1,18 + 1119: -1,19 + 1120: -1,20 + 1121: -1,21 + 1122: -1,22 + 1123: -1,23 + 1124: -1,24 + 1125: -1,25 + 1126: -1,29 + 1127: -1,30 + 1128: -2,31 + 1129: -2,32 + 1130: -2,33 + 1131: -2,34 + 1132: -2,35 + 1133: -2,36 + 1134: -2,37 + 1135: -2,38 + 1150: -13,53 + 1152: -12,53 + 1153: -11,53 + 1154: -10,53 + 1155: -9,53 + 1160: -8,50 + 1161: -7,50 + 1162: -6,50 + 1163: -5,50 + 1164: -5,50 + 1165: -4,50 + 1166: -3,50 + 1167: -3,51 + 1168: -3,52 + 1169: -3,53 + 1170: -2,53 + 1171: -1,53 + 1172: 0,53 + 1174: 1,53 + 1216: -2,26 + 1217: -2,27 + 1218: -2,27 + 1219: -2,28 + 1255: 53,1 + 1256: 53,2 + 1257: 54,3 + 1258: 55,4 + 1259: 56,5 + 1300: 45,-3 + 1301: 45,-2 + 1313: 59,-3 + 1327: 57,5 + 1328: 58,5 + 1329: 59,5 + 1330: 60,5 + 1331: 61,5 + 1337: 62,0 + 1931: 3,-83 + 1932: 3,-82 + 1933: 3,-81 + 1934: 3,-80 + 1935: 3,-79 + 1936: 3,-78 + 1937: 3,-77 + 1938: 3,-76 + 1939: 3,-75 + 1940: 3,-74 + 1941: 3,-73 + 1942: 3,-72 + 1943: 3,-71 + 1944: 3,-70 + 1945: 3,-69 + 1946: 3,-68 + 1947: 3,-67 + 1948: 3,-66 + 1949: 3,-65 + 1950: 3,-64 + 1985: -10,-81 + 1986: -10,-80 + 1987: -10,-79 + 1988: -10,-78 + 1989: -11,-77 + 1990: -11,-76 + 1991: -11,-75 + 1992: -11,-75 + 1993: -10,-75 + 1994: -10,-74 + 1995: -10,-73 + 1996: -10,-72 + 1997: -10,-71 + 1998: -11,-70 + 1999: -11,-69 + 2000: -11,-68 + 2001: -10,-68 + 2002: -10,-67 + 2003: -10,-66 + 2004: -10,-65 + 2005: -10,-64 + 2006: -10,-63 + 2007: -10,-62 + 2008: -10,-61 + 2009: -10,-60 + 2010: -10,-59 + 2011: -10,-58 + 2012: -10,-57 + 2013: -9,-57 + 2014: -1,-57 + 2015: -1,-56 + 2016: -1,-55 + 2017: -1,-54 + 2018: -1,-53 + 2019: -1,-52 + 2020: -1,-51 + 2021: -1,-50 + 2022: -1,-49 + 2023: -1,-46 + 2024: -1,-45 + 2025: -1,-44 + 2026: -1,-43 + 2027: -1,-42 + 2028: -1,-41 + 2348: -1,-47 + 2349: -1,-48 - node: color: '#D4D4D433' id: QuarterTileOverlayGreyscale decals: - 3139: 0,48 - 3140: 0,47 - 3141: 0,46 - 3142: 0,45 - 3143: 0,44 - 3144: 0,43 - 3145: 0,42 - 3146: 0,41 - 3147: 0,40 - 3148: 0,38 - 3149: 0,39 - 3150: -1,38 + 3137: 0,48 + 3138: 0,47 + 3139: 0,46 + 3140: 0,45 + 3141: 0,44 + 3142: 0,43 + 3143: 0,42 + 3144: 0,41 + 3145: 0,40 + 3146: 0,38 + 3147: 0,39 + 3148: -1,38 - node: color: '#DE3A3A96' id: QuarterTileOverlayGreyscale decals: - 2734: 57,-13 + 2732: 57,-13 - node: color: '#1D1D21FF' id: QuarterTileOverlayGreyscale180 decals: - 2434: 43,39 - 2437: 43,36 + 2432: 43,39 + 2435: 43,36 - node: color: '#334E6DC8' id: QuarterTileOverlayGreyscale180 decals: - 630: 27,5 - 1346: 33,-9 + 628: 27,5 + 1344: 33,-9 + 3598: 25,12 - node: color: '#52B4E996' id: QuarterTileOverlayGreyscale180 @@ -4820,305 +4852,306 @@ entities: 381: -16,-28 382: -15,-28 391: -19,-28 - 522: -31,-31 - 523: -31,-33 - 526: -22,-36 - 527: -22,-35 - 528: -24,-28 - 539: -14,-28 - 551: -27,-40 - 569: -12,-31 - 581: -12,-33 - 3030: -36,-32 - 3031: -37,-32 - 3032: -38,-32 - 3038: -35,-32 - 3040: -34,-32 + 520: -31,-31 + 521: -31,-33 + 524: -22,-36 + 525: -22,-35 + 526: -24,-28 + 537: -14,-28 + 549: -27,-40 + 567: -12,-31 + 579: -12,-33 + 3028: -36,-32 + 3029: -37,-32 + 3030: -38,-32 + 3036: -35,-32 + 3038: -34,-32 - node: color: '#639137FF' id: QuarterTileOverlayGreyscale180 decals: - 639: 4,22 + 637: 4,22 - node: color: '#D381C996' id: QuarterTileOverlayGreyscale180 decals: - 826: -14,-48 + 824: -14,-48 - node: color: '#D4D4D428' id: QuarterTileOverlayGreyscale180 decals: - 1041: -18,-1 - 1042: -19,-1 - 1043: -20,-1 - 1044: -21,-1 - 1045: -22,-1 - 1046: -23,-1 - 1047: -27,-1 - 1048: -28,-1 - 1049: -29,-1 - 1050: -29,-2 - 1051: -31,-2 - 1053: -33,-2 - 1056: -34,-1 - 1057: -35,-1 - 1058: -36,-1 - 1059: -37,-1 - 1060: -38,-1 - 1061: -39,-1 - 1062: -40,-1 - 1063: -41,-1 - 1064: -41,-2 - 1065: -41,-3 - 1066: -41,-4 - 1067: -41,-5 - 1068: -41,-6 - 1069: -41,-7 - 1070: -41,-8 - 1071: -41,-9 - 1072: -41,-10 - 1073: -41,-13 - 1074: -41,-14 - 1075: -41,-15 - 1076: -41,-16 - 1077: -41,-17 - 1078: -41,-18 - 1079: -41,-19 - 1080: -41,-20 - 1081: -41,-21 - 1082: -41,-22 - 1083: -41,-23 - 1084: -41,-24 - 1085: -41,-25 - 1086: -41,-26 - 1087: -41,-27 - 1088: -41,-28 - 1089: -41,-29 - 1090: -41,-30 - 1091: -41,-31 - 1092: -43,-31 - 1159: -9,53 - 1160: -9,52 - 1161: -9,51 - 1177: 1,53 - 1202: 2,31 - 1205: -2,31 - 1268: 52,-1 - 1269: 51,-1 - 1270: 50,-1 - 1271: 49,-1 - 1272: 48,-1 - 1273: 47,-2 - 1274: 47,-3 - 1275: 46,-3 - 1276: 44,-1 - 1277: 42,-1 - 1278: 39,-1 - 1279: 38,-1 - 1280: 37,-1 - 1281: 36,-1 - 1282: 35,-1 - 1283: 34,-1 - 1284: 33,-1 - 1285: 32,-1 - 1286: 31,-1 - 1287: 29,-1 - 1288: 28,-2 - 1289: 27,-2 - 1290: 26,-2 - 1291: 25,-1 - 1292: 24,-1 - 1293: 23,-1 - 1294: 22,-1 - 1295: 21,-1 - 1296: 20,-1 - 1297: 19,-1 - 1298: 18,-1 - 1301: 45,-3 - 1316: 57,2 - 1317: 57,1 - 1318: 57,0 - 1319: 57,-1 - 1334: 61,5 - 1335: 61,4 - 1336: 61,3 - 1337: 61,2 - 1338: 61,1 - 1342: 62,-1 - 1343: 30,-1 - 1884: 1,-19 - 1885: 1,-20 - 1886: 1,-18 - 1887: 1,-21 - 1888: 1,-22 - 1889: 1,-23 - 1890: 2,-26 - 1891: 2,-28 - 1892: 1,-29 - 1893: 1,-30 - 1894: 1,-31 - 1895: 1,-32 - 1931: 4,-83 - 1932: 3,-83 - 1953: 2,-63 - 1954: 1,-63 - 1955: 0,-63 - 1956: -1,-63 - 1957: -2,-63 - 1964: -3,-63 - 2042: 1,-33 - 2043: 1,-34 - 2044: 1,-35 - 2045: 1,-36 - 2046: 1,-37 - 2047: 1,-38 - 2048: 1,-39 - 2049: 1,-40 - 2069: 1,-25 + 1039: -18,-1 + 1040: -19,-1 + 1041: -20,-1 + 1042: -21,-1 + 1043: -22,-1 + 1044: -23,-1 + 1045: -27,-1 + 1046: -28,-1 + 1047: -29,-1 + 1048: -29,-2 + 1049: -31,-2 + 1051: -33,-2 + 1054: -34,-1 + 1055: -35,-1 + 1056: -36,-1 + 1057: -37,-1 + 1058: -38,-1 + 1059: -39,-1 + 1060: -40,-1 + 1061: -41,-1 + 1062: -41,-2 + 1063: -41,-3 + 1064: -41,-4 + 1065: -41,-5 + 1066: -41,-6 + 1067: -41,-7 + 1068: -41,-8 + 1069: -41,-9 + 1070: -41,-10 + 1071: -41,-13 + 1072: -41,-14 + 1073: -41,-15 + 1074: -41,-16 + 1075: -41,-17 + 1076: -41,-18 + 1077: -41,-19 + 1078: -41,-20 + 1079: -41,-21 + 1080: -41,-22 + 1081: -41,-23 + 1082: -41,-24 + 1083: -41,-25 + 1084: -41,-26 + 1085: -41,-27 + 1086: -41,-28 + 1087: -41,-29 + 1088: -41,-30 + 1089: -41,-31 + 1090: -43,-31 + 1157: -9,53 + 1158: -9,52 + 1159: -9,51 + 1175: 1,53 + 1200: 2,31 + 1203: -2,31 + 1266: 52,-1 + 1267: 51,-1 + 1268: 50,-1 + 1269: 49,-1 + 1270: 48,-1 + 1271: 47,-2 + 1272: 47,-3 + 1273: 46,-3 + 1274: 44,-1 + 1275: 42,-1 + 1276: 39,-1 + 1277: 38,-1 + 1278: 37,-1 + 1279: 36,-1 + 1280: 35,-1 + 1281: 34,-1 + 1282: 33,-1 + 1283: 32,-1 + 1284: 31,-1 + 1285: 29,-1 + 1286: 28,-2 + 1287: 27,-2 + 1288: 26,-2 + 1289: 25,-1 + 1290: 24,-1 + 1291: 23,-1 + 1292: 22,-1 + 1293: 21,-1 + 1294: 20,-1 + 1295: 19,-1 + 1296: 18,-1 + 1299: 45,-3 + 1314: 57,2 + 1315: 57,1 + 1316: 57,0 + 1317: 57,-1 + 1332: 61,5 + 1333: 61,4 + 1334: 61,3 + 1335: 61,2 + 1336: 61,1 + 1340: 62,-1 + 1341: 30,-1 + 1882: 1,-19 + 1883: 1,-20 + 1884: 1,-18 + 1885: 1,-21 + 1886: 1,-22 + 1887: 1,-23 + 1888: 2,-26 + 1889: 2,-28 + 1890: 1,-29 + 1891: 1,-30 + 1892: 1,-31 + 1893: 1,-32 + 1929: 4,-83 + 1930: 3,-83 + 1951: 2,-63 + 1952: 1,-63 + 1953: 0,-63 + 1954: -1,-63 + 1955: -2,-63 + 1962: -3,-63 + 2040: 1,-33 + 2041: 1,-34 + 2042: 1,-35 + 2043: 1,-36 + 2044: 1,-37 + 2045: 1,-38 + 2046: 1,-39 + 2047: 1,-40 + 2067: 1,-25 - node: color: '#334E6DC8' id: QuarterTileOverlayGreyscale270 decals: - 1345: 30,-9 - 1349: 30,-7 - 1350: 30,-4 - 1353: 30,-6 + 1343: 30,-9 + 1347: 30,-7 + 1348: 30,-4 + 1351: 30,-6 + 3599: 22,12 - node: color: '#52B4E996' id: QuarterTileOverlayGreyscale270 decals: 249: -7,-38 - 553: -25,-40 - 738: -2,-36 - 3035: -37,-32 + 551: -25,-40 + 736: -2,-36 + 3033: -37,-32 - node: color: '#639137FF' id: QuarterTileOverlayGreyscale270 decals: - 638: 9,22 + 636: 9,22 - node: color: '#D381C996' id: QuarterTileOverlayGreyscale270 decals: - 827: -11,-48 + 825: -11,-48 - node: color: '#D4D4D428' id: QuarterTileOverlayGreyscale270 decals: - 1019: -48,3 - 1052: -31,-2 - 1054: -33,-2 - 1094: -43,-29 - 1095: -43,-28 - 1096: -43,-27 - 1097: -43,-26 - 1098: -43,-25 - 1099: -43,-24 - 1100: -43,-23 - 1101: -43,-22 - 1102: -43,-21 - 1103: -43,-20 - 1104: -43,-19 - 1105: -43,-18 - 1106: -43,-14 - 1107: -43,-13 - 1108: -43,-12 - 1109: -43,-8 - 1110: -43,-7 - 1111: -43,-6 - 1112: -44,-5 - 1113: -45,-5 - 1114: -46,-5 - 1115: -47,-5 - 1116: -48,-5 - 1117: -43,-5 - 1118: -29,-2 - 1138: -4,49 - 1139: -5,49 - 1140: -6,49 - 1141: -7,49 - 1142: -8,49 - 1143: -9,49 - 1144: -10,49 - 1145: -11,49 - 1146: -12,49 - 1147: -13,49 - 1148: -13,50 - 1149: -13,51 - 1150: -13,52 - 1151: -13,53 - 1203: 2,31 - 1204: -2,31 - 1262: 53,-3 - 1263: 54,-4 - 1264: 55,-5 - 1265: 56,-6 - 1266: 53,-1 - 1267: 53,-2 - 1299: 41,-1 - 1300: 45,-3 - 1314: 59,2 - 1320: 59,-1 - 1321: 59,0 - 1322: 59,1 - 1323: 61,-6 - 1340: 62,-1 - 1958: -8,-63 - 1959: -7,-63 - 1960: -6,-63 - 1961: -5,-63 - 1962: -4,-63 - 1963: -3,-63 - 1985: -9,-83 - 1986: -10,-83 - 2031: -1,-32 - 2032: -1,-31 - 2033: -1,-29 - 2034: -1,-30 - 2035: -1,-26 - 2036: -2,-23 - 2037: -2,-22 - 2038: -1,-21 - 2039: -1,-20 - 2040: -1,-19 - 2041: -1,-18 - 2062: 4,-51 - 2063: 3,-51 - 2064: 2,-51 - 2065: -1,-24 - 2066: -1,-25 - 2067: -1,-27 - 2068: -1,-28 + 1017: -48,3 + 1050: -31,-2 + 1052: -33,-2 + 1092: -43,-29 + 1093: -43,-28 + 1094: -43,-27 + 1095: -43,-26 + 1096: -43,-25 + 1097: -43,-24 + 1098: -43,-23 + 1099: -43,-22 + 1100: -43,-21 + 1101: -43,-20 + 1102: -43,-19 + 1103: -43,-18 + 1104: -43,-14 + 1105: -43,-13 + 1106: -43,-12 + 1107: -43,-8 + 1108: -43,-7 + 1109: -43,-6 + 1110: -44,-5 + 1111: -45,-5 + 1112: -46,-5 + 1113: -47,-5 + 1114: -48,-5 + 1115: -43,-5 + 1116: -29,-2 + 1136: -4,49 + 1137: -5,49 + 1138: -6,49 + 1139: -7,49 + 1140: -8,49 + 1141: -9,49 + 1142: -10,49 + 1143: -11,49 + 1144: -12,49 + 1145: -13,49 + 1146: -13,50 + 1147: -13,51 + 1148: -13,52 + 1149: -13,53 + 1201: 2,31 + 1202: -2,31 + 1260: 53,-3 + 1261: 54,-4 + 1262: 55,-5 + 1263: 56,-6 + 1264: 53,-1 + 1265: 53,-2 + 1297: 41,-1 + 1298: 45,-3 + 1312: 59,2 + 1318: 59,-1 + 1319: 59,0 + 1320: 59,1 + 1321: 61,-6 + 1338: 62,-1 + 1956: -8,-63 + 1957: -7,-63 + 1958: -6,-63 + 1959: -5,-63 + 1960: -4,-63 + 1961: -3,-63 + 1983: -9,-83 + 1984: -10,-83 + 2029: -1,-32 + 2030: -1,-31 + 2031: -1,-29 + 2032: -1,-30 + 2033: -1,-26 + 2034: -2,-23 + 2035: -2,-22 + 2036: -1,-21 + 2037: -1,-20 + 2038: -1,-19 + 2039: -1,-18 + 2060: 4,-51 + 2061: 3,-51 + 2062: 2,-51 + 2063: -1,-24 + 2064: -1,-25 + 2065: -1,-27 + 2066: -1,-28 - node: color: '#D4D4D433' id: QuarterTileOverlayGreyscale270 decals: - 3135: -3,49 - 3136: -2,49 - 3137: -1,49 + 3133: -3,49 + 3134: -2,49 + 3135: -1,49 - node: color: '#DE3A3A96' id: QuarterTileOverlayGreyscale270 decals: - 2733: 57,-9 + 2731: 57,-9 - node: color: '#1D1D21FF' id: QuarterTileOverlayGreyscale90 decals: - 2435: 42,40 + 2433: 42,40 - node: color: '#334E6DC8' id: QuarterTileOverlayGreyscale90 decals: - 629: 27,8 - 1347: 33,-3 + 627: 27,8 + 1345: 33,-3 - node: color: '#52B4E996' id: QuarterTileOverlayGreyscale90 decals: 247: -8,-40 - 552: -27,-42 - 3034: -38,-33 + 550: -27,-42 + 3032: -38,-33 - node: color: '#9FED5896' id: QuarterTileOverlayGreyscale90 @@ -5128,246 +5161,249 @@ entities: color: '#D381C996' id: QuarterTileOverlayGreyscale90 decals: - 833: -14,-50 + 831: -14,-50 - node: color: '#D4D4D428' id: QuarterTileOverlayGreyscale90 decals: - 1021: -48,3 - 1022: -47,3 - 1023: -46,3 - 1024: -46,2 - 1025: -46,1 - 1026: -45,1 - 1027: -34,1 - 1028: -33,1 - 1029: -32,1 - 1030: -31,1 - 1031: -30,1 - 1032: -29,1 - 1033: -28,1 - 1034: -27,1 - 1035: -23,1 - 1036: -22,1 - 1037: -21,1 - 1038: -20,1 - 1039: -19,1 - 1040: -18,1 - 1093: -44,-30 - 1119: -29,-2 - 1153: -13,53 - 1158: -9,53 - 1175: 1,53 - 1178: 1,52 - 1179: 1,51 - 1180: 1,50 - 1181: 1,48 - 1182: 1,47 - 1183: 1,46 - 1184: 1,45 - 1185: 1,44 - 1186: 1,43 - 1187: 1,42 - 1188: 1,41 - 1189: 1,40 - 1190: 1,39 - 1191: 1,38 - 1192: 2,38 - 1193: 2,37 - 1194: 2,37 - 1195: 2,36 - 1196: 2,35 - 1197: 2,34 - 1198: 2,33 - 1199: 2,32 - 1200: 2,31 - 1201: 1,30 - 1206: 1,29 - 1207: 1,25 - 1208: 1,24 - 1209: 1,23 - 1210: 1,22 - 1211: 1,21 - 1212: 1,20 - 1213: 1,20 - 1214: 1,19 - 1215: 1,18 - 1216: 2,26 - 1217: 2,27 - 1222: 18,1 - 1223: 19,1 - 1224: 20,1 - 1225: 21,1 - 1226: 22,1 - 1227: 23,1 - 1228: 24,1 - 1229: 25,1 - 1230: 26,1 - 1231: 27,1 - 1232: 28,1 - 1233: 29,1 - 1234: 30,1 - 1235: 31,1 - 1236: 32,1 - 1237: 33,1 - 1238: 34,2 - 1239: 35,2 - 1240: 36,2 - 1241: 37,1 - 1242: 38,1 - 1243: 39,1 - 1244: 40,1 - 1245: 41,1 - 1246: 42,1 - 1247: 43,1 - 1248: 44,1 - 1249: 45,1 - 1250: 46,1 - 1251: 47,1 - 1252: 48,1 - 1253: 49,1 - 1254: 50,1 - 1255: 51,1 - 1256: 52,1 - 1313: 57,-3 - 1324: 61,-6 - 1325: 61,-5 - 1326: 61,-4 - 1327: 61,-3 - 1328: 61,-2 - 1341: 62,0 - 1896: 1,-52 - 1897: 1,-53 - 1898: 1,-54 - 1899: 1,-55 - 1900: 1,-56 - 1901: 1,-57 - 1902: 1,-58 - 1903: 1,-59 - 1904: 1,-60 - 1905: 2,-60 - 1906: 3,-60 - 1907: 4,-60 - 1908: 4,-61 - 1909: 4,-62 - 1910: 4,-63 - 1911: 4,-64 - 1912: 4,-65 - 1913: 4,-66 - 1914: 4,-68 - 1915: 5,-68 - 1916: 5,-69 - 1917: 5,-70 - 1918: 4,-71 - 1919: 4,-67 - 1920: 4,-72 - 1921: 4,-73 - 1922: 4,-74 - 1923: 4,-75 - 1924: 5,-75 - 1925: 5,-76 - 1926: 5,-77 - 1927: 4,-78 - 1928: 4,-79 - 1929: 4,-80 - 1930: 4,-81 - 1965: -9,-64 - 1966: -9,-65 - 1967: -9,-66 - 1968: -9,-67 - 1969: -9,-68 - 1970: -9,-69 - 1971: -9,-70 - 1972: -9,-71 - 1973: -9,-72 - 1974: -9,-73 - 1975: -9,-74 - 1976: -9,-75 - 1977: -9,-76 - 1978: -9,-77 - 1979: -9,-78 - 1980: -9,-79 - 1981: -9,-80 - 1982: -9,-81 - 1983: -9,-82 - 1984: -9,-83 - 2050: 1,-41 - 2051: 2,-42 - 2052: 3,-42 - 2053: 3,-43 - 2054: 3,-44 - 2055: 3,-45 - 2056: 3,-46 - 2057: 3,-47 - 2058: 3,-48 - 2059: 4,-49 - 2060: 4,-50 - 2061: 4,-51 + 1019: -48,3 + 1020: -47,3 + 1021: -46,3 + 1022: -46,2 + 1023: -46,1 + 1024: -45,1 + 1025: -34,1 + 1026: -33,1 + 1027: -32,1 + 1028: -31,1 + 1029: -30,1 + 1030: -29,1 + 1031: -28,1 + 1032: -27,1 + 1033: -23,1 + 1034: -22,1 + 1035: -21,1 + 1036: -20,1 + 1037: -19,1 + 1038: -18,1 + 1091: -44,-30 + 1117: -29,-2 + 1151: -13,53 + 1156: -9,53 + 1173: 1,53 + 1176: 1,52 + 1177: 1,51 + 1178: 1,50 + 1179: 1,48 + 1180: 1,47 + 1181: 1,46 + 1182: 1,45 + 1183: 1,44 + 1184: 1,43 + 1185: 1,42 + 1186: 1,41 + 1187: 1,40 + 1188: 1,39 + 1189: 1,38 + 1190: 2,38 + 1191: 2,37 + 1192: 2,37 + 1193: 2,36 + 1194: 2,35 + 1195: 2,34 + 1196: 2,33 + 1197: 2,32 + 1198: 2,31 + 1199: 1,30 + 1204: 1,29 + 1205: 1,25 + 1206: 1,24 + 1207: 1,23 + 1208: 1,22 + 1209: 1,21 + 1210: 1,20 + 1211: 1,20 + 1212: 1,19 + 1213: 1,18 + 1214: 2,26 + 1215: 2,27 + 1220: 18,1 + 1221: 19,1 + 1222: 20,1 + 1223: 21,1 + 1224: 22,1 + 1225: 23,1 + 1226: 24,1 + 1227: 25,1 + 1228: 26,1 + 1229: 27,1 + 1230: 28,1 + 1231: 29,1 + 1232: 30,1 + 1233: 31,1 + 1234: 32,1 + 1235: 33,1 + 1236: 34,2 + 1237: 35,2 + 1238: 36,2 + 1239: 37,1 + 1240: 38,1 + 1241: 39,1 + 1242: 40,1 + 1243: 41,1 + 1244: 42,1 + 1245: 43,1 + 1246: 44,1 + 1247: 45,1 + 1248: 46,1 + 1249: 47,1 + 1250: 48,1 + 1251: 49,1 + 1252: 50,1 + 1253: 51,1 + 1254: 52,1 + 1311: 57,-3 + 1322: 61,-6 + 1323: 61,-5 + 1324: 61,-4 + 1325: 61,-3 + 1326: 61,-2 + 1339: 62,0 + 1894: 1,-52 + 1895: 1,-53 + 1896: 1,-54 + 1897: 1,-55 + 1898: 1,-56 + 1899: 1,-57 + 1900: 1,-58 + 1901: 1,-59 + 1902: 1,-60 + 1903: 2,-60 + 1904: 3,-60 + 1905: 4,-60 + 1906: 4,-61 + 1907: 4,-62 + 1908: 4,-63 + 1909: 4,-64 + 1910: 4,-65 + 1911: 4,-66 + 1912: 4,-68 + 1913: 5,-68 + 1914: 5,-69 + 1915: 5,-70 + 1916: 4,-71 + 1917: 4,-67 + 1918: 4,-72 + 1919: 4,-73 + 1920: 4,-74 + 1921: 4,-75 + 1922: 5,-75 + 1923: 5,-76 + 1924: 5,-77 + 1925: 4,-78 + 1926: 4,-79 + 1927: 4,-80 + 1928: 4,-81 + 1963: -9,-64 + 1964: -9,-65 + 1965: -9,-66 + 1966: -9,-67 + 1967: -9,-68 + 1968: -9,-69 + 1969: -9,-70 + 1970: -9,-71 + 1971: -9,-72 + 1972: -9,-73 + 1973: -9,-74 + 1974: -9,-75 + 1975: -9,-76 + 1976: -9,-77 + 1977: -9,-78 + 1978: -9,-79 + 1979: -9,-80 + 1980: -9,-81 + 1981: -9,-82 + 1982: -9,-83 + 2048: 1,-41 + 2049: 2,-42 + 2050: 3,-42 + 2051: 3,-43 + 2052: 3,-44 + 2053: 3,-45 + 2054: 3,-46 + 2055: 3,-47 + 2056: 3,-48 + 2057: 4,-49 + 2058: 4,-50 + 2059: 4,-51 - node: color: '#D4D4D433' id: QuarterTileOverlayGreyscale90 decals: - 3138: 1,49 - 3209: -35,1 + 3136: 1,49 + 3207: -35,1 - node: color: '#FFFFFFFF' id: Rock06 decals: - 2684: -6.549043,-18.995234 + 2682: -6.549043,-18.995234 - node: color: '#FFFFFFFF' id: Rock07 decals: - 2685: -10.21571,-19.245234 - 2686: -19.922543,-12.716649 - 2687: -18.60001,-10.259648 - 2688: -18.846893,-8.106161 + 2683: -10.21571,-19.245234 + 2684: -19.922543,-12.716649 + 2685: -18.60001,-10.259648 + 2686: -18.846893,-8.106161 - node: color: '#FFFFFFFF' id: SpaceStationSign1 decals: - 956: 31,0 + 954: 31,0 - node: color: '#FFFFFFFF' id: SpaceStationSign2 decals: - 955: 32,0 + 953: 32,0 - node: color: '#FFFFFFFF' id: SpaceStationSign3 decals: - 954: 33,0 + 952: 33,0 - node: color: '#FFFFFFFF' id: SpaceStationSign4 decals: - 953: 34,0 + 951: 34,0 - node: color: '#FFFFFFFF' id: SpaceStationSign5 decals: - 952: 35,0 + 950: 35,0 - node: color: '#FFFFFFFF' id: SpaceStationSign6 decals: - 951: 36,0 + 949: 36,0 - node: color: '#FFFFFFFF' id: SpaceStationSign7 decals: - 950: 37,0 + 948: 37,0 - node: angle: 1.5707963267948966 rad color: '#FFFFFFFF' id: StandClearGreyscale decals: - 3369: -56,-4 + 3367: -56,-4 - node: color: '#334E6DC8' id: ThreeQuarterTileOverlayGreyscale decals: - 582: 19,9 + 580: 19,9 + 3574: 21,18 + 3600: 28,15 + 3601: 29,16 - node: color: '#52B4E996' id: ThreeQuarterTileOverlayGreyscale @@ -5377,7 +5413,7 @@ entities: color: '#639137FF' id: ThreeQuarterTileOverlayGreyscale decals: - 661: 3,24 + 659: 3,24 - node: color: '#9FED5896' id: ThreeQuarterTileOverlayGreyscale @@ -5392,25 +5428,29 @@ entities: color: '#C6FF91FF' id: ThreeQuarterTileOverlayGreyscale decals: - 3025: -39,-31 + 3023: -39,-31 - node: color: '#334E6DC8' id: ThreeQuarterTileOverlayGreyscale180 decals: - 624: 27,4 - 625: 28,5 - 626: 28,5 + 622: 27,4 + 623: 28,5 + 624: 28,5 + 3578: 25,11 + 3579: 26,12 + 3604: 33,12 + 3605: 32,11 - node: color: '#52B4E996' id: ThreeQuarterTileOverlayGreyscale180 decals: 489: -14,-36 - 540: -12,-28 + 538: -12,-28 - node: color: '#639137FF' id: ThreeQuarterTileOverlayGreyscale180 decals: - 664: 10,19 + 662: 10,19 - node: color: '#9FED5896' id: ThreeQuarterTileOverlayGreyscale180 @@ -5426,7 +5466,11 @@ entities: color: '#334E6DC8' id: ThreeQuarterTileOverlayGreyscale270 decals: - 583: 19,4 + 581: 19,4 + 3576: 21,12 + 3577: 22,11 + 3606: 29,11 + 3607: 28,12 - node: color: '#52B4E996' id: ThreeQuarterTileOverlayGreyscale270 @@ -5436,7 +5480,7 @@ entities: color: '#639137FF' id: ThreeQuarterTileOverlayGreyscale270 decals: - 663: 3,19 + 661: 3,19 - node: color: '#9FED5896' id: ThreeQuarterTileOverlayGreyscale270 @@ -5452,13 +5496,16 @@ entities: color: '#C6FF91FF' id: ThreeQuarterTileOverlayGreyscale270 decals: - 3016: -39,-35 + 3014: -39,-35 - node: color: '#334E6DC8' id: ThreeQuarterTileOverlayGreyscale90 decals: - 627: 28,8 - 628: 27,9 + 625: 28,8 + 626: 27,9 + 3575: 26,18 + 3602: 32,16 + 3603: 33,15 - node: color: '#52B4E996' id: ThreeQuarterTileOverlayGreyscale90 @@ -5468,7 +5515,7 @@ entities: color: '#639137FF' id: ThreeQuarterTileOverlayGreyscale90 decals: - 662: 10,24 + 660: 10,24 - node: color: '#9FED5896' id: ThreeQuarterTileOverlayGreyscale90 @@ -5478,200 +5525,201 @@ entities: 174: -29,-11 175: -32,-11 483: -29,-23 - 3036: -35,-31 + 3034: -35,-31 - node: color: '#FFFFFFFF' id: WarnBox decals: - 3559: -24,36 - 3560: -25,37 - 3561: -26,37 - 3562: -27,37 - 3563: -28,37 - 3564: -29,37 - 3565: -30,37 - 3566: -31,36 - 3567: -25,35 - 3568: -26,35 - 3569: -28,35 - 3570: -29,35 - 3571: -30,35 + 3557: -24,36 + 3558: -25,37 + 3559: -26,37 + 3560: -27,37 + 3561: -28,37 + 3562: -29,37 + 3563: -30,37 + 3564: -31,36 + 3565: -25,35 + 3566: -26,35 + 3567: -28,35 + 3568: -29,35 + 3569: -30,35 - node: color: '#FFFFFFFF' id: WarnCornerGreyscaleNW decals: - 3492: -6,-26 + 3490: -6,-26 - node: color: '#FFFFFFFF' id: WarnCornerSmallGreyscaleNW decals: - 3508: -6,-29 + 3506: -6,-29 - node: color: '#FFFFFFFF' id: WarnCornerSmallNE decals: - 3342: -58,-13 - 3558: -22,42 - 3574: -31,35 + 3340: -58,-13 + 3556: -22,42 + 3572: -31,35 - node: color: '#FFFFFFFF' id: WarnCornerSmallNW decals: - 981: -56,-7 - 985: -56,-3 - 1001: -54,-13 - 3557: -18,42 - 3575: -24,35 + 979: -56,-7 + 983: -56,-3 + 999: -54,-13 + 3555: -18,42 + 3573: -24,35 - node: color: '#FFFFFFFF' id: WarnCornerSmallSE decals: - 3341: -58,-8 - 3555: -22,44 - 3573: -31,37 + 3339: -58,-8 + 3553: -22,44 + 3571: -31,37 - node: color: '#FFFFFFFF' id: WarnCornerSmallSW decals: - 979: -56,-1 - 980: -56,-1 - 986: -56,-5 - 1000: -54,-8 - 3556: -18,44 - 3572: -24,37 + 977: -56,-1 + 978: -56,-1 + 984: -56,-5 + 998: -54,-8 + 3554: -18,44 + 3570: -24,37 - node: color: '#FFFFFFFF' id: WarnFull decals: - 2481: 12,53 - 2482: 13,53 - 2483: 14,53 + 2479: 12,53 + 2480: 13,53 + 2481: 14,53 - node: color: '#BC863FFF' id: WarnFullGreyscale decals: - 3365: -51,-1 - 3366: -51,0 - 3367: -52,-1 - 3368: -52,0 + 3363: -51,-1 + 3364: -51,0 + 3365: -52,-1 + 3366: -52,0 - node: color: '#FFFFFFFF' id: WarnLineE decals: - 2463: 9,49 - 2465: 19,49 - 2466: 19,48 - 2467: 19,47 - 2468: 19,46 - 3336: -58,-12 - 3337: -58,-11 - 3338: -58,-10 - 3339: -58,-9 - 3551: -22,43 + 2461: 9,49 + 2463: 19,49 + 2464: 19,48 + 2465: 19,47 + 2466: 19,46 + 3334: -58,-12 + 3335: -58,-11 + 3336: -58,-10 + 3337: -58,-9 + 3549: -22,43 - node: color: '#FFFFFFFF' id: WarnLineGreyscaleN decals: - 3493: -5,-26 - 3494: -4,-26 - 3495: -3,-26 - 3505: -9,-29 - 3506: -8,-29 - 3507: -7,-29 + 3491: -5,-26 + 3492: -4,-26 + 3493: -3,-26 + 3503: -9,-29 + 3504: -8,-29 + 3505: -7,-29 - node: color: '#FFFFFFFF' id: WarnLineGreyscaleS decals: - 3498: -9,-30 - 3499: -8,-30 - 3500: -7,-30 - 3501: -6,-30 - 3502: -5,-30 - 3503: -4,-30 - 3504: -3,-30 + 3496: -9,-30 + 3497: -8,-30 + 3498: -7,-30 + 3499: -6,-30 + 3500: -5,-30 + 3501: -4,-30 + 3502: -3,-30 - node: color: '#FFFFFFFF' id: WarnLineGreyscaleW decals: - 982: -56,-5 - 983: -56,-4 - 984: -56,-3 - 3496: -6,-27 - 3497: -6,-28 + 980: -56,-5 + 981: -56,-4 + 982: -56,-3 + 3494: -6,-27 + 3495: -6,-28 - node: color: '#FFFFFFFF' id: WarnLineN decals: - 976: -57,-1 - 990: -57,-8 - 991: -56,-8 - 992: -56,-8 - 993: -55,-8 - 3343: -58,-1 - 3548: -19,44 - 3549: -20,44 - 3550: -21,44 + 974: -57,-1 + 988: -57,-8 + 989: -56,-8 + 990: -56,-8 + 991: -55,-8 + 3341: -58,-1 + 3546: -19,44 + 3547: -20,44 + 3548: -21,44 - node: color: '#FFFFFFFF' id: WarnLineS decals: - 977: -56,-6 - 978: -56,-2 - 994: -54,-10 - 995: -54,-11 - 996: -54,-12 - 2464: 17,49 - 3340: -54,-9 - 3542: 21,46 - 3543: 21,47 - 3544: 21,48 - 3545: 21,49 - 3547: -18,43 + 975: -56,-6 + 976: -56,-2 + 992: -54,-10 + 993: -54,-11 + 994: -54,-12 + 2462: 17,49 + 3338: -54,-9 + 3540: 21,46 + 3541: 21,47 + 3542: 21,48 + 3543: 21,49 + 3545: -18,43 - node: color: '#FFFFFFFF' id: WarnLineW decals: - 975: -57,-7 - 997: -55,-13 - 998: -56,-13 - 999: -57,-13 - 2460: 12,46 - 2461: 13,46 - 2462: 14,46 - 2473: 7,51 - 2474: 8,51 - 2475: 9,51 - 2476: 17,51 - 2477: 18,51 - 2478: 19,51 - 2479: 15,53 - 2480: 11,53 - 3344: -58,-7 - 3552: -21,42 - 3553: -20,42 - 3554: -19,42 + 973: -57,-7 + 995: -55,-13 + 996: -56,-13 + 997: -57,-13 + 2458: 12,46 + 2459: 13,46 + 2460: 14,46 + 2471: 7,51 + 2472: 8,51 + 2473: 9,51 + 2474: 17,51 + 2475: 18,51 + 2476: 19,51 + 2477: 15,53 + 2478: 11,53 + 3342: -58,-7 + 3550: -21,42 + 3551: -20,42 + 3552: -19,42 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerNe decals: 266: -30,-39 286: -29,-35 - 685: 37,-7 - 691: 44,-5 - 739: -4,38 - 740: -12,33 - 781: -16,32 - 797: -19,-3 - 851: -49,7 - 854: -53,12 - 855: -51,10 - 897: 36,18 - 904: 40,16 - 924: 44,-9 - 931: 17,-30 - 932: 20,-30 - 2831: 41,23 - 3066: 19,37 + 683: 37,-7 + 689: 44,-5 + 737: -4,38 + 738: -12,33 + 779: -16,32 + 795: -19,-3 + 849: -49,7 + 852: -53,12 + 853: -51,10 + 895: 36,18 + 902: 40,16 + 922: 44,-9 + 929: 17,-30 + 930: 20,-30 + 2829: 41,23 + 3064: 19,37 + 3614: 10,-19 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerNw @@ -5679,108 +5727,111 @@ entities: 269: -31,-39 270: -31,-39 287: -33,-35 - 678: 35,-7 - 679: 35,-3 - 692: 39,-5 - 741: -14,38 - 742: -14,33 - 782: -19,32 - 798: -22,-3 - 850: -50,7 - 856: -55,12 - 857: -57,10 - 898: 35,18 - 905: 38,16 - 906: 35,15 - 921: 42,-9 - 933: 13,-30 - 934: 19,-30 - 2832: 39,23 - 3067: 12,37 + 676: 35,-7 + 677: 35,-3 + 690: 39,-5 + 739: -14,38 + 740: -14,33 + 780: -19,32 + 796: -22,-3 + 848: -50,7 + 854: -55,12 + 855: -57,10 + 896: 35,18 + 903: 38,16 + 904: 35,15 + 919: 42,-9 + 931: 13,-30 + 932: 19,-30 + 2830: 39,23 + 3065: 12,37 + 3615: 7,-19 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerSe decals: 268: -30,-41 297: -29,-37 - 689: 37,-5 - 704: 44,-7 - 743: -12,31 - 744: -4,31 - 783: -16,27 - 799: -19,-5 - 848: -49,5 - 859: -51,9 - 889: 41,18 - 900: 36,17 - 901: 40,11 - 922: 44,-10 - 935: 17,-32 - 936: 20,-32 - 3077: 19,36 + 687: 37,-5 + 702: 44,-7 + 741: -12,31 + 742: -4,31 + 781: -16,27 + 797: -19,-5 + 846: -49,5 + 857: -51,9 + 887: 41,18 + 898: 36,17 + 899: 40,11 + 920: 44,-10 + 933: 17,-32 + 934: 20,-32 + 3075: 19,36 + 3617: 10,-21 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerSw decals: 267: -31,-41 295: -33,-37 - 676: 35,-5 - 677: 35,-9 - 693: 39,-7 - 745: -14,31 - 746: -14,35 - 747: -10,31 - 784: -19,27 - 800: -22,-5 - 849: -50,5 - 858: -57,9 - 888: 39,18 - 899: 35,17 - 902: 38,11 - 903: 35,12 - 923: 42,-10 - 937: 13,-32 - 938: 19,-32 + 674: 35,-5 + 675: 35,-9 + 691: 39,-7 + 743: -14,31 + 744: -14,35 + 745: -10,31 + 782: -19,27 + 798: -22,-5 + 847: -50,5 + 856: -57,9 + 886: 39,18 + 897: 35,17 + 900: 38,11 + 901: 35,12 + 921: 42,-10 + 935: 13,-32 + 936: 19,-32 + 3616: 7,-21 - node: color: '#FFFFFFFF' id: WoodTrimThinEndE decals: - 671: 38,-3 - 672: 38,-9 + 669: 38,-3 + 670: 38,-9 - node: color: '#FFFFFFFF' id: WoodTrimThinEndN decals: - 919: 46,-5 + 917: 46,-5 - node: color: '#FFFFFFFF' id: WoodTrimThinEndS decals: - 920: 46,-6 + 918: 46,-6 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerNe decals: - 687: 37,-9 - 870: -53,10 + 685: 37,-9 + 868: -53,10 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerNw decals: - 871: -55,10 - 918: 38,15 + 869: -55,10 + 916: 38,15 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerSe decals: - 690: 37,-3 - 3079: 17,36 + 688: 37,-3 + 3077: 17,36 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerSw decals: - 777: -10,35 - 917: 38,12 + 775: -10,35 + 915: 38,12 - node: color: '#FFFFFFFF' id: WoodTrimThinLineE @@ -5797,34 +5848,35 @@ entities: 279: -32.293655,-40.00201 280: -32.29232,-41.003887 298: -29,-36 - 686: 37,-8 - 688: 37,-4 - 705: 44,-6 - 754: -4,32 - 755: -4,33 - 756: -4,34 - 757: -4,35 - 758: -4,36 - 759: -4,37 - 760: -12,32 - 785: -16,31 - 786: -16,30 - 787: -16,29 - 788: -16,28 - 801: -19,-4 - 853: -49,6 - 869: -53,11 - 890: 41,19 - 891: 41,20 - 892: 41,21 - 907: 40,14 - 908: 40,15 - 909: 40,12 - 910: 40,13 - 939: 20,-31 - 940: 17,-31 - 2833: 41,22 - 3068: 17,35 + 684: 37,-8 + 686: 37,-4 + 703: 44,-6 + 752: -4,32 + 753: -4,33 + 754: -4,34 + 755: -4,35 + 756: -4,36 + 757: -4,37 + 758: -12,32 + 783: -16,31 + 784: -16,30 + 785: -16,29 + 786: -16,28 + 799: -19,-4 + 851: -49,6 + 867: -53,11 + 888: 41,19 + 889: 41,20 + 890: 41,21 + 905: 40,14 + 906: 40,15 + 907: 40,12 + 908: 40,13 + 937: 20,-31 + 938: 17,-31 + 2831: 41,22 + 3066: 17,35 + 3623: 10,-20 - node: color: '#FFFFFFFF' id: WoodTrimThinLineN @@ -5834,46 +5886,48 @@ entities: 288: -32,-35 289: -31,-35 290: -30,-35 - 680: 36,-3 - 681: 37,-3 - 684: 36,-7 - 699: 40,-5 - 700: 41,-5 - 701: 41,-5 - 702: 42,-5 - 703: 43,-5 - 761: -5,38 - 762: -6,38 - 763: -7,38 - 764: -8,38 - 765: -9,38 - 766: -10,38 - 767: -11,38 - 768: -12,38 - 769: -13,38 - 770: -13,33 - 791: -17,32 - 792: -18,32 - 805: -21,-3 - 806: -20,-3 - 807: -19,-3 - 865: -54,12 - 866: -56,10 - 867: -52,10 - 913: 36,15 - 914: 37,15 - 926: 43,-9 - 946: 14,-30 - 947: 15,-30 - 948: 15,-30 - 949: 16,-30 - 2835: 40,23 - 3071: 13,37 - 3072: 14,37 - 3073: 15,37 - 3074: 16,37 - 3075: 17,37 - 3076: 18,37 + 678: 36,-3 + 679: 37,-3 + 682: 36,-7 + 697: 40,-5 + 698: 41,-5 + 699: 41,-5 + 700: 42,-5 + 701: 43,-5 + 759: -5,38 + 760: -6,38 + 761: -7,38 + 762: -8,38 + 763: -9,38 + 764: -10,38 + 765: -11,38 + 766: -12,38 + 767: -13,38 + 768: -13,33 + 789: -17,32 + 790: -18,32 + 803: -21,-3 + 804: -20,-3 + 805: -19,-3 + 863: -54,12 + 864: -56,10 + 865: -52,10 + 911: 36,15 + 912: 37,15 + 924: 43,-9 + 944: 14,-30 + 945: 15,-30 + 946: 15,-30 + 947: 16,-30 + 2833: 40,23 + 3069: 13,37 + 3070: 14,37 + 3071: 15,37 + 3072: 16,37 + 3073: 17,37 + 3074: 18,37 + 3621: 8,-19 + 3622: 9,-19 - node: color: '#FFFFFFFF' id: WoodTrimThinLineS @@ -5885,71 +5939,74 @@ entities: 292: -31,-37 293: -31,-37 294: -30,-37 - 673: 37,-9 - 674: 36,-9 - 675: 36,-5 - 695: 40,-7 - 696: 41,-7 - 697: 42,-7 - 698: 43,-7 - 748: -13,31 - 749: -9,31 - 750: -8,31 - 751: -7,31 - 752: -6,31 - 753: -5,31 - 778: -11,35 - 779: -12,35 - 780: -13,35 - 789: -17,27 - 790: -18,27 - 803: -21,-5 - 804: -20,-5 - 860: -56,9 - 861: -55,9 - 862: -54,9 - 863: -53,9 - 864: -52,9 - 893: 40,18 - 915: 36,12 - 916: 37,12 - 925: 43,-10 - 943: 14,-32 - 944: 15,-32 - 945: 16,-32 - 3078: 18,36 + 671: 37,-9 + 672: 36,-9 + 673: 36,-5 + 693: 40,-7 + 694: 41,-7 + 695: 42,-7 + 696: 43,-7 + 746: -13,31 + 747: -9,31 + 748: -8,31 + 749: -7,31 + 750: -6,31 + 751: -5,31 + 776: -11,35 + 777: -12,35 + 778: -13,35 + 787: -17,27 + 788: -18,27 + 801: -21,-5 + 802: -20,-5 + 858: -56,9 + 859: -55,9 + 860: -54,9 + 861: -53,9 + 862: -52,9 + 891: 40,18 + 913: 36,12 + 914: 37,12 + 923: 43,-10 + 941: 14,-32 + 942: 15,-32 + 943: 16,-32 + 3076: 18,36 + 3618: 9,-21 + 3619: 8,-21 - node: color: '#FFFFFFFF' id: WoodTrimThinLineW decals: 264: -31,-40 296: -33,-36 - 682: 35,-4 - 683: 35,-8 - 694: 39,-6 - 771: -14,37 - 772: -14,36 - 773: -14,32 - 774: -10,32 - 775: -10,33 - 776: -10,34 - 793: -19,31 - 794: -19,30 - 795: -19,29 - 796: -19,28 - 802: -22,-4 - 852: -50,6 - 868: -55,11 - 894: 39,19 - 895: 39,20 - 896: 39,21 - 911: 35,13 - 912: 35,14 - 941: 19,-31 - 942: 13,-31 - 2834: 39,22 - 3069: 12,35 - 3070: 12,36 + 680: 35,-4 + 681: 35,-8 + 692: 39,-6 + 769: -14,37 + 770: -14,36 + 771: -14,32 + 772: -10,32 + 773: -10,33 + 774: -10,34 + 791: -19,31 + 792: -19,30 + 793: -19,29 + 794: -19,28 + 800: -22,-4 + 850: -50,6 + 866: -55,11 + 892: 39,19 + 893: 39,20 + 894: 39,21 + 909: 35,13 + 910: 35,14 + 939: 19,-31 + 940: 13,-31 + 2832: 39,22 + 3067: 12,35 + 3068: 12,36 + 3620: 7,-20 - type: GridAtmosphere version: 2 data: @@ -6313,7 +6370,8 @@ entities: 1,6: 0: 65295 1,7: - 0: 65295 + 0: 62223 + 2: 3072 1,8: 0: 65535 2,5: @@ -6646,7 +6704,7 @@ entities: 0: 16383 1,-13: 0: 57104 - 2: 8 + 3: 8 2,-12: 0: 65308 2,-11: @@ -6655,7 +6713,7 @@ entities: 0: 28671 2,-13: 0: 7936 - 2: 8 + 3: 8 3,-12: 0: 62349 3,-11: @@ -6664,7 +6722,7 @@ entities: 0: 61182 3,-13: 0: 55040 - 2: 4 + 3: 4 3,-9: 0: 3822 4,-12: @@ -6792,7 +6850,7 @@ entities: 10,-10: 0: 62207 10,-13: - 2: 9902 + 3: 9902 11,-12: 0: 4913 11,-11: @@ -6801,7 +6859,7 @@ entities: 0: 65262 11,-13: 0: 4352 - 2: 127 + 3: 127 12,-10: 0: 65488 12,-9: @@ -6907,14 +6965,14 @@ entities: 12,6: 0: 64271 12,7: - 2: 16368 + 3: 16368 -12,-12: 0: 13119 -12,-13: 0: 65427 -13,-12: 0: 56524 - 3: 17 + 4: 17 -12,-11: 0: 60931 -13,-11: @@ -7012,70 +7070,70 @@ entities: -13,1: 0: 57296 -12,1: - 2: 36352 + 3: 36352 -12,3: - 2: 34956 + 3: 34956 -11,1: 0: 127 - 2: 30464 + 3: 30464 -12,2: - 2: 34952 + 3: 34952 -11,2: - 2: 255 - 4: 57344 + 3: 255 + 5: 57344 -12,4: - 2: 53192 + 3: 53192 -11,3: - 2: 61440 - 5: 224 + 3: 61440 + 6: 224 -10,1: 0: 40847 -10,2: - 2: 8755 + 3: 8755 0: 34952 -10,3: - 2: 12834 + 3: 12834 0: 34952 -10,4: - 2: 8738 + 3: 8738 0: 34952 -13,4: - 2: 32630 + 3: 32630 -12,7: - 2: 52476 + 3: 52476 -13,7: - 2: 26615 + 3: 26615 -12,6: - 2: 51336 + 3: 51336 -12,5: - 2: 34952 + 3: 34952 -11,6: - 2: 61440 - 3: 224 + 3: 61440 + 4: 224 -12,8: - 2: 34952 + 3: 34952 -11,4: - 6: 224 - 3: 57344 + 7: 224 + 4: 57344 -11,5: - 3: 57568 + 4: 57568 -11,7: - 3: 57568 + 4: 57568 -10,6: - 2: 12834 + 3: 12834 0: 34952 -10,5: - 2: 8738 + 3: 8738 0: 34952 -10,7: - 2: 8738 + 3: 8738 0: 34952 -10,8: - 2: 62258 + 3: 62258 0: 136 -9,8: 0: 52479 - 2: 4096 + 3: 4096 0,-16: 0: 65528 -1,-16: @@ -7096,23 +7154,23 @@ entities: 0: 257 1,-14: 0: 4369 - 2: 34956 + 3: 34956 1,-17: 0: 4371 2,-14: - 2: 63631 + 3: 63631 2,-15: - 2: 39315 + 3: 39315 2,-16: - 2: 27776 + 3: 27776 3,-16: - 2: 57375 + 3: 57375 3,-15: - 2: 12443 + 3: 12443 3,-14: - 2: 61488 + 3: 61488 4,-16: - 2: 4883 + 3: 4883 -4,-15: 0: 65088 -4,-14: @@ -7136,7 +7194,7 @@ entities: -2,-14: 0: 65520 -9,-15: - 3: 2048 + 4: 2048 -8,-14: 0: 4080 -9,-14: @@ -7146,69 +7204,69 @@ entities: -9,-13: 0: 4095 -7,-15: - 3: 61184 + 4: 61184 -7,-14: 0: 32752 -6,-15: - 3: 256 + 4: 256 0: 32768 -6,-14: 0: 65528 -12,-16: - 2: 4880 + 3: 4880 -13,-16: - 2: 65520 + 3: 65520 -12,-15: - 3: 53128 + 4: 53128 -12,-14: 0: 30483 - 3: 4 + 4: 4 -13,-14: 0: 52232 - 2: 23 + 3: 23 -11,-16: - 3: 4352 + 4: 4352 -11,-15: - 3: 65425 + 4: 65425 -11,-14: 0: 65520 -11,-13: 0: 831 -10,-15: - 3: 14327 + 4: 14327 -10,-14: 0: 16304 -10,-13: 0: 2187 -10,-16: - 3: 8704 + 4: 8704 -10,-17: - 3: 49152 + 4: 49152 -16,-7: - 2: 52416 + 3: 52416 -16,-6: - 2: 3276 + 3: 3276 0: 32768 -16,-5: 0: 3080 -16,-4: - 2: 140 + 3: 140 -15,-7: - 2: 4368 + 3: 4368 0: 3276 -15,-6: - 2: 273 + 3: 273 0: 52428 -15,-5: 0: 53199 -15,-4: - 2: 4369 + 3: 4369 0: 52416 -15,-8: 0: 52416 -15,-9: 0: 34952 - 3: 256 + 4: 256 -14,-8: 0: 49080 -14,-7: @@ -7228,31 +7286,31 @@ entities: -13,-7: 0: 26214 -16,-12: - 3: 32 + 4: 32 -16,-11: - 3: 32768 + 4: 32768 -16,-10: - 3: 8 + 4: 8 -15,-11: - 3: 13036 + 4: 13036 0: 32768 -15,-10: - 3: 307 + 4: 307 0: 34952 -15,-12: - 3: 51336 + 4: 51336 -14,-12: - 3: 4607 + 4: 4607 0: 49152 -14,-11: - 3: 17 + 4: 17 0: 61644 -14,-10: 0: 65535 -14,-13: - 3: 59392 + 4: 59392 -13,-13: - 3: 4352 + 4: 4352 0: 1604 8,9: 0: 65535 @@ -7281,28 +7339,28 @@ entities: 10,10: 0: 3549 10,11: - 3: 275 + 4: 275 10,12: 0: 305 - 2: 3276 + 3: 3276 11,9: 0: 4469 - 2: 49152 + 3: 49152 11,10: 0: 273 - 2: 52428 + 3: 52428 11,11: - 2: 61166 + 3: 61166 11,12: - 2: 53247 + 3: 53247 12,8: - 2: 13107 + 3: 13107 12,9: - 2: 13107 + 3: 13107 12,10: - 2: 63923 + 3: 63923 12,11: - 2: 61443 + 3: 61443 4,9: 0: 57599 3,9: @@ -7325,7 +7383,7 @@ entities: 0: 60928 5,12: 0: 238 - 2: 49152 + 3: 49152 6,9: 0: 65535 6,10: @@ -7394,26 +7452,26 @@ entities: 0: 16183 15,1: 0: 13119 - 2: 18432 + 3: 18432 15,2: 0: 13107 - 2: 32836 + 3: 32836 15,3: 0: 13107 - 2: 2184 + 3: 2184 15,-1: 0: 30527 15,4: 0: 13107 - 2: 32768 + 3: 32768 16,0: 0: 1793 - 2: 4 + 3: 4 16,1: 0: 7 - 2: 1024 + 3: 1024 16,3: - 2: 4368 + 3: 4368 13,-4: 0: 26215 13,-3: @@ -7432,22 +7490,22 @@ entities: 0: 61098 15,-4: 0: 4113 - 2: 34952 + 3: 34952 15,-3: 0: 4369 - 2: 34952 + 3: 34952 15,-2: 0: 16177 - 2: 8 + 3: 8 15,-5: 0: 4353 - 2: 34952 + 3: 34952 16,-2: 0: 1792 - 2: 4 + 3: 4 16,-1: 0: 4359 - 2: 17408 + 3: 17408 13,-8: 0: 15 13,-6: @@ -7461,56 +7519,56 @@ entities: 14,-9: 0: 36623 15,-8: - 3: 16 + 4: 16 15,-6: - 3: 16 + 4: 16 0: 4096 - 2: 32768 + 3: 32768 15,-9: 0: 4353 16,-5: - 2: 304 + 3: 304 12,-11: - 3: 49156 + 4: 49156 12,-12: - 2: 12 + 3: 12 12,-13: - 2: 52303 + 3: 52303 13,-12: - 2: 15 - 3: 16384 + 3: 15 + 4: 16384 13,-11: - 3: 65228 + 4: 65228 13,-10: 0: 65520 13,-13: - 2: 65295 + 3: 65295 14,-12: - 2: 15 + 3: 15 14,-11: - 3: 65521 + 4: 65521 14,-10: 0: 65392 14,-13: - 2: 65295 + 3: 65295 15,-12: - 2: 1 + 3: 1 15,-11: - 3: 4112 + 4: 4112 15,-10: - 3: 52451 + 4: 52451 0: 4096 15,-13: - 2: 4511 + 3: 4511 16,-10: - 3: 19 + 4: 19 -4,9: 0: 7421 -5,9: 0: 62719 -4,10: 0: 65533 - 7: 2 + 8: 2 -5,10: 0: 65535 -4,11: @@ -7519,13 +7577,13 @@ entities: 0: 32767 -4,12: 0: 34945 - 3: 13072 + 4: 13072 -3,9: 0: 4095 -3,10: 0: 65535 -3,11: - 3: 61408 + 4: 61408 -2,9: 0: 4095 -2,10: @@ -7538,23 +7596,23 @@ entities: 0: 61678 -9,9: 0: 52428 - 2: 4369 + 3: 4369 -8,10: 0: 65535 -9,10: 0: 52428 -8,11: - 2: 43808 + 3: 43808 -9,11: - 2: 20224 + 3: 20224 -8,12: - 2: 43690 + 3: 43690 -7,9: 0: 45311 -7,10: 0: 49087 -7,11: - 2: 768 + 3: 768 0: 34952 -6,9: 0: 61661 @@ -7562,44 +7620,44 @@ entities: 0: 65535 -6,11: 0: 64255 - 8: 256 - 7: 1024 + 9: 256 + 8: 1024 -7,12: 0: 34952 - 2: 12322 + 3: 12322 -6,12: 0: 65535 -5,12: 0: 13111 - 3: 34816 + 4: 34816 -12,9: - 2: 65433 + 3: 65433 -13,9: - 2: 8 + 3: 8 -12,10: - 2: 52428 + 3: 52428 -11,8: - 2: 65520 + 3: 65520 -11,9: - 2: 4607 - 3: 49152 + 3: 4607 + 4: 49152 -11,10: - 2: 33041 - 3: 204 + 3: 33041 + 4: 204 -12,11: - 2: 136 + 3: 136 -11,11: - 2: 248 + 3: 248 -10,9: - 2: 52479 - 3: 4096 + 3: 52479 + 4: 4096 -10,10: - 3: 17 - 2: 34952 + 4: 17 + 3: 34952 -10,11: - 2: 2296 + 3: 2296 -9,12: - 2: 17476 + 3: 17476 8,-15: 0: 65535 7,-15: @@ -7613,50 +7671,50 @@ entities: 9,-14: 0: 4403 10,-16: - 2: 3584 + 3: 3584 11,-16: - 2: 7936 + 3: 7936 10,-14: - 2: 34816 + 3: 34816 11,-14: - 2: 29489 + 3: 29489 11,-15: - 2: 4369 + 3: 4369 12,-16: - 2: 3840 + 3: 3840 4,-17: - 2: 4096 + 3: 4096 4,-14: - 2: 2048 + 3: 2048 5,-14: - 2: 1024 + 3: 1024 6,-14: - 2: 512 + 3: 512 -8,13: - 2: 29666 + 3: 29666 -9,13: - 2: 3140 + 3: 3140 -8,14: - 2: 15 + 3: 15 -7,13: - 2: 32816 + 3: 32816 0: 1032 -7,14: - 2: 15 + 3: 15 -6,13: 0: 255 -6,14: - 2: 49 + 3: 49 -5,13: 0: 51 - 3: 51208 + 4: 51208 -5,14: - 3: 264 + 4: 264 -4,13: - 3: 29443 + 4: 29443 0: 136 -4,14: - 3: 3 + 4: 3 -3,12: 0: 65520 -3,13: @@ -7675,166 +7733,166 @@ entities: 0: 8866 1,14: 0: 8710 - 2: 34952 + 3: 34952 1,15: 0: 8226 - 2: 34952 + 3: 34952 1,16: 0: 8738 - 2: 34952 + 3: 34952 2,13: 0: 184 2,14: - 2: 49023 + 3: 49023 2,15: - 2: 44974 + 3: 44974 2,16: - 2: 32702 + 3: 32702 3,13: 0: 255 3,14: - 2: 44847 + 3: 44847 3,15: - 2: 44975 + 3: 44975 3,16: - 2: 12207 + 3: 12207 4,14: - 2: 61439 + 3: 61439 4,15: - 2: 44971 + 3: 44971 4,13: 0: 224 4,16: - 2: 65515 + 3: 65515 5,15: - 2: 1279 + 3: 1279 0: 8192 5,13: 0: 8738 - 3: 136 + 4: 136 5,14: 0: 546 - 2: 16384 + 3: 16384 5,16: 0: 8738 6,15: - 2: 255 + 3: 255 6,13: 0: 1262 7,13: 0: 1279 7,15: - 2: 255 + 3: 255 8,15: - 2: 255 + 3: 255 9,15: - 2: 255 + 3: 255 10,15: - 2: 55 + 3: 55 10,14: - 2: 65224 + 3: 65224 11,14: - 2: 311 + 3: 311 11,13: - 2: 65228 + 3: 65228 12,12: - 2: 65535 + 3: 65535 13,10: - 2: 17 + 3: 17 13,9: - 2: 13028 + 3: 13028 13,8: - 2: 19652 + 3: 19652 13,7: - 2: 20478 + 3: 20478 14,9: - 2: 248 + 3: 248 14,8: - 2: 52428 + 3: 52428 14,7: - 2: 51711 + 3: 51711 15,8: - 2: 56797 + 3: 56797 15,9: - 2: 248 + 3: 248 15,7: - 2: 55539 + 3: 55539 16,8: - 2: 56797 + 3: 56797 16,9: - 2: 248 + 3: 248 13,5: 0: 1911 13,6: 0: 4111 - 2: 60928 + 3: 60928 14,5: 0: 4369 14,6: 0: 1 - 2: 13056 + 3: 13056 15,6: - 2: 14024 + 3: 14024 16,4: - 2: 29233 + 3: 29233 16,6: - 2: 34947 + 3: 34947 16,7: - 2: 55544 + 3: 55544 13,12: - 2: 4095 + 3: 4095 14,12: - 2: 4095 + 3: 4095 15,12: - 2: 4095 + 3: 4095 16,12: - 2: 883 + 3: 883 0,18: - 2: 49160 + 3: 49160 0,17: - 2: 34816 + 3: 34816 1,17: - 2: 24856 + 3: 24856 0: 3106 1,18: - 2: 61987 + 3: 61987 2,17: - 2: 57359 + 3: 57359 0: 1792 2,18: - 2: 4238 + 3: 4238 3,17: - 2: 61455 + 3: 61455 0: 1792 3,18: - 2: 255 + 3: 255 4,17: - 2: 12303 + 3: 12303 0: 3840 4,18: - 2: 49155 + 3: 49155 5,17: 0: 290 - 2: 48192 + 3: 48192 5,18: - 2: 61998 + 3: 61998 6,17: - 2: 18244 + 3: 18244 6,18: - 2: 4164 + 3: 4164 6,16: - 2: 16384 + 3: 16384 -15,0: - 2: 1 + 3: 1 0: 52428 -15,1: - 2: 4401 + 3: 4401 0: 34944 -15,2: - 2: 4369 + 3: 4369 0: 2176 -15,3: - 2: 34959 + 3: 34959 -15,-1: 0: 52732 -14,0: @@ -7844,49 +7902,49 @@ entities: -14,2: 0: 61439 -14,3: - 2: 61440 + 3: 61440 0: 14 -14,-1: 0: 65535 -13,2: 0: 817 - 2: 128 + 3: 128 -13,3: - 2: 12834 + 3: 12834 -13,5: - 2: 8742 + 3: 8742 -13,6: - 2: 25122 + 3: 25122 -13,8: - 2: 50722 + 3: 50722 -16,-16: - 2: 30583 + 3: 30583 -16,-17: - 2: 29187 + 3: 29187 -16,-15: - 2: 29426 + 3: 29426 -17,-15: - 2: 29426 + 3: 29426 -16,-14: - 2: 30583 + 3: 30583 -16,-13: - 2: 2 + 3: 2 -15,-15: - 2: 240 + 3: 240 -15,-16: - 2: 65520 + 3: 65520 -15,-13: - 3: 64 + 4: 64 -14,-16: - 2: 24404 + 3: 24404 -14,-15: - 2: 52980 + 3: 52980 -14,-17: - 2: 24404 + 3: 24404 -13,-15: - 2: 29456 + 3: 29456 -14,-14: - 2: 8 + 3: 8 0,-20: 0: 34952 0,-19: @@ -7920,140 +7978,140 @@ entities: -2,-18: 0: 4096 -16,-2: - 2: 12 + 3: 12 0: 51200 -16,-1: 0: 2240 -16,-3: - 2: 32768 + 3: 32768 -15,-3: - 2: 4369 + 3: 4369 0: 52428 -15,-2: - 2: 1 + 3: 1 0: 64972 -14,-3: 0: 65535 -14,-2: 0: 65535 16,5: - 2: 62242 + 3: 62242 17,5: - 2: 61440 + 3: 61440 17,6: - 2: 65520 + 3: 65520 17,7: - 2: 55536 + 3: 55536 17,8: - 2: 56797 + 3: 56797 18,5: - 2: 61440 + 3: 61440 18,6: - 2: 65520 + 3: 65520 18,7: - 2: 55536 + 3: 55536 18,8: - 2: 56797 + 3: 56797 19,5: - 2: 61440 + 3: 61440 19,6: - 2: 48056 + 3: 48056 19,7: - 2: 39162 + 3: 39162 19,8: - 2: 39321 + 3: 39321 20,7: - 2: 16 + 3: 16 -12,-19: - 2: 61440 + 3: 61440 -13,-19: - 2: 61440 + 3: 61440 -12,-18: - 2: 4880 + 3: 4880 -13,-18: - 2: 65520 + 3: 65520 -12,-17: - 2: 4880 + 3: 4880 -13,-17: - 2: 65520 + 3: 65520 -11,-19: - 2: 61440 + 3: 61440 -10,-19: - 2: 4096 + 3: 4096 -10,-18: 0: 4 -18,-12: - 2: 68 + 3: 68 -18,-13: - 2: 17476 + 3: 17476 -18,-15: - 2: 17636 + 3: 17636 -18,-16: - 2: 17476 + 3: 17476 -18,-17: - 2: 17484 + 3: 17484 -18,-14: - 2: 17476 + 3: 17476 -17,-16: - 2: 30583 + 3: 30583 -17,-17: - 2: 29199 + 3: 29199 -17,-14: - 2: 30583 + 3: 30583 -17,-13: - 2: 2 + 3: 2 16,-12: - 2: 546 + 3: 546 16,-13: - 2: 8743 + 3: 8743 -16,-19: - 2: 57344 + 3: 57344 -16,-18: - 2: 10786 + 3: 10786 -15,-19: - 2: 61440 + 3: 61440 -15,-18: - 2: 65520 + 3: 65520 -15,-17: - 2: 65520 + 3: 65520 -14,-19: - 2: 62464 + 3: 62464 -14,-18: - 2: 24404 + 3: 24404 12,-15: - 2: 30496 + 3: 30496 12,-14: - 2: 10103 + 3: 10103 13,-16: - 2: 3840 + 3: 3840 13,-15: - 2: 30496 + 3: 30496 13,-14: - 2: 10103 + 3: 10103 14,-16: - 2: 3840 + 3: 3840 14,-15: - 2: 30496 + 3: 30496 14,-14: - 2: 10103 + 3: 10103 15,-16: - 2: 3840 + 3: 3840 15,-15: - 2: 30496 + 3: 30496 15,-14: - 2: 10103 + 3: 10103 16,-16: - 2: 8960 + 3: 8960 16,-15: - 2: 8738 + 3: 8738 16,-14: - 2: 8738 + 3: 8738 17,9: - 2: 248 + 3: 248 18,9: - 2: 248 + 3: 248 19,9: - 2: 248 + 3: 248 uniqueMixes: - volume: 2500 temperature: 293.15 @@ -8085,6 +8143,21 @@ entities: - 0 - 0 - 0 + - volume: 2500 + temperature: 293.14975 + moles: + - 20.078888 + - 75.53487 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 - volume: 2500 immutable: True moles: @@ -9836,6 +9909,16 @@ entities: container: 8991 - proto: AirAlarm entities: + - uid: 3220 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -14.5,30.5 + parent: 2 + - type: DeviceList + devices: + - 16149 + - 16148 - uid: 5583 components: - type: Transform @@ -9919,6 +10002,17 @@ entities: - 5218 - 16531 - 16532 + - uid: 14996 + components: + - type: Transform + pos: -3.5,39.5 + parent: 2 + - type: DeviceList + devices: + - 876 + - 18504 + - 16179 + - 16180 - uid: 15512 components: - type: Transform @@ -10525,26 +10619,6 @@ entities: - 18457 - 14690 - 14689 - - uid: 18469 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 33.5,16.5 - parent: 2 - - type: DeviceList - devices: - - 18471 - - 18472 - - 18473 - - 18474 - - 18475 - - 18476 - - 18468 - - 18467 - - 18459 - - 14721 - - 18461 - - 14720 - uid: 18478 components: - type: Transform @@ -10620,7 +10694,7 @@ entities: - 18490 - 16551 - 16552 - - 18502 + - 876 - 18504 - 18485 - 13281 @@ -10710,15 +10784,12 @@ entities: parent: 2 - type: DeviceList devices: - - 18560 - - 18559 - - 18571 - 18572 - - 18568 - - 18569 - - 18574 - - 16794 + - 18571 + - 18559 + - 18560 - 13584 + - 16794 - 18573 - uid: 18570 components: @@ -10740,7 +10811,6 @@ entities: - 18577 - 13560 - 13559 - - 18574 - uid: 18582 components: - type: Transform @@ -11399,6 +11469,26 @@ entities: - 3136 - 9112 - 28612 + - uid: 28879 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 33.5,11.5 + parent: 2 + - type: DeviceList + devices: + - 18459 + - 14721 + - 18461 + - 14720 + - 18474 + - 18473 + - 18475 + - 18476 + - 18467 + - 18468 + - 18471 + - 18472 - proto: AirCanister entities: - uid: 4223 @@ -11770,21 +11860,43 @@ entities: - type: Transform pos: -32.5,34.5 parent: 2 + - type: DeviceLinkSource + linkedPorts: + 28923: + - DoorStatus: InputB - uid: 8505 components: - type: Transform pos: -33.5,34.5 parent: 2 + - type: DeviceLinkSink + invokeCounter: 1 + - type: DeviceLinkSource + linkedPorts: + 28923: + - DoorStatus: InputA - uid: 8506 components: - type: Transform pos: -32.5,38.5 parent: 2 + - type: DeviceLinkSink + invokeCounter: 1 + - type: DeviceLinkSource + linkedPorts: + 28922: + - DoorStatus: InputB - uid: 8507 components: - type: Transform pos: -33.5,38.5 parent: 2 + - type: DeviceLinkSink + invokeCounter: 1 + - type: DeviceLinkSource + linkedPorts: + 28922: + - DoorStatus: InputA - proto: AirlockAtmosphericsLocked entities: - uid: 8143 @@ -12432,6 +12544,22 @@ entities: linkedPorts: 8424: - DoorStatus: DoorBolt + - uid: 28436 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -34.5,36.5 + parent: 2 + - type: DeviceLinkSink + invokeCounter: 5 + - type: DeviceLinkSource + linkedPorts: + 8507: + - DoorStatus: DoorBolt + 8506: + - DoorStatus: DoorBolt + 8505: + - DoorStatus: DoorBolt - proto: AirlockExternalGlassCargoLocked entities: - uid: 826 @@ -12439,6 +12567,12 @@ entities: - type: Transform pos: -60.5,-20.5 parent: 2 + - type: DeviceLinkSink + invokeCounter: 1 + - type: DeviceLinkSource + linkedPorts: + 28494: + - DoorStatus: DoorBolt - uid: 11331 components: - type: Transform @@ -12454,6 +12588,12 @@ entities: - type: Transform pos: -58.5,-19.5 parent: 2 + - type: DeviceLinkSink + invokeCounter: 1 + - type: DeviceLinkSource + linkedPorts: + 826: + - DoorStatus: DoorBolt - uid: 28495 components: - type: Transform @@ -12839,10 +12979,6 @@ entities: rot: 3.141592653589793 rad pos: 26.5,54.5 parent: 2 - - type: DeviceLinkSource - linkedPorts: - 6863: - - DoorStatus: DoorBolt - uid: 6991 components: - type: Transform @@ -13083,6 +13219,48 @@ entities: - type: Transform pos: 17.5,-17.5 parent: 2 + - uid: 858 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 29.5,51.5 + parent: 2 + - uid: 859 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 30.5,51.5 + parent: 2 + - uid: 873 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -2.5,37.5 + parent: 2 + - uid: 1284 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -0.5,-28.5 + parent: 2 + - uid: 1324 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.5,-28.5 + parent: 2 + - uid: 1325 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.5,-55.5 + parent: 2 + - uid: 1326 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -0.5,-55.5 + parent: 2 - uid: 3448 components: - type: Transform @@ -13107,29 +13285,191 @@ entities: rot: -1.5707963267948966 rad pos: -29.5,2.5 parent: 2 - - uid: 6863 + - uid: 8247 components: - type: Transform - rot: 3.141592653589793 rad - pos: 30.5,51.5 + rot: -1.5707963267948966 rad + pos: -41.5,-5.5 parent: 2 - - uid: 6864 + - uid: 8252 components: - type: Transform - rot: 3.141592653589793 rad - pos: 29.5,51.5 + rot: -1.5707963267948966 rad + pos: -0.5,18.5 parent: 2 - - uid: 7850 + - uid: 8254 components: - type: Transform - rot: 1.5707963267948966 rad - pos: -2.5,38.5 + rot: -1.5707963267948966 rad + pos: -0.5,-17.5 parent: 2 - - uid: 7851 + - uid: 8256 components: - type: Transform - rot: 1.5707963267948966 rad - pos: -2.5,37.5 + rot: -1.5707963267948966 rad + pos: 18.5,0.5 + parent: 2 + - uid: 8257 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.5,48.5 + parent: 2 + - uid: 8259 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -27.5,0.5 + parent: 2 + - uid: 8261 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -17.5,-0.5 + parent: 2 + - uid: 8262 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 29.5,-0.5 + parent: 2 + - uid: 8263 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 52.5,-0.5 + parent: 2 + - uid: 8393 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -42.5,-5.5 + parent: 2 + - uid: 8515 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -40.5,-5.5 + parent: 2 + - uid: 8542 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 52.5,0.5 + parent: 2 + - uid: 8580 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,18.5 + parent: 2 + - uid: 8581 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -0.5,29.5 + parent: 2 + - uid: 8588 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,48.5 + parent: 2 + - uid: 8589 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,-17.5 + parent: 2 + - uid: 8623 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.5,18.5 + parent: 2 + - uid: 8624 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,29.5 + parent: 2 + - uid: 8625 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.5,29.5 + parent: 2 + - uid: 8627 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,-28.5 + parent: 2 + - uid: 8775 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -27.5,1.5 + parent: 2 + - uid: 8780 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 18.5,-0.5 + parent: 2 + - uid: 8818 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 52.5,1.5 + parent: 2 + - uid: 8821 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 18.5,1.5 + parent: 2 + - uid: 8890 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 29.5,0.5 + parent: 2 + - uid: 8891 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 29.5,1.5 + parent: 2 + - uid: 8918 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -17.5,0.5 + parent: 2 + - uid: 8919 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -17.5,1.5 + parent: 2 + - uid: 8927 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.5,-17.5 + parent: 2 + - uid: 9161 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -27.5,-0.5 + parent: 2 + - uid: 9311 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,-55.5 parent: 2 - uid: 12229 components: @@ -13163,6 +13503,12 @@ entities: - type: Transform pos: 4.5,-63.5 parent: 2 + - uid: 28603 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -2.5,36.5 + parent: 2 - proto: AirlockHatch entities: - uid: 10942 @@ -13729,21 +14075,18 @@ entities: - type: Transform pos: -22.5,-39.5 parent: 2 - - uid: 1372 + - uid: 877 components: - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,-36.5 + rot: 3.141592653589793 rad + pos: -3.5,-35.5 parent: 2 - - uid: 1373 + - uid: 1372 components: - type: Transform rot: 1.5707963267948966 rad - pos: -3.5,-35.5 + pos: -3.5,-36.5 parent: 2 - - type: Door - secondsUntilStateChange: -583970.1 - state: Opening - uid: 1496 components: - type: Transform @@ -13899,6 +14242,12 @@ entities: parent: 2 - proto: AirlockScienceGlassLocked entities: + - uid: 878 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -9.5,-48.5 + parent: 2 - uid: 9731 components: - type: Transform @@ -13931,11 +14280,6 @@ entities: rot: -1.5707963267948966 rad pos: -5.5,-43.5 parent: 2 - - uid: 10272 - components: - - type: Transform - pos: -9.5,-48.5 - parent: 2 - uid: 10308 components: - type: Transform @@ -14119,23 +14463,47 @@ entities: - type: Transform pos: 60.5,48.5 parent: 2 + - type: DeviceLinkSource + lastSignals: + DoorStatus: True + - type: Door + secondsUntilStateChange: -4821.3525 + state: Opening - uid: 6934 components: - type: Transform rot: 3.141592653589793 rad pos: 60.5,50.5 parent: 2 + - type: DeviceLinkSource + lastSignals: + DoorStatus: True + - type: Door + secondsUntilStateChange: -4823.986 + state: Opening - uid: 6935 components: - type: Transform rot: 3.141592653589793 rad pos: 62.5,50.5 parent: 2 + - type: DeviceLinkSource + lastSignals: + DoorStatus: True + - type: Door + secondsUntilStateChange: -4822.836 + state: Opening - uid: 6936 components: - type: Transform pos: 62.5,48.5 parent: 2 + - type: DeviceLinkSource + lastSignals: + DoorStatus: True + - type: Door + secondsUntilStateChange: -4822.0522 + state: Opening - proto: AirlockTheatreLocked entities: - uid: 2191 @@ -14479,7 +14847,7 @@ entities: parent: 2 - type: DeviceNetwork deviceLists: - - 18469 + - 28879 - uid: 18460 components: - type: Transform @@ -14494,7 +14862,7 @@ entities: parent: 2 - type: DeviceNetwork deviceLists: - - 18469 + - 28879 - uid: 18462 components: - type: Transform @@ -14650,16 +15018,6 @@ entities: - type: DeviceNetwork deviceLists: - 18567 - - uid: 18574 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -33.5,36.5 - parent: 2 - - type: DeviceNetwork - deviceLists: - - 18567 - - 18570 - uid: 18576 components: - type: Transform @@ -15515,6 +15873,12 @@ entities: rot: -1.5707963267948966 rad pos: 20.5,45.5 parent: 2 + - uid: 884 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 52.5,17.5 + parent: 2 - uid: 2023 components: - type: MetaData @@ -15528,12 +15892,6 @@ entities: - type: Transform pos: 12.5,-40.5 parent: 2 - - uid: 12830 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 52.5,17.5 - parent: 2 - proto: APCSuperCapacity entities: - uid: 733 @@ -15548,8 +15906,36 @@ entities: rot: 1.5707963267948966 rad pos: -9.5,-45.5 parent: 2 +- proto: Ash + entities: + - uid: 28873 + components: + - type: Transform + pos: 35.773716,-16.714659 + parent: 2 - proto: Ashtray entities: + - uid: 10272 + components: + - type: Transform + pos: 34.393116,-15.167919 + parent: 2 + - type: Storage + storedItems: + 11535: + position: 0,0 + _rotation: South + 11867: + position: 1,0 + _rotation: South + - type: ContainerContainer + containers: + storagebase: !type:Container + showEnts: False + occludes: True + ents: + - 11535 + - 11867 - uid: 23244 components: - type: Transform @@ -34704,36 +35090,6 @@ entities: - type: Transform pos: -42.5,25.5 parent: 2 - - uid: 9293 - components: - - type: Transform - pos: -40.5,29.5 - parent: 2 - - uid: 9294 - components: - - type: Transform - pos: -41.5,29.5 - parent: 2 - - uid: 9295 - components: - - type: Transform - pos: -42.5,29.5 - parent: 2 - - uid: 9296 - components: - - type: Transform - pos: -40.5,31.5 - parent: 2 - - uid: 9297 - components: - - type: Transform - pos: -41.5,31.5 - parent: 2 - - uid: 9298 - components: - - type: Transform - pos: -42.5,31.5 - parent: 2 - uid: 9299 components: - type: Transform @@ -35889,10 +36245,10 @@ entities: parent: 2 - proto: Autolathe entities: - - uid: 6716 + - uid: 6864 components: - type: Transform - pos: 8.5,31.5 + pos: 7.5,30.5 parent: 2 - uid: 9959 components: @@ -37250,6 +37606,12 @@ entities: rot: 3.141592653589793 rad pos: -53.658516,9.595246 parent: 2 + - uid: 28614 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 34.492344,-15.954241 + parent: 2 - proto: BoxFolderWhite entities: - uid: 1115 @@ -37581,11 +37943,6 @@ entities: - type: Transform pos: 7.3088074,9.718449 parent: 21002 - - uid: 23354 - components: - - type: Transform - pos: 38.630417,16.50916 - parent: 2 - proto: ButtonFrameGrey entities: - uid: 4519 @@ -37678,11 +38035,26 @@ entities: - type: Transform pos: -21.5,-10.5 parent: 2 + - uid: 1282 + components: + - type: Transform + pos: -39.5,27.5 + parent: 2 + - uid: 1283 + components: + - type: Transform + pos: -39.5,32.5 + parent: 2 - uid: 1330 components: - type: Transform pos: -11.5,-80.5 parent: 2 + - uid: 1373 + components: + - type: Transform + pos: -38.5,32.5 + parent: 2 - uid: 1434 components: - type: Transform @@ -38493,6 +38865,11 @@ entities: - type: Transform pos: -9.5,-82.5 parent: 2 + - uid: 1865 + components: + - type: Transform + pos: -38.5,27.5 + parent: 2 - uid: 1929 components: - type: Transform @@ -49138,6 +49515,11 @@ entities: - type: Transform pos: -40.5,40.5 parent: 2 + - uid: 14151 + components: + - type: Transform + pos: -40.5,32.5 + parent: 2 - uid: 14189 components: - type: Transform @@ -51858,46 +52240,6 @@ entities: - type: Transform pos: -37.5,33.5 parent: 2 - - uid: 23308 - components: - - type: Transform - pos: -38.5,31.5 - parent: 2 - - uid: 23309 - components: - - type: Transform - pos: -39.5,31.5 - parent: 2 - - uid: 23310 - components: - - type: Transform - pos: -40.5,31.5 - parent: 2 - - uid: 23311 - components: - - type: Transform - pos: -41.5,31.5 - parent: 2 - - uid: 23312 - components: - - type: Transform - pos: -41.5,29.5 - parent: 2 - - uid: 23313 - components: - - type: Transform - pos: -40.5,29.5 - parent: 2 - - uid: 23314 - components: - - type: Transform - pos: -39.5,29.5 - parent: 2 - - uid: 23315 - components: - - type: Transform - pos: -38.5,29.5 - parent: 2 - uid: 23316 components: - type: Transform @@ -54923,6 +55265,76 @@ entities: - type: Transform pos: -31.5,9.5 parent: 2 + - uid: 28908 + components: + - type: Transform + pos: -41.5,32.5 + parent: 2 + - uid: 28909 + components: + - type: Transform + pos: -42.5,32.5 + parent: 2 + - uid: 28910 + components: + - type: Transform + pos: -43.5,32.5 + parent: 2 + - uid: 28911 + components: + - type: Transform + pos: -44.5,32.5 + parent: 2 + - uid: 28912 + components: + - type: Transform + pos: -44.5,31.5 + parent: 2 + - uid: 28913 + components: + - type: Transform + pos: -44.5,30.5 + parent: 2 + - uid: 28914 + components: + - type: Transform + pos: -44.5,29.5 + parent: 2 + - uid: 28915 + components: + - type: Transform + pos: -44.5,28.5 + parent: 2 + - uid: 28916 + components: + - type: Transform + pos: -44.5,27.5 + parent: 2 + - uid: 28917 + components: + - type: Transform + pos: -44.5,33.5 + parent: 2 + - uid: 28918 + components: + - type: Transform + pos: -44.5,34.5 + parent: 2 + - uid: 28919 + components: + - type: Transform + pos: -44.5,35.5 + parent: 2 + - uid: 28920 + components: + - type: Transform + pos: -44.5,36.5 + parent: 2 + - uid: 28921 + components: + - type: Transform + pos: -44.5,37.5 + parent: 2 - proto: CableApcStack1 entities: - uid: 23589 @@ -68331,26 +68743,6 @@ entities: - type: Transform pos: 22.5,-16.5 parent: 2 - - uid: 857 - components: - - type: Transform - pos: 22.5,-23.5 - parent: 2 - - uid: 858 - components: - - type: Transform - pos: 23.5,-22.5 - parent: 2 - - uid: 859 - components: - - type: Transform - pos: 24.5,-21.5 - parent: 2 - - uid: 873 - components: - - type: Transform - pos: 21.5,-23.5 - parent: 2 - uid: 874 components: - type: Transform @@ -68361,36 +68753,6 @@ entities: - type: Transform pos: 19.5,-23.5 parent: 2 - - uid: 876 - components: - - type: Transform - pos: 22.5,-22.5 - parent: 2 - - uid: 877 - components: - - type: Transform - pos: 20.5,-23.5 - parent: 2 - - uid: 878 - components: - - type: Transform - pos: 24.5,-20.5 - parent: 2 - - uid: 880 - components: - - type: Transform - pos: 23.5,-21.5 - parent: 2 - - uid: 884 - components: - - type: Transform - pos: 23.5,-21.5 - parent: 2 - - uid: 885 - components: - - type: Transform - pos: 24.5,-19.5 - parent: 2 - uid: 886 components: - type: Transform @@ -68401,21 +68763,6 @@ entities: - type: Transform pos: 24.5,-17.5 parent: 2 - - uid: 888 - components: - - type: Transform - pos: 21.5,-22.5 - parent: 2 - - uid: 889 - components: - - type: Transform - pos: 22.5,-21.5 - parent: 2 - - uid: 890 - components: - - type: Transform - pos: 23.5,-20.5 - parent: 2 - uid: 891 components: - type: Transform @@ -68568,11 +68915,53 @@ entities: rot: -1.5707963267948966 rad pos: 7.5,-23.5 parent: 2 + - uid: 2604 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 21.5,-23.5 + parent: 2 + - uid: 2605 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 24.5,-21.5 + parent: 2 + - uid: 2730 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 23.5,-21.5 + parent: 2 + - uid: 3227 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 22.5,-21.5 + parent: 2 + - uid: 5571 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 23.5,-20.5 + parent: 2 - uid: 5738 components: - type: Transform pos: 13.5,29.5 parent: 2 + - uid: 6258 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 23.5,-22.5 + parent: 2 + - uid: 6259 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 21.5,-22.5 + parent: 2 - uid: 6376 components: - type: Transform @@ -68608,6 +68997,24 @@ entities: - type: Transform pos: 16.5,28.5 parent: 2 + - uid: 6716 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 22.5,-22.5 + parent: 2 + - uid: 6849 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 22.5,-23.5 + parent: 2 + - uid: 6857 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 24.5,-20.5 + parent: 2 - uid: 12160 components: - type: Transform @@ -68628,6 +69035,42 @@ entities: - type: Transform pos: -38.5,-23.5 parent: 2 + - uid: 28886 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 7.5,-19.5 + parent: 2 + - uid: 28887 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 8.5,-19.5 + parent: 2 + - uid: 28888 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 9.5,-19.5 + parent: 2 + - uid: 28889 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 7.5,-20.5 + parent: 2 + - uid: 28890 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 8.5,-20.5 + parent: 2 + - uid: 28891 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 9.5,-20.5 + parent: 2 - proto: CarpetBlue entities: - uid: 2676 @@ -70638,6 +71081,12 @@ entities: rot: 1.5707963267948966 rad pos: -27.5,36.5 parent: 2 + - uid: 9212 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 56.5,-31.5 + parent: 2 - uid: 9384 components: - type: Transform @@ -73527,6 +73976,12 @@ entities: rot: -1.5707963267948966 rad pos: -25.5,23.5 parent: 2 + - uid: 28604 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 57.5,-31.5 + parent: 2 - proto: Chair entities: - uid: 495 @@ -73724,12 +74179,6 @@ entities: rot: 1.5707963267948966 rad pos: -56.5,-21.5 parent: 2 - - uid: 18707 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -56.5,-21.5 - parent: 2 - uid: 18708 components: - type: Transform @@ -74569,6 +75018,19 @@ entities: rot: 3.141592653589793 rad pos: -9.4977665,-59.404213 parent: 2 +- proto: ChurchBell + entities: + - uid: 28892 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 19.5,-17.5 + parent: 2 + - uid: 28893 + components: + - type: Transform + pos: 18.5,-18.5 + parent: 2 - proto: ChurchOrganInstrument entities: - uid: 45 @@ -74608,6 +75070,26 @@ entities: - type: Transform pos: -54.0773,9.794919 parent: 2 +- proto: Cigarette + entities: + - uid: 28871 + components: + - type: Transform + pos: 34.674366,-15.053335 + parent: 2 + - uid: 28872 + components: + - type: Transform + pos: 34.580616,-15.188752 + parent: 2 +- proto: CigaretteSpent + entities: + - uid: 11535 + components: + - type: Transform + parent: 10272 + - type: Physics + canCollide: False - proto: CigarGold entities: - uid: 2705 @@ -74640,6 +75122,21 @@ entities: rot: 1.5707963267948966 rad pos: -46.538147,-11.384542 parent: 2 +- proto: CigarSpent + entities: + - uid: 11867 + components: + - type: Transform + parent: 10272 + - type: Physics + canCollide: False +- proto: CigPackRed + entities: + - uid: 28869 + components: + - type: Transform + pos: 34.622284,-14.886669 + parent: 2 - proto: CircuitImprinter entities: - uid: 9961 @@ -76703,6 +77200,12 @@ entities: - type: Transform pos: -16.5,14.5 parent: 2 + - uid: 28595 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -4.5,35.5 + parent: 2 - proto: ComputerAlert entities: - uid: 9322 @@ -77607,10 +78110,10 @@ entities: parent: 2 - proto: CrateElectrical entities: - - uid: 6259 + - uid: 9603 components: - type: Transform - pos: 7.5,30.5 + pos: 8.5,31.5 parent: 2 - uid: 19667 components: @@ -77703,10 +78206,10 @@ entities: parent: 2 - proto: CrateEngineeringElectricalSupplies entities: - - uid: 6258 + - uid: 1276 components: - type: Transform - pos: 6.5,30.5 + pos: 8.5,30.5 parent: 2 - proto: CrateEngineeringMiniJetpack entities: @@ -78341,7 +78844,7 @@ entities: - uid: 28353 components: - type: Transform - pos: -20.5,-4.5 + pos: -24.5,-20.5 parent: 2 - type: EntityStorage open: True @@ -87605,7 +88108,7 @@ entities: - uid: 23355 components: - type: Transform - pos: 38.60958,16.707075 + pos: 38.62831,16.89455 parent: 2 - uid: 23370 components: @@ -87718,6 +88221,11 @@ entities: - type: Transform pos: 19.668665,37.711403 parent: 2 + - uid: 23353 + components: + - type: Transform + pos: 34.69026,-16.54799 + parent: 2 - uid: 23571 components: - type: Transform @@ -87772,12 +88280,12 @@ entities: - type: Transform pos: -48.22078,-11.387981 parent: 2 -- proto: DrinkIceJug +- proto: DrinkIceBucket entities: - - uid: 23353 + - uid: 7849 components: - type: Transform - pos: 38.8075,16.75916 + pos: 38.63873,16.467466 parent: 2 - proto: DrinkJar entities: @@ -88136,6 +88644,11 @@ entities: - type: Transform pos: 36.738503,-2.8382018 parent: 2 + - uid: 8622 + components: + - type: Transform + pos: 34.48193,-16.51674 + parent: 2 - uid: 23618 components: - type: Transform @@ -89153,6 +89666,13 @@ entities: - type: Transform pos: -59.512844,-33.467316 parent: 2 +- proto: EvidenceMarkerOne + entities: + - uid: 28866 + components: + - type: Transform + pos: 34.392616,-14.27478 + parent: 2 - proto: ExosuitFabricator entities: - uid: 10470 @@ -89247,12 +89767,6 @@ entities: rot: 3.141592653589793 rad pos: 5.5,-47.5 parent: 2 - - uid: 23799 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -9.5,-51.5 - parent: 2 - uid: 23800 components: - type: Transform @@ -89270,6 +89784,12 @@ entities: - type: Transform pos: -29.5,34.5 parent: 2 + - uid: 28905 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -9.5,-52.5 + parent: 2 - proto: FaxMachineBase entities: - uid: 1043 @@ -89405,6 +89925,14 @@ entities: - type: Transform pos: 32.5,20.5 parent: 2 +- proto: FenceWoodSmallGate + entities: + - uid: 28615 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -55.5,-36.5 + parent: 2 - proto: FigureSpawner entities: - uid: 23863 @@ -89688,6 +90216,16 @@ entities: - 17899 - 16671 - 12062 + - uid: 15810 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -2.5,38.5 + parent: 2 + - type: DeviceList + devices: + - 876 + - 18504 - uid: 18231 components: - type: Transform @@ -90302,7 +90840,7 @@ entities: - 18490 - 16551 - 16552 - - 18502 + - 876 - 18504 - uid: 18531 components: @@ -90934,6 +91472,15 @@ entities: - 26798 - 26787 - 26792 + - uid: 28901 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 6.5,51.5 + parent: 2 + - type: DeviceList + devices: + - 18546 - proto: FireAxeCabinetFilled entities: - uid: 2471 @@ -92346,6 +92893,18 @@ entities: - 18288 - 18282 - 18271 + - uid: 876 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -2.5,36.5 + parent: 2 + - type: DeviceNetwork + deviceLists: + - 18500 + - 18501 + - 15810 + - 14996 - uid: 2200 components: - type: Transform @@ -93488,7 +94047,7 @@ entities: - 18464 - 18463 - 18470 - - 18469 + - 28879 - uid: 18468 components: - type: Transform @@ -93500,7 +94059,7 @@ entities: - 18464 - 18463 - 18470 - - 18469 + - 28879 - uid: 18471 components: - type: Transform @@ -93510,7 +94069,7 @@ entities: - type: DeviceNetwork deviceLists: - 18470 - - 18469 + - 28879 - 18477 - 18478 - uid: 18472 @@ -93522,7 +94081,7 @@ entities: - type: DeviceNetwork deviceLists: - 18470 - - 18469 + - 28879 - 18477 - 18478 - uid: 18473 @@ -93534,7 +94093,7 @@ entities: - type: DeviceNetwork deviceLists: - 18470 - - 18469 + - 28879 - 18484 - 18480 - uid: 18474 @@ -93546,7 +94105,7 @@ entities: - type: DeviceNetwork deviceLists: - 18470 - - 18469 + - 28879 - 18484 - 18480 - uid: 18475 @@ -93558,7 +94117,7 @@ entities: - type: DeviceNetwork deviceLists: - 18470 - - 18469 + - 28879 - 18483 - 18482 - uid: 18476 @@ -93570,7 +94129,7 @@ entities: - type: DeviceNetwork deviceLists: - 18470 - - 18469 + - 28879 - 18483 - 18482 - uid: 18488 @@ -93685,15 +94244,6 @@ entities: deviceLists: - 18498 - 18499 - - uid: 18502 - components: - - type: Transform - pos: -2.5,38.5 - parent: 2 - - type: DeviceNetwork - deviceLists: - - 18500 - - 18501 - uid: 18504 components: - type: Transform @@ -93703,6 +94253,8 @@ entities: deviceLists: - 18500 - 18501 + - 15810 + - 14996 - uid: 18522 components: - type: Transform @@ -93830,6 +94382,7 @@ entities: - 18551 - 18553 - 9410 + - 28901 - uid: 18547 components: - type: Transform @@ -93903,7 +94456,6 @@ entities: - type: DeviceNetwork deviceLists: - 18566 - - 18567 - 18575 - 18570 - uid: 18569 @@ -93915,7 +94467,6 @@ entities: - type: DeviceNetwork deviceLists: - 18566 - - 18567 - 18575 - 18570 - uid: 18571 @@ -95382,16 +95933,6 @@ entities: - type: Transform pos: -42.5,25.5 parent: 2 - - uid: 8580 - components: - - type: Transform - pos: -42.5,29.5 - parent: 2 - - uid: 8581 - components: - - type: Transform - pos: -42.5,31.5 - parent: 2 - uid: 9778 components: - type: Transform @@ -95468,18 +96009,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 8523 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -40.5,31.5 - parent: 2 - - uid: 8524 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -40.5,29.5 - parent: 2 - uid: 8527 components: - type: Transform @@ -95662,17 +96191,6 @@ entities: - type: Transform pos: 52.5,16.5 parent: 21002 - - uid: 28594 - components: - - type: Transform - pos: -41.5,29.5 - parent: 2 - - uid: 28595 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -41.5,31.5 - parent: 2 - proto: GasPipeBend entities: - uid: 51 @@ -95864,18 +96382,6 @@ entities: rot: 3.141592653589793 rad pos: -42.5,24.5 parent: 2 - - uid: 8588 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -42.5,28.5 - parent: 2 - - uid: 8589 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -42.5,30.5 - parent: 2 - uid: 8652 components: - type: Transform @@ -96036,30 +96542,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 9201 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -44.5,34.5 - parent: 2 - - uid: 9204 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -41.5,27.5 - parent: 2 - - uid: 9212 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -40.5,36.5 - parent: 2 - - uid: 9234 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -44.5,27.5 - parent: 2 - uid: 9390 components: - type: Transform @@ -98016,46 +98498,6 @@ entities: parent: 21002 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 28599 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -41.5,33.5 - parent: 2 - - uid: 28600 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -39.5,33.5 - parent: 2 - - uid: 28613 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -40.5,34.5 - parent: 2 - - uid: 28614 - components: - - type: Transform - anchored: False - rot: 3.141592653589793 rad - pos: -40.5,34.5 - parent: 2 - - type: Physics - canCollide: True - bodyType: Dynamic - - uid: 28615 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -42.5,36.5 - parent: 2 - - uid: 28616 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -41.5,34.5 - parent: 2 - uid: 28634 components: - type: Transform @@ -98902,6 +99344,14 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' + - uid: 8250 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -34.5,35.5 + parent: 2 + - type: AtmosPipeColor + color: '#B3A234FF' - uid: 8534 components: - type: Transform @@ -98944,18 +99394,6 @@ entities: rot: 1.5707963267948966 rad pos: -39.5,25.5 parent: 2 - - uid: 8541 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -39.5,29.5 - parent: 2 - - uid: 8542 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -39.5,31.5 - parent: 2 - uid: 8543 components: - type: Transform @@ -99286,42 +99724,14 @@ entities: rot: 1.5707963267948966 rad pos: -38.5,28.5 parent: 2 - - uid: 8622 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -39.5,28.5 - parent: 2 - - uid: 8623 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -40.5,28.5 - parent: 2 - - uid: 8624 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -41.5,28.5 - parent: 2 - - uid: 8625 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -41.5,30.5 - parent: 2 - uid: 8626 components: - type: Transform - rot: 1.5707963267948966 rad - pos: -40.5,30.5 - parent: 2 - - uid: 8627 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -39.5,30.5 + rot: -1.5707963267948966 rad + pos: -33.5,35.5 parent: 2 + - type: AtmosPipeColor + color: '#B3A234FF' - uid: 8628 components: - type: Transform @@ -99963,13 +100373,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#3AB334FF' - - uid: 8775 - components: - - type: Transform - pos: -33.5,37.5 - parent: 2 - - type: AtmosPipeColor - color: '#3AB334FF' - uid: 8776 components: - type: Transform @@ -99998,13 +100401,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#3AB334FF' - - uid: 8780 - components: - - type: Transform - pos: -32.5,35.5 - parent: 2 - - type: AtmosPipeColor - color: '#B3A234FF' - uid: 8781 components: - type: Transform @@ -100050,17 +100446,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 8818 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -43.5,34.5 - parent: 2 - - uid: 8821 - components: - - type: Transform - pos: -44.5,32.5 - parent: 2 - uid: 8822 components: - type: Transform @@ -100302,16 +100687,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#03FCD3FF' - - uid: 9199 - components: - - type: Transform - pos: -44.5,29.5 - parent: 2 - - uid: 9200 - components: - - type: Transform - pos: -44.5,28.5 - parent: 2 - uid: 9386 components: - type: Transform @@ -100408,12 +100783,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#FF1212FF' - - uid: 9604 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -43.5,27.5 - parent: 2 - uid: 9611 components: - type: Transform @@ -105924,18 +106293,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 14128 - components: - - type: Transform - anchored: False - rot: -1.5707963267948966 rad - pos: 10.5,-19.5 - parent: 2 - - type: AtmosPipeColor - color: '#0335FCFF' - - type: Physics - canCollide: True - bodyType: Dynamic - uid: 14129 components: - type: Transform @@ -106071,17 +106428,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 14151 - components: - - type: Transform - anchored: False - pos: 32.5,-1.5 - parent: 2 - - type: AtmosPipeColor - color: '#0335FCFF' - - type: Physics - canCollide: True - bodyType: Dynamic - uid: 14155 components: - type: Transform @@ -117403,16 +117749,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 16792 - components: - - type: Transform - pos: -44.5,33.5 - parent: 2 - - uid: 16793 - components: - - type: Transform - pos: -44.5,31.5 - parent: 2 - uid: 16796 components: - type: Transform @@ -118944,6 +119280,14 @@ entities: parent: 2 - type: AtmosPipeColor color: '#FF1212FF' + - uid: 23463 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -34.5,37.5 + parent: 2 + - type: AtmosPipeColor + color: '#3AB334FF' - uid: 23478 components: - type: Transform @@ -119299,11 +119643,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#FF1212FF' - - uid: 24118 - components: - - type: Transform - pos: -44.5,30.5 - parent: 2 - uid: 25219 components: - type: Transform @@ -119846,28 +120185,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 28593 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -41.5,28.5 - parent: 2 - - uid: 28597 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -41.5,32.5 - parent: 2 - - uid: 28598 - components: - - type: Transform - anchored: False - rot: 3.141592653589793 rad - pos: -41.5,32.5 - parent: 2 - - type: Physics - canCollide: True - bodyType: Dynamic - uid: 28620 components: - type: Transform @@ -120197,6 +120514,22 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' + - uid: 8524 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -33.5,37.5 + parent: 2 + - type: AtmosPipeColor + color: '#3AB334FF' + - uid: 8541 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -32.5,35.5 + parent: 2 + - type: AtmosPipeColor + color: '#B3A234FF' - uid: 8683 components: - type: Transform @@ -122911,30 +123244,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 28602 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -39.5,34.5 - parent: 2 - - uid: 28604 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -39.5,36.5 - parent: 2 - - uid: 28617 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -42.5,34.5 - parent: 2 - - uid: 28618 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -41.5,36.5 - parent: 2 - uid: 28624 components: - type: Transform @@ -123269,22 +123578,6 @@ entities: rot: 1.5707963267948966 rad pos: -36.5,29.5 parent: 2 - - uid: 9202 - components: - - type: Transform - pos: -42.5,35.5 - parent: 2 - - uid: 9311 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -41.5,35.5 - parent: 2 - - uid: 9603 - components: - - type: Transform - pos: -40.5,35.5 - parent: 2 - uid: 9752 components: - type: Transform @@ -123319,12 +123612,6 @@ entities: targetPressure: 501.325 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 28603 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -39.5,35.5 - parent: 2 - proto: GasThermoMachineFreezer entities: - uid: 9281 @@ -123384,6 +123671,16 @@ entities: bodyType: Dynamic - proto: GasValve entities: + - uid: 888 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -35.5,37.5 + parent: 2 + - type: GasValve + open: False + - type: AtmosPipeColor + color: '#3AB334FF' - uid: 8100 components: - type: Transform @@ -123434,6 +123731,48 @@ entities: open: False - type: AtmosPipeColor color: '#B3A234FF' + - uid: 8248 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -35.5,35.5 + parent: 2 + - type: GasValve + open: False + - type: AtmosPipeColor + color: '#B3A234FF' + - uid: 8329 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -39.5,30.5 + parent: 2 + - type: GasValve + open: False + - uid: 8359 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -39.5,28.5 + parent: 2 + - type: GasValve + open: False + - uid: 8361 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -39.5,31.5 + parent: 2 + - type: GasValve + open: False + - uid: 8523 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -39.5,29.5 + parent: 2 + - type: GasValve + open: False - uid: 8689 components: - type: Transform @@ -123499,14 +123838,6 @@ entities: parent: 2 - type: GasValve open: False - - uid: 9211 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -42.5,27.5 - parent: 2 - - type: GasValve - open: False - uid: 9759 components: - type: Transform @@ -123554,14 +123885,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#0335FCFF' - - uid: 28601 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -40.5,33.5 - parent: 2 - - type: GasValve - open: False - uid: 28605 components: - type: Transform @@ -124248,7 +124571,7 @@ entities: parent: 2 - type: DeviceNetwork deviceLists: - - 18469 + - 28879 - type: AtmosPipeColor color: '#0335FCFF' - uid: 14741 @@ -124954,6 +125277,9 @@ entities: rot: 3.141592653589793 rad pos: -17.5,29.5 parent: 2 + - type: DeviceNetwork + deviceLists: + - 3220 - type: AtmosPipeColor color: '#0335FCFF' - uid: 16179 @@ -124962,6 +125288,9 @@ entities: rot: 3.141592653589793 rad pos: -6.5,35.5 parent: 2 + - type: DeviceNetwork + deviceLists: + - 14996 - type: AtmosPipeColor color: '#0335FCFF' - uid: 16188 @@ -126065,7 +126394,7 @@ entities: parent: 2 - type: DeviceNetwork deviceLists: - - 18469 + - 28879 - type: AtmosPipeColor color: '#FF1212FF' - uid: 14740 @@ -126608,18 +126937,6 @@ entities: parent: 2 - type: AtmosPipeColor color: '#FF1212FF' - - uid: 15810 - components: - - type: Transform - anchored: False - rot: 3.141592653589793 rad - pos: -6.5,-28.5 - parent: 2 - - type: AtmosPipeColor - color: '#FF1212FF' - - type: Physics - canCollide: True - bodyType: Dynamic - uid: 15814 components: - type: Transform @@ -126776,6 +127093,9 @@ entities: rot: 3.141592653589793 rad pos: -16.5,28.5 parent: 2 + - type: DeviceNetwork + deviceLists: + - 3220 - type: AtmosPipeColor color: '#FF1212FF' - uid: 16180 @@ -126784,6 +127104,9 @@ entities: rot: 3.141592653589793 rad pos: -8.5,35.5 parent: 2 + - type: DeviceNetwork + deviceLists: + - 14996 - type: AtmosPipeColor color: '#FF1212FF' - uid: 16189 @@ -129202,12 +129525,6 @@ entities: rot: 3.141592653589793 rad pos: 27.5,54.5 parent: 2 - - uid: 6857 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 28.5,54.5 - parent: 2 - uid: 6858 components: - type: Transform @@ -130189,12 +130506,6 @@ entities: rot: 3.141592653589793 rad pos: -37.5,16.5 parent: 2 - - uid: 8393 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -37.5,15.5 - parent: 2 - uid: 8394 components: - type: Transform @@ -130243,16 +130554,6 @@ entities: rot: 3.141592653589793 rad pos: -40.5,2.5 parent: 2 - - uid: 8514 - components: - - type: Transform - pos: -39.5,31.5 - parent: 2 - - uid: 8515 - components: - - type: Transform - pos: -39.5,29.5 - parent: 2 - uid: 8516 components: - type: Transform @@ -131070,6 +131371,12 @@ entities: rot: -1.5707963267948966 rad pos: -53.5,-15.5 parent: 2 + - uid: 11983 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -37.5,15.5 + parent: 2 - uid: 12307 components: - type: Transform @@ -135868,7 +136175,7 @@ entities: pos: 36.5,-35.5 parent: 2 - type: Door - secondsUntilStateChange: -16897.393 + secondsUntilStateChange: -32977.18 state: Opening - uid: 5211 components: @@ -136775,6 +137082,14 @@ entities: - type: Transform pos: 27.345627,0.6012745 parent: 21002 +- proto: Lighter + entities: + - uid: 28870 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 34.559784,-14.813752 + parent: 2 - proto: LightReplacer entities: - uid: 9677 @@ -137567,6 +137882,41 @@ entities: - type: Transform pos: 35.5,35.5 parent: 2 +- proto: LogicGate + entities: + - uid: 28922 + components: + - type: Transform + pos: -32.477474,37.47289 + parent: 2 + - type: DeviceLinkSink + invokeCounter: 2 + - type: DeviceLinkSource + linkedPorts: + 28924: + - Output: InputA + - uid: 28923 + components: + - type: Transform + pos: -32.49831,35.52497 + parent: 2 + - type: DeviceLinkSink + invokeCounter: 4 + - type: DeviceLinkSource + linkedPorts: + 28924: + - Output: InputB + - uid: 28924 + components: + - type: Transform + pos: -33.46706,36.483307 + parent: 2 + - type: DeviceLinkSink + invokeCounter: 2 + - type: DeviceLinkSource + linkedPorts: + 28436: + - Output: DoorBolt - proto: MachineAnomalyGenerator entities: - uid: 3797 @@ -137849,6 +138199,11 @@ entities: - type: Transform pos: 58.5,7.5 parent: 2 + - uid: 12259 + components: + - type: Transform + pos: -18.5,18.5 + parent: 2 - uid: 23232 components: - type: Transform @@ -137874,6 +138229,21 @@ entities: - type: Transform pos: -11.5,26.5 parent: 2 + - uid: 28594 + components: + - type: Transform + pos: 48.5,-31.5 + parent: 2 + - uid: 28880 + components: + - type: Transform + pos: -22.5,20.5 + parent: 2 + - uid: 28882 + components: + - type: Transform + pos: 41.5,-44.5 + parent: 2 - proto: MaintenanceToolSpawner entities: - uid: 255 @@ -138004,11 +138374,6 @@ entities: - type: Transform pos: -54.5,-30.5 parent: 2 - - uid: 8712 - components: - - type: Transform - pos: -57.5,-14.5 - parent: 2 - proto: MatterBinStockPart entities: - uid: 23592 @@ -138592,11 +138957,6 @@ entities: - type: Transform pos: 40.5,50.5 parent: 2 - - uid: 11868 - components: - - type: Transform - pos: -57.5,-21.5 - parent: 2 - uid: 15320 components: - type: Transform @@ -138757,10 +139117,10 @@ entities: parent: 2 - proto: OreProcessor entities: - - uid: 11983 + - uid: 9204 components: - type: Transform - pos: -56.5,-16.5 + pos: -57.5,-15.5 parent: 2 - proto: OxygenCanister entities: @@ -138799,6 +139159,11 @@ entities: - type: Transform pos: -42.5,13.5 parent: 2 + - uid: 9211 + components: + - type: Transform + pos: -57.5,-21.5 + parent: 2 - uid: 9468 components: - type: Transform @@ -138809,11 +139174,6 @@ entities: - type: Transform pos: 8.5,-35.5 parent: 2 - - uid: 11867 - components: - - type: Transform - pos: -57.5,-16.5 - parent: 2 - uid: 18928 components: - type: Transform @@ -139604,6 +139964,12 @@ entities: - type: Transform pos: -16.680094,39.619514 parent: 2 + - uid: 28865 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 34.554844,-15.797991 + parent: 2 - proto: PenCap entities: - uid: 2672 @@ -139656,6 +140022,13 @@ entities: - type: Transform pos: -4.5151863,-48.460827 parent: 2 +- proto: PetCarrier + entities: + - uid: 16800 + components: + - type: Transform + pos: -20.5,-4.5 + parent: 2 - proto: PhoneInstrument entities: - uid: 2675 @@ -140255,15 +140628,24 @@ entities: - type: Transform pos: 22.5,35.5 parent: 2 - - uid: 28331 + - uid: 28332 components: - type: Transform - pos: 3.5,30.5 + pos: -32.5,7.5 parent: 2 - - uid: 28332 + - uid: 28881 components: - type: Transform - pos: -32.5,7.5 + rot: -1.5707963267948966 rad + pos: 8.5,39.5 + parent: 2 +- proto: PosterLegitAnatomyPoster + entities: + - uid: 9399 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -32.5,-33.5 parent: 2 - proto: PosterLegitCarpMount entities: @@ -140348,6 +140730,22 @@ entities: - type: Transform pos: -5.5,53.5 parent: 2 +- proto: PosterLegitSafetyMothEpi + entities: + - uid: 1051 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -12.5,-30.5 + parent: 2 +- proto: PosterLegitSafetyMothMeth + entities: + - uid: 8712 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -17.5,-37.5 + parent: 2 - proto: PosterLegitThereIsNoGasGiant entities: - uid: 9176 @@ -141638,11 +142036,6 @@ entities: rot: -1.5707963267948966 rad pos: 26.5,22.5 parent: 2 - - uid: 5571 - components: - - type: Transform - pos: -4.5,38.5 - parent: 2 - uid: 5641 components: - type: Transform @@ -141826,18 +142219,6 @@ entities: rot: -1.5707963267948966 rad pos: 1.5,52.5 parent: 2 - - uid: 7938 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -10.5,35.5 - parent: 2 - - uid: 7939 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -3.5,31.5 - parent: 2 - uid: 7940 components: - type: Transform @@ -141983,6 +142364,23 @@ entities: - type: Transform pos: -11.5,43.5 parent: 2 + - uid: 9294 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -3.5,31.5 + parent: 2 + - uid: 9295 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -10.5,35.5 + parent: 2 + - uid: 9296 + components: + - type: Transform + pos: -4.5,38.5 + parent: 2 - uid: 9578 components: - type: Transform @@ -142888,6 +143286,12 @@ entities: powerLoad: 10 - proto: PoweredLightPostSmall entities: + - uid: 1042 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -45.5,37.5 + parent: 2 - uid: 2259 components: - type: Transform @@ -142898,6 +143302,12 @@ entities: - type: Transform pos: 46.5,-50.5 parent: 2 + - uid: 8258 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -45.5,31.5 + parent: 2 - uid: 11558 components: - type: Transform @@ -142950,11 +143360,6 @@ entities: - type: Transform pos: -41.5,7.5 parent: 2 - - uid: 14996 - components: - - type: Transform - pos: -38.5,34.5 - parent: 2 - uid: 20783 components: - type: Transform @@ -143123,12 +143528,6 @@ entities: - type: Transform pos: 30.5,-14.5 parent: 2 - - uid: 4011 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 35.5,-16.5 - parent: 2 - uid: 4239 components: - type: Transform @@ -143199,16 +143598,6 @@ entities: - type: Transform pos: -41.5,25.5 parent: 2 - - uid: 9161 - components: - - type: Transform - pos: -41.5,29.5 - parent: 2 - - uid: 9162 - components: - - type: Transform - pos: -41.5,31.5 - parent: 2 - uid: 9186 components: - type: Transform @@ -143233,6 +143622,12 @@ entities: rot: 3.141592653589793 rad pos: -12.5,46.5 parent: 2 + - uid: 9298 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 35.5,-15.5 + parent: 2 - uid: 9852 components: - type: Transform @@ -143854,6 +144249,12 @@ entities: rot: 1.5707963267948966 rad pos: -21.5,25.5 parent: 2 + - uid: 28877 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 43.5,8.5 + parent: 2 - proto: PresentRandomCash entities: - uid: 9641 @@ -143881,10 +144282,10 @@ entities: color: '#03FCD3FF' - proto: Protolathe entities: - - uid: 6715 + - uid: 7789 components: - type: Transform - pos: 8.5,30.5 + pos: 6.5,30.5 parent: 2 - uid: 9960 components: @@ -145603,6 +146004,16 @@ entities: rot: -1.5707963267948966 rad pos: 3.5,-16.5 parent: 21002 + - uid: 28894 + components: + - type: Transform + pos: 20.5,-22.5 + parent: 2 + - uid: 28895 + components: + - type: Transform + pos: 23.5,-19.5 + parent: 2 - proto: RailingCornerSmall entities: - uid: 380 @@ -146014,6 +146425,30 @@ entities: - type: Transform pos: 19.5,-25.5 parent: 21002 + - uid: 28896 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 19.5,-22.5 + parent: 2 + - uid: 28897 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 22.5,-19.5 + parent: 2 + - uid: 28898 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 20.5,-21.5 + parent: 2 + - uid: 28899 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 23.5,-18.5 + parent: 2 - proto: RailingRound entities: - uid: 3408 @@ -147322,21 +147757,11 @@ entities: - type: Transform pos: -7.5,46.5 parent: 2 - - uid: 8359 - components: - - type: Transform - pos: -39.5,31.5 - parent: 2 - uid: 8360 components: - type: Transform pos: -39.5,25.5 parent: 2 - - uid: 8361 - components: - - type: Transform - pos: -39.5,29.5 - parent: 2 - uid: 8508 components: - type: Transform @@ -148760,11 +149185,6 @@ entities: - type: Transform pos: 31.5,54.5 parent: 2 - - uid: 6849 - components: - - type: Transform - pos: 28.5,54.5 - parent: 2 - uid: 6850 components: - type: Transform @@ -149034,12 +149454,6 @@ entities: rot: 3.141592653589793 rad pos: -37.5,14.5 parent: 2 - - uid: 8329 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -37.5,15.5 - parent: 2 - uid: 8330 components: - type: Transform @@ -149244,6 +149658,12 @@ entities: rot: 1.5707963267948966 rad pos: 2.5,-30.5 parent: 2 + - uid: 9200 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -37.5,15.5 + parent: 2 - uid: 9256 components: - type: Transform @@ -150906,6 +151326,29 @@ entities: rot: 1.5707963267948966 rad pos: 56.5,-7.5 parent: 2 + - uid: 23309 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 62.5,-4.5 + parent: 2 + - uid: 23310 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 62.5,3.5 + parent: 2 + - uid: 23311 + components: + - type: Transform + pos: 56.5,6.5 + parent: 2 + - uid: 23312 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 20.5,3.5 + parent: 2 - uid: 23440 components: - type: Transform @@ -150988,6 +151431,16 @@ entities: rot: -1.5707963267948966 rad pos: 2.5,46.5 parent: 2 + - uid: 24118 + components: + - type: Transform + pos: 10.5,18.5 + parent: 2 + - uid: 28331 + components: + - type: Transform + pos: 20.5,10.5 + parent: 2 - uid: 28364 components: - type: Transform @@ -151302,18 +151755,6 @@ entities: parent: 21002 - proto: ShuttersNormal entities: - - uid: 2604 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 34.5,12.5 - parent: 2 - - uid: 2605 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 34.5,15.5 - parent: 2 - uid: 7762 components: - type: Transform @@ -151337,6 +151778,18 @@ entities: - type: Transform pos: 20.5,-1.5 parent: 2 + - uid: 12261 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 34.5,15.5 + parent: 2 + - uid: 12830 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 34.5,12.5 + parent: 2 - uid: 16922 components: - type: Transform @@ -151953,10 +152406,18 @@ entities: parent: 2 - proto: SignAi entities: - - uid: 23184 + - uid: 23308 components: - type: Transform - rot: 3.141592653589793 rad + rot: -1.5707963267948966 rad + pos: 57.5,18.5 + parent: 2 +- proto: SignAiUpload + entities: + - uid: 12285 + components: + - type: Transform + rot: -1.5707963267948966 rad pos: 59.5,6.5 parent: 2 - proto: SignalButtonDirectional @@ -152102,18 +152563,6 @@ entities: - Pressed: Toggle 5742: - Pressed: Toggle - - uid: 2730 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 35.5,11.5 - parent: 2 - - type: DeviceLinkSource - linkedPorts: - 2604: - - Pressed: Toggle - 2605: - - Pressed: Toggle - uid: 2735 components: - type: MetaData @@ -152314,22 +152763,6 @@ entities: - Pressed: Toggle 7860: - Pressed: Toggle - - uid: 7984 - components: - - type: MetaData - name: light switch - - type: Transform - rot: -1.5707963267948966 rad - pos: -2.5,36.5 - parent: 2 - - type: DeviceLinkSource - linkedPorts: - 5571: - - Pressed: Toggle - 7939: - - Pressed: Toggle - 7938: - - Pressed: Toggle - uid: 8946 components: - type: Transform @@ -152553,6 +152986,17 @@ entities: linkedPorts: 23781: - Pressed: Toggle + - uid: 18469 + components: + - type: Transform + pos: 35.5,16.5 + parent: 2 + - type: DeviceLinkSource + linkedPorts: + 12261: + - Pressed: Toggle + 12830: + - Pressed: Toggle - uid: 18694 components: - type: MetaData @@ -152874,14 +153318,78 @@ entities: linkedPorts: 12131: - Pressed: DoorBolt + - uid: 28868 + components: + - type: MetaData + name: light + - type: Transform + rot: 3.141592653589793 rad + pos: 35.5,-17.5 + parent: 2 + - type: DeviceLinkSource + linkedPorts: + 9298: + - Pressed: Toggle + - uid: 28874 + components: + - type: MetaData + name: light + - type: Transform + pos: 32.5,-13.5 + parent: 2 + - type: DeviceLinkSource + linkedPorts: + 3764: + - Pressed: Toggle + - uid: 28878 + components: + - type: MetaData + name: door bolt + - type: Transform + rot: -1.5707963267948966 rad + pos: 11.5,36.5 + parent: 2 + - type: DeviceLinkSource + linkedPorts: + 23642: + - Pressed: DoorBolt + - uid: 28900 + components: + - type: MetaData + name: lights + - type: Transform + pos: -4.5,39.5 + parent: 2 + - type: DeviceLinkSource + linkedPorts: + 9296: + - Pressed: Toggle + 9294: + - Pressed: Toggle + 9295: + - Pressed: Toggle - proto: SignAnomaly entities: + - uid: 16793 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 2.5,-36.5 + parent: 2 - uid: 23200 components: - type: Transform rot: -1.5707963267948966 rad pos: 12.5,-36.5 parent: 2 +- proto: SignArcade + entities: + - uid: 6863 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -47.5,-40.5 + parent: 2 - proto: SignArmory entities: - uid: 23185 @@ -152914,6 +153422,14 @@ entities: rot: 3.141592653589793 rad pos: 24.5,2.5 parent: 2 +- proto: SignCans + entities: + - uid: 8260 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -32.5,11.5 + parent: 2 - proto: SignCargo entities: - uid: 23190 @@ -152938,7 +153454,7 @@ entities: rot: 3.141592653589793 rad pos: 2.5,-21.5 parent: 2 -- proto: SignChemistry1 +- proto: SignChem entities: - uid: 8921 components: @@ -152962,16 +153478,27 @@ entities: rot: 3.141592653589793 rad pos: 28.5,16.5 parent: 2 -- proto: SignCourt +- proto: SignCryo entities: - - uid: 8922 + - uid: 23799 components: - type: Transform - rot: 1.5707963267948966 rad - pos: 34.5,-1.5 + pos: -45.5,-28.5 parent: 2 - proto: SignDangerMed entities: + - uid: 889 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 19.5,-52.5 + parent: 2 + - uid: 7938 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 22.5,-52.5 + parent: 2 - uid: 28305 components: - type: Transform @@ -152994,6 +153521,12 @@ entities: parent: 2 - proto: SignDirectionalChapel entities: + - uid: 1279 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 2.5,-20.5 + parent: 2 - uid: 3461 components: - type: Transform @@ -153056,11 +153589,6 @@ entities: rot: 3.141592653589793 rad pos: -1.497997,-40.258747 parent: 2 - - uid: 20992 - components: - - type: Transform - pos: -2.4500175,39.76776 - parent: 2 - uid: 20995 components: - type: Transform @@ -153073,8 +153601,18 @@ entities: rot: 1.5707963267948966 rad pos: 38.525524,2.687672 parent: 2 + - uid: 28601 + components: + - type: Transform + pos: -0.50126964,39.711143 + parent: 2 - proto: SignDirectionalFood entities: + - uid: 14128 + components: + - type: Transform + pos: -0.5,39.5 + parent: 2 - uid: 20980 components: - type: Transform @@ -153093,11 +153631,6 @@ entities: rot: 3.141592653589793 rad pos: -1.497997,-40.456665 parent: 2 - - uid: 20993 - components: - - type: Transform - pos: -2.4500175,39.54901 - parent: 2 - uid: 20994 components: - type: Transform @@ -153407,6 +153940,12 @@ entities: parent: 2 - proto: SignEngineering entities: + - uid: 9293 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 3.5,30.5 + parent: 2 - uid: 23196 components: - type: Transform @@ -153429,6 +153968,12 @@ entities: rot: 1.5707963267948966 rad pos: -10.5,-34.5 parent: 2 + - uid: 23198 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -36.5,-38.5 + parent: 2 - proto: SignFire entities: - uid: 28553 @@ -153436,7 +153981,65 @@ entities: - type: Transform pos: -27.5,34.5 parent: 2 -- proto: SignHydro2 +- proto: SignGravity + entities: + - uid: 9201 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 34.5,34.5 + parent: 2 +- proto: SignHead + entities: + - uid: 857 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 33.5,16.5 + parent: 2 + - uid: 7939 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -22.5,-36.5 + parent: 2 + - uid: 8251 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 47.5,-3.5 + parent: 2 + - uid: 9604 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 6.5,45.5 + parent: 2 + - uid: 18707 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -28.5,-33.5 + parent: 2 + - uid: 23313 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 38.5,-37.5 + parent: 2 + - uid: 23314 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -55.5,4.5 + parent: 2 + - uid: 28593 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 17.5,-32.5 + parent: 2 +- proto: SignHydro1 entities: - uid: 23182 components: @@ -153446,11 +154049,11 @@ entities: parent: 2 - proto: SignInterrogation entities: - - uid: 8927 + - uid: 23315 components: - type: Transform - rot: 1.5707963267948966 rad - pos: 36.5,-13.5 + rot: -1.5707963267948966 rad + pos: 33.5,-13.5 parent: 2 - proto: SignJanitor entities: @@ -153462,6 +154065,12 @@ entities: parent: 2 - proto: SignLawyer entities: + - uid: 8922 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 34.5,-1.5 + parent: 2 - uid: 8925 components: - type: Transform @@ -153566,13 +154175,21 @@ entities: rot: -1.5707963267948966 rad pos: -1.5,-47.5 parent: 2 +- proto: SignSalvage + entities: + - uid: 28902 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -52.5,-15.5 + parent: 2 - proto: SignScience entities: - - uid: 23198 + - uid: 28906 components: - type: Transform rot: -1.5707963267948966 rad - pos: 2.5,-36.5 + pos: 4.5,-40.5 parent: 2 - proto: SignSecurity entities: @@ -153594,6 +154211,22 @@ entities: rot: 1.5707963267948966 rad pos: 26.5,-26.5 parent: 2 +- proto: SignServer + entities: + - uid: 28903 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 18.5,-33.5 + parent: 2 +- proto: SignShipDock + entities: + - uid: 8514 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 52.5,2.5 + parent: 2 - proto: SignShock entities: - uid: 5411 @@ -153657,11 +154290,35 @@ entities: parent: 2 - proto: SignSpace entities: - - uid: 7789 + - uid: 880 components: - type: Transform - rot: 1.5707963267948966 rad - pos: 58.5,-18.5 + rot: -1.5707963267948966 rad + pos: -34.5,38.5 + parent: 2 + - uid: 885 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 5.5,-81.5 + parent: 2 + - uid: 890 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -50.5,-51.5 + parent: 2 + - uid: 7984 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 45.5,-47.5 + parent: 2 + - uid: 8249 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -58.5,-20.5 parent: 2 - uid: 8936 components: @@ -153669,6 +154326,24 @@ entities: rot: 1.5707963267948966 rad pos: 55.5,-32.5 parent: 2 + - uid: 9162 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -34.5,34.5 + parent: 2 + - uid: 9297 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -37.5,7.5 + parent: 2 + - uid: 23354 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 56.5,-18.5 + parent: 2 - uid: 28314 components: - type: Transform @@ -153689,6 +154364,18 @@ entities: - type: Transform pos: 47.5,-45.5 parent: 21002 + - uid: 28437 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -46.5,-54.5 + parent: 2 + - uid: 28864 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -10.5,-81.5 + parent: 2 - proto: SignSurgery entities: - uid: 8937 @@ -153704,6 +154391,14 @@ entities: - type: Transform pos: -30.5,-2.5 parent: 2 +- proto: SignTheater + entities: + - uid: 28904 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -28.5,-48.5 + parent: 2 - proto: SignToolStorage entities: - uid: 5794 @@ -153712,6 +154407,22 @@ entities: rot: -1.5707963267948966 rad pos: -27.5,2.5 parent: 2 +- proto: SignVirology + entities: + - uid: 28907 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -30.5,-24.5 + parent: 2 +- proto: SignXenobio + entities: + - uid: 7850 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -9.5,-51.5 + parent: 2 - proto: SingularityGenerator entities: - uid: 7089 @@ -154006,11 +154717,6 @@ entities: - type: Transform pos: 15.5,37.5 parent: 2 - - uid: 9399 - components: - - type: Transform - pos: 15.5,37.5 - parent: 2 - proto: SodaDispenserMachineCircuitboard entities: - uid: 5812 @@ -157422,6 +158128,18 @@ entities: parent: 2 - proto: StairStageDark entities: + - uid: 4011 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 24.5,-19.5 + parent: 2 + - uid: 6715 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 20.5,-23.5 + parent: 2 - uid: 28344 components: - type: Transform @@ -157455,6 +158173,17 @@ entities: parent: 2 - proto: StationMap entities: + - uid: 18502 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -39.5,-16.5 + parent: 2 + - uid: 18574 + components: + - type: Transform + pos: -47.5,-28.5 + parent: 2 - uid: 23439 components: - type: Transform @@ -157494,11 +158223,6 @@ entities: rot: -1.5707963267948966 rad pos: -39.5,-1.5 parent: 2 - - uid: 23463 - components: - - type: Transform - pos: -43.5,-28.5 - parent: 2 - uid: 23493 components: - type: Transform @@ -157828,16 +158552,6 @@ entities: - type: Transform pos: -42.5,25.5 parent: 2 - - uid: 8890 - components: - - type: Transform - pos: -42.5,29.5 - parent: 2 - - uid: 8891 - components: - - type: Transform - pos: -42.5,31.5 - parent: 2 - uid: 9743 components: - type: Transform @@ -159009,14 +159723,19 @@ entities: pos: -20.5,-2.5 parent: 2 - type: SurveillanceCamera + setupAvailableNetworks: + - SurveillanceCameraEntertainment id: Exhibit A - uid: 532 components: - type: Transform + anchored: False pos: -21.5,-2.5 parent: 2 - type: SurveillanceCamera id: Exhibit B + - type: Physics + bodyType: Dynamic - uid: 3481 components: - type: Transform @@ -160050,6 +160769,12 @@ entities: - type: Transform pos: 37.5,-34.5 parent: 2 + - uid: 9202 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 34.5,-16.5 + parent: 2 - uid: 13006 components: - type: Transform @@ -160080,6 +160805,18 @@ entities: - type: Transform pos: 58.5,14.5 parent: 2 + - uid: 16792 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 34.5,-14.5 + parent: 2 + - uid: 28613 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 34.5,-15.5 + parent: 2 - proto: TableCounterWood entities: - uid: 294 @@ -160146,24 +160883,12 @@ entities: rot: 1.5707963267948966 rad pos: 2.5,-54.5 parent: 2 - - uid: 12259 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -54.5,-36.5 - parent: 2 - uid: 12260 components: - type: Transform rot: -1.5707963267948966 rad pos: -53.5,-36.5 parent: 2 - - uid: 12261 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -56.5,-36.5 - parent: 2 - uid: 12263 components: - type: Transform @@ -160206,6 +160931,16 @@ entities: rot: 3.141592653589793 rad pos: 12.5,34.5 parent: 2 + - uid: 20992 + components: + - type: Transform + pos: -54.5,-36.5 + parent: 2 + - uid: 20993 + components: + - type: Transform + pos: -56.5,-36.5 + parent: 2 - uid: 23276 components: - type: Transform @@ -161105,11 +161840,6 @@ entities: - type: Transform pos: 8.5,-18.5 parent: 2 - - uid: 1042 - components: - - type: Transform - pos: 8.5,-19.5 - parent: 2 - uid: 1572 components: - type: Transform @@ -161729,6 +162459,11 @@ entities: - type: Transform pos: 16.5,1.5 parent: 21002 + - uid: 23184 + components: + - type: Transform + pos: 8.5,-19.5 + parent: 2 - uid: 23374 components: - type: Transform @@ -169819,96 +170554,6 @@ entities: rot: 3.141592653589793 rad pos: -37.5,34.5 parent: 2 - - uid: 8247 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -40.5,32.5 - parent: 2 - - uid: 8248 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -41.5,32.5 - parent: 2 - - uid: 8249 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -42.5,32.5 - parent: 2 - - uid: 8250 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -43.5,32.5 - parent: 2 - - uid: 8251 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -43.5,31.5 - parent: 2 - - uid: 8252 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -43.5,30.5 - parent: 2 - - uid: 8254 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -41.5,30.5 - parent: 2 - - uid: 8256 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -39.5,32.5 - parent: 2 - - uid: 8257 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -39.5,30.5 - parent: 2 - - uid: 8258 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -39.5,28.5 - parent: 2 - - uid: 8259 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -40.5,28.5 - parent: 2 - - uid: 8260 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -41.5,28.5 - parent: 2 - - uid: 8261 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -42.5,28.5 - parent: 2 - - uid: 8262 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -43.5,28.5 - parent: 2 - - uid: 8263 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -43.5,29.5 - parent: 2 - uid: 8264 components: - type: Transform @@ -170428,6 +171073,11 @@ entities: - type: Transform pos: -29.5,24.5 parent: 2 + - uid: 9199 + components: + - type: Transform + pos: 28.5,54.5 + parent: 2 - uid: 9383 components: - type: Transform @@ -172831,6 +173481,11 @@ entities: - type: Transform pos: -48.5,-28.5 parent: 2 + - uid: 11868 + components: + - type: Transform + pos: 28.5,55.5 + parent: 2 - uid: 11962 components: - type: Transform @@ -173535,12 +174190,6 @@ entities: rot: -1.5707963267948966 rad pos: -5.5,48.5 parent: 2 - - uid: 16800 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -34.5,36.5 - parent: 2 - uid: 18052 components: - type: Transform @@ -176079,18 +176728,6 @@ entities: rot: -1.5707963267948966 rad pos: -5.5,32.5 parent: 21002 - - uid: 28436 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -40.5,30.5 - parent: 2 - - uid: 28437 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -42.5,30.5 - parent: 2 - uid: 28521 components: - type: Transform @@ -176665,12 +177302,6 @@ entities: rot: 3.141592653589793 rad pos: 3.5,-17.5 parent: 2 - - uid: 1276 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 7.5,-17.5 - parent: 2 - uid: 1277 components: - type: Transform @@ -176683,54 +177314,12 @@ entities: rot: 3.141592653589793 rad pos: 4.5,-17.5 parent: 2 - - uid: 1279 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 8.5,-17.5 - parent: 2 - uid: 1280 components: - type: Transform rot: 3.141592653589793 rad pos: 18.5,-4.5 parent: 2 - - uid: 1282 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 18.5,-7.5 - parent: 2 - - uid: 1283 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 18.5,-6.5 - parent: 2 - - uid: 1284 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 18.5,-9.5 - parent: 2 - - uid: 1324 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 18.5,-8.5 - parent: 2 - - uid: 1325 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 9.5,-17.5 - parent: 2 - - uid: 1326 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 10.5,-17.5 - parent: 2 - uid: 1327 components: - type: Transform @@ -178589,11 +179178,11 @@ entities: rot: 1.5707963267948966 rad pos: -2.5,35.5 parent: 2 - - uid: 7849 + - uid: 7851 components: - type: Transform - rot: 1.5707963267948966 rad - pos: -2.5,36.5 + rot: 3.141592653589793 rad + pos: -2.5,38.5 parent: 2 - uid: 7852 components: @@ -179710,11 +180299,6 @@ entities: - type: Transform pos: -51.5,-18.5 parent: 2 - - uid: 11535 - components: - - type: Transform - pos: -57.5,-15.5 - parent: 2 - uid: 11536 components: - type: Transform @@ -180482,6 +181066,54 @@ entities: - type: Transform pos: -22.5,27.5 parent: 2 + - uid: 28597 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 8.5,-17.5 + parent: 2 + - uid: 28598 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 7.5,-17.5 + parent: 2 + - uid: 28599 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 18.5,-9.5 + parent: 2 + - uid: 28600 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 9.5,-17.5 + parent: 2 + - uid: 28602 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 18.5,-8.5 + parent: 2 + - uid: 28883 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 10.5,-17.5 + parent: 2 + - uid: 28884 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 18.5,-6.5 + parent: 2 + - uid: 28885 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 18.5,-7.5 + parent: 2 - proto: WallSolidRust entities: - uid: 24642 @@ -181248,18 +181880,6 @@ entities: rot: -1.5707963267948966 rad pos: -22.5,22.5 parent: 2 - - uid: 8918 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -39.5,30.5 - parent: 2 - - uid: 8919 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -39.5,28.5 - parent: 2 - uid: 8938 components: - type: Transform @@ -181703,11 +182323,6 @@ entities: rot: 1.5707963267948966 rad pos: 49.5,-37.5 parent: 2 - - uid: 12285 - components: - - type: Transform - pos: -55.5,-36.5 - parent: 2 - proto: WindoorHydroponicsLocked entities: - uid: 3318 @@ -181892,6 +182507,14 @@ entities: - type: Transform pos: -5.5,-34.5 parent: 2 +- proto: WindoorSecureSalvageLocked + entities: + - uid: 9234 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -57.5,-16.5 + parent: 2 - proto: WindoorSecureScienceLocked entities: - uid: 9918 @@ -182767,6 +183390,44 @@ entities: rot: 3.141592653589793 rad pos: -19.5,-26.5 parent: 2 + - uid: 28616 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -56.5,-28.5 + parent: 2 + - uid: 28617 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -56.5,-29.5 + parent: 2 + - uid: 28618 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -56.5,-27.5 + parent: 2 +- proto: WindowFrostedDirectional + entities: + - uid: 28867 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 34.5,-16.5 + parent: 2 + - uid: 28875 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 34.5,-15.5 + parent: 2 + - uid: 28876 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 34.5,-14.5 + parent: 2 - proto: WindowReinforcedDirectional entities: - uid: 352 @@ -182925,12 +183586,6 @@ entities: rot: -1.5707963267948966 rad pos: -14.5,-12.5 parent: 2 - - uid: 1865 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -56.5,-28.5 - parent: 2 - uid: 2329 components: - type: Transform @@ -182967,18 +183622,6 @@ entities: rot: -1.5707963267948966 rad pos: 19.5,4.5 parent: 2 - - uid: 3220 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -56.5,-27.5 - parent: 2 - - uid: 3227 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -56.5,-29.5 - parent: 2 - uid: 3424 components: - type: Transform @@ -183261,11 +183904,6 @@ entities: - type: Transform pos: -35.5,-4.5 parent: 2 - - uid: 1051 - components: - - type: Transform - pos: 11.5,-19.5 - parent: 2 - uid: 1596 components: - type: Transform @@ -183312,8 +183950,13 @@ entities: pos: 24.5,2.5 parent: 21002 - type: Door - secondsUntilStateChange: -362102 + secondsUntilStateChange: -378181.78 state: Opening + - uid: 28863 + components: + - type: Transform + pos: 11.5,-19.5 + parent: 2 - proto: WoodenBench entities: - uid: 21 From 12089285644fca383be893c6c4ae284bbbfc23f8 Mon Sep 17 00:00:00 2001 From: JIPDawg <51352440+JIPDawg@users.noreply.github.com> Date: Sat, 20 Jul 2024 01:23:07 -0500 Subject: [PATCH 088/134] Added missing builld components to RCD [empty] (#30177) * Added missing stuff to rcd[empty] * do the smart thing --------- Co-authored-by: JIP --- .../Prototypes/Entities/Objects/Tools/tools.yml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Tools/tools.yml b/Resources/Prototypes/Entities/Objects/Tools/tools.yml index 36e629c21c1..fba506d1f95 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/tools.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/tools.yml @@ -401,20 +401,6 @@ components: - type: LimitedCharges charges: 0 - - type: RCD - availablePrototypes: - - WallSolid - - FloorSteel - - Plating - - Catwalk - - Grille - - Window - - WindowDirectional - - WindowReinforcedDirectional - - ReinforcedWindow - - Airlock - - AirlockGlass - - Firelock - type: entity id: RCDRecharging From 297baaca2324b57d93dc61d59e3a402886c0847f Mon Sep 17 00:00:00 2001 From: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com> Date: Sat, 20 Jul 2024 01:06:52 -0700 Subject: [PATCH 089/134] Add user to AttemptMeleeEvent, add ThrowItemAttemptEvent (#30193) * Add user to AttemptMeleeEvent, add ThrowItemAttemptEvent * Add xmldoc --- Content.Shared/ActionBlocker/ActionBlockerSystem.cs | 8 +++++++- Content.Shared/Throwing/ThrowAttemptEvent.cs | 8 ++++++++ Content.Shared/Weapons/Melee/Events/AttemptMeleeEvent.cs | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Content.Shared/ActionBlocker/ActionBlockerSystem.cs b/Content.Shared/ActionBlocker/ActionBlockerSystem.cs index 005c7dc78ec..afa1e19eade 100644 --- a/Content.Shared/ActionBlocker/ActionBlockerSystem.cs +++ b/Content.Shared/ActionBlocker/ActionBlockerSystem.cs @@ -120,7 +120,13 @@ public bool CanThrow(EntityUid user, EntityUid itemUid) var ev = new ThrowAttemptEvent(user, itemUid); RaiseLocalEvent(user, ev); - return !ev.Cancelled; + if (ev.Cancelled) + return false; + + var itemEv = new ThrowItemAttemptEvent(user); + RaiseLocalEvent(itemUid, ref itemEv); + + return !itemEv.Cancelled; } public bool CanSpeak(EntityUid uid) diff --git a/Content.Shared/Throwing/ThrowAttemptEvent.cs b/Content.Shared/Throwing/ThrowAttemptEvent.cs index bf8cad6c746..dfb3dca5c7d 100644 --- a/Content.Shared/Throwing/ThrowAttemptEvent.cs +++ b/Content.Shared/Throwing/ThrowAttemptEvent.cs @@ -13,6 +13,14 @@ public ThrowAttemptEvent(EntityUid uid, EntityUid itemUid) public EntityUid ItemUid { get; } } + /// + /// Raised on the item entity that is thrown. + /// + /// The user that threw this entity. + /// Whether or not the throw should be cancelled. + [ByRefEvent] + public record struct ThrowItemAttemptEvent(EntityUid User, bool Cancelled = false); + /// /// Raised when we try to pushback an entity from throwing /// diff --git a/Content.Shared/Weapons/Melee/Events/AttemptMeleeEvent.cs b/Content.Shared/Weapons/Melee/Events/AttemptMeleeEvent.cs index 2800e3b34da..cbcadcd19f9 100644 --- a/Content.Shared/Weapons/Melee/Events/AttemptMeleeEvent.cs +++ b/Content.Shared/Weapons/Melee/Events/AttemptMeleeEvent.cs @@ -4,4 +4,4 @@ namespace Content.Shared.Weapons.Melee.Events; /// Raised directed on a weapon when attempt a melee attack. /// [ByRefEvent] -public record struct AttemptMeleeEvent(bool Cancelled, string? Message); +public record struct AttemptMeleeEvent(EntityUid User, bool Cancelled = false, string? Message = null); From c89186a26f282b00a84c248490b2ba8fbcdd2da1 Mon Sep 17 00:00:00 2001 From: chavonadelal <156101927+chavonadelal@users.noreply.github.com> Date: Sat, 20 Jul 2024 19:14:41 +0300 Subject: [PATCH 090/134] Localization of encryption keys (#30172) * Localization of encryption keys * Localization of encryption keys update --- Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs | 4 ++-- Content.Shared/Radio/RadioChannelPrototype.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs index cfa553661a3..7b050273db6 100644 --- a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs +++ b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs @@ -239,14 +239,14 @@ public void AddChannelsExamine(HashSet channels, string? defaultChannel, { var msg = Loc.GetString("examine-headset-default-channel", ("prefix", SharedChatSystem.DefaultChannelPrefix), - ("channel", defaultChannel), + ("channel", proto.LocalizedName), ("color", proto.Color)); examineEvent.PushMarkup(msg); } if (HasComp(examineEvent.Examined)) { var msg = Loc.GetString("examine-encryption-default-channel", - ("channel", defaultChannel), + ("channel", proto.LocalizedName), ("color", proto.Color)); examineEvent.PushMarkup(msg); } diff --git a/Content.Shared/Radio/RadioChannelPrototype.cs b/Content.Shared/Radio/RadioChannelPrototype.cs index cc65f885375..166db0577ea 100644 --- a/Content.Shared/Radio/RadioChannelPrototype.cs +++ b/Content.Shared/Radio/RadioChannelPrototype.cs @@ -9,7 +9,7 @@ public sealed partial class RadioChannelPrototype : IPrototype /// Human-readable name for the channel. /// [DataField("name")] - public string Name { get; private set; } = string.Empty; + public LocId Name { get; private set; } = string.Empty; [ViewVariables(VVAccess.ReadOnly)] public string LocalizedName => Loc.GetString(Name); From 6d664c9157cd9da7cecd5abb1beb93b4cf29cb19 Mon Sep 17 00:00:00 2001 From: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> Date: Sat, 20 Jul 2024 18:28:43 -0500 Subject: [PATCH 091/134] Add debug logs to baby jail and fix playtime logic (#30158) * add debug logs * Update Model.cs * fix playtime logic for null playtime * remove unnecessary condition * either me or the compiler is having a C# skill issue --- Content.Server.Database/Model.cs | 3 +++ Content.Server/Connection/ConnectionManager.cs | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Content.Server.Database/Model.cs b/Content.Server.Database/Model.cs index dea8f9558ab..d195201c29c 100644 --- a/Content.Server.Database/Model.cs +++ b/Content.Server.Database/Model.cs @@ -903,6 +903,9 @@ public enum ConnectionDenyReason : byte Panic = 3, /* * TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future. + * + * If baby jail is removed, please reserve this value for as long as can reasonably be done to prevent causing ambiguity in connection denial reasons. + * Reservation by commenting out the value is likely sufficient for this purpose, but may impact projects which depend on SS14 like SS14.Admin. */ BabyJail = 4, } diff --git a/Content.Server/Connection/ConnectionManager.cs b/Content.Server/Connection/ConnectionManager.cs index cf7581aa4e6..1d675842c76 100644 --- a/Content.Server/Connection/ConnectionManager.cs +++ b/Content.Server/Connection/ConnectionManager.cs @@ -308,6 +308,12 @@ session.Status is SessionStatus.Connected or SessionStatus.InGame return (false, ""); var isAccountAgeInvalid = record.FirstSeenTime.CompareTo(DateTimeOffset.Now - TimeSpan.FromMinutes(maxAccountAgeMinutes)) <= 0; + + if (isAccountAgeInvalid) + { + _sawmill.Debug($"Baby jail will deny {userId} for account age {record.FirstSeenTime}"); // Remove on or after 2024-09 + } + if (isAccountAgeInvalid && showReason) { var locAccountReason = reason != string.Empty @@ -322,7 +328,12 @@ session.Status is SessionStatus.Connected or SessionStatus.InGame } var overallTime = ( await _db.GetPlayTimes(e.UserId)).Find(p => p.Tracker == PlayTimeTrackingShared.TrackerOverall); - var isTotalPlaytimeInvalid = overallTime == null || overallTime.TimeSpent.TotalMinutes >= maxPlaytimeMinutes; + var isTotalPlaytimeInvalid = overallTime != null && overallTime.TimeSpent.TotalMinutes >= maxPlaytimeMinutes; + + if (isTotalPlaytimeInvalid) + { + _sawmill.Debug($"Baby jail will deny {userId} for playtime {overallTime!.TimeSpent}"); // Remove on or after 2024-09 + } if (isTotalPlaytimeInvalid && showReason) { From cb0ba66be38677d248ce11f809221230ebe89642 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Sat, 20 Jul 2024 20:42:27 -0400 Subject: [PATCH 092/134] Revert "Remove some BUI boilerplate" (#30214) Revert "Remove some BUI boilerplate (#28399)" This reverts commit cbf329a82d77eed2bb5e51666dab5d8a21fd3fff. --- .../UI/AccessOverriderBoundUserInterface.cs | 45 ++--- .../Access/UI/AccessOverriderWindow.xaml.cs | 41 +++-- .../UI/AgentIDCardBoundUserInterface.cs | 19 +- .../Access/UI/AgentIDCardWindow.xaml.cs | 10 +- .../Ame/UI/AmeControllerBoundUserInterface.cs | 16 +- Content.Client/Ame/UI/AmeWindow.xaml.cs | 19 +- .../Ui/AnomalyGeneratorBoundUserInterface.cs | 20 +- .../Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs | 8 +- Content.Client/Arcade/BlockGameMenu.cs | 45 ++--- .../Arcade/SpaceVillainArcadeMenu.cs | 45 +++-- .../Arcade/UI/BlockGameBoundUserInterface.cs | 5 +- .../SpaceVillainArcadeBoundUserInterface.cs | 16 +- .../Monitor/UI/AirAlarmBoundUserInterface.cs | 12 +- .../Atmos/Monitor/UI/AirAlarmWindow.xaml.cs | 7 +- .../Atmos/UI/GasCanisterBoundUserInterface.cs | 9 +- .../Atmos/UI/GasFilterBoundUserInterface.cs | 11 +- .../Atmos/UI/GasFilterWindow.xaml.cs | 7 +- .../Atmos/UI/GasMixerBoundUserInteface.cs | 18 +- .../UI/GasPressurePumpBoundUserInterface.cs | 17 +- .../UI/GasThermomachineBoundUserInterface.cs | 17 +- .../UI/GasVolumePumpBoundUserInterface.cs | 19 +- .../Atmos/UI/SpaceHeaterBoundUserInterface.cs | 10 +- .../Jukebox/JukeboxBoundUserInterface.cs | 21 ++- .../CryostorageBoundUserInterface.cs | 15 +- .../CargoBountyConsoleBoundUserInterface.cs | 17 +- .../CargoPalletConsoleBoundUserInterface.cs | 15 +- .../CargoShuttleConsoleBoundUserInterface.cs | 24 ++- .../Cargo/UI/CargoShuttleMenu.xaml.cs | 13 +- .../UI/ChemMasterBoundUserInterface.cs | 20 +- .../UI/ReagentDispenserBoundUserInterface.cs | 27 ++- .../UI/TransferAmountBoundUserInterface.cs | 12 +- .../UI/CloningConsoleBoundUserInterface.cs | 25 ++- .../UI/ChameleonBoundUserInterface.cs | 16 +- ...CommunicationsConsoleBoundUserInterface.cs | 72 +++++--- .../UI/CommunicationsConsoleMenu.xaml.cs | 81 ++++----- .../Computer/ComputerBoundUserInterface.cs | 15 +- .../UI/ConfigurationBoundUserInterface.cs | 28 ++- .../Configurable/UI/ConfigurationMenu.cs | 18 +- .../UI/FlatpackCreatorBoundUserInterface.cs | 14 +- .../UI/FlatpackCreatorMenu.xaml.cs | 13 +- .../Crayon/UI/CrayonBoundUserInterface.cs | 40 ++-- Content.Client/Crayon/UI/CrayonWindow.xaml.cs | 18 +- .../UI/DisposalRouterBoundUserInterface.cs | 22 ++- .../UI/DisposalTaggerBoundUserInterface.cs | 23 ++- .../DoorElectronicsBoundUserInterface.cs | 31 ++-- .../DoorElectronicsConfigurationMenu.xaml.cs | 21 +-- Content.Client/Fax/UI/FaxBoundUi.cs | 12 +- .../ForensicScannerBoundUserInterface.cs | 15 +- .../Gateway/UI/GatewayBoundUserInterface.cs | 16 +- .../Gateway/UI/GatewayWindow.xaml.cs | 10 +- .../UI/GravityGeneratorBoundUserInterface.cs | 23 ++- .../Gravity/UI/GravityGeneratorWindow.xaml.cs | 15 +- .../UI/HealthAnalyzerBoundUserInterface.cs | 23 ++- ...manoidMarkingModifierBoundUserInterface.cs | 4 +- .../Instruments/UI/BandMenu.xaml.cs | 6 +- .../Instruments/UI/ChannelsMenu.xaml.cs | 5 +- .../UI/InstrumentBoundUserInterface.cs | 36 +--- .../Instruments/UI/InstrumentMenu.xaml.cs | 171 ++++++++---------- .../Inventory/StrippableBoundUserInterface.cs | 25 +-- Content.Client/Kitchen/UI/GrinderMenu.xaml.cs | 42 +++-- .../Kitchen/UI/MicrowaveBoundUserInterface.cs | 43 ++++- .../Kitchen/UI/MicrowaveMenu.xaml.cs | 24 +-- .../UI/ReagentGrinderBoundUserInterface.cs | 34 ++-- .../UI/HandLabelerBoundUserInterface.cs | 16 +- .../Lathe/UI/LatheBoundUserInterface.cs | 17 +- Content.Client/Lathe/UI/LatheMenu.xaml.cs | 29 ++- .../UI/SignalTimerBoundUserInterface.cs | 24 ++- .../UI/SignalTimerWindow.xaml.cs | 24 ++- .../MagicMirrorBoundUserInterface.cs | 15 +- .../Ui/NewsWriterBoundUserInterface.cs | 18 +- .../MassMedia/Ui/NewsWriterMenu.xaml.cs | 6 +- .../Mech/Ui/MechBoundUserInterface.cs | 16 +- Content.Client/Mech/Ui/MechMenu.xaml.cs | 9 +- .../CrewMonitoringBoundUserInterface.cs | 18 +- .../CrewMonitoringWindow.xaml.cs | 17 +- .../NetworkConfiguratorBoundUserInterface.cs | 39 ++-- ...tworkConfiguratorConfigurationMenu.xaml.cs | 8 +- .../NetworkConfiguratorDeviceList.xaml.cs | 12 +- .../NetworkConfiguratorLinkMenu.xaml.cs | 16 +- .../NetworkConfiguratorListMenu.xaml.cs | 13 +- Content.Client/Nuke/NukeBoundUserInterface.cs | 17 +- .../WarDeclaratorBoundUserInterface.cs | 18 +- .../NukeOps/WarDeclaratorWindow.xaml.cs | 9 +- Content.Client/PDA/PdaBoundUserInterface.cs | 17 +- .../PDA/Ringer/RingerBoundUserInterface.cs | 4 +- .../Paper/UI/PaperBoundUserInterface.cs | 17 +- Content.Client/Paper/UI/PaperWindow.xaml.cs | 6 +- .../ParticleAcceleratorBoundUserInterface.cs | 16 +- .../UI/ParticleAcceleratorControlMenu.cs | 30 ++- .../UI/NavMapBeaconBoundUserInterface.cs | 16 +- .../Pinpointer/UI/NavMapBeaconWindow.xaml.cs | 25 +-- .../UI/StationMapBoundUserInterface.cs | 15 +- .../Pinpointer/UI/StationMapWindow.xaml.cs | 11 +- .../UI/UntrackedMapBoundUserInterface.cs | 15 +- .../Power/APC/ApcBoundUserInterface.cs | 16 +- Content.Client/Power/APC/UI/ApcMenu.xaml.cs | 12 +- .../Power/Generator/GeneratorWindow.xaml.cs | 52 +++--- .../PortableGeneratorBoundUserInterface.cs | 25 +-- ...owerMonitoringConsoleBoundUserInterface.cs | 19 +- .../PowerMonitoringWindow.xaml.Widgets.cs | 6 +- .../Power/PowerMonitoringWindow.xaml.cs | 84 ++++----- Content.Client/RCD/RCDMenu.xaml.cs | 35 ++-- .../RCD/RCDMenuBoundUserInterface.cs | 16 +- .../Radio/Ui/IntercomBoundUserInterface.cs | 20 +- Content.Client/Radio/Ui/IntercomMenu.xaml.cs | 4 +- .../UI/DiskConsoleBoundUserInterface.cs | 15 +- .../UI/ResearchClientBoundUserInterface.cs | 16 +- .../ResearchClientServerSelectionMenu.xaml.cs | 11 +- .../UI/ResearchConsoleBoundUserInterface.cs | 28 ++- .../Research/UI/ResearchConsoleMenu.xaml.cs | 29 ++- .../UI/RoboticsConsoleBoundUserInterface.cs | 18 +- .../Robotics/UI/RoboticsConsoleWindow.xaml.cs | 25 +-- ...vageExpeditionConsoleBoundUserInterface.cs | 12 +- .../UI/SalvageMagnetBoundUserInterface.cs | 21 ++- .../BUI/IFFConsoleBoundUserInterface.cs | 4 +- .../BUI/RadarConsoleBoundUserInterface.cs | 14 +- .../BUI/ShuttleConsoleBoundUserInterface.cs | 5 +- .../Silicons/Borgs/BorgBoundUserInterface.cs | 18 +- Content.Client/Silicons/Borgs/BorgMenu.xaml | 2 +- .../Silicons/Borgs/BorgMenu.xaml.cs | 49 ++--- .../Laws/Ui/SiliconLawBoundUserInterface.cs | 14 +- .../UI/SprayPainterBoundUserInterface.cs | 27 ++- ...lStationRecordConsoleBoundUserInterface.cs | 13 +- .../Store/Ui/StoreBoundUserInterface.cs | 15 +- Content.Client/Strip/StrippingMenu.cs | 11 +- .../UI/SurveillanceCameraMonitorBoundUi.cs | 11 +- .../Thief/ThiefBackpackBoundUserInterface.cs | 19 +- .../Thief/ThiefBackpackMenu.xaml.cs | 28 +-- .../GasTank/GasTankBoundUserInterface.cs | 11 +- .../Systems/Atmos/GasTank/GasTankWindow.cs | 43 ++--- .../VendingMachineBoundUserInterface.cs | 8 +- .../VoiceMask/VoiceMaskBoundUserInterface.cs | 8 +- .../VoiceMaskNameChangeWindow.xaml.cs | 6 +- .../Melee/UI/MeleeSpeechBoundUserInterface.cs | 10 +- .../Wires/UI/WiresBoundUserInterface.cs | 7 +- Content.Client/Wires/UI/WiresMenu.cs | 16 +- .../Ui/AnalysisConsoleBoundUserInterface.cs | 6 +- 137 files changed, 1751 insertions(+), 1092 deletions(-) diff --git a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs index d80c600c03e..c1b63dc4d05 100644 --- a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs +++ b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.Containers.ItemSlots; -using Robust.Client.UserInterface; using Robust.Shared.Prototypes; using static Content.Shared.Access.Components.AccessOverriderComponent; @@ -24,28 +23,6 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - RefreshAccess(); - _window.Title = EntMan.GetComponent(Owner).EntityName; - _window.OnSubmit += SubmitData; - - _window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId)); - } - - public override void OnProtoReload(PrototypesReloadedEventArgs args) - { - base.OnProtoReload(args); - if (!args.WasModified()) - return; - - RefreshAccess(); - - if (State != null) - _window?.UpdateState(_prototypeManager, (AccessOverriderBoundUserInterfaceState) State); - } - - private void RefreshAccess() - { List> accessLevels; if (EntMan.TryGetComponent(Owner, out var accessOverrider)) @@ -53,20 +30,38 @@ private void RefreshAccess() accessLevels = accessOverrider.AccessLevels; accessLevels.Sort(); } + else { accessLevels = new List>(); _accessOverriderSystem.Log.Error($"No AccessOverrider component found for {EntMan.ToPrettyString(Owner)}!"); } - _window?.SetAccessLevels(_prototypeManager, accessLevels); + _window = new AccessOverriderWindow(this, _prototypeManager, accessLevels) + { + Title = EntMan.GetComponent(Owner).EntityName + }; + + _window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId)); + + _window.OnClose += Close; + _window.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _window?.Dispose(); } protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); var castState = (AccessOverriderBoundUserInterfaceState) state; - _window?.UpdateState(_prototypeManager, castState); + _window?.UpdateState(castState); } public void SubmitData(List> newAccessList) diff --git a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs index ba087718583..6025c3b551f 100644 --- a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs +++ b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs @@ -13,24 +13,26 @@ namespace Content.Client.Access.UI [GenerateTypedNameReferences] public sealed partial class AccessOverriderWindow : DefaultWindow { - private readonly Dictionary _accessButtons = new(); + [Dependency] private readonly ILogManager _logManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - public event Action>>? OnSubmit; + private readonly AccessOverriderBoundUserInterface _owner; + private readonly Dictionary _accessButtons = new(); - public AccessOverriderWindow() + public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototypeManager prototypeManager, + List> accessLevels) { RobustXamlLoader.Load(this); - } + IoCManager.InjectDependencies(this); + var logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill); - public void SetAccessLevels(IPrototypeManager protoManager, List> accessLevels) - { - _accessButtons.Clear(); - AccessLevelGrid.DisposeAllChildren(); + _owner = owner; foreach (var access in accessLevels) { - if (!protoManager.TryIndex(access, out var accessLevel)) + if (!prototypeManager.TryIndex(access, out var accessLevel)) { + logMill.Error($"Unable to find accesslevel for {access}"); continue; } @@ -42,16 +44,11 @@ public void SetAccessLevels(IPrototypeManager protoManager, List - { - OnSubmit?.Invoke( - // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair - _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList()); - }; + newButton.OnPressed += _ => SubmitData(); } } - public void UpdateState(IPrototypeManager protoManager, AccessOverriderBoundUserInterfaceState state) + public void UpdateState(AccessOverriderBoundUserInterfaceState state) { PrivilegedIdLabel.Text = state.PrivilegedIdName; PrivilegedIdButton.Text = state.IsPrivilegedIdPresent @@ -69,11 +66,11 @@ public void UpdateState(IPrototypeManager protoManager, AccessOverriderBoundUser if (state.MissingPrivilegesList != null && state.MissingPrivilegesList.Any()) { - var missingPrivileges = new List(); + List missingPrivileges = new List(); foreach (string tag in state.MissingPrivilegesList) { - var privilege = Loc.GetString(protoManager.Index(tag)?.Name ?? "generic-unknown"); + string privilege = Loc.GetString(_prototypeManager.Index(tag)?.Name ?? "generic-unknown"); missingPrivileges.Add(privilege); } @@ -93,5 +90,13 @@ public void UpdateState(IPrototypeManager protoManager, AccessOverriderBoundUser } } } + + private void SubmitData() + { + _owner.SubmitData( + + // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair + _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList()); + } } } diff --git a/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs b/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs index 50add43dc91..761f52988a9 100644 --- a/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs +++ b/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Access.Systems; using Content.Shared.StatusIcon; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Access.UI @@ -21,11 +20,16 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window?.Dispose(); + _window = new AgentIDCardWindow(this); + if (State != null) + UpdateState(State); + _window.OpenCentered(); + + _window.OnClose += Close; _window.OnNameChanged += OnNameChanged; _window.OnJobChanged += OnJobChanged; - _window.OnJobIconChanged += OnJobIconChanged; } private void OnNameChanged(string newName) @@ -57,5 +61,14 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetCurrentJob(cast.CurrentJob); _window.SetAllowedIcons(cast.Icons, cast.CurrentJobIconId); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _window?.Dispose(); + } } } diff --git a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs index 071ce41a069..6d0b2a184f4 100644 --- a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs +++ b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs @@ -17,19 +17,19 @@ public sealed partial class AgentIDCardWindow : DefaultWindow [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IEntitySystemManager _entitySystem = default!; private readonly SpriteSystem _spriteSystem; + private readonly AgentIDCardBoundUserInterface _bui; private const int JobIconColumnCount = 10; public event Action? OnNameChanged; public event Action? OnJobChanged; - public event Action>? OnJobIconChanged; - - public AgentIDCardWindow() + public AgentIDCardWindow(AgentIDCardBoundUserInterface bui) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); _spriteSystem = _entitySystem.GetEntitySystem(); + _bui = bui; NameLineEdit.OnTextEntered += e => OnNameChanged?.Invoke(e.Text); NameLineEdit.OnFocusExit += e => OnNameChanged?.Invoke(e.Text); @@ -67,7 +67,7 @@ public void SetAllowedIcons(HashSet> icons, string }; // Generate buttons textures - var jobIconTexture = new TextureRect + TextureRect jobIconTexture = new TextureRect { Texture = _spriteSystem.Frame0(jobIcon.Icon), TextureScale = new Vector2(2.5f, 2.5f), @@ -75,7 +75,7 @@ public void SetAllowedIcons(HashSet> icons, string }; jobIconButton.AddChild(jobIconTexture); - jobIconButton.OnPressed += _ => OnJobIconChanged?.Invoke(jobIcon.ID); + jobIconButton.OnPressed += _ => _bui.OnJobIconChanged(jobIconId); IconGrid.AddChild(jobIconButton); if (jobIconId.Equals(currentJobIconId)) diff --git a/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs b/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs index 3d65f751899..e84cf5d34de 100644 --- a/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs +++ b/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Ame.Components; using JetBrains.Annotations; -using Robust.Client.UserInterface; namespace Content.Client.Ame.UI { @@ -17,8 +16,9 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.OnAmeButton += ButtonPressed; + _window = new AmeWindow(this); + _window.OnClose += Close; + _window.OpenCentered(); } /// @@ -40,5 +40,15 @@ public void ButtonPressed(UiButton button) { SendMessage(new UiButtonPressedMessage(button)); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + _window?.Dispose(); + } + } } } diff --git a/Content.Client/Ame/UI/AmeWindow.xaml.cs b/Content.Client/Ame/UI/AmeWindow.xaml.cs index d6d580bcdaf..8b91ec59660 100644 --- a/Content.Client/Ame/UI/AmeWindow.xaml.cs +++ b/Content.Client/Ame/UI/AmeWindow.xaml.cs @@ -1,4 +1,3 @@ -using System.Linq; using Content.Client.UserInterface; using Content.Shared.Ame.Components; using Robust.Client.AutoGenerated; @@ -10,17 +9,15 @@ namespace Content.Client.Ame.UI [GenerateTypedNameReferences] public sealed partial class AmeWindow : DefaultWindow { - public event Action? OnAmeButton; - - public AmeWindow() + public AmeWindow(AmeControllerBoundUserInterface ui) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - EjectButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.Eject); - ToggleInjection.OnPressed += _ => OnAmeButton?.Invoke(UiButton.ToggleInjection); - IncreaseFuelButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.IncreaseFuel); - DecreaseFuelButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.DecreaseFuel); + EjectButton.OnPressed += _ => ui.ButtonPressed(UiButton.Eject); + ToggleInjection.OnPressed += _ => ui.ButtonPressed(UiButton.ToggleInjection); + IncreaseFuelButton.OnPressed += _ => ui.ButtonPressed(UiButton.IncreaseFuel); + DecreaseFuelButton.OnPressed += _ => ui.ButtonPressed(UiButton.DecreaseFuel); } /// @@ -32,7 +29,7 @@ public void UpdateState(BoundUserInterfaceState state) var castState = (AmeControllerBoundUserInterfaceState) state; // Disable all buttons if not powered - if (Contents.Children.Any()) + if (Contents.Children != null) { ButtonHelpers.SetButtonDisabledRecursive(Contents, !castState.HasPower); EjectButton.Disabled = false; @@ -68,8 +65,8 @@ public void UpdateState(BoundUserInterfaceState state) CoreCount.Text = $"{castState.CoreCount}"; InjectionAmount.Text = $"{castState.InjectionAmount}"; // format power statistics to pretty numbers - CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply:N1}"; - TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply:N1}"; + CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply.ToString("N1")}"; + TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply.ToString("N1")}"; } } } diff --git a/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs b/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs index 5d1985485c4..5764d0a097d 100644 --- a/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs +++ b/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Gravity; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Anomaly.Ui; @@ -19,8 +18,10 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.SetEntity(Owner); + _window = new(Owner); + + _window.OpenCentered(); + _window.OnClose += Close; _window.OnGenerateButtonPressed += () => { @@ -36,5 +37,18 @@ protected override void UpdateState(BoundUserInterfaceState state) return; _window?.UpdateState(msg); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + + _window?.Dispose(); + } + + public void SetPowerSwitch(bool on) + { + SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on)); + } } diff --git a/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs b/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs index 82d41192dd0..08438e2a1b2 100644 --- a/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs +++ b/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs @@ -18,21 +18,17 @@ public sealed partial class AnomalyGeneratorWindow : FancyWindow public Action? OnGenerateButtonPressed; - public AnomalyGeneratorWindow() + public AnomalyGeneratorWindow(EntityUid gen) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); + EntityView.SetEntity(gen); EntityView.SpriteOffset = false; GenerateButton.OnPressed += _ => OnGenerateButtonPressed?.Invoke(); } - public void SetEntity(EntityUid uid) - { - EntityView.SetEntity(uid); - } - public void UpdateState(AnomalyGeneratorUserInterfaceState state) { _cooldownEnd = state.CooldownEndTime; diff --git a/Content.Client/Arcade/BlockGameMenu.cs b/Content.Client/Arcade/BlockGameMenu.cs index 4a579fc4bf4..eeda2a31020 100644 --- a/Content.Client/Arcade/BlockGameMenu.cs +++ b/Content.Client/Arcade/BlockGameMenu.cs @@ -28,6 +28,8 @@ public sealed class BlockGameMenu : DefaultWindow private static readonly Vector2 BlockSize = new(15, 15); + private readonly BlockGameBoundUserInterface _owner; + private readonly PanelContainer _mainPanel; private readonly BoxContainer _gameRootContainer; @@ -56,11 +58,10 @@ public sealed class BlockGameMenu : DefaultWindow private bool _isPlayer = false; private bool _gameOver = false; - public event Action? OnAction; - - public BlockGameMenu() + public BlockGameMenu(BlockGameBoundUserInterface owner) { Title = Loc.GetString("blockgame-menu-title"); + _owner = owner; MinSize = SetSize = new Vector2(410, 490); @@ -175,7 +176,7 @@ public BlockGameMenu() }; _newGameButton.OnPressed += (e) => { - OnAction?.Invoke(BlockGamePlayerAction.NewGame); + _owner.SendAction(BlockGamePlayerAction.NewGame); }; pauseMenuContainer.AddChild(_newGameButton); pauseMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) }); @@ -185,10 +186,7 @@ public BlockGameMenu() Text = Loc.GetString("blockgame-menu-button-scoreboard"), TextAlign = Label.AlignMode.Center }; - _scoreBoardButton.OnPressed += (e) => - { - OnAction?.Invoke(BlockGamePlayerAction.ShowHighscores); - }; + _scoreBoardButton.OnPressed += (e) => _owner.SendAction(BlockGamePlayerAction.ShowHighscores); pauseMenuContainer.AddChild(_scoreBoardButton); _unpauseButtonMargin = new Control { MinSize = new Vector2(1, 10), Visible = false }; pauseMenuContainer.AddChild(_unpauseButtonMargin); @@ -201,7 +199,7 @@ public BlockGameMenu() }; _unpauseButton.OnPressed += (e) => { - OnAction?.Invoke(BlockGamePlayerAction.Unpause); + _owner.SendAction(BlockGamePlayerAction.Unpause); }; pauseMenuContainer.AddChild(_unpauseButton); @@ -259,7 +257,7 @@ public BlockGameMenu() }; _finalNewGameButton.OnPressed += (e) => { - OnAction?.Invoke(BlockGamePlayerAction.NewGame); + _owner.SendAction(BlockGamePlayerAction.NewGame); }; gameOverMenuContainer.AddChild(_finalNewGameButton); @@ -329,10 +327,7 @@ public BlockGameMenu() Text = Loc.GetString("blockgame-menu-button-back"), TextAlign = Label.AlignMode.Center }; - _highscoreBackButton.OnPressed += (e) => - { - OnAction?.Invoke(BlockGamePlayerAction.Pause); - }; + _highscoreBackButton.OnPressed += (e) => _owner.SendAction(BlockGamePlayerAction.Pause); menuContainer.AddChild(_highscoreBackButton); menuInnerPanel.AddChild(menuContainer); @@ -478,7 +473,7 @@ protected override void KeyboardFocusExited() private void TryPause() { - OnAction?.Invoke(BlockGamePlayerAction.Pause); + _owner.SendAction(BlockGamePlayerAction.Pause); } public void SetStarted() @@ -581,19 +576,19 @@ protected override void KeyBindDown(GUIBoundKeyEventArgs args) return; else if (args.Function == ContentKeyFunctions.ArcadeLeft) - OnAction?.Invoke(BlockGamePlayerAction.StartLeft); + _owner.SendAction(BlockGamePlayerAction.StartLeft); else if (args.Function == ContentKeyFunctions.ArcadeRight) - OnAction?.Invoke(BlockGamePlayerAction.StartRight); + _owner.SendAction(BlockGamePlayerAction.StartRight); else if (args.Function == ContentKeyFunctions.ArcadeUp) - OnAction?.Invoke(BlockGamePlayerAction.Rotate); + _owner.SendAction(BlockGamePlayerAction.Rotate); else if (args.Function == ContentKeyFunctions.Arcade3) - OnAction?.Invoke(BlockGamePlayerAction.CounterRotate); + _owner.SendAction(BlockGamePlayerAction.CounterRotate); else if (args.Function == ContentKeyFunctions.ArcadeDown) - OnAction?.Invoke(BlockGamePlayerAction.SoftdropStart); + _owner.SendAction(BlockGamePlayerAction.SoftdropStart); else if (args.Function == ContentKeyFunctions.Arcade2) - OnAction?.Invoke(BlockGamePlayerAction.Hold); + _owner.SendAction(BlockGamePlayerAction.Hold); else if (args.Function == ContentKeyFunctions.Arcade1) - OnAction?.Invoke(BlockGamePlayerAction.Harddrop); + _owner.SendAction(BlockGamePlayerAction.Harddrop); } protected override void KeyBindUp(GUIBoundKeyEventArgs args) @@ -604,11 +599,11 @@ protected override void KeyBindUp(GUIBoundKeyEventArgs args) return; else if (args.Function == ContentKeyFunctions.ArcadeLeft) - OnAction?.Invoke(BlockGamePlayerAction.EndLeft); + _owner.SendAction(BlockGamePlayerAction.EndLeft); else if (args.Function == ContentKeyFunctions.ArcadeRight) - OnAction?.Invoke(BlockGamePlayerAction.EndRight); + _owner.SendAction(BlockGamePlayerAction.EndRight); else if (args.Function == ContentKeyFunctions.ArcadeDown) - OnAction?.Invoke(BlockGamePlayerAction.SoftdropEnd); + _owner.SendAction(BlockGamePlayerAction.SoftdropEnd); } public void UpdateNextBlock(BlockGameBlock[] blocks) diff --git a/Content.Client/Arcade/SpaceVillainArcadeMenu.cs b/Content.Client/Arcade/SpaceVillainArcadeMenu.cs index 1ee4c268184..e5542a5848e 100644 --- a/Content.Client/Arcade/SpaceVillainArcadeMenu.cs +++ b/Content.Client/Arcade/SpaceVillainArcadeMenu.cs @@ -8,6 +8,8 @@ namespace Content.Client.Arcade { public sealed class SpaceVillainArcadeMenu : DefaultWindow { + public SpaceVillainArcadeBoundUserInterface Owner { get; set; } + private readonly Label _enemyNameLabel; private readonly Label _playerInfoLabel; private readonly Label _enemyInfoLabel; @@ -15,13 +17,11 @@ public sealed class SpaceVillainArcadeMenu : DefaultWindow private readonly Label _enemyActionLabel; private readonly Button[] _gameButtons = new Button[3]; //used to disable/enable all game buttons - - public event Action? OnPlayerAction; - - public SpaceVillainArcadeMenu() + public SpaceVillainArcadeMenu(SpaceVillainArcadeBoundUserInterface owner) { MinSize = SetSize = new Vector2(300, 225); Title = Loc.GetString("spacevillain-menu-title"); + Owner = owner; var grid = new GridContainer { Columns = 1 }; @@ -47,43 +47,32 @@ public SpaceVillainArcadeMenu() grid.AddChild(_enemyActionLabel); var buttonGrid = new GridContainer { Columns = 3 }; - _gameButtons[0] = new Button() + _gameButtons[0] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Attack) { Text = Loc.GetString("spacevillain-menu-button-attack") }; - - _gameButtons[0].OnPressed += - _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Attack); buttonGrid.AddChild(_gameButtons[0]); - _gameButtons[1] = new Button() + _gameButtons[1] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Heal) { Text = Loc.GetString("spacevillain-menu-button-heal") }; - - _gameButtons[1].OnPressed += - _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Heal); buttonGrid.AddChild(_gameButtons[1]); - _gameButtons[2] = new Button() + _gameButtons[2] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Recharge) { Text = Loc.GetString("spacevillain-menu-button-recharge") }; - - _gameButtons[2].OnPressed += - _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Recharge); buttonGrid.AddChild(_gameButtons[2]); centerContainer = new CenterContainer(); centerContainer.AddChild(buttonGrid); grid.AddChild(centerContainer); - var newGame = new Button() + var newGame = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.NewGame) { Text = Loc.GetString("spacevillain-menu-button-new-game") }; - - newGame.OnPressed += _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.NewGame); grid.AddChild(newGame); Contents.AddChild(grid); @@ -110,5 +99,23 @@ public void UpdateInfo(SharedSpaceVillainArcadeComponent.SpaceVillainArcadeDataU _playerActionLabel.Text = message.PlayerActionMessage; _enemyActionLabel.Text = message.EnemyActionMessage; } + + private sealed class ActionButton : Button + { + private readonly SpaceVillainArcadeBoundUserInterface _owner; + private readonly SharedSpaceVillainArcadeComponent.PlayerAction _playerAction; + + public ActionButton(SpaceVillainArcadeBoundUserInterface owner, SharedSpaceVillainArcadeComponent.PlayerAction playerAction) + { + _owner = owner; + _playerAction = playerAction; + OnPressed += Clicked; + } + + private void Clicked(ButtonEventArgs e) + { + _owner.SendAction(_playerAction); + } + } } } diff --git a/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs b/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs index 8fa8035afd6..1a3422dec0f 100644 --- a/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs +++ b/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Arcade; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Arcade.UI; @@ -16,7 +15,9 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new BlockGameMenu(this); + _menu.OnClose += Close; + _menu.OpenCentered(); } protected override void ReceiveMessage(BoundUserInterfaceMessage message) diff --git a/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs b/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs index c0704530de2..40bbe8b2d8c 100644 --- a/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs +++ b/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs @@ -1,5 +1,4 @@ using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Shared.GameObjects; using Robust.Shared.ViewVariables; using static Content.Shared.Arcade.SharedSpaceVillainArcadeComponent; @@ -10,6 +9,8 @@ public sealed class SpaceVillainArcadeBoundUserInterface : BoundUserInterface { [ViewVariables] private SpaceVillainArcadeMenu? _menu; + //public SharedSpaceVillainArcadeComponent SpaceVillainArcade; + public SpaceVillainArcadeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { SendAction(PlayerAction.RequestData); @@ -24,7 +25,10 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new SpaceVillainArcadeMenu(this); + + _menu.OnClose += Close; + _menu.OpenCentered(); } protected override void ReceiveMessage(BoundUserInterfaceMessage message) @@ -32,4 +36,12 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) if (message is SpaceVillainArcadeDataUpdateMessage msg) _menu?.UpdateInfo(msg); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + _menu?.Dispose(); + } } diff --git a/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs b/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs index 2ae15188355..8f3b507c806 100644 --- a/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs +++ b/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Monitor.Components; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Log; @@ -21,9 +20,16 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.SetEntity(Owner); + _window = new AirAlarmWindow(this); + if (State != null) + { + UpdateState(State); + } + + _window.OpenCentered(); + + _window.OnClose += Close; _window.AtmosDeviceDataChanged += OnDeviceDataChanged; _window.AtmosDeviceDataCopied += OnDeviceDataCopied; _window.AtmosAlarmThresholdChanged += OnThresholdChanged; diff --git a/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs b/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs index eeec11c7660..43be67c9d6b 100644 --- a/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs +++ b/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs @@ -47,7 +47,7 @@ public sealed partial class AirAlarmWindow : FancyWindow private CheckBox _autoMode => AutoModeCheckBox; - public AirAlarmWindow() + public AirAlarmWindow(BoundUserInterface owner) { RobustXamlLoader.Load(this); @@ -95,11 +95,8 @@ public AirAlarmWindow() _sensors.Clear(); ResyncAllRequested!.Invoke(); }; - } - public void SetEntity(EntityUid uid) - { - EntityView.SetEntity(uid); + EntityView.SetEntity(owner.Owner); } public void UpdateState(AirAlarmUIState state) diff --git a/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs b/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs index 7bf9b396d5e..a5e316a8def 100644 --- a/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Atmos.Piping.Binary.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -22,8 +21,14 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new GasCanisterWindow(); + if (State != null) + UpdateState(State); + + _window.OpenCentered(); + + _window.OnClose += Close; _window.ReleaseValveCloseButtonPressed += OnReleaseValveClosePressed; _window.ReleaseValveOpenButtonPressed += OnReleaseValveOpenPressed; _window.ReleasePressureSet += OnReleasePressureSet; diff --git a/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs b/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs index 2b8020924cf..1904e2b3402 100644 --- a/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs @@ -3,7 +3,6 @@ using Content.Shared.Atmos.Piping.Trinary.Components; using Content.Shared.Localizations; using JetBrains.Annotations; -using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -29,8 +28,14 @@ protected override void Open() var atmosSystem = EntMan.System(); - _window = this.CreateWindow(); - _window.PopulateGasList(atmosSystem.Gases); + _window = new GasFilterWindow(atmosSystem.Gases); + + if (State != null) + UpdateState(State); + + _window.OpenCentered(); + + _window.OnClose += Close; _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.FilterTransferRateChanged += OnFilterTransferRatePressed; diff --git a/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs b/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs index 62748b52592..28766c688a0 100644 --- a/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs +++ b/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs @@ -26,9 +26,10 @@ public sealed partial class GasFilterWindow : DefaultWindow public event Action? FilterTransferRateChanged; public event Action? SelectGasPressed; - public GasFilterWindow() + public GasFilterWindow(IEnumerable gases) { RobustXamlLoader.Load(this); + PopulateGasList(gases); ToggleStatusButton.OnPressed += _ => SetFilterStatus(!FilterStatus); ToggleStatusButton.OnPressed += _ => ToggleStatusButtonPressed?.Invoke(); @@ -72,7 +73,7 @@ public void SetGasFiltered(string? id, string name) SelectGasButton.Disabled = true; } - public void PopulateGasList(IEnumerable gases) + private void PopulateGasList(IEnumerable gases) { GasList.Add(new ItemList.Item(GasList) { @@ -80,7 +81,7 @@ public void PopulateGasList(IEnumerable gases) Text = Loc.GetString("comp-gas-filter-ui-filter-gas-none") }); - foreach (var gas in gases) + foreach (GasPrototype gas in gases) { var gasName = Loc.GetString(gas.Name); GasList.Add(GetGasItem(gas.ID, gasName, GasList)); diff --git a/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs b/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs index 392fbf1cd9a..709c06517cb 100644 --- a/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs +++ b/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs @@ -2,7 +2,7 @@ using Content.Shared.Atmos.Piping.Trinary.Components; using Content.Shared.Localizations; using JetBrains.Annotations; -using Robust.Client.UserInterface; +using Robust.Client.GameObjects; namespace Content.Client.Atmos.UI { @@ -26,7 +26,14 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new GasMixerWindow(); + + if (State != null) + UpdateState(State); + + _window.OpenCentered(); + + _window.OnClose += Close; _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.MixerOutputPressureChanged += OnMixerOutputPressurePressed; @@ -76,5 +83,12 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetOutputPressure(cast.OutputPressure); _window.SetNodePercentages(cast.NodeOne); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + _window?.Dispose(); + } } } diff --git a/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs b/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs index 220fdbe875c..6eba2e0d215 100644 --- a/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs @@ -3,7 +3,6 @@ using Content.Shared.Localizations; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -27,7 +26,14 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new GasPressurePumpWindow(); + + if (State != null) + UpdateState(State); + + _window.OpenCentered(); + + _window.OnClose += Close; _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.PumpOutputPressureChanged += OnPumpOutputPressurePressed; @@ -61,5 +67,12 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetPumpStatus(cast.Enabled); _window.SetOutputPressure(cast.OutputPressure); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + _window?.Dispose(); + } } } diff --git a/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs b/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs index d62be8f4bb4..1664c8b9d75 100644 --- a/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Atmos.Piping.Unary.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -32,7 +31,14 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new GasThermomachineWindow(); + + if (State != null) + UpdateState(State); + + _window.OpenCentered(); + + _window.OnClose += Close; _window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed(); _window.TemperatureSpinbox.OnValueChanged += _ => OnTemperatureChanged(_window.TemperatureSpinbox.Value); @@ -85,5 +91,12 @@ protected override void UpdateState(BoundUserInterfaceState state) true => Loc.GetString("comp-gas-thermomachine-ui-title-heater") }; } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + _window?.Dispose(); + } } } diff --git a/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs b/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs index 642f34c2f92..1b39306181a 100644 --- a/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs @@ -3,7 +3,6 @@ using Content.Shared.Localizations; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -27,7 +26,14 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new GasVolumePumpWindow(); + + if (State != null) + UpdateState(State); + + _window.OpenCentered(); + + _window.OnClose += Close; _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.PumpTransferRateChanged += OnPumpTransferRatePressed; @@ -58,9 +64,16 @@ protected override void UpdateState(BoundUserInterfaceState state) if (_window == null || state is not GasVolumePumpBoundUserInterfaceState cast) return; - _window.Title = cast.PumpLabel; + _window.Title = (cast.PumpLabel); _window.SetPumpStatus(cast.Enabled); _window.SetTransferRate(cast.TransferRate); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + _window?.Dispose(); + } } } diff --git a/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs b/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs index e70426575d4..4d8d1191e91 100644 --- a/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Atmos.Piping.Portable.Components; using JetBrains.Annotations; -using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.Atmos.UI; @@ -22,7 +21,14 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new SpaceHeaterWindow(); + + if (State != null) + UpdateState(State); + + _window.OpenCentered(); + + _window.OnClose += Close; _window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed(); _window.IncreaseTempRange.OnPressed += _ => OnTemperatureRangeChanged(_window.TemperatureChangeDelta); diff --git a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs index 865dfc478d0..60fe339069a 100644 --- a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs +++ b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs @@ -1,7 +1,8 @@ using Content.Shared.Audio.Jukebox; using Robust.Client.Audio; -using Robust.Client.UserInterface; +using Robust.Client.Player; using Robust.Shared.Audio.Components; +using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Client.Audio.Jukebox; @@ -22,7 +23,9 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new JukeboxMenu(); + _menu.OnClose += Close; + _menu.OpenCentered(); _menu.OnPlayPressed += args => { @@ -97,5 +100,19 @@ public void SetTime(float time) SendMessage(new JukeboxSetTimeMessage(sentTime)); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + if (_menu == null) + return; + + _menu.OnClose -= Close; + _menu.Dispose(); + _menu = null; + } } diff --git a/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs b/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs index 09f3cec8fbf..ffab1625483 100644 --- a/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs +++ b/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Bed.Cryostorage; using JetBrains.Annotations; -using Robust.Client.UserInterface; namespace Content.Client.Bed.Cryostorage; @@ -18,7 +17,9 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new(); + + _menu.OnClose += Close; _menu.SlotRemoveButtonPressed += (ent, slot) => { @@ -29,6 +30,8 @@ protected override void Open() { SendMessage(new CryostorageRemoveItemBuiMessage(ent, hand, CryostorageRemoveItemBuiMessage.RemovalType.Hand)); }; + + _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -42,4 +45,12 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + _menu?.Dispose(); + } } diff --git a/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs index 44c40143d83..d3365702bcf 100644 --- a/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Client.Cargo.UI; using Content.Shared.Cargo.Components; using JetBrains.Annotations; -using Robust.Client.UserInterface; namespace Content.Client.Cargo.BUI; @@ -19,7 +18,9 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new(); + + _menu.OnClose += Close; _menu.OnLabelButtonPressed += id => { @@ -30,6 +31,8 @@ protected override void Open() { SendMessage(new BountySkipMessage(id)); }; + + _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState message) @@ -41,4 +44,14 @@ protected override void UpdateState(BoundUserInterfaceState message) _menu?.UpdateEntries(state.Bounties, state.UntilNextSkip); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (!disposing) + return; + + _menu?.Dispose(); + } } diff --git a/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs index 2461dafb5f3..20c23a48a0d 100644 --- a/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Cargo.BUI; using Content.Shared.Cargo.Events; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Cargo.BUI; @@ -19,9 +18,21 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new CargoPalletMenu(); _menu.AppraiseRequested += OnAppraisal; _menu.SellRequested += OnSell; + _menu.OnClose += Close; + + _menu.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + { + _menu?.Dispose(); + } } private void OnAppraisal() diff --git a/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs index 02b721b9020..422d03707a0 100644 --- a/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Cargo.BUI; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Cargo.BUI; @@ -10,8 +9,6 @@ namespace Content.Client.Cargo.BUI; [UsedImplicitly] public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _protoManager = default!; - [ViewVariables] private CargoShuttleMenu? _menu; @@ -22,7 +19,24 @@ public CargoShuttleConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + var collection = IoCManager.Instance; + + if (collection == null) + return; + + _menu = new CargoShuttleMenu(collection.Resolve(), collection.Resolve().GetEntitySystem()); + _menu.OnClose += Close; + + _menu.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + { + _menu?.Dispose(); + } } protected override void UpdateState(BoundUserInterfaceState state) @@ -31,6 +45,6 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not CargoShuttleConsoleBoundUserInterfaceState cargoState) return; _menu?.SetAccountName(cargoState.AccountName); _menu?.SetShuttleName(cargoState.ShuttleName); - _menu?.SetOrders(EntMan.System(), _protoManager, cargoState.Orders); + _menu?.SetOrders(cargoState.Orders); } } diff --git a/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs b/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs index 43b00089e16..c591f917da3 100644 --- a/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs +++ b/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs @@ -12,9 +12,14 @@ namespace Content.Client.Cargo.UI [GenerateTypedNameReferences] public sealed partial class CargoShuttleMenu : FancyWindow { - public CargoShuttleMenu() + private readonly IPrototypeManager _protoManager; + private readonly SpriteSystem _spriteSystem; + + public CargoShuttleMenu(IPrototypeManager protoManager, SpriteSystem spriteSystem) { RobustXamlLoader.Load(this); + _protoManager = protoManager; + _spriteSystem = spriteSystem; Title = Loc.GetString("cargo-shuttle-console-menu-title"); } @@ -28,19 +33,19 @@ public void SetShuttleName(string name) ShuttleNameLabel.Text = name; } - public void SetOrders(SpriteSystem sprites, IPrototypeManager protoManager, List orders) + public void SetOrders(List orders) { Orders.DisposeAllChildren(); foreach (var order in orders) { - var product = protoManager.Index(order.ProductId); + var product = _protoManager.Index(order.ProductId); var productName = product.Name; var row = new CargoOrderRow { Order = order, - Icon = { Texture = sprites.Frame0(product) }, + Icon = { Texture = _spriteSystem.Frame0(product) }, ProductName = { Text = Loc.GetString( diff --git a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs index 3ef7f0ae73e..988fea7978b 100644 --- a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Containers.ItemSlots; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -28,8 +27,13 @@ protected override void Open() base.Open(); // Setup window layout/elements - _window = this.CreateWindow(); - _window.Title = EntMan.GetComponent(Owner).EntityName; + _window = new ChemMasterWindow + { + Title = EntMan.GetComponent(Owner).EntityName, + }; + + _window.OpenCentered(); + _window.OnClose += Close; // Setup static button actions. _window.InputEjectButton.OnPressed += _ => SendMessage( @@ -71,5 +75,15 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); // Update window state } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + _window?.Dispose(); + } + } } } diff --git a/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs b/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs index 2ad1b718887..99e5a3d3953 100644 --- a/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs @@ -3,7 +3,6 @@ using Content.Shared.Containers.ItemSlots; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -16,6 +15,9 @@ public sealed class ReagentDispenserBoundUserInterface : BoundUserInterface [ViewVariables] private ReagentDispenserWindow? _window; + [ViewVariables] + private ReagentDispenserBoundUserInterfaceState? _lastState; + public ReagentDispenserBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -30,9 +32,14 @@ protected override void Open() base.Open(); // Setup window layout/elements - _window = this.CreateWindow(); - _window.Title = EntMan.GetComponent(Owner).EntityName; - _window.HelpGuidebookIds = EntMan.GetComponent(Owner).Guides; + _window = new() + { + Title = EntMan.GetComponent(Owner).EntityName, + HelpGuidebookIds = EntMan.GetComponent(Owner).Guides + }; + + _window.OpenCentered(); + _window.OnClose += Close; // Setup static button actions. _window.EjectButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(SharedReagentDispenser.OutputSlotName)); @@ -56,7 +63,19 @@ protected override void UpdateState(BoundUserInterfaceState state) base.UpdateState(state); var castState = (ReagentDispenserBoundUserInterfaceState) state; + _lastState = castState; + _window?.UpdateState(castState); //Update window state } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + _window?.Dispose(); + } + } } } diff --git a/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs b/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs index f1cb27a62a4..35df131312d 100644 --- a/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.FixedPoint; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -19,7 +18,7 @@ public TransferAmountBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new TransferAmountWindow(); _window.ApplyButton.OnPressed += _ => { @@ -29,6 +28,15 @@ protected override void Open() _window.Close(); } }; + _window.OnClose += Close; + _window.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + _window?.Dispose(); } } } diff --git a/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs b/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs index 62a02f37186..26f0994701e 100644 --- a/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs +++ b/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs @@ -1,7 +1,6 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; using Content.Shared.Cloning.CloningConsole; -using Robust.Client.UserInterface; namespace Content.Client.CloningConsole.UI { @@ -18,11 +17,13 @@ public CloningConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - - _window = this.CreateWindow(); - _window.Title = Loc.GetString("cloning-console-window-title"); - + _window = new CloningConsoleWindow + { + Title = Loc.GetString("cloning-console-window-title") + }; + _window.OnClose += Close; _window.CloneButton.OnPressed += _ => SendMessage(new UiButtonPressedMessage(UiButton.Clone)); + _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -31,5 +32,19 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.Populate((CloningConsoleBoundUserInterfaceState) state); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + if (_window != null) + { + _window.OnClose -= Close; + _window.CloneButton.OnPressed -= _ => SendMessage(new UiButtonPressedMessage(UiButton.Clone)); + } + _window?.Dispose(); + } } } diff --git a/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs b/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs index 83f6ba15662..5b0d5fcf21f 100644 --- a/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs +++ b/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Clothing.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Clothing.UI; @@ -23,8 +22,10 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new ChameleonMenu(); + _menu.OnClose += Close; _menu.OnIdSelected += OnIdSelected; + _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -41,4 +42,15 @@ private void OnIdSelected(string selectedId) { SendMessage(new ChameleonPrototypeSelectedMessage(selectedId)); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + _menu?.Close(); + _menu = null; + } + } } diff --git a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs index 0310e91eeb0..1c94d32bf8d 100644 --- a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs +++ b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.CCVar; using Content.Shared.Chat; using Content.Shared.Communications; -using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Timing; @@ -9,11 +8,34 @@ namespace Content.Client.Communications.UI { public sealed class CommunicationsConsoleBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; [ViewVariables] private CommunicationsConsoleMenu? _menu; + [ViewVariables] + public bool CanAnnounce { get; private set; } + [ViewVariables] + public bool CanBroadcast { get; private set; } + + [ViewVariables] + public bool CanCall { get; private set; } + + [ViewVariables] + public bool CountdownStarted { get; private set; } + + [ViewVariables] + public bool AlertLevelSelectable { get; private set; } + + [ViewVariables] + public string CurrentLevel { get; private set; } = default!; + + [ViewVariables] + private TimeSpan? _expectedCountdownTime; + + public int Countdown => _expectedCountdownTime == null ? 0 : Math.Max((int) _expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0); + public CommunicationsConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -22,25 +44,23 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.OnAnnounce += AnnounceButtonPressed; - _menu.OnBroadcast += BroadcastButtonPressed; - _menu.OnAlertLevel += AlertLevelSelected; - _menu.OnEmergencyLevel += EmergencyShuttleButtonPressed; + _menu = new CommunicationsConsoleMenu(this); + _menu.OnClose += Close; + _menu.OpenCentered(); } public void AlertLevelSelected(string level) { - if (_menu!.AlertLevelSelectable) + if (AlertLevelSelectable) { - _menu.CurrentLevel = level; + CurrentLevel = level; SendMessage(new CommunicationsConsoleSelectAlertLevelMessage(level)); } } public void EmergencyShuttleButtonPressed() { - if (_menu!.CountdownStarted) + if (CountdownStarted) RecallShuttle(); else CallShuttle(); @@ -75,23 +95,31 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not CommunicationsConsoleInterfaceState commsState) return; + CanAnnounce = commsState.CanAnnounce; + CanBroadcast = commsState.CanBroadcast; + CanCall = commsState.CanCall; + _expectedCountdownTime = commsState.ExpectedCountdownEnd; + CountdownStarted = commsState.CountdownStarted; + AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0; + CurrentLevel = commsState.CurrentAlert; + if (_menu != null) { - _menu.CanAnnounce = commsState.CanAnnounce; - _menu.CanBroadcast = commsState.CanBroadcast; - _menu.CanCall = commsState.CanCall; - _menu.CountdownStarted = commsState.CountdownStarted; - _menu.AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0; - _menu.CurrentLevel = commsState.CurrentAlert; - _menu.CountdownEnd = commsState.ExpectedCountdownEnd; - _menu.UpdateCountdown(); - _menu.UpdateAlertLevels(commsState.AlertLevels, _menu.CurrentLevel); - _menu.AlertLevelButton.Disabled = !_menu.AlertLevelSelectable; - _menu.EmergencyShuttleButton.Disabled = !_menu.CanCall; - _menu.AnnounceButton.Disabled = !_menu.CanAnnounce; - _menu.BroadcastButton.Disabled = !_menu.CanBroadcast; + _menu.UpdateAlertLevels(commsState.AlertLevels, CurrentLevel); + _menu.AlertLevelButton.Disabled = !AlertLevelSelectable; + _menu.EmergencyShuttleButton.Disabled = !CanCall; + _menu.AnnounceButton.Disabled = !CanAnnounce; + _menu.BroadcastButton.Disabled = !CanBroadcast; } } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + + _menu?.Dispose(); + } } } diff --git a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs index cef68efd1f3..bbca06f5194 100644 --- a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs +++ b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs @@ -1,40 +1,31 @@ -using System.Globalization; -using Content.Client.UserInterface.Controls; +using Content.Client.UserInterface.Controls; +using System.Threading; using Content.Shared.CCVar; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.XAML; using Robust.Shared.Configuration; -using Robust.Shared.Timing; using Robust.Shared.Utility; +using Timer = Robust.Shared.Timing.Timer; namespace Content.Client.Communications.UI { [GenerateTypedNameReferences] public sealed partial class CommunicationsConsoleMenu : FancyWindow { + private CommunicationsConsoleBoundUserInterface Owner { get; set; } + private readonly CancellationTokenSource _timerCancelTokenSource = new(); + [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly ILocalizationManager _loc = default!; - - public bool CanAnnounce; - public bool CanBroadcast; - public bool CanCall; - public bool AlertLevelSelectable; - public bool CountdownStarted; - public string CurrentLevel = string.Empty; - public TimeSpan? CountdownEnd; - - public event Action? OnEmergencyLevel; - public event Action? OnAlertLevel; - public event Action? OnAnnounce; - public event Action? OnBroadcast; - - public CommunicationsConsoleMenu() + + public CommunicationsConsoleMenu(CommunicationsConsoleBoundUserInterface owner) { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - MessageInput.Placeholder = new Rope.Leaf(_loc.GetString("comms-console-menu-announcement-placeholder")); + Owner = owner; + + var loc = IoCManager.Resolve(); + MessageInput.Placeholder = new Rope.Leaf(loc.GetString("comms-console-menu-announcement-placeholder")); var maxAnnounceLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength); MessageInput.OnTextChanged += (args) => @@ -46,38 +37,33 @@ public CommunicationsConsoleMenu() } else { - AnnounceButton.Disabled = !CanAnnounce; + AnnounceButton.Disabled = !owner.CanAnnounce; AnnounceButton.ToolTip = null; } }; - AnnounceButton.OnPressed += _ => OnAnnounce?.Invoke(Rope.Collapse(MessageInput.TextRope)); - AnnounceButton.Disabled = !CanAnnounce; + AnnounceButton.OnPressed += (_) => Owner.AnnounceButtonPressed(Rope.Collapse(MessageInput.TextRope)); + AnnounceButton.Disabled = !owner.CanAnnounce; - BroadcastButton.OnPressed += _ => OnBroadcast?.Invoke(Rope.Collapse(MessageInput.TextRope)); - BroadcastButton.Disabled = !CanBroadcast; + BroadcastButton.OnPressed += (_) => Owner.BroadcastButtonPressed(Rope.Collapse(MessageInput.TextRope)); + BroadcastButton.Disabled = !owner.CanBroadcast; AlertLevelButton.OnItemSelected += args => { var metadata = AlertLevelButton.GetItemMetadata(args.Id); if (metadata != null && metadata is string cast) { - OnAlertLevel?.Invoke(cast); + Owner.AlertLevelSelected(cast); } }; + AlertLevelButton.Disabled = !owner.AlertLevelSelectable; + EmergencyShuttleButton.OnPressed += (_) => Owner.EmergencyShuttleButtonPressed(); + EmergencyShuttleButton.Disabled = !owner.CanCall; - AlertLevelButton.Disabled = !AlertLevelSelectable; - - EmergencyShuttleButton.OnPressed += _ => OnEmergencyLevel?.Invoke(); - EmergencyShuttleButton.Disabled = !CanCall; - } - - protected override void FrameUpdate(FrameEventArgs args) - { - base.FrameUpdate(args); UpdateCountdown(); + Timer.SpawnRepeating(1000, UpdateCountdown, _timerCancelTokenSource.Token); } // The current alert could make levels unselectable, so we need to ensure that the UI reacts properly. @@ -119,19 +105,32 @@ public void UpdateAlertLevels(List? alerts, string currentAlert) public void UpdateCountdown() { - if (!CountdownStarted) + if (!Owner.CountdownStarted) { - CountdownLabel.SetMessage(string.Empty); + CountdownLabel.SetMessage(""); EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-call-shuttle"); return; } - var diff = (CountdownEnd - _timing.CurTime) ?? TimeSpan.Zero; - EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-recall-shuttle"); var infoText = Loc.GetString($"comms-console-menu-time-remaining", - ("time", diff.TotalSeconds.ToString(CultureInfo.CurrentCulture))); + ("time", Owner.Countdown.ToString())); CountdownLabel.SetMessage(infoText); } + + public override void Close() + { + base.Close(); + + _timerCancelTokenSource.Cancel(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + _timerCancelTokenSource.Cancel(); + } } } diff --git a/Content.Client/Computer/ComputerBoundUserInterface.cs b/Content.Client/Computer/ComputerBoundUserInterface.cs index 11c26b252e9..bdbfe03fa10 100644 --- a/Content.Client/Computer/ComputerBoundUserInterface.cs +++ b/Content.Client/Computer/ComputerBoundUserInterface.cs @@ -1,5 +1,4 @@ using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; namespace Content.Client.Computer @@ -20,8 +19,10 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = (TWindow) _dynamicTypeFactory.CreateInstance(typeof(TWindow)); _window.SetupComputerWindow(this); + _window.OnClose += Close; + _window.OpenCentered(); } // Alas, this constructor has to be copied to the subclass. :( @@ -41,6 +42,16 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState((TState) state); } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + _window?.Dispose(); + } + } + protected override void ReceiveMessage(BoundUserInterfaceMessage message) { _window?.ReceiveMessage(message); diff --git a/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs b/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs index e4966f1ec43..4fea44f2253 100644 --- a/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs +++ b/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs @@ -1,6 +1,5 @@ using System.Text.RegularExpressions; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using static Content.Shared.Configurable.ConfigurationComponent; namespace Content.Client.Configurable.UI @@ -10,6 +9,9 @@ public sealed class ConfigurationBoundUserInterface : BoundUserInterface [ViewVariables] private ConfigurationMenu? _menu; + [ViewVariables] + public Regex? Validation { get; internal set; } + public ConfigurationBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -17,8 +19,10 @@ public ConfigurationBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.OnConfiguration += SendConfiguration; + _menu = new ConfigurationMenu(this); + + _menu.OnClose += Close; + _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -26,7 +30,9 @@ protected override void UpdateState(BoundUserInterfaceState state) base.UpdateState(state); if (state is not ConfigurationBoundUserInterfaceState configurationState) + { return; + } _menu?.Populate(configurationState); } @@ -35,12 +41,9 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) { base.ReceiveMessage(message); - if (_menu == null) - return; - if (message is ValidationUpdateMessage msg) { - _menu.Validation = new Regex(msg.ValidationString, RegexOptions.Compiled); + Validation = new Regex(msg.ValidationString, RegexOptions.Compiled); } } @@ -48,5 +51,16 @@ public void SendConfiguration(Dictionary config) { SendMessage(new ConfigurationUpdatedMessage(config)); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing && _menu != null) + { + _menu.OnClose -= Close; + _menu.Close(); + } + } } } diff --git a/Content.Client/Configurable/UI/ConfigurationMenu.cs b/Content.Client/Configurable/UI/ConfigurationMenu.cs index 29217eef7be..cc24af28692 100644 --- a/Content.Client/Configurable/UI/ConfigurationMenu.cs +++ b/Content.Client/Configurable/UI/ConfigurationMenu.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Numerics; -using System.Text.RegularExpressions; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; @@ -14,25 +13,23 @@ namespace Content.Client.Configurable.UI { public sealed class ConfigurationMenu : DefaultWindow { + public ConfigurationBoundUserInterface Owner { get; } + private readonly BoxContainer _column; private readonly BoxContainer _row; private readonly List<(string name, LineEdit input)> _inputs; - [ViewVariables] - public Regex? Validation { get; internal set; } - - public event Action>? OnConfiguration; - - public ConfigurationMenu() + public ConfigurationMenu(ConfigurationBoundUserInterface owner) { MinSize = SetSize = new Vector2(300, 250); + Owner = owner; _inputs = new List<(string name, LineEdit input)>(); Title = Loc.GetString("configuration-menu-device-title"); - var baseContainer = new BoxContainer + BoxContainer baseContainer = new BoxContainer { Orientation = LayoutOrientation.Vertical, VerticalExpand = true, @@ -119,13 +116,14 @@ public void Populate(ConfigurationBoundUserInterfaceState state) private void OnConfirm(ButtonEventArgs args) { var config = GenerateDictionary(_inputs, "Text"); - OnConfiguration?.Invoke(config); + + Owner.SendConfiguration(config); Close(); } private bool Validate(string value) { - return Validation?.IsMatch(value) != false; + return Owner.Validation == null || Owner.Validation.IsMatch(value); } private Dictionary GenerateDictionary(IEnumerable<(string name, LineEdit input)> inputs, string propertyName) diff --git a/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs b/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs index 887492955e9..86f1b8b83c7 100644 --- a/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs +++ b/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Construction.Components; using JetBrains.Annotations; -using Robust.Client.UserInterface; namespace Content.Client.Construction.UI { @@ -18,8 +17,8 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.SetEntity(Owner); + _menu = new FlatpackCreatorMenu(Owner); + _menu.OnClose += Close; _menu.PackButtonPressed += () => { @@ -28,5 +27,14 @@ protected override void Open() _menu.OpenCentered(); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _menu?.Dispose(); + } } } diff --git a/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs b/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs index 269694ebf9e..9f3d5695bb6 100644 --- a/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs +++ b/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs @@ -24,7 +24,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow private readonly FlatpackSystem _flatpack; private readonly MaterialStorageSystem _materialStorage; - private EntityUid _owner; + private readonly EntityUid _owner; [ValidatePrototypeId] public const string NoBoardEffectId = "FlatpackerNoBoardEffect"; @@ -33,7 +33,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow public event Action? PackButtonPressed; - public FlatpackCreatorMenu() + public FlatpackCreatorMenu(EntityUid uid) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -42,15 +42,12 @@ public FlatpackCreatorMenu() _flatpack = _entityManager.System(); _materialStorage = _entityManager.System(); - PackButton.OnPressed += _ => PackButtonPressed?.Invoke(); + _owner = uid; - InsertLabel.SetMarkup(Loc.GetString("flatpacker-ui-insert-board")); - } + PackButton.OnPressed += _ => PackButtonPressed?.Invoke(); - public void SetEntity(EntityUid uid) - { - _owner = uid; MaterialStorageControl.SetOwner(uid); + InsertLabel.SetMarkup(Loc.GetString("flatpacker-ui-insert-board")); } protected override void FrameUpdate(FrameEventArgs args) diff --git a/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs b/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs index e5be0b1811f..e2c4d51ecd1 100644 --- a/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs +++ b/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs @@ -2,15 +2,12 @@ using Content.Shared.Crayon; using Content.Shared.Decals; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Crayon.UI { public sealed class CrayonBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _protoManager = default!; - [ViewVariables] private CrayonWindow? _menu; @@ -21,27 +18,13 @@ public CrayonBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.OnColorSelected += SelectColor; - _menu.OnSelected += Select; - PopulateCrayons(); - _menu.OpenCenteredLeft(); - } - - private void PopulateCrayons() - { - var crayonDecals = _protoManager.EnumeratePrototypes().Where(x => x.Tags.Contains("crayon")); - _menu?.Populate(crayonDecals); - } - - public override void OnProtoReload(PrototypesReloadedEventArgs args) - { - base.OnProtoReload(args); - - if (!args.WasModified()) - return; + _menu = new CrayonWindow(this); - PopulateCrayons(); + _menu.OnClose += Close; + var prototypeManager = IoCManager.Resolve(); + var crayonDecals = prototypeManager.EnumeratePrototypes().Where(x => x.Tags.Contains("crayon")); + _menu.Populate(crayonDecals); + _menu.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -60,5 +43,16 @@ public void SelectColor(Color color) { SendMessage(new CrayonColorMessage(color)); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + _menu?.Close(); + _menu = null; + } + } } } diff --git a/Content.Client/Crayon/UI/CrayonWindow.xaml.cs b/Content.Client/Crayon/UI/CrayonWindow.xaml.cs index b97786cd41a..2a5801ccf2d 100644 --- a/Content.Client/Crayon/UI/CrayonWindow.xaml.cs +++ b/Content.Client/Crayon/UI/CrayonWindow.xaml.cs @@ -18,17 +18,18 @@ namespace Content.Client.Crayon.UI [GenerateTypedNameReferences] public sealed partial class CrayonWindow : DefaultWindow { + public CrayonBoundUserInterface Owner { get; } + private Dictionary? _decals; private string? _selected; private Color _color; - public event Action? OnColorSelected; - public event Action? OnSelected; - - public CrayonWindow() + public CrayonWindow(CrayonBoundUserInterface owner) { RobustXamlLoader.Load(this); + Owner = owner; + Search.OnTextChanged += _ => RefreshList(); ColorSelector.OnColorChanged += SelectColor; } @@ -37,16 +38,16 @@ private void SelectColor(Color color) { _color = color; - OnColorSelected?.Invoke(color); + Owner.SelectColor(color); + RefreshList(); } private void RefreshList() { // Clear - Grid.DisposeAllChildren(); - if (_decals == null) - return; + Grid.RemoveAllChildren(); + if (_decals == null) return; var filter = Search.Text; foreach (var (decal, tex) in _decals) @@ -88,6 +89,7 @@ private void ButtonOnPressed(ButtonEventArgs obj) { if (obj.Button.Name == null) return; + Owner.Select(obj.Button.Name); _selected = obj.Button.Name; RefreshList(); } diff --git a/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs b/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs index 296e71d3a95..e8e77217ea5 100644 --- a/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs +++ b/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs @@ -1,6 +1,5 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent; namespace Content.Client.Disposal.UI @@ -22,16 +21,20 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new DisposalRouterWindow(); + + _window.OpenCentered(); + _window.OnClose += Close; _window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text); _window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text); + } private void ButtonPressed(UiAction action, string tag) { SendMessage(new UiActionMessage(action, tag)); - Close(); + _window?.Close(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -45,5 +48,18 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + _window?.Dispose(); + } + } + + } + } diff --git a/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs b/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs index 7fc0eb85401..3aeed8dc802 100644 --- a/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs +++ b/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs @@ -1,6 +1,5 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent; namespace Content.Client.Disposal.UI @@ -22,17 +21,20 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new DisposalTaggerWindow(); + + _window.OpenCentered(); + _window.OnClose += Close; _window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text); _window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text); + } private void ButtonPressed(UiAction action, string tag) { - // TODO: This looks copy-pasted with the other mailing stuff... SendMessage(new UiActionMessage(action, tag)); - Close(); + _window?.Close(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -46,5 +48,18 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + _window?.Dispose(); + } + } + + } + } diff --git a/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs b/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs index 9b7e23c03aa..cd7ea717ce3 100644 --- a/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs +++ b/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Access; using Content.Shared.Doors.Electronics; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Doors.Electronics; @@ -19,23 +18,6 @@ public DoorElectronicsBoundUserInterface(EntityUid owner, Enum uiKey) : base(own protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.OnAccessChanged += UpdateConfiguration; - Reset(); - } - - public override void OnProtoReload(PrototypesReloadedEventArgs args) - { - base.OnProtoReload(args); - - if (!args.WasModified()) - return; - - Reset(); - } - - private void Reset() - { List> accessLevels = new(); foreach (var accessLevel in _prototypeManager.EnumeratePrototypes()) @@ -47,7 +29,10 @@ private void Reset() } accessLevels.Sort(); - _window?.Reset(_prototypeManager, accessLevels); + + _window = new DoorElectronicsConfigurationMenu(this, accessLevels, _prototypeManager); + _window.OnClose += Close; + _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -59,6 +44,14 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + + _window?.Dispose(); + } + public void UpdateConfiguration(List> newAccessList) { SendMessage(new DoorElectronicsUpdateConfigurationMessage(newAccessList)); diff --git a/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs index 2112a562971..c01f13a462e 100644 --- a/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs +++ b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs @@ -15,23 +15,22 @@ namespace Content.Client.Doors.Electronics; [GenerateTypedNameReferences] public sealed partial class DoorElectronicsConfigurationMenu : FancyWindow { - private readonly AccessLevelControl _buttonsList = new(); + private readonly DoorElectronicsBoundUserInterface _owner; + private AccessLevelControl _buttonsList = new(); - public event Action>>? OnAccessChanged; - - public DoorElectronicsConfigurationMenu() + public DoorElectronicsConfigurationMenu(DoorElectronicsBoundUserInterface ui, List> accessLevels, IPrototypeManager prototypeManager) { RobustXamlLoader.Load(this); - AccessLevelControlContainer.AddChild(_buttonsList); - } - public void Reset(IPrototypeManager protoManager, List> accessLevels) - { - _buttonsList.Populate(accessLevels, protoManager); + _owner = ui; + + _buttonsList.Populate(accessLevels, prototypeManager); + AccessLevelControlContainer.AddChild(_buttonsList); - foreach (var button in _buttonsList.ButtonsList.Values) + foreach (var (id, button) in _buttonsList.ButtonsList) { - button.OnPressed += _ => OnAccessChanged?.Invoke(_buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); + button.OnPressed += _ => _owner.UpdateConfiguration( + _buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); } } diff --git a/Content.Client/Fax/UI/FaxBoundUi.cs b/Content.Client/Fax/UI/FaxBoundUi.cs index ca2e834b4fe..a95066a3b58 100644 --- a/Content.Client/Fax/UI/FaxBoundUi.cs +++ b/Content.Client/Fax/UI/FaxBoundUi.cs @@ -25,7 +25,10 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new FaxWindow(); + _window.OpenCentered(); + + _window.OnClose += Close; _window.FileButtonPressed += OnFileButtonPressed; _window.CopyButtonPressed += OnCopyButtonPressed; _window.SendButtonPressed += OnSendButtonPressed; @@ -101,4 +104,11 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState(cast); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + _window?.Dispose(); + } } diff --git a/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs b/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs index 08596b04e6e..ba49f11ea0f 100644 --- a/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs +++ b/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs @@ -1,7 +1,6 @@ using Robust.Client.GameObjects; using Robust.Shared.Timing; using Content.Shared.Forensics; -using Robust.Client.UserInterface; namespace Content.Client.Forensics { @@ -22,9 +21,11 @@ public ForensicScannerBoundUserInterface(EntityUid owner, Enum uiKey) : base(own protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new ForensicScannerMenu(); + _window.OnClose += Close; _window.Print.OnPressed += _ => Print(); _window.Clear.OnPressed += _ => Clear(); + _window.OpenCentered(); } private void Print() @@ -61,7 +62,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _printCooldown = cast.PrintCooldown; - // TODO: Fix this if (cast.PrintReadyAt > _gameTiming.CurTime) Timer.Spawn(cast.PrintReadyAt - _gameTiming.CurTime, () => { @@ -71,5 +71,14 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState(cast); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _window?.Dispose(); + } } } diff --git a/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs b/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs index 457b70ca7ca..fdb3cdbc010 100644 --- a/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs +++ b/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Gateway; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Gateway.UI; @@ -18,13 +17,24 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.SetEntity(EntMan.GetNetEntity(Owner)); + _window = new GatewayWindow(EntMan.GetNetEntity(Owner)); _window.OpenPortal += destination => { SendMessage(new GatewayOpenPortalMessage(destination)); }; + _window.OnClose += Close; + _window?.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + { + _window?.Dispose(); + _window = null; + } } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Gateway/UI/GatewayWindow.xaml.cs b/Content.Client/Gateway/UI/GatewayWindow.xaml.cs index 1c779b2b350..889dd6e1759 100644 --- a/Content.Client/Gateway/UI/GatewayWindow.xaml.cs +++ b/Content.Client/Gateway/UI/GatewayWindow.xaml.cs @@ -22,7 +22,7 @@ public sealed partial class GatewayWindow : FancyWindow, public event Action? OpenPortal; private List _destinations = new(); - public NetEntity Owner; + public readonly NetEntity Owner; private NetEntity? _current; private TimeSpan _nextReady; @@ -46,20 +46,16 @@ public sealed partial class GatewayWindow : FancyWindow, /// private bool _isCooldownPending = true; - public GatewayWindow() + public GatewayWindow(NetEntity netEntity) { RobustXamlLoader.Load(this); var dependencies = IoCManager.Instance!; _timing = dependencies.Resolve(); + Owner = netEntity; NextUnlockBar.ForegroundStyleBoxOverride = new StyleBoxFlat(Color.FromHex("#C74EBD")); } - public void SetEntity(NetEntity entity) - { - - } - public void UpdateState(GatewayBoundUserInterfaceState state) { _destinations = state.Destinations; diff --git a/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs b/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs index 32b40747d55..d72da3e8120 100644 --- a/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs +++ b/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.Gravity; using JetBrains.Annotations; -using Robust.Client.UserInterface; +using Robust.Client.GameObjects; namespace Content.Client.Gravity.UI { @@ -18,8 +18,17 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.SetEntity(Owner); + _window = new GravityGeneratorWindow(this); + + /* + _window.Switch.OnPressed += _ => + { + SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(!IsOn)); + }; + */ + + _window.OpenCentered(); + _window.OnClose += Close; } protected override void UpdateState(BoundUserInterfaceState state) @@ -30,6 +39,14 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + + _window?.Dispose(); + } + public void SetPowerSwitch(bool on) { SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on)); diff --git a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs b/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs index 6f04133b594..75f8eb479b5 100644 --- a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs +++ b/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs @@ -12,23 +12,22 @@ public sealed partial class GravityGeneratorWindow : FancyWindow { private readonly ButtonGroup _buttonGroup = new(); - public event Action? OnPowerSwitch; + private readonly GravityGeneratorBoundUserInterface _owner; - public GravityGeneratorWindow() + public GravityGeneratorWindow(GravityGeneratorBoundUserInterface owner) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); + _owner = owner; + OnButton.Group = _buttonGroup; OffButton.Group = _buttonGroup; - OnButton.OnPressed += _ => OnPowerSwitch?.Invoke(true); - OffButton.OnPressed += _ => OnPowerSwitch?.Invoke(false); - } + OnButton.OnPressed += _ => _owner.SetPowerSwitch(true); + OffButton.OnPressed += _ => _owner.SetPowerSwitch(false); - public void SetEntity(EntityUid uid) - { - EntityView.SetEntity(uid); + EntityView.SetEntity(owner.Owner); } public void UpdateState(SharedGravityGeneratorComponent.GeneratorState state) diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs index 38760f4aa3c..dc0a3e9fccd 100644 --- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs +++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.MedicalScanner; using JetBrains.Annotations; -using Robust.Client.UserInterface; +using Robust.Client.GameObjects; namespace Content.Client.HealthAnalyzer.UI { @@ -17,9 +17,12 @@ public HealthAnalyzerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = this.CreateWindow(); - - _window.Title = EntMan.GetComponent(Owner).EntityName; + _window = new HealthAnalyzerWindow + { + Title = EntMan.GetComponent(Owner).EntityName, + }; + _window.OnClose += Close; + _window.OpenCentered(); } protected override void ReceiveMessage(BoundUserInterfaceMessage message) @@ -32,5 +35,17 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) _window.Populate(cast); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + if (_window != null) + _window.OnClose -= Close; + + _window?.Dispose(); + } } } diff --git a/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs b/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs index 53977eb636b..a8872604a4c 100644 --- a/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs +++ b/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Humanoid; using Content.Shared.Humanoid.Markings; -using Robust.Client.UserInterface; namespace Content.Client.Humanoid; @@ -21,7 +20,8 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new(); + _window.OnClose += Close; _window.OnMarkingAdded += SendMarkingSet; _window.OnMarkingRemoved += SendMarkingSet; _window.OnMarkingColorChange += SendMarkingSetNoResend; diff --git a/Content.Client/Instruments/UI/BandMenu.xaml.cs b/Content.Client/Instruments/UI/BandMenu.xaml.cs index 26cd1369e55..5fb293a194d 100644 --- a/Content.Client/Instruments/UI/BandMenu.xaml.cs +++ b/Content.Client/Instruments/UI/BandMenu.xaml.cs @@ -11,9 +11,7 @@ public sealed partial class BandMenu : DefaultWindow { private readonly InstrumentBoundUserInterface _owner; - public EntityUid? Master; - - public BandMenu(InstrumentBoundUserInterface owner) + public BandMenu(InstrumentBoundUserInterface owner) : base() { RobustXamlLoader.Load(this); @@ -42,7 +40,7 @@ public void Populate((NetEntity, string)[] nearby, IEntityManager entManager) { var uid = entManager.GetEntity(nent); var item = BandList.AddItem(name, null, true, uid); - item.Selected = Master == uid; + item.Selected = _owner.Instrument?.Master == uid; } } } diff --git a/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs b/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs index c175e67842f..2814d415365 100644 --- a/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs +++ b/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs @@ -51,7 +51,7 @@ private void OnClearPressed(BaseButton.ButtonEventArgs obj) } } - public void Populate(InstrumentComponent? instrument) + public void Populate() { ChannelList.Clear(); @@ -60,8 +60,7 @@ public void Populate(InstrumentComponent? instrument) var item = ChannelList.AddItem(_owner.Loc.GetString("instrument-component-channel-name", ("number", i)), null, true, i); - - item.Selected = !instrument?.FilteredChannels[i] ?? false; + item.Selected = !_owner.Instrument?.FilteredChannels[i] ?? false; } } } diff --git a/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs b/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs index 4816ce8c365..0f5729f55b1 100644 --- a/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs +++ b/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs @@ -24,6 +24,8 @@ public sealed class InstrumentBoundUserInterface : BoundUserInterface [ViewVariables] private BandMenu? _bandMenu; [ViewVariables] private ChannelsMenu? _channelsMenu; + [ViewVariables] public InstrumentComponent? Instrument { get; private set; } + public InstrumentBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { IoCManager.InjectDependencies(this); @@ -41,20 +43,14 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) protected override void Open() { - _instrumentMenu = this.CreateWindow(); - _instrumentMenu.Title = EntMan.GetComponent(Owner).EntityName; - - _instrumentMenu.OnOpenBand += OpenBandMenu; - _instrumentMenu.OnOpenChannels += OpenChannelsMenu; - _instrumentMenu.OnCloseChannels += CloseChannelsMenu; - _instrumentMenu.OnCloseBands += CloseBandMenu; + if (!EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) + return; - _instrumentMenu.SetMIDI(MidiManager.IsAvailable); + Instrument = instrument; + _instrumentMenu = new InstrumentMenu(this); + _instrumentMenu.OnClose += Close; - if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) - { - _instrumentMenu.SetInstrument((Owner, instrument)); - } + _instrumentMenu.OpenCentered(); } protected override void Dispose(bool disposing) @@ -62,12 +58,7 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); if (!disposing) return; - - if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) - { - _instrumentMenu?.RemoveInstrument(instrument); - } - + _instrumentMenu?.Dispose(); _bandMenu?.Dispose(); _channelsMenu?.Dispose(); } @@ -81,11 +72,6 @@ public void OpenBandMenu() { _bandMenu ??= new BandMenu(this); - if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) - { - _bandMenu.Master = instrument.Master; - } - // Refresh cache... RefreshBands(); @@ -101,9 +87,7 @@ public void CloseBandMenu() public void OpenChannelsMenu() { _channelsMenu ??= new ChannelsMenu(this); - EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument); - - _channelsMenu.Populate(instrument); + _channelsMenu.Populate(); _channelsMenu.OpenCenteredRight(); } diff --git a/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs b/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs index fc863648d79..da443e3fb5b 100644 --- a/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs +++ b/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs @@ -1,10 +1,7 @@ using System.IO; using System.Numerics; using System.Threading.Tasks; -using Content.Client.Interactable; -using Content.Shared.ActionBlocker; using Robust.Client.AutoGenerated; -using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; @@ -19,23 +16,33 @@ namespace Content.Client.Instruments.UI [GenerateTypedNameReferences] public sealed partial class InstrumentMenu : DefaultWindow { - [Dependency] private readonly IEntityManager _entManager = default!; - [Dependency] private readonly IFileDialogManager _dialogs = default!; - [Dependency] private readonly IPlayerManager _player = default!; + private readonly InstrumentBoundUserInterface _owner; private bool _isMidiFileDialogueWindowOpen; - public event Action? OnOpenBand; - public event Action? OnOpenChannels; - public event Action? OnCloseBands; - public event Action? OnCloseChannels; - - public EntityUid Entity; - - public InstrumentMenu() + public InstrumentMenu(InstrumentBoundUserInterface owner) { RobustXamlLoader.Load(this); - IoCManager.InjectDependencies(this); + + _owner = owner; + + if (_owner.Instrument != null) + { + _owner.Instrument.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded; + Title = _owner.Entities.GetComponent(_owner.Owner).EntityName; + LoopButton.Disabled = !_owner.Instrument.IsMidiOpen; + LoopButton.Pressed = _owner.Instrument.LoopMidi; + ChannelsButton.Disabled = !_owner.Instrument.IsRendererAlive; + StopButton.Disabled = !_owner.Instrument.IsMidiOpen; + PlaybackSlider.MouseFilter = _owner.Instrument.IsMidiOpen ? MouseFilterMode.Pass : MouseFilterMode.Ignore; + } + + if (!_owner.MidiManager.IsAvailable) + { + UnavailableOverlay.Visible = true; + // We return early as to not give the buttons behavior. + return; + } InputButton.OnToggled += MidiInputButtonOnOnToggled; BandButton.OnPressed += BandButtonOnPressed; @@ -50,34 +57,12 @@ public InstrumentMenu() MinSize = SetSize = new Vector2(400, 150); } - public void SetInstrument(Entity entity) - { - Entity = entity; - var component = entity.Comp; - component.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded; - LoopButton.Disabled = !component.IsMidiOpen; - LoopButton.Pressed = component.LoopMidi; - ChannelsButton.Disabled = !component.IsRendererAlive; - StopButton.Disabled = !component.IsMidiOpen; - PlaybackSlider.MouseFilter = component.IsMidiOpen ? MouseFilterMode.Pass : MouseFilterMode.Ignore; - } - - public void RemoveInstrument(InstrumentComponent component) - { - component.OnMidiPlaybackEnded -= InstrumentOnMidiPlaybackEnded; - } - - public void SetMIDI(bool available) - { - UnavailableOverlay.Visible = !available; - } - private void BandButtonOnPressed(ButtonEventArgs obj) { if (!PlayCheck()) return; - OnOpenBand?.Invoke(); + _owner.OpenBandMenu(); } private void BandButtonOnToggled(ButtonToggledEventArgs obj) @@ -85,15 +70,12 @@ private void BandButtonOnToggled(ButtonToggledEventArgs obj) if (obj.Pressed) return; - if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) - { - _entManager.System().SetMaster(Entity, instrument.Master); - } + _owner.Instruments.SetMaster(_owner.Owner, null); } private void ChannelsButtonOnPressed(ButtonEventArgs obj) { - OnOpenChannels?.Invoke(); + _owner.OpenChannelsMenu(); } private void InstrumentOnMidiPlaybackEnded() @@ -103,10 +85,8 @@ private void InstrumentOnMidiPlaybackEnded() public void MidiPlaybackSetButtonsDisabled(bool disabled) { - if (disabled) - { - OnCloseChannels?.Invoke(); - } + if(disabled) + _owner.CloseChannelsMenu(); LoopButton.Disabled = disabled; StopButton.Disabled = disabled; @@ -120,7 +100,7 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) if (_isMidiFileDialogueWindowOpen) return; - OnCloseBands?.Invoke(); + _owner.CloseBandMenu(); var filters = new FileDialogFilters(new FileDialogFilters.Group("mid", "midi")); @@ -128,7 +108,7 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) // or focus the previously-opened window. _isMidiFileDialogueWindowOpen = true; - await using var file = await _dialogs.OpenFile(filters); + await using var file = await _owner.FileDialogManager.OpenFile(filters); _isMidiFileDialogueWindowOpen = false; @@ -149,18 +129,9 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) await file.CopyToAsync(memStream); - if (!_entManager.TryGetComponent(Entity, out var instrument)) - { + if (_owner.Instrument is not {} instrument + || !_owner.Instruments.OpenMidi(_owner.Owner, memStream.GetBuffer().AsSpan(0, (int) memStream.Length), instrument)) return; - } - - if (!_entManager.System() - .OpenMidi(Entity, - memStream.GetBuffer().AsSpan(0, (int) memStream.Length), - instrument)) - { - return; - } MidiPlaybackSetButtonsDisabled(false); if (InputButton.Pressed) @@ -169,7 +140,7 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) private void MidiInputButtonOnOnToggled(ButtonToggledEventArgs obj) { - OnCloseBands?.Invoke(); + _owner.CloseBandMenu(); if (obj.Pressed) { @@ -177,99 +148,109 @@ private void MidiInputButtonOnOnToggled(ButtonToggledEventArgs obj) return; MidiStopButtonOnPressed(null); - - if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) - _entManager.System().OpenInput(Entity, instrument); + if(_owner.Instrument is {} instrument) + _owner.Instruments.OpenInput(_owner.Owner, instrument); } - else + else if (_owner.Instrument is { } instrument) { - _entManager.System().CloseInput(Entity, false); - OnCloseChannels?.Invoke(); + _owner.Instruments.CloseInput(_owner.Owner, false, instrument); + _owner.CloseChannelsMenu(); } } private bool PlayCheck() { // TODO all of these checks should also be done server-side. - if (!_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) + + var instrumentEnt = _owner.Owner; + var instrument = _owner.Instrument; + + if (instrument == null) return false; - var localEntity = _player.LocalEntity; + var localEntity = _owner.PlayerManager.LocalEntity; // If we don't have a player or controlled entity, we return. if (localEntity == null) return false; // By default, allow an instrument to play itself and skip all other checks - if (localEntity == Entity) + if (localEntity == instrumentEnt) return true; - var container = _entManager.System(); + var container = _owner.Entities.System(); // If we're a handheld instrument, we might be in a container. Get it just in case. - container.TryGetContainingContainer(Entity, out var conMan); + container.TryGetContainingContainer(instrumentEnt, out var conMan); // If the instrument is handheld and we're not holding it, we return. - if (instrument.Handheld && (conMan == null || conMan.Owner != localEntity)) + if ((instrument.Handheld && (conMan == null || conMan.Owner != localEntity))) return false; - if (!_entManager.System().CanInteract(localEntity.Value, Entity)) + if (!_owner.ActionBlocker.CanInteract(localEntity.Value, instrumentEnt)) return false; // We check that we're in range unobstructed just in case. - return _entManager.System().InRangeUnobstructed(localEntity.Value, Entity); + return _owner.Interactions.InRangeUnobstructed(localEntity.Value, instrumentEnt); } private void MidiStopButtonOnPressed(ButtonEventArgs? obj) { MidiPlaybackSetButtonsDisabled(true); - _entManager.System().CloseMidi(Entity, false); - OnCloseChannels?.Invoke(); + if (_owner.Instrument is not {} instrument) + return; + + _owner.Instruments.CloseMidi(_owner.Owner, false, instrument); + _owner.CloseChannelsMenu(); } private void MidiLoopButtonOnOnToggled(ButtonToggledEventArgs obj) { - var instrument = _entManager.System(); - - if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrumentComp)) - { - instrumentComp.LoopMidi = obj.Pressed; - } + if (_owner.Instrument == null) + return; - instrument.UpdateRenderer(Entity); + _owner.Instrument.LoopMidi = obj.Pressed; + _owner.Instruments.UpdateRenderer(_owner.Owner, _owner.Instrument); } private void PlaybackSliderSeek(Range _) { // Do not seek while still grabbing. - if (PlaybackSlider.Grabbed) + if (PlaybackSlider.Grabbed || _owner.Instrument is not {} instrument) return; - _entManager.System().SetPlayerTick(Entity, (int)Math.Ceiling(PlaybackSlider.Value)); + _owner.Instruments.SetPlayerTick(_owner.Owner, (int)Math.Ceiling(PlaybackSlider.Value), instrument); } private void PlaybackSliderKeyUp(GUIBoundKeyEventArgs args) { - if (args.Function != EngineKeyFunctions.UIClick) + if (args.Function != EngineKeyFunctions.UIClick || _owner.Instrument is not {} instrument) return; - _entManager.System().SetPlayerTick(Entity, (int)Math.Ceiling(PlaybackSlider.Value)); + _owner.Instruments.SetPlayerTick(_owner.Owner, (int)Math.Ceiling(PlaybackSlider.Value), instrument); + } + + public override void Close() + { + base.Close(); + _owner.CloseBandMenu(); + _owner.CloseChannelsMenu(); } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - if (!_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) + if (_owner.Instrument == null) return; - var hasMaster = instrument.Master != null; + var hasMaster = _owner.Instrument.Master != null; BandButton.ToggleMode = hasMaster; BandButton.Pressed = hasMaster; - BandButton.Disabled = instrument.IsMidiOpen || instrument.IsInputOpen; - ChannelsButton.Disabled = !instrument.IsRendererAlive; + BandButton.Disabled = _owner.Instrument.IsMidiOpen || _owner.Instrument.IsInputOpen; + ChannelsButton.Disabled = !_owner.Instrument.IsRendererAlive; - if (!instrument.IsMidiOpen) + if (!_owner.Instrument.IsMidiOpen) { PlaybackSlider.MaxValue = 1; PlaybackSlider.SetValueWithoutEvent(0); @@ -279,8 +260,8 @@ protected override void FrameUpdate(FrameEventArgs args) if (PlaybackSlider.Grabbed) return; - PlaybackSlider.MaxValue = instrument.PlayerTotalTick; - PlaybackSlider.SetValueWithoutEvent(instrument.PlayerTick); + PlaybackSlider.MaxValue = _owner.Instrument.PlayerTotalTick; + PlaybackSlider.SetValueWithoutEvent(_owner.Instrument.PlayerTick); } } } diff --git a/Content.Client/Inventory/StrippableBoundUserInterface.cs b/Content.Client/Inventory/StrippableBoundUserInterface.cs index 132c5ed654c..7e50eb1c68a 100644 --- a/Content.Client/Inventory/StrippableBoundUserInterface.cs +++ b/Content.Client/Inventory/StrippableBoundUserInterface.cs @@ -41,7 +41,7 @@ public sealed class StrippableBoundUserInterface : BoundUserInterface public const string HiddenPocketEntityId = "StrippingHiddenEntity"; [ViewVariables] - private StrippingMenu? _strippingMenu; + private readonly StrippingMenu? _strippingMenu; [ViewVariables] private readonly EntityUid _virtualHiddenEntity; @@ -51,30 +51,33 @@ public StrippableBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, u _examine = EntMan.System(); _inv = EntMan.System(); _cuffable = EntMan.System(); + + // TODO update name when identity changes + var title = Loc.GetString("strippable-bound-user-interface-stripping-menu-title", ("ownerName", Identity.Name(Owner, EntMan))); + _strippingMenu = new StrippingMenu(title, this); + _strippingMenu.OnClose += Close; + + // TODO use global entity + // BUIs are opened and closed while applying comp sates, so spawning entities here is probably not the best idea. _virtualHiddenEntity = EntMan.SpawnEntity(HiddenPocketEntityId, MapCoordinates.Nullspace); } protected override void Open() { base.Open(); - - _strippingMenu = this.CreateWindow(); - _strippingMenu.OnDirty += UpdateMenu; - _strippingMenu.Title = Loc.GetString("strippable-bound-user-interface-stripping-menu-title", ("ownerName", Identity.Name(Owner, EntMan))); - _strippingMenu?.OpenCenteredLeft(); } protected override void Dispose(bool disposing) { + base.Dispose(disposing); + + EntMan.DeleteEntity(_virtualHiddenEntity); + if (!disposing) return; - if (_strippingMenu != null) - _strippingMenu.OnDirty -= UpdateMenu; - - EntMan.DeleteEntity(_virtualHiddenEntity); - base.Dispose(disposing); + _strippingMenu?.Dispose(); } public void DirtyMenu() diff --git a/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs b/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs index 7884268c428..f97d8a73302 100644 --- a/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs +++ b/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs @@ -12,34 +12,42 @@ namespace Content.Client.Kitchen.UI [GenerateTypedNameReferences] public sealed partial class GrinderMenu : FancyWindow { - [Dependency] private readonly IEntityManager _entityManager = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + private readonly IEntityManager _entityManager; + private readonly IPrototypeManager _prototypeManager; + private readonly ReagentGrinderBoundUserInterface _owner; private readonly Dictionary _chamberVisualContents = new(); - public event Action? OnToggleAuto; - public event Action? OnGrind; - public event Action? OnJuice; - public event Action? OnEjectAll; - public event Action? OnEjectBeaker; - public event Action? OnEjectChamber; - - public GrinderMenu() + public GrinderMenu(ReagentGrinderBoundUserInterface owner, IEntityManager entityManager, IPrototypeManager prototypeManager) { RobustXamlLoader.Load(this); - IoCManager.InjectDependencies(this); - AutoModeButton.OnPressed += _ => OnToggleAuto?.Invoke(); - GrindButton.OnPressed += _ => OnGrind?.Invoke(); - JuiceButton.OnPressed += _ => OnJuice?.Invoke(); - ChamberContentBox.EjectButton.OnPressed += _ => OnEjectAll?.Invoke(); - BeakerContentBox.EjectButton.OnPressed += _ => OnEjectBeaker?.Invoke(); + _entityManager = entityManager; + _prototypeManager = prototypeManager; + _owner = owner; + AutoModeButton.OnPressed += owner.ToggleAutoMode; + GrindButton.OnPressed += owner.StartGrinding; + JuiceButton.OnPressed += owner.StartJuicing; + ChamberContentBox.EjectButton.OnPressed += owner.EjectAll; + BeakerContentBox.EjectButton.OnPressed += owner.EjectBeaker; ChamberContentBox.BoxContents.OnItemSelected += OnChamberBoxContentsItemSelected; BeakerContentBox.BoxContents.SelectMode = ItemList.ItemListSelectMode.None; } private void OnChamberBoxContentsItemSelected(ItemList.ItemListSelectedEventArgs args) { - OnEjectChamber?.Invoke(_chamberVisualContents[args.ItemIndex]); + _owner.EjectChamberContent(_chamberVisualContents[args.ItemIndex]); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + _chamberVisualContents.Clear(); + GrindButton.OnPressed -= _owner.StartGrinding; + JuiceButton.OnPressed -= _owner.StartJuicing; + ChamberContentBox.EjectButton.OnPressed -= _owner.EjectAll; + BeakerContentBox.EjectButton.OnPressed -= _owner.EjectBeaker; + ChamberContentBox.BoxContents.OnItemSelected -= OnChamberBoxContentsItemSelected; } public void UpdateState(ReagentGrinderInterfaceState state) diff --git a/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs b/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs index 643ac47054b..7e7dd2d6935 100644 --- a/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs +++ b/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs @@ -3,7 +3,6 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Client.Graphics; -using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Timing; @@ -20,15 +19,28 @@ public sealed class MicrowaveBoundUserInterface : BoundUserInterface [ViewVariables] private readonly Dictionary _reagents = new(); + [Dependency] private readonly IGameTiming _gameTiming = default!; + + public MicrowaveUpdateUserInterfaceState currentState = default!; + + private IEntityManager _entManager; public MicrowaveBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { + _entManager = IoCManager.Resolve(); + } + + public TimeSpan GetCurrentTime() + { + return _gameTiming.CurTime; } protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new MicrowaveMenu(this); + _menu.OpenCentered(); + _menu.OnClose += Close; _menu.StartButton.OnPressed += _ => SendPredictedMessage(new MicrowaveStartCookMessage()); _menu.EjectButton.OnPressed += _ => SendPredictedMessage(new MicrowaveEjectMessage()); _menu.IngredientsList.OnItemSelected += args => @@ -62,23 +74,38 @@ protected override void Open() }; } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (!disposing) + { + return; + } + + _solids.Clear(); + _menu?.Dispose(); + } + protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); - if (state is not MicrowaveUpdateUserInterfaceState cState || _menu == null) + if (state is not MicrowaveUpdateUserInterfaceState cState) { return; } - _menu.IsBusy = cState.IsMicrowaveBusy; - _menu.CurrentCooktimeEnd = cState.CurrentCookTimeEnd; - _menu.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0); + _menu?.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0); + currentState = cState; + // TODO move this to a component state and ensure the net ids. - RefreshContentsDisplay(EntMan.GetEntityArray(cState.ContainedSolids)); + RefreshContentsDisplay(_entManager.GetEntityArray(cState.ContainedSolids)); + + if (_menu == null) return; //Set the cook time info label - var cookTime = cState.ActiveButtonIndex == 0 + var cookTime = cState.ActiveButtonIndex == 0 ? Loc.GetString("microwave-menu-instant-button") : cState.CurrentCookTime.ToString(); diff --git a/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs b/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs index 7565075f86f..b292e9f1465 100644 --- a/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs +++ b/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs @@ -9,20 +9,22 @@ namespace Content.Client.Kitchen.UI [GenerateTypedNameReferences] public sealed partial class MicrowaveMenu : FancyWindow { - [Dependency] private readonly IGameTiming _timing = default!; + public sealed class MicrowaveCookTimeButton : Button + { + public uint CookTime; + } public event Action? OnCookTimeSelected; public ButtonGroup CookTimeButtonGroup { get; } + private readonly MicrowaveBoundUserInterface _owner; - public bool IsBusy; - public TimeSpan CurrentCooktimeEnd; - - public MicrowaveMenu() + public MicrowaveMenu(MicrowaveBoundUserInterface owner) { RobustXamlLoader.Load(this); CookTimeButtonGroup = new ButtonGroup(); InstantCookButton.Group = CookTimeButtonGroup; + _owner = owner; InstantCookButton.OnPressed += args => { OnCookTimeSelected?.Invoke(args, 0); @@ -63,20 +65,14 @@ public void ToggleBusyDisableOverlayPanel(bool shouldDisable) protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - - if (!IsBusy) + if(!_owner.currentState.IsMicrowaveBusy) return; - if (CurrentCooktimeEnd > _timing.CurTime) + if(_owner.currentState.CurrentCookTimeEnd > _owner.GetCurrentTime()) { CookTimeInfoLabel.Text = Loc.GetString("microwave-bound-user-interface-cook-time-label", - ("time", CurrentCooktimeEnd.Subtract(_timing.CurTime).Seconds)); + ("time",_owner.currentState.CurrentCookTimeEnd.Subtract(_owner.GetCurrentTime()).Seconds)); } } - - public sealed class MicrowaveCookTimeButton : Button - { - public uint CookTime; - } } } diff --git a/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs b/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs index bc4cc75b4d1..e6f108b3050 100644 --- a/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs +++ b/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Containers.ItemSlots; using Content.Shared.Kitchen; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Prototypes; @@ -9,6 +8,8 @@ namespace Content.Client.Kitchen.UI { public sealed class ReagentGrinderBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [ViewVariables] private GrinderMenu? _menu; @@ -20,13 +21,20 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.OnToggleAuto += ToggleAutoMode; - _menu.OnGrind += StartGrinding; - _menu.OnJuice += StartJuicing; - _menu.OnEjectAll += EjectAll; - _menu.OnEjectBeaker += EjectBeaker; - _menu.OnEjectChamber += EjectChamberContent; + _menu = new GrinderMenu(this, EntMan, _prototypeManager); + _menu.OpenCentered(); + _menu.OnClose += Close; + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + { + return; + } + + _menu?.Dispose(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -44,27 +52,27 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) _menu?.HandleMessage(message); } - public void ToggleAutoMode() + public void ToggleAutoMode(BaseButton.ButtonEventArgs args) { SendMessage(new ReagentGrinderToggleAutoModeMessage()); } - public void StartGrinding() + public void StartGrinding(BaseButton.ButtonEventArgs? _ = null) { SendMessage(new ReagentGrinderStartMessage(GrinderProgram.Grind)); } - public void StartJuicing() + public void StartJuicing(BaseButton.ButtonEventArgs? _ = null) { SendMessage(new ReagentGrinderStartMessage(GrinderProgram.Juice)); } - public void EjectAll() + public void EjectAll(BaseButton.ButtonEventArgs? _ = null) { SendMessage(new ReagentGrinderEjectChamberAllMessage()); } - public void EjectBeaker() + public void EjectBeaker(BaseButton.ButtonEventArgs? _ = null) { SendMessage(new ItemSlotButtonPressedEvent(SharedReagentGrinder.BeakerSlotId)); } diff --git a/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs b/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs index 6b656123412..555f1ff09e6 100644 --- a/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs +++ b/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Labels; using Content.Shared.Labels.Components; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Labels.UI { @@ -24,8 +23,13 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new HandLabelerWindow(); + if (State != null) + UpdateState(State); + _window.OpenCentered(); + + _window.OnClose += Close; _window.OnLabelChanged += OnLabelChanged; Reload(); } @@ -47,5 +51,13 @@ public void Reload() _window.SetCurrentLabel(component.AssignedLabel); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + _window?.Dispose(); + } } + } diff --git a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs index a599f79152e..6e6d1b91761 100644 --- a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs +++ b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Lathe; using Content.Shared.Research.Components; using JetBrains.Annotations; -using Robust.Client.UserInterface; namespace Content.Client.Lathe.UI { @@ -18,9 +17,9 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.SetEntity(Owner); - _menu.OpenCenteredRight(); + _menu = new LatheMenu(this); + _menu.OnClose += Close; + _menu.OnServerListButtonPressed += _ => { @@ -31,6 +30,8 @@ protected override void Open() { SendMessage(new LatheQueueRecipeMessage(recipe, amount)); }; + + _menu.OpenCenteredRight(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -49,5 +50,13 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + _menu?.Dispose(); + } } } diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml.cs b/Content.Client/Lathe/UI/LatheMenu.xaml.cs index 6f530b76c75..f2f52b67b5b 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml.cs +++ b/Content.Client/Lathe/UI/LatheMenu.xaml.cs @@ -1,4 +1,3 @@ -using System.Buffers; using System.Linq; using System.Text; using Content.Client.Materials; @@ -23,6 +22,7 @@ public sealed partial class LatheMenu : DefaultWindow [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + private EntityUid _owner; private readonly SpriteSystem _spriteSystem; private readonly LatheSystem _lathe; private readonly MaterialStorageSystem _materialStorage; @@ -36,10 +36,9 @@ public sealed partial class LatheMenu : DefaultWindow public ProtoId? CurrentCategory; - public EntityUid Entity; - - public LatheMenu() + public LatheMenu(LatheBoundUserInterface owner) { + _owner = owner.Owner; RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -47,6 +46,8 @@ public LatheMenu() _lathe = _entityManager.System(); _materialStorage = _entityManager.System(); + Title = _entityManager.GetComponent(owner.Owner).EntityName; + SearchBar.OnTextChanged += _ => { PopulateRecipes(); @@ -59,13 +60,8 @@ public LatheMenu() FilterOption.OnItemSelected += OnItemSelected; ServerListButton.OnPressed += a => OnServerListButtonPressed?.Invoke(a); - } - public void SetEntity(EntityUid uid) - { - Entity = uid; - - if (_entityManager.TryGetComponent(Entity, out var latheComponent)) + if (_entityManager.TryGetComponent(owner.Owner, out var latheComponent)) { if (!latheComponent.DynamicRecipes.Any()) { @@ -73,7 +69,7 @@ public void SetEntity(EntityUid uid) } } - MaterialsList.SetOwner(Entity); + MaterialsList.SetOwner(owner.Owner); } /// @@ -106,15 +102,13 @@ public void PopulateRecipes() var sortedRecipesToShow = recipesToShow.OrderBy(p => p.Name); RecipeList.Children.Clear(); - _entityManager.TryGetComponent(Entity, out LatheComponent? lathe); - foreach (var prototype in sortedRecipesToShow) { EntityPrototype? recipeProto = null; - if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto)) + if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto) && entityProto != null) recipeProto = entityProto; - var canProduce = _lathe.CanProduce(Entity, prototype, quantity, component: lathe); + var canProduce = _lathe.CanProduce(_owner, prototype, quantity); var control = new RecipeControl(prototype, () => GenerateTooltipText(prototype), canProduce, recipeProto); control.OnButtonPressed += s => @@ -130,20 +124,19 @@ public void PopulateRecipes() private string GenerateTooltipText(LatheRecipePrototype prototype) { StringBuilder sb = new(); - var multiplier = _entityManager.GetComponent(Entity).MaterialUseMultiplier; foreach (var (id, amount) in prototype.RequiredMaterials) { if (!_prototypeManager.TryIndex(id, out var proto)) continue; - var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, multiplier); + var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, _entityManager.GetComponent(_owner).MaterialUseMultiplier); var sheetVolume = _materialStorage.GetSheetVolume(proto); var unit = Loc.GetString(proto.Unit); var sheets = adjustedAmount / (float) sheetVolume; - var availableAmount = _materialStorage.GetMaterialAmount(Entity, id); + var availableAmount = _materialStorage.GetMaterialAmount(_owner, id); var missingAmount = Math.Max(0, adjustedAmount - availableAmount); var missingSheets = missingAmount / (float) sheetVolume; diff --git a/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs b/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs index 11abe8c2451..09bdedfd94c 100644 --- a/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs +++ b/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.MachineLinking; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Shared.Timing; namespace Content.Client.MachineLinking.UI; @@ -20,14 +19,19 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.OnStartTimer += StartTimer; + _window = new SignalTimerWindow(this); + + if (State != null) + UpdateState(State); + + _window.OpenCentered(); + _window.OnClose += Close; _window.OnCurrentTextChanged += OnTextChanged; _window.OnCurrentDelayMinutesChanged += OnDelayChanged; _window.OnCurrentDelaySecondsChanged += OnDelayChanged; } - public void StartTimer() + public void OnStartTimer() { SendMessage(new SignalTimerStartMessage()); } @@ -44,6 +48,11 @@ private void OnDelayChanged(string newDelay) SendMessage(new SignalTimerDelayChangedMessage(_window.GetDelay())); } + public TimeSpan GetCurrentTime() + { + return _gameTiming.CurTime; + } + /// /// Update the UI state based on server-sent info /// @@ -63,4 +72,11 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetTimerStarted(cast.TimerStarted); _window.SetHasAccess(cast.HasAccess); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + _window?.Dispose(); + } } diff --git a/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs b/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs index 6133abfcb70..b62595595e5 100644 --- a/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs +++ b/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs @@ -9,44 +9,42 @@ namespace Content.Client.MachineLinking.UI; [GenerateTypedNameReferences] public sealed partial class SignalTimerWindow : DefaultWindow { - [Dependency] private readonly IGameTiming _timing = default!; - private const int MaxTextLength = 5; public event Action? OnCurrentTextChanged; public event Action? OnCurrentDelayMinutesChanged; public event Action? OnCurrentDelaySecondsChanged; + private readonly SignalTimerBoundUserInterface _owner; + private TimeSpan? _triggerTime; private bool _timerStarted; - public event Action? OnStartTimer; - - public SignalTimerWindow() + public SignalTimerWindow(SignalTimerBoundUserInterface owner) { RobustXamlLoader.Load(this); - IoCManager.InjectDependencies(this); + + _owner = owner; CurrentTextEdit.OnTextChanged += e => OnCurrentTextChange(e.Text); CurrentDelayEditMinutes.OnTextChanged += e => OnCurrentDelayMinutesChange(e.Text); CurrentDelayEditSeconds.OnTextChanged += e => OnCurrentDelaySecondsChange(e.Text); - StartTimer.OnPressed += _ => StartTimerWeh(); + StartTimer.OnPressed += _ => OnStartTimer(); } - private void StartTimerWeh() + public void OnStartTimer() { if (!_timerStarted) { _timerStarted = true; - _triggerTime = _timing.CurTime + GetDelay(); + _triggerTime = _owner.GetCurrentTime() + GetDelay(); } else { SetTimerStarted(false); } - - OnStartTimer?.Invoke(); + _owner.OnStartTimer(); } protected override void FrameUpdate(FrameEventArgs args) @@ -56,9 +54,9 @@ protected override void FrameUpdate(FrameEventArgs args) if (!_timerStarted || _triggerTime == null) return; - if (_timing.CurTime < _triggerTime.Value) + if (_owner.GetCurrentTime() < _triggerTime.Value) { - StartTimer.Text = TextScreenSystem.TimeToString(_triggerTime.Value - _timing.CurTime); + StartTimer.Text = TextScreenSystem.TimeToString(_triggerTime.Value - _owner.GetCurrentTime()); } else { diff --git a/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs b/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs index 0a87948ff62..f6979bf8d7b 100644 --- a/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs +++ b/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Humanoid.Markings; using Content.Shared.MagicMirror; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.MagicMirror; @@ -18,7 +17,7 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new(); _window.OnHairSelected += tuple => SelectHair(MagicMirrorCategory.Hair, tuple.id, tuple.slot); _window.OnHairColorChanged += args => ChangeColor(MagicMirrorCategory.Hair, args.marking, args.slot); @@ -30,6 +29,9 @@ protected override void Open() args => ChangeColor(MagicMirrorCategory.FacialHair, args.marking, args.slot); _window.OnFacialHairSlotAdded += delegate () { AddSlot(MagicMirrorCategory.FacialHair); }; _window.OnFacialHairSlotRemoved += args => RemoveSlot(MagicMirrorCategory.FacialHair, args); + + _window.OnClose += Close; + _window.OpenCentered(); } private void SelectHair(MagicMirrorCategory category, string marking, int slot) @@ -63,5 +65,14 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState(data); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _window?.Dispose(); + } } diff --git a/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs b/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs index 22e5bc452a0..80eca82e324 100644 --- a/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs +++ b/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs @@ -1,7 +1,6 @@ using JetBrains.Annotations; using Content.Shared.MassMedia.Systems; using Content.Shared.MassMedia.Components; -using Robust.Client.UserInterface; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -10,6 +9,8 @@ namespace Content.Client.MassMedia.Ui; [UsedImplicitly] public sealed class NewsWriterBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IGameTiming _gameTiming = default!; + [ViewVariables] private NewsWriterMenu? _menu; @@ -20,7 +21,10 @@ public NewsWriterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, u protected override void Open() { - _menu = this.CreateWindow(); + _menu = new NewsWriterMenu(_gameTiming); + + _menu.OpenCentered(); + _menu.OnClose += Close; _menu.ArticleEditorPanel.PublishButtonPressed += OnPublishButtonPressed; _menu.DeleteButtonPressed += OnDeleteButtonPressed; @@ -28,6 +32,16 @@ protected override void Open() SendMessage(new NewsWriterArticlesRequestMessage()); } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _menu?.Close(); + _menu?.Dispose(); + } + protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); diff --git a/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs b/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs index c059ce785af..e2d57935e3a 100644 --- a/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs +++ b/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs @@ -10,17 +10,17 @@ namespace Content.Client.MassMedia.Ui; [GenerateTypedNameReferences] public sealed partial class NewsWriterMenu : FancyWindow { - [Dependency] private readonly IGameTiming _gameTiming = default!; + private readonly IGameTiming _gameTiming; private TimeSpan? _nextPublish; public event Action? DeleteButtonPressed; - public NewsWriterMenu() + public NewsWriterMenu(IGameTiming gameTiming) { RobustXamlLoader.Load(this); - IoCManager.InjectDependencies(this); + _gameTiming = gameTiming; ContentsContainer.RectClipContent = false; // Customize scrollbar width and margin. This is not possible in xaml diff --git a/Content.Client/Mech/Ui/MechBoundUserInterface.cs b/Content.Client/Mech/Ui/MechBoundUserInterface.cs index 2130a8c6099..4172bdc90f1 100644 --- a/Content.Client/Mech/Ui/MechBoundUserInterface.cs +++ b/Content.Client/Mech/Ui/MechBoundUserInterface.cs @@ -3,7 +3,6 @@ using Content.Shared.Mech.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Mech.Ui; @@ -21,8 +20,9 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.SetEntity(Owner); + _menu = new(Owner); + + _menu.OnClose += Close; _menu.OpenCenteredLeft(); _menu.OnRemoveButtonPressed += uid => @@ -60,6 +60,16 @@ public void UpdateEquipmentControls(MechBoundUiState state) } } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (!disposing) + return; + + _menu?.Close(); + } + public UIFragment? GetEquipmentUi(EntityUid? uid) { var component = EntMan.GetComponentOrNull(uid); diff --git a/Content.Client/Mech/Ui/MechMenu.xaml.cs b/Content.Client/Mech/Ui/MechMenu.xaml.cs index 6f39bc386ee..fad76488086 100644 --- a/Content.Client/Mech/Ui/MechMenu.xaml.cs +++ b/Content.Client/Mech/Ui/MechMenu.xaml.cs @@ -16,15 +16,14 @@ public sealed partial class MechMenu : FancyWindow public event Action? OnRemoveButtonPressed; - public MechMenu() + public MechMenu(EntityUid mech) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - } - public void SetEntity(EntityUid uid) - { - MechView.SetEntity(uid); + _mech = mech; + + MechView.SetEntity(mech); } public void UpdateMechStats() diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs index b1f239cd78e..39788809871 100644 --- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs @@ -1,5 +1,4 @@ using Content.Shared.Medical.CrewMonitoring; -using Robust.Client.UserInterface; namespace Content.Client.Medical.CrewMonitoring; @@ -15,7 +14,7 @@ public CrewMonitoringBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { EntityUid? gridUid = null; - var stationName = string.Empty; + string stationName = string.Empty; if (EntMan.TryGetComponent(Owner, out var xform)) { @@ -27,8 +26,10 @@ protected override void Open() } } - _menu = this.CreateWindow(); - _menu.Set(stationName, gridUid); + _menu = new CrewMonitoringWindow(stationName, gridUid); + + _menu.OpenCentered(); + _menu.OnClose += Close; } protected override void UpdateState(BoundUserInterfaceState state) @@ -43,4 +44,13 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _menu?.Dispose(); + } } diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs index e861864c144..863412e5532 100644 --- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs @@ -23,27 +23,22 @@ namespace Content.Client.Medical.CrewMonitoring; [GenerateTypedNameReferences] public sealed partial class CrewMonitoringWindow : FancyWindow { - [Dependency] private readonly IEntityManager _entManager = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + private readonly IEntityManager _entManager; + private readonly IPrototypeManager _prototypeManager; private readonly SpriteSystem _spriteSystem; private NetEntity? _trackedEntity; private bool _tryToScrollToListFocus; private Texture? _blipTexture; - public CrewMonitoringWindow() + public CrewMonitoringWindow(string stationName, EntityUid? mapUid) { RobustXamlLoader.Load(this); - IoCManager.InjectDependencies(this); + _entManager = IoCManager.Resolve(); + _prototypeManager = IoCManager.Resolve(); _spriteSystem = _entManager.System(); - NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; - - } - - public void Set(string stationName, EntityUid? mapUid) - { _blipTexture = _spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png"))); if (_entManager.TryGetComponent(mapUid, out var xform)) @@ -54,6 +49,8 @@ public void Set(string stationName, EntityUid? mapUid) StationName.AddStyleClass("LabelBig"); StationName.Text = stationName; + + NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; NavMap.ForceNavMapUpdate(); } diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs index f85220a9266..80c98f143b9 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Client.NetworkConfigurator.Systems; using Content.Shared.DeviceNetwork; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.NetworkConfigurator; @@ -36,12 +35,14 @@ protected override void Open() switch (UiKey) { case NetworkConfiguratorUiKey.List: - _listMenu = this.CreateWindow(); + _listMenu = new NetworkConfiguratorListMenu(this); + _listMenu.OnClose += Close; _listMenu.ClearButton.OnPressed += _ => OnClearButtonPressed(); - _listMenu.OnRemoveAddress += OnRemoveButtonPressed; + _listMenu.OpenCenteredRight(); break; case NetworkConfiguratorUiKey.Configure: - _configurationMenu = this.CreateWindow(); + _configurationMenu = new NetworkConfiguratorConfigurationMenu(); + _configurationMenu.OnClose += Close; _configurationMenu.Set.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Set); _configurationMenu.Add.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Add); //_configurationMenu.Edit.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Edit); @@ -49,24 +50,12 @@ protected override void Open() _configurationMenu.Copy.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Copy); _configurationMenu.Show.OnPressed += OnShowPressed; _configurationMenu.Show.Pressed = _netConfig.ConfiguredListIsTracked(Owner); - _configurationMenu.OnRemoveAddress += OnRemoveButtonPressed; + _configurationMenu.OpenCentered(); break; case NetworkConfiguratorUiKey.Link: - _linkMenu = this.CreateWindow(); - _linkMenu.OnLinkDefaults += args => - { - SendMessage(new NetworkConfiguratorLinksSaveMessage(args)); - }; - - _linkMenu.OnToggleLink += (left, right) => - { - SendMessage(new NetworkConfiguratorToggleLinkMessage(left, right)); - }; - - _linkMenu.OnClearLinks += () => - { - SendMessage(new NetworkConfiguratorClearLinksMessage()); - }; + _linkMenu = new NetworkConfiguratorLinkMenu(this); + _linkMenu.OnClose += Close; + _linkMenu.OpenCentered(); break; } } @@ -94,6 +83,16 @@ protected override void UpdateState(BoundUserInterfaceState state) } } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + + _linkMenu?.Dispose(); + _listMenu?.Dispose(); + _configurationMenu?.Dispose(); + } + private void OnClearButtonPressed() { SendMessage(new NetworkConfiguratorClearDevicesMessage()); diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs index fcd2f759187..19d04cd3464 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs @@ -9,23 +9,17 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorConfigurationMenu : FancyWindow { - public event Action? OnRemoveAddress; - public NetworkConfiguratorConfigurationMenu() { RobustXamlLoader.Load(this); Clear.StyleClasses.Add(StyleBase.ButtonOpenLeft); Clear.StyleClasses.Add(StyleNano.StyleClassButtonColorRed); - DeviceList.OnRemoveAddress += args => - { - OnRemoveAddress?.Invoke(args); - }; } public void UpdateState(DeviceListUserInterfaceState state) { - DeviceList.UpdateState(state.DeviceList, false); + DeviceList.UpdateState(null, state.DeviceList); Count.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count)); } diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs index e75c60058cb..8cfa97dc6c2 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs @@ -7,19 +7,17 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorDeviceList : ScrollContainer { - public event Action? OnRemoveAddress; - - public void UpdateState(HashSet<(string address, string name)> devices, bool ui) + public void UpdateState(NetworkConfiguratorBoundUserInterface? ui, HashSet<(string address, string name)> devices) { DeviceList.RemoveAllChildren(); foreach (var device in devices) { - DeviceList.AddChild(BuildDeviceListRow(device, ui)); + DeviceList.AddChild(BuildDeviceListRow(ui, device)); } } - private BoxContainer BuildDeviceListRow((string address, string name) savedDevice, bool ui) + private static BoxContainer BuildDeviceListRow(NetworkConfiguratorBoundUserInterface? ui, (string address, string name) savedDevice) { var row = new BoxContainer() { @@ -50,10 +48,10 @@ private BoxContainer BuildDeviceListRow((string address, string name) savedDevic row.AddChild(name); row.AddChild(address); - if (ui) + if (ui != null) { row.AddChild(removeButton); - removeButton.OnPressed += _ => OnRemoveAddress?.Invoke(savedDevice.address); + removeButton.OnPressed += _ => ui.OnRemoveButtonPressed(savedDevice.address); } return row; diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs index 8cdffd16af6..c04b42f249b 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs @@ -18,20 +18,20 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow private readonly LinksRender _links; + private readonly List _sources = new(); private readonly List _sinks = new(); + private readonly NetworkConfiguratorBoundUserInterface _userInterface; + private (ButtonPosition position, string id, int index)? _selectedButton; private List<(string left, string right)>? _defaults; - public event Action? OnClearLinks; - public event Action? OnToggleLink; - public event Action>? OnLinkDefaults; - - public NetworkConfiguratorLinkMenu() + public NetworkConfiguratorLinkMenu(NetworkConfiguratorBoundUserInterface userInterface) { + _userInterface = userInterface; RobustXamlLoader.Load(this); var footerStyleBox = new StyleBoxFlat() @@ -52,7 +52,7 @@ public NetworkConfiguratorLinkMenu() ButtonOk.OnPressed += _ => Close(); ButtonLinkDefault.OnPressed += _ => LinkDefaults(); - ButtonClear.OnPressed += _ => OnClearLinks?.Invoke(); + ButtonClear.OnPressed += _ => _userInterface.SendMessage(new NetworkConfiguratorClearLinksMessage()); } public void UpdateState(DeviceLinkUserInterfaceState linkState) @@ -98,7 +98,7 @@ private void LinkDefaults() if (_defaults == default) return; - OnLinkDefaults?.Invoke(_defaults); + _userInterface.SendMessage(new NetworkConfiguratorLinksSaveMessage(_defaults)); } private Button CreateButton(ButtonPosition position, string name, string description, string id, int index) @@ -138,7 +138,7 @@ private void OnButtonPressed(BaseButton.ButtonEventArgs args, ButtonPosition pos var left = _selectedButton.Value.position == ButtonPosition.Left ? _selectedButton.Value.id : id; var right = _selectedButton.Value.position == ButtonPosition.Left ? id : _selectedButton.Value.id; - OnToggleLink?.Invoke(left, right); + _userInterface.SendMessage(new NetworkConfiguratorToggleLinkMessage(left, right)); args.Button.Pressed = false; diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs index 6294facaeed..fb4aec1974b 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs @@ -9,20 +9,17 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorListMenu : FancyWindow { - public event Action? OnRemoveAddress; - - public NetworkConfiguratorListMenu() + private readonly NetworkConfiguratorBoundUserInterface _ui; + public NetworkConfiguratorListMenu(NetworkConfiguratorBoundUserInterface ui) { RobustXamlLoader.Load(this); - DeviceList.OnRemoveAddress += args => - { - OnRemoveAddress?.Invoke(args); - }; + + _ui = ui; } public void UpdateState(NetworkConfiguratorUserInterfaceState state) { DeviceCountLabel.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count)); - DeviceList.UpdateState(state.DeviceList, true); + DeviceList.UpdateState(_ui, state.DeviceList); } } diff --git a/Content.Client/Nuke/NukeBoundUserInterface.cs b/Content.Client/Nuke/NukeBoundUserInterface.cs index 2e150423734..59fbc5b319b 100644 --- a/Content.Client/Nuke/NukeBoundUserInterface.cs +++ b/Content.Client/Nuke/NukeBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Nuke; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Nuke { @@ -12,13 +11,15 @@ public sealed class NukeBoundUserInterface : BoundUserInterface [ViewVariables] private NukeMenu? _menu; - public NukeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + public NukeBoundUserInterface([NotNull] EntityUid owner, [NotNull] Enum uiKey) : base(owner, uiKey) { } protected override void Open() { - _menu = this.CreateWindow(); + _menu = new NukeMenu(); + _menu.OpenCentered(); + _menu.OnClose += Close; _menu.OnKeypadButtonPressed += i => { @@ -61,5 +62,15 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _menu?.Close(); + _menu?.Dispose(); + } } } diff --git a/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs b/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs index ad4f1a75d47..ec055b3240c 100644 --- a/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs +++ b/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Chat; using Content.Shared.NukeOps; using JetBrains.Annotations; -using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Timing; @@ -12,6 +11,8 @@ namespace Content.Client.NukeOps; public sealed class WarDeclaratorBoundUserInterface : BoundUserInterface { [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly ILocalizationManager _localizationManager = default!; [ViewVariables] private WarDeclaratorWindow? _window; @@ -22,7 +23,13 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new WarDeclaratorWindow(_gameTiming, _localizationManager); + if (State != null) + UpdateState(State); + + _window.OpenCentered(); + + _window.OnClose += Close; _window.OnActivated += OnWarDeclaratorActivated; } @@ -35,6 +42,13 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + _window?.Dispose(); + } + private void OnWarDeclaratorActivated(string message) { var maxLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength); diff --git a/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs b/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs index aeceae13275..b4a3f1c7fa5 100644 --- a/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs +++ b/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs @@ -11,8 +11,7 @@ namespace Content.Client.NukeOps; [GenerateTypedNameReferences] public sealed partial class WarDeclaratorWindow : FancyWindow { - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly ILocalizationManager _localizationManager = default!; + private readonly IGameTiming _gameTiming; public event Action? OnActivated; @@ -20,13 +19,15 @@ public sealed partial class WarDeclaratorWindow : FancyWindow private TimeSpan _shuttleDisabledTime; private WarConditionStatus _status; - public WarDeclaratorWindow() + public WarDeclaratorWindow(IGameTiming gameTiming, ILocalizationManager localizationManager) { RobustXamlLoader.Load(this); + _gameTiming = gameTiming; + WarButton.OnPressed += (_) => OnActivated?.Invoke(Rope.Collapse(MessageEdit.TextRope)); - MessageEdit.Placeholder = new Rope.Leaf(_localizationManager.GetString("war-declarator-message-placeholder")); + MessageEdit.Placeholder = new Rope.Leaf(localizationManager.GetString("war-declarator-message-placeholder")); } protected override void FrameUpdate(FrameEventArgs args) diff --git a/Content.Client/PDA/PdaBoundUserInterface.cs b/Content.Client/PDA/PdaBoundUserInterface.cs index 37ce9c4280f..f8f4c67076c 100644 --- a/Content.Client/PDA/PdaBoundUserInterface.cs +++ b/Content.Client/PDA/PdaBoundUserInterface.cs @@ -24,13 +24,14 @@ protected override void Open() if (_menu == null) CreateMenu(); + + _menu?.OpenCenteredLeft(); } private void CreateMenu() { - _menu = this.CreateWindow(); - _menu.OpenCenteredLeft(); - + _menu = new PdaMenu(); + _menu.OnClose += Close; _menu.FlashLightToggleButton.OnToggled += _ => { SendMessage(new PdaToggleFlashlightMessage()); @@ -95,6 +96,7 @@ protected override void UpdateState(BoundUserInterfaceState state) _menu?.UpdateState(updateState); } + protected override void AttachCartridgeUI(Control cartridgeUIFragment, string? title) { _menu?.ProgramView.AddChild(cartridgeUIFragment); @@ -116,6 +118,15 @@ protected override void UpdateAvailablePrograms(List<(EntityUid, CartridgeCompon _menu?.UpdateAvailablePrograms(programs); } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _menu?.Dispose(); + } + private PdaBorderColorComponent? GetBorderColorComponent() { return EntMan.GetComponentOrNull(Owner); diff --git a/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs b/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs index 170a296ac2e..a0688523f1e 100644 --- a/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs +++ b/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.PDA; using Content.Shared.PDA.Ringer; using JetBrains.Annotations; -using Robust.Client.UserInterface; using Robust.Shared.Timing; namespace Content.Client.PDA.Ringer @@ -19,8 +18,9 @@ public RingerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new RingtoneMenu(); _menu.OpenToLeft(); + _menu.OnClose += Close; _menu.TestRingerButton.OnPressed += _ => { diff --git a/Content.Client/Paper/UI/PaperBoundUserInterface.cs b/Content.Client/Paper/UI/PaperBoundUserInterface.cs index f3ad1e347e7..4b0ac868f01 100644 --- a/Content.Client/Paper/UI/PaperBoundUserInterface.cs +++ b/Content.Client/Paper/UI/PaperBoundUserInterface.cs @@ -1,5 +1,4 @@ using JetBrains.Annotations; -using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Utility; using static Content.Shared.Paper.SharedPaperComponent; @@ -20,13 +19,16 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.OnSaved += InputOnTextEntered; + _window = new PaperWindow(); + _window.OnClose += Close; + _window.OnSaved += Input_OnTextEntered; if (EntMan.TryGetComponent(Owner, out var visuals)) { _window.InitVisuals(Owner, visuals); } + + _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -35,7 +37,7 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.Populate((PaperBoundUserInterfaceState) state); } - private void InputOnTextEntered(string text) + private void Input_OnTextEntered(string text) { SendMessage(new PaperInputTextMessage(text)); @@ -45,4 +47,11 @@ private void InputOnTextEntered(string text) _window.Input.CursorPosition = new TextEdit.CursorPos(0, TextEdit.LineBreakBias.Top); } } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + _window?.Dispose(); + } } diff --git a/Content.Client/Paper/UI/PaperWindow.xaml.cs b/Content.Client/Paper/UI/PaperWindow.xaml.cs index f7cace642ce..7a5fd652643 100644 --- a/Content.Client/Paper/UI/PaperWindow.xaml.cs +++ b/Content.Client/Paper/UI/PaperWindow.xaml.cs @@ -17,7 +17,6 @@ namespace Content.Client.Paper.UI public sealed partial class PaperWindow : BaseWindow { [Dependency] private readonly IInputManager _inputManager = default!; - [Dependency] private readonly IResourceCache _resCache = default!; private static Color DefaultTextColor = new(25, 25, 25); @@ -86,10 +85,11 @@ public void InitVisuals(EntityUid entity, PaperVisualsComponent visuals) // Randomize the placement of any stamps based on the entity UID // so that there's some variety in different papers. StampDisplay.PlacementSeed = (int)entity; + var resCache = IoCManager.Resolve(); // Initialize the background: PaperBackground.ModulateSelfOverride = visuals.BackgroundModulate; - var backgroundImage = visuals.BackgroundImagePath != null? _resCache.GetResource(visuals.BackgroundImagePath) : null; + var backgroundImage = visuals.BackgroundImagePath != null? resCache.GetResource(visuals.BackgroundImagePath) : null; if (backgroundImage != null) { var backgroundImageMode = visuals.BackgroundImageTile ? StyleBoxTexture.StretchMode.Tile : StyleBoxTexture.StretchMode.Stretch; @@ -127,7 +127,7 @@ public void InitVisuals(EntityUid entity, PaperVisualsComponent visuals) PaperContent.ModulateSelfOverride = visuals.ContentImageModulate; WrittenTextLabel.ModulateSelfOverride = visuals.FontAccentColor; - var contentImage = visuals.ContentImagePath != null ? _resCache.GetResource(visuals.ContentImagePath) : null; + var contentImage = visuals.ContentImagePath != null ? resCache.GetResource(visuals.ContentImagePath) : null; if (contentImage != null) { // Setup the paper content texture, but keep a reference to it, as we can't set diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs index ff1eae36f55..cde5ba9ef79 100644 --- a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs +++ b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Singularity.Components; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.ParticleAccelerator.UI { @@ -17,10 +16,9 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.OnOverallState += SendEnableMessage; - _menu.OnPowerState += SendPowerStateMessage; - _menu.OnScanPartsRequested += SendScanPartsMessage; + _menu = new ParticleAcceleratorControlMenu(this); + _menu.OnClose += Close; + _menu.OpenCentered(); } public void SendEnableMessage(bool enable) @@ -42,5 +40,13 @@ protected override void UpdateState(BoundUserInterfaceState state) { _menu?.DataUpdate((ParticleAcceleratorUIState) state); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + _menu?.Dispose(); + _menu = null; + } } } diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs index 85a5f476293..c69e0271372 100644 --- a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs +++ b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs @@ -18,11 +18,10 @@ namespace Content.Client.ParticleAccelerator.UI { public sealed class ParticleAcceleratorControlMenu : BaseWindow { - [Dependency] private readonly IPrototypeManager _protoManager = default!; - [Dependency] private readonly IResourceCache _cache = default!; - private readonly ShaderInstance _greyScaleShader; + private readonly ParticleAcceleratorBoundUserInterface _owner; + private readonly Label _drawLabel; private readonly FastNoiseLite _drawNoiseGenerator; private readonly Button _onButton; @@ -51,21 +50,19 @@ public sealed class ParticleAcceleratorControlMenu : BaseWindow private bool _shouldContinueAnimating; private int _maxStrength = 3; - public event Action? OnOverallState; - public event Action? OnPowerState; - public event Action? OnScanPartsRequested; - - public ParticleAcceleratorControlMenu() + public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owner) { SetSize = new Vector2(400, 320); - _greyScaleShader = _protoManager.Index("Greyscale").Instance(); + _greyScaleShader = IoCManager.Resolve().Index("Greyscale").Instance(); + _owner = owner; _drawNoiseGenerator = new(); _drawNoiseGenerator.SetFractalType(FastNoiseLite.FractalType.FBm); _drawNoiseGenerator.SetFrequency(0.5f); - var font = _cache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); - var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); + var resourceCache = IoCManager.Resolve(); + var font = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); + var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); MouseFilter = MouseFilterMode.Stop; @@ -115,8 +112,7 @@ public ParticleAcceleratorControlMenu() Text = Loc.GetString("particle-accelerator-control-menu-off-button"), StyleClasses = { StyleBase.ButtonOpenRight }, }; - - _offButton.OnPressed += args => OnOverallState?.Invoke(false); + _offButton.OnPressed += args => owner.SendEnableMessage(false); _onButton = new Button { @@ -124,7 +120,7 @@ public ParticleAcceleratorControlMenu() Text = Loc.GetString("particle-accelerator-control-menu-on-button"), StyleClasses = { StyleBase.ButtonOpenLeft }, }; - _onButton.OnPressed += args => OnOverallState?.Invoke(true); + _onButton.OnPressed += args => owner.SendEnableMessage(true); var closeButton = new TextureButton { @@ -320,7 +316,7 @@ public ParticleAcceleratorControlMenu() } }); - _scanButton.OnPressed += args => OnScanPartsRequested?.Invoke(); + _scanButton.OnPressed += args => _owner.SendScanPartsMessage(); _alarmControl.AnimationCompleted += s => { @@ -336,7 +332,7 @@ public ParticleAcceleratorControlMenu() PASegmentControl Segment(string name) { - return new(this, _cache, name); + return new(this, resourceCache, name); } UpdateUI(false, false, false, false); @@ -372,7 +368,7 @@ private void PowerStateChanged(ValueChangedEventArgs e) } _stateSpinBox.SetButtonDisabled(true); - OnPowerState?.Invoke(newState); + _owner.SendPowerStateMessage(newState); } protected override DragMode GetDragModeFor(Vector2 relativeMousePos) diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs b/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs index 0df6787170a..3ebcf7cbced 100644 --- a/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Pinpointer; using JetBrains.Annotations; -using Robust.Client.UserInterface; namespace Content.Client.Pinpointer.UI; @@ -17,16 +16,19 @@ public NavMapBeaconBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, protected override void Open() { base.Open(); - _window = this.CreateWindow(); - - if (EntMan.TryGetComponent(Owner, out NavMapBeaconComponent? beacon)) - { - _window.SetEntity(Owner, beacon); - } + _window = new NavMapBeaconWindow(Owner); + _window.OpenCentered(); + _window.OnClose += Close; _window.OnApplyButtonPressed += (label, enabled, color) => { SendMessage(new NavMapBeaconConfigureBuiMessage(label, enabled, color)); }; } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + _window?.Dispose(); + } } diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs b/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs index b77f1af0472..968fe188f75 100644 --- a/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs +++ b/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs @@ -10,35 +10,36 @@ namespace Content.Client.Pinpointer.UI; [GenerateTypedNameReferences] public sealed partial class NavMapBeaconWindow : FancyWindow { + [Dependency] private readonly IEntityManager _entityManager = default!; + private string? _defaultLabel; private bool _defaultEnabled; private Color _defaultColor; public event Action? OnApplyButtonPressed; - public NavMapBeaconWindow() + public NavMapBeaconWindow(EntityUid beaconEntity) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - - VisibleButton.OnPressed += args => UpdateVisibleButton(args.Button.Pressed); - LabelLineEdit.OnTextChanged += OnTextChanged; - ColorSelector.OnColorChanged += _ => TryEnableApplyButton(); - - TryEnableApplyButton(); - ApplyButton.OnPressed += OnApplyPressed; - } - - public void SetEntity(EntityUid uid, NavMapBeaconComponent navMap) - { + if (!_entityManager.TryGetComponent(beaconEntity, out var navMap)) + return; _defaultLabel = navMap.Text; _defaultEnabled = navMap.Enabled; _defaultColor = navMap.Color; UpdateVisibleButton(navMap.Enabled); + VisibleButton.OnPressed += args => UpdateVisibleButton(args.Button.Pressed); + LabelLineEdit.Text = navMap.Text ?? string.Empty; + LabelLineEdit.OnTextChanged += OnTextChanged; + ColorSelector.Color = navMap.Color; + ColorSelector.OnColorChanged += _ => TryEnableApplyButton(); + + TryEnableApplyButton(); + ApplyButton.OnPressed += OnApplyPressed; } private void UpdateVisibleButton(bool value) diff --git a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs index 7417fafede5..1483e75e732 100644 --- a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs @@ -1,4 +1,4 @@ -using Robust.Client.UserInterface; +using Robust.Client.GameObjects; namespace Content.Client.Pinpointer.UI; @@ -14,6 +14,7 @@ public StationMapBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, u protected override void Open() { base.Open(); + _window?.Close(); EntityUid? gridUid = null; if (EntMan.TryGetComponent(Owner, out var xform)) @@ -21,8 +22,14 @@ protected override void Open() gridUid = xform.GridUid; } - _window = this.CreateWindow(); - _window.Title = EntMan.GetComponent(Owner).EntityName; - _window.Set(gridUid, Owner); + _window = new StationMapWindow(gridUid, Owner); + _window.OpenCentered(); + _window.OnClose += Close; + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + _window?.Dispose(); } } diff --git a/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs b/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs index 7cbb8b7d0db..1b01fe4e304 100644 --- a/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs +++ b/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs @@ -9,18 +9,19 @@ namespace Content.Client.Pinpointer.UI; [GenerateTypedNameReferences] public sealed partial class StationMapWindow : FancyWindow { - public StationMapWindow() + public StationMapWindow(EntityUid? mapUid, EntityUid? trackedEntity) { RobustXamlLoader.Load(this); - } - - public void Set(EntityUid? mapUid, EntityUid? trackedEntity) - { NavMapScreen.MapUid = mapUid; if (trackedEntity != null) NavMapScreen.TrackedCoordinates.Add(new EntityCoordinates(trackedEntity.Value, Vector2.Zero), (true, Color.Cyan)); + if (IoCManager.Resolve().TryGetComponent(mapUid, out var metadata)) + { + Title = metadata.EntityName; + } + NavMapScreen.ForceNavMapUpdate(); } } diff --git a/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs b/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs index a3ca6f65da2..57965b030a2 100644 --- a/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs @@ -1,4 +1,4 @@ -using Robust.Client.UserInterface; +using Robust.Client.GameObjects; namespace Content.Client.Pinpointer.UI; @@ -14,15 +14,22 @@ public UntrackedStationMapBoundUserInterface(EntityUid owner, Enum uiKey) : base protected override void Open() { base.Open(); + _window?.Close(); EntityUid? gridUid = null; - // TODO: What this just looks like it's been copy-pasted wholesale from StationMapBoundUserInterface? if (EntMan.TryGetComponent(Owner, out var xform)) { gridUid = xform.GridUid; } - _window = this.CreateWindow(); - _window.Set(gridUid, Owner); + _window = new StationMapWindow(gridUid, null); + _window.OpenCentered(); + _window.OnClose += Close; + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + _window?.Dispose(); } } diff --git a/Content.Client/Power/APC/ApcBoundUserInterface.cs b/Content.Client/Power/APC/ApcBoundUserInterface.cs index 759a5949ba6..fbcbf011569 100644 --- a/Content.Client/Power/APC/ApcBoundUserInterface.cs +++ b/Content.Client/Power/APC/ApcBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.APC; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Power.APC { @@ -20,8 +19,9 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.OnBreaker += BreakerPressed; + _menu = new ApcMenu(this); + _menu.OnClose += Close; + _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -36,5 +36,15 @@ public void BreakerPressed() { SendMessage(new ApcToggleMainBreakerMessage()); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + _menu?.Dispose(); + } + } } } diff --git a/Content.Client/Power/APC/UI/ApcMenu.xaml.cs b/Content.Client/Power/APC/UI/ApcMenu.xaml.cs index 2f61ea63a86..dbf68ea07b0 100644 --- a/Content.Client/Power/APC/UI/ApcMenu.xaml.cs +++ b/Content.Client/Power/APC/UI/ApcMenu.xaml.cs @@ -17,19 +17,13 @@ namespace Content.Client.Power.APC.UI [GenerateTypedNameReferences] public sealed partial class ApcMenu : FancyWindow { - public event Action? OnBreaker; - - public ApcMenu() + public ApcMenu(ApcBoundUserInterface owner) { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - BreakerButton.OnPressed += _ => OnBreaker?.Invoke(); - } - - public void SetEntity(EntityUid entity) - { - EntityView.SetEntity(entity); + EntityView.SetEntity(owner.Owner); + BreakerButton.OnPressed += _ => owner.BreakerPressed(); } public void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Power/Generator/GeneratorWindow.xaml.cs b/Content.Client/Power/Generator/GeneratorWindow.xaml.cs index e975e5d466e..bd5b75de1da 100644 --- a/Content.Client/Power/Generator/GeneratorWindow.xaml.cs +++ b/Content.Client/Power/Generator/GeneratorWindow.xaml.cs @@ -9,39 +9,35 @@ namespace Content.Client.Power.Generator; [GenerateTypedNameReferences] public sealed partial class GeneratorWindow : FancyWindow { + private readonly EntityUid _entity; + [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly ILocalizationManager _loc = default!; - private EntityUid _entity; - - public float? MaximumPower; - - public event Action? OnPower; - public event Action? OnState; - public event Action? OnSwitchOutput; - public event Action? OnEjectFuel; + private readonly SharedPowerSwitchableSystem _switchable; + private readonly FuelGeneratorComponent? _component; + private PortableGeneratorComponentBuiState? _lastState; - public GeneratorWindow() + public GeneratorWindow(PortableGeneratorBoundUserInterface bui, EntityUid entity) { + _entity = entity; RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); + _entityManager.TryGetComponent(entity, out _component); + _switchable = _entityManager.System(); + + EntityView.SetEntity(entity); TargetPower.IsValid += IsValid; TargetPower.ValueChanged += (args) => { - OnPower?.Invoke(args.Value); + bui.SetTargetPower(args.Value); }; - StartButton.OnPressed += _ => OnState?.Invoke(true); - StopButton.OnPressed += _ => OnState?.Invoke(false); - OutputSwitchButton.OnPressed += _ => OnSwitchOutput?.Invoke(); - FuelEject.OnPressed += _ => OnEjectFuel?.Invoke(); - } - - public void SetEntity(EntityUid entity) - { - _entity = entity; - EntityView.SetEntity(entity); + StartButton.OnPressed += _ => bui.Start(); + StopButton.OnPressed += _ => bui.Stop(); + OutputSwitchButton.OnPressed += _ => bui.SwitchOutput(); + FuelEject.OnPressed += _ => bui.EjectFuel(); } private bool IsValid(int arg) @@ -49,7 +45,7 @@ private bool IsValid(int arg) if (arg < 0) return false; - if (arg > (MaximumPower / 1000.0f ?? 0)) + if (arg > (_lastState?.MaximumPower / 1000.0f ?? 0)) return false; return true; @@ -57,17 +53,16 @@ private bool IsValid(int arg) public void Update(PortableGeneratorComponentBuiState state) { - MaximumPower = state.MaximumPower; - - if (!_entityManager.TryGetComponent(_entity, out FuelGeneratorComponent? component)) + if (_component == null) return; + _lastState = state; if (!TargetPower.LineEditControl.HasKeyboardFocus()) TargetPower.OverrideValue((int)(state.TargetPower / 1000.0f)); - var efficiency = SharedGeneratorSystem.CalcFuelEfficiency(state.TargetPower, state.OptimalPower, component); + var efficiency = SharedGeneratorSystem.CalcFuelEfficiency(state.TargetPower, state.OptimalPower, _component); Efficiency.Text = efficiency.ToString("P1"); - var burnRate = component.OptimalBurnRate / efficiency; + var burnRate = _component.OptimalBurnRate / efficiency; var left = state.RemainingFuel / burnRate; Eta.Text = Loc.GetString( @@ -107,15 +102,14 @@ public void Update(PortableGeneratorComponentBuiState state) } var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableComponent? switchable); - var switcher = _entityManager.System(); OutputSwitchLabel.Visible = canSwitch; OutputSwitchButton.Visible = canSwitch; if (switchable != null) { - var voltage = switcher.VoltageString(switcher.GetVoltage(_entity, switchable)); + var voltage = _switchable.VoltageString(_switchable.GetVoltage(_entity, switchable)); OutputSwitchLabel.Text = Loc.GetString("portable-generator-ui-current-output", ("voltage", voltage)); - var nextVoltage = switcher.VoltageString(switcher.GetNextVoltage(_entity, switchable)); + var nextVoltage = _switchable.VoltageString(_switchable.GetNextVoltage(_entity, switchable)); OutputSwitchButton.Text = Loc.GetString("power-switchable-switch-voltage", ("voltage", nextVoltage)); OutputSwitchButton.Disabled = state.On; } diff --git a/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs b/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs index 550e1041b62..30679d71fd6 100644 --- a/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs +++ b/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Power.Generator; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Power.Generator; @@ -17,25 +16,10 @@ public PortableGeneratorBoundUserInterface(EntityUid owner, Enum uiKey) : base(o protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.SetEntity(Owner); - _window.OnState += args => - { - if (args) - { - Start(); - } - else - { - Stop(); - } - }; - - _window.OnPower += SetTargetPower; - _window.OnEjectFuel += EjectFuel; - _window.OnSwitchOutput += SwitchOutput; + _window = new GeneratorWindow(this, Owner); _window.OpenCenteredLeft(); + _window.OnClose += Close; } protected override void UpdateState(BoundUserInterfaceState state) @@ -46,6 +30,11 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.Update(msg); } + protected override void Dispose(bool disposing) + { + _window?.Dispose(); + } + public void SetTargetPower(int target) { SendMessage(new PortableGeneratorSetTargetPowerMessage(target)); diff --git a/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs b/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs index cbc343c06c6..dc1dcd03ef1 100644 --- a/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs +++ b/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs @@ -1,5 +1,4 @@ using Content.Shared.Power; -using Robust.Client.UserInterface; namespace Content.Client.Power; @@ -12,9 +11,9 @@ public PowerMonitoringConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : b protected override void Open() { - _menu = this.CreateWindow(); - _menu.SetEntity(Owner); - _menu.SendPowerMonitoringConsoleMessageAction += SendPowerMonitoringConsoleMessage; + _menu = new PowerMonitoringWindow(this, Owner); + _menu.OpenCentered(); + _menu.OnClose += Close; } protected override void UpdateState(BoundUserInterfaceState state) @@ -23,6 +22,9 @@ protected override void UpdateState(BoundUserInterfaceState state) var castState = (PowerMonitoringConsoleBoundInterfaceState) state; + if (castState == null) + return; + EntMan.TryGetComponent(Owner, out var xform); _menu?.ShowEntites (castState.TotalSources, @@ -38,4 +40,13 @@ public void SendPowerMonitoringConsoleMessage(NetEntity? netEntity, PowerMonitor { SendMessage(new PowerMonitoringConsoleMessage(netEntity, group)); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _menu?.Dispose(); + } } diff --git a/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs b/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs index d9952992070..74752ddc534 100644 --- a/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs +++ b/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs @@ -32,7 +32,7 @@ private void UpdateWindowConsoleEntry if (windowEntry == null) return; - // Update sources and loads + // Update sources and loads UpdateEntrySourcesOrLoads(masterContainer, windowEntry.SourcesContainer, focusSources, _sourceIcon); UpdateEntrySourcesOrLoads(masterContainer, windowEntry.LoadsContainer, focusLoads, _loadIconPath); @@ -134,7 +134,7 @@ private void UpdateEntrySourcesOrLoads(BoxContainer masterContainer, BoxContaine subEntry.Button.OnButtonUp += args => { ButtonAction(subEntry, masterContainer); }; } - if (!_entManager.TryGetComponent(Entity, out var console)) + if (!_entManager.TryGetComponent(_owner, out var console)) return; // Update all children @@ -379,7 +379,7 @@ public PowerMonitoringWindowEntry(PowerMonitoringConsoleEntry entry) : base(entr AddChild(MainContainer); - // Grid container to hold the list of sources when selected + // Grid container to hold the list of sources when selected SourcesContainer = new BoxContainer() { Orientation = LayoutOrientation.Vertical, diff --git a/Content.Client/Power/PowerMonitoringWindow.xaml.cs b/Content.Client/Power/PowerMonitoringWindow.xaml.cs index e3043252486..81fe1f4d047 100644 --- a/Content.Client/Power/PowerMonitoringWindow.xaml.cs +++ b/Content.Client/Power/PowerMonitoringWindow.xaml.cs @@ -15,12 +15,13 @@ namespace Content.Client.Power; [GenerateTypedNameReferences] public sealed partial class PowerMonitoringWindow : FancyWindow { - [Dependency] private IEntityManager _entManager = default!; + private readonly IEntityManager _entManager; private readonly SpriteSystem _spriteSystem; - [Dependency] private IGameTiming _gameTiming = default!; + private readonly IGameTiming _gameTiming; private const float BlinkFrequency = 1f; + private EntityUid? _owner; private NetEntity? _focusEntity; public event Action? SendPowerMonitoringConsoleMessageAction; @@ -33,56 +34,31 @@ public sealed partial class PowerMonitoringWindow : FancyWindow { PowerMonitoringConsoleGroup.APC, (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_triangle.png")), Color.LimeGreen) }, }; - public EntityUid Entity; - - public PowerMonitoringWindow() + public PowerMonitoringWindow(PowerMonitoringConsoleBoundUserInterface userInterface, EntityUid? owner) { RobustXamlLoader.Load(this); - IoCManager.InjectDependencies(this); + _entManager = IoCManager.Resolve(); + _gameTiming = IoCManager.Resolve(); _spriteSystem = _entManager.System(); - - // Set trackable entity selected action - NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; - - // Update nav map - NavMap.ForceNavMapUpdate(); - - // Set UI tab titles - MasterTabContainer.SetTabTitle(0, Loc.GetString("power-monitoring-window-label-sources")); - MasterTabContainer.SetTabTitle(1, Loc.GetString("power-monitoring-window-label-smes")); - MasterTabContainer.SetTabTitle(2, Loc.GetString("power-monitoring-window-label-substation")); - MasterTabContainer.SetTabTitle(3, Loc.GetString("power-monitoring-window-label-apc")); - - // Track when the MasterTabContainer changes its tab - MasterTabContainer.OnTabChanged += OnTabChanged; - - // Set UI toggles - ShowHVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.HighVoltage); - ShowMVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.MediumVoltage); - ShowLVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.Apc); - } - - public void SetEntity(EntityUid uid) - { - Entity = uid; + _owner = owner; // Pass owner to nav map - NavMap.Owner = uid; + NavMap.Owner = _owner; // Set nav map grid uid var stationName = Loc.GetString("power-monitoring-window-unknown-location"); - if (_entManager.TryGetComponent(uid, out var xform)) + if (_entManager.TryGetComponent(owner, out var xform)) { NavMap.MapUid = xform.GridUid; - // Assign station name + // Assign station name if (_entManager.TryGetComponent(xform.GridUid, out var stationMetaData)) stationName = stationMetaData.EntityName; var msg = new FormattedMessage(); - msg.AddMarkupOrThrow(Loc.GetString("power-monitoring-window-station-name", ("stationName", stationName))); + msg.AddMarkup(Loc.GetString("power-monitoring-window-station-name", ("stationName", stationName))); StationName.SetMessage(msg); } @@ -92,6 +68,29 @@ public void SetEntity(EntityUid uid) StationName.SetMessage(stationName); NavMap.Visible = false; } + + // Set trackable entity selected action + NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; + + // Update nav map + NavMap.ForceNavMapUpdate(); + + // Set UI tab titles + MasterTabContainer.SetTabTitle(0, Loc.GetString("power-monitoring-window-label-sources")); + MasterTabContainer.SetTabTitle(1, Loc.GetString("power-monitoring-window-label-smes")); + MasterTabContainer.SetTabTitle(2, Loc.GetString("power-monitoring-window-label-substation")); + MasterTabContainer.SetTabTitle(3, Loc.GetString("power-monitoring-window-label-apc")); + + // Track when the MasterTabContainer changes its tab + MasterTabContainer.OnTabChanged += OnTabChanged; + + // Set UI toggles + ShowHVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.HighVoltage); + ShowMVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.MediumVoltage); + ShowLVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.Apc); + + // Set power monitoring message action + SendPowerMonitoringConsoleMessageAction += userInterface.SendPowerMonitoringConsoleMessage; } private void OnTabChanged(int tab) @@ -114,7 +113,10 @@ public void ShowEntites PowerMonitoringConsoleEntry[] focusLoads, EntityCoordinates? monitorCoords) { - if (!_entManager.TryGetComponent(Entity, out var console)) + if (_owner == null) + return; + + if (!_entManager.TryGetComponent(_owner.Value, out var console)) return; // Update power status text @@ -159,13 +161,13 @@ public void ShowEntites } // Show monitor location - var mon = _entManager.GetNetEntity(Entity); + var mon = _entManager.GetNetEntity(_owner); - if (monitorCoords != null && mon.IsValid()) + if (monitorCoords != null && mon != null) { var texture = _spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png"))); var blip = new NavMapBlip(monitorCoords.Value, texture, Color.Cyan, true, false); - NavMap.TrackedEntities[mon] = blip; + NavMap.TrackedEntities[mon.Value] = blip; } // If the entry group doesn't match the current tab, the data is out dated, do not use it @@ -237,7 +239,7 @@ private void SetTrackedEntityFromNavMap(NetEntity? netEntity) if (netEntity == null) return; - if (!_entManager.TryGetComponent(Entity, out var console)) + if (!_entManager.TryGetComponent(_owner, out var console)) return; if (!console.PowerMonitoringDeviceMetaData.TryGetValue(netEntity.Value, out var metaData)) @@ -264,7 +266,7 @@ protected override void FrameUpdate(FrameEventArgs args) { AutoScrollToFocus(); - // Warning sign pulse + // Warning sign pulse var lit = _gameTiming.RealTime.TotalSeconds % BlinkFrequency > BlinkFrequency / 2f; SystemWarningPanel.Modulate = lit ? Color.White : new Color(178, 178, 178); } diff --git a/Content.Client/RCD/RCDMenu.xaml.cs b/Content.Client/RCD/RCDMenu.xaml.cs index aefb3191812..3eb0397a690 100644 --- a/Content.Client/RCD/RCDMenu.xaml.cs +++ b/Content.Client/RCD/RCDMenu.xaml.cs @@ -20,36 +20,31 @@ public sealed partial class RCDMenu : RadialMenu [Dependency] private readonly IPrototypeManager _protoManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; - private SharedPopupSystem _popup; - private SpriteSystem _sprites; + private readonly SpriteSystem _spriteSystem; + private readonly SharedPopupSystem _popup; public event Action>? SendRCDSystemMessageAction; private EntityUid _owner; - public RCDMenu() + public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); + _spriteSystem = _entManager.System(); _popup = _entManager.System(); - _sprites = _entManager.System(); - OnChildAdded += AddRCDMenuButtonOnClickActions; - } - - public void SetEntity(EntityUid uid) - { - _owner = uid; - } + _owner = owner; - public void Refresh() - { // Find the main radial container var main = FindControl("Main"); + if (main == null) + return; + // Populate secondary radial containers - if (!_entManager.TryGetComponent(_owner, out var rcd)) + if (!_entManager.TryGetComponent(owner, out var rcd)) return; foreach (var protoId in rcd.AvailablePrototypes) @@ -61,6 +56,10 @@ public void Refresh() continue; var parent = FindControl(proto.Category); + + if (parent == null) + continue; + var tooltip = Loc.GetString(proto.SetName); if ((proto.Mode == RcdMode.ConstructTile || proto.Mode == RcdMode.ConstructObject) && @@ -85,7 +84,7 @@ public void Refresh() { VerticalAlignment = VAlignment.Center, HorizontalAlignment = HAlignment.Center, - Texture = _sprites.Frame0(proto.Sprite), + Texture = _spriteSystem.Frame0(proto.Sprite), TextureScale = new Vector2(2f, 2f), }; @@ -113,9 +112,11 @@ public void Refresh() // Set up menu actions foreach (var child in Children) - { AddRCDMenuButtonOnClickActions(child); - } + + OnChildAdded += AddRCDMenuButtonOnClickActions; + + SendRCDSystemMessageAction += bui.SendRCDSystemMessage; } private static string OopsConcat(string a, string b) diff --git a/Content.Client/RCD/RCDMenuBoundUserInterface.cs b/Content.Client/RCD/RCDMenuBoundUserInterface.cs index 1dd03626ae6..a37dbcecf8c 100644 --- a/Content.Client/RCD/RCDMenuBoundUserInterface.cs +++ b/Content.Client/RCD/RCDMenuBoundUserInterface.cs @@ -3,7 +3,6 @@ using JetBrains.Annotations; using Robust.Client.Graphics; using Robust.Client.Input; -using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.RCD; @@ -25,9 +24,8 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.SetEntity(Owner); - _menu.SendRCDSystemMessageAction += SendRCDSystemMessage; + _menu = new(Owner, this); + _menu.OnClose += Close; // Open the menu, centered on the mouse var vpSize = _displayManager.ScreenSize; @@ -36,8 +34,16 @@ protected override void Open() public void SendRCDSystemMessage(ProtoId protoId) { - // A predicted message cannot be used here as the RCD UI is closed immediately + // A predicted message cannot be used here as the RCD UI is closed immediately // after this message is sent, which will stop the server from receiving it SendMessage(new RCDSystemMessage(protoId)); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + + _menu?.Dispose(); + } } diff --git a/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs b/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs index 401e7edd44a..7b3e39aa084 100644 --- a/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs +++ b/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs @@ -1,8 +1,6 @@ using Content.Shared.Radio; using Content.Shared.Radio.Components; using JetBrains.Annotations; -using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Radio.Ui; @@ -21,12 +19,9 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + var comp = EntMan.GetComponent(Owner); - if (EntMan.TryGetComponent(Owner, out IntercomComponent? intercom)) - { - _menu.Update((Owner, intercom)); - } + _menu = new((Owner, comp)); _menu.OnMicPressed += enabled => { @@ -40,6 +35,17 @@ protected override void Open() { SendMessage(new SelectIntercomChannelMessage(channel)); }; + + _menu.OnClose += Close; + _menu.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + _menu?.Close(); } public void Update(Entity ent) diff --git a/Content.Client/Radio/Ui/IntercomMenu.xaml.cs b/Content.Client/Radio/Ui/IntercomMenu.xaml.cs index 20d2e4a3e54..2e08913051c 100644 --- a/Content.Client/Radio/Ui/IntercomMenu.xaml.cs +++ b/Content.Client/Radio/Ui/IntercomMenu.xaml.cs @@ -18,13 +18,15 @@ public sealed partial class IntercomMenu : FancyWindow private readonly List _channels = new(); - public IntercomMenu() + public IntercomMenu(Entity entity) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); MicButton.OnPressed += args => OnMicPressed?.Invoke(args.Button.Pressed); SpeakerButton.OnPressed += args => OnSpeakerPressed?.Invoke(args.Button.Pressed); + + Update(entity); } public void Update(Entity entity) diff --git a/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs b/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs index 9641adb5b2d..c14a8c5bd05 100644 --- a/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs +++ b/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs @@ -1,7 +1,5 @@ using Content.Shared.Research; using Content.Shared.Research.Components; -using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Research.UI { @@ -18,7 +16,10 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new(); + + _menu.OnClose += Close; + _menu.OpenCentered(); _menu.OnServerButtonPressed += () => { @@ -30,6 +31,14 @@ protected override void Open() }; } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + _menu?.Close(); + } + protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); diff --git a/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs b/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs index 288445e4dea..a0a2b58e889 100644 --- a/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs +++ b/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs @@ -1,6 +1,4 @@ using Content.Shared.Research.Components; -using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Research.UI { @@ -17,9 +15,10 @@ public ResearchClientBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.OnServerSelected += SelectServer; - _menu.OnServerDeselected += DeselectServer; + + _menu = new ResearchClientServerSelectionMenu(this); + _menu.OnClose += Close; + _menu.OpenCentered(); } public void SelectServer(int serverId) @@ -38,5 +37,12 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not ResearchClientBoundInterfaceState rState) return; _menu?.Populate(rState.ServerCount, rState.ServerNames, rState.ServerIds, rState.SelectedServerId); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + _menu?.Dispose(); + } } } diff --git a/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs b/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs index d10f8b39f48..ceaa965e59f 100644 --- a/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs +++ b/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs @@ -13,26 +13,27 @@ public sealed partial class ResearchClientServerSelectionMenu : DefaultWindow private int[] _serverIds = Array.Empty(); private int _selectedServerId = -1; - public event Action? OnServerSelected; - public event Action? OnServerDeselected; + private ResearchClientBoundUserInterface Owner { get; } - public ResearchClientServerSelectionMenu() + public ResearchClientServerSelectionMenu(ResearchClientBoundUserInterface owner) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); + Owner = owner; + Servers.OnItemSelected += OnItemSelected; Servers.OnItemDeselected += OnItemDeselected; } public void OnItemSelected(ItemList.ItemListSelectedEventArgs itemListSelectedEventArgs) { - OnServerSelected?.Invoke(_serverIds[itemListSelectedEventArgs.ItemIndex]); + Owner.SelectServer(_serverIds[itemListSelectedEventArgs.ItemIndex]); } public void OnItemDeselected(ItemList.ItemListDeselectedEventArgs itemListDeselectedEventArgs) { - OnServerDeselected?.Invoke(); + Owner.DeselectServer(); } public void Populate(int serverCount, string[] serverNames, int[] serverIds, int selectedServerId) diff --git a/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs b/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs index 2895ada61fb..2a9782045b8 100644 --- a/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs +++ b/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs @@ -1,8 +1,5 @@ using Content.Shared.Research.Components; -using Content.Shared.Research.Prototypes; using JetBrains.Annotations; -using Robust.Client.UserInterface; -using Robust.Shared.Prototypes; namespace Content.Client.Research.UI; @@ -22,8 +19,7 @@ protected override void Open() var owner = Owner; - _consoleMenu = this.CreateWindow(); - _consoleMenu.SetEntity(owner); + _consoleMenu = new ResearchConsoleMenu(owner); _consoleMenu.OnTechnologyCardPressed += id => { @@ -34,20 +30,10 @@ protected override void Open() { SendMessage(new ConsoleServerSelectionMessage()); }; - } - - public override void OnProtoReload(PrototypesReloadedEventArgs args) - { - base.OnProtoReload(args); - - if (!args.WasModified()) - return; - if (State is not ResearchConsoleBoundInterfaceState rState) - return; + _consoleMenu.OnClose += Close; - _consoleMenu?.UpdatePanels(rState); - _consoleMenu?.UpdateInformationPanel(rState); + _consoleMenu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -59,4 +45,12 @@ protected override void UpdateState(BoundUserInterfaceState state) _consoleMenu?.UpdatePanels(castState); _consoleMenu?.UpdateInformationPanel(castState); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + _consoleMenu?.Dispose(); + } } diff --git a/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs b/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs index eafbe75fbb9..77ebe6740c5 100644 --- a/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs +++ b/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs @@ -25,13 +25,14 @@ public sealed partial class ResearchConsoleMenu : FancyWindow [Dependency] private readonly IEntityManager _entity = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IPlayerManager _player = default!; + private readonly TechnologyDatabaseComponent? _technologyDatabase; private readonly ResearchSystem _research; private readonly SpriteSystem _sprite; private readonly AccessReaderSystem _accessReader; - public EntityUid Entity; + public readonly EntityUid Entity; - public ResearchConsoleMenu() + public ResearchConsoleMenu(EntityUid entity) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -39,23 +40,21 @@ public ResearchConsoleMenu() _research = _entity.System(); _sprite = _entity.System(); _accessReader = _entity.System(); + Entity = entity; ServerButton.OnPressed += _ => OnServerButtonPressed?.Invoke(); - } - public void SetEntity(EntityUid entity) - { - Entity = entity; + _entity.TryGetComponent(entity, out _technologyDatabase); } - public void UpdatePanels(ResearchConsoleBoundInterfaceState state) + public void UpdatePanels(ResearchConsoleBoundInterfaceState state) { TechnologyCardsContainer.Children.Clear(); var availableTech = _research.GetAvailableTechnologies(Entity); SyncTechnologyList(AvailableCardsContainer, availableTech); - if (!_entity.TryGetComponent(Entity, out TechnologyDatabaseComponent? database)) + if (_technologyDatabase == null) return; // i can't figure out the spacing so here you go @@ -67,7 +66,7 @@ public void UpdatePanels(ResearchConsoleBoundInterfaceState state) var hasAccess = _player.LocalEntity is not { } local || !_entity.TryGetComponent(Entity, out var access) || _accessReader.IsAllowed(local, Entity, access); - foreach (var techId in database.CurrentTechnologyCards) + foreach (var techId in _technologyDatabase.CurrentTechnologyCards) { var tech = _prototype.Index(techId); var cardControl = new TechnologyCardControl(tech, _prototype, _sprite, _research.GetTechnologyDescription(tech, includeTier: false), state.Points, hasAccess); @@ -75,7 +74,7 @@ public void UpdatePanels(ResearchConsoleBoundInterfaceState state) TechnologyCardsContainer.AddChild(cardControl); } - var unlockedTech = database.UnlockedTechnologies.Select(x => _prototype.Index(x)); + var unlockedTech = _technologyDatabase.UnlockedTechnologies.Select(x => _prototype.Index(x)); SyncTechnologyList(UnlockedCardsContainer, unlockedTech); } @@ -86,14 +85,14 @@ public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state) ("points", state.Points))); ResearchAmountLabel.SetMessage(amountMsg); - if (!_entity.TryGetComponent(Entity, out TechnologyDatabaseComponent? database)) + if (_technologyDatabase == null) return; var disciplineText = Loc.GetString("research-discipline-none"); var disciplineColor = Color.Gray; - if (database.MainDiscipline != null) + if (_technologyDatabase.MainDiscipline != null) { - var discipline = _prototype.Index(database.MainDiscipline); + var discipline = _prototype.Index(_technologyDatabase.MainDiscipline); disciplineText = Loc.GetString(discipline.Name); disciplineColor = discipline.Color; } @@ -104,10 +103,10 @@ public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state) MainDisciplineLabel.SetMessage(msg); TierDisplayContainer.Children.Clear(); - foreach (var disciplineId in database.SupportedDisciplines) + foreach (var disciplineId in _technologyDatabase.SupportedDisciplines) { var discipline = _prototype.Index(disciplineId); - var tier = _research.GetHighestDisciplineTier(database, discipline); + var tier = _research.GetHighestDisciplineTier(_technologyDatabase, discipline); // don't show tiers with no available tech if (tier == 0) diff --git a/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs b/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs index 9a5159880f9..6185979eee6 100644 --- a/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs +++ b/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Robotics; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Robotics.UI; @@ -17,9 +16,7 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.SetEntity(Owner); - + _window = new RoboticsConsoleWindow(Owner); _window.OnDisablePressed += address => { SendMessage(new RoboticsConsoleDisableMessage(address)); @@ -28,6 +25,9 @@ protected override void Open() { SendMessage(new RoboticsConsoleDestroyMessage(address)); }; + _window.OnClose += Close; + + _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -37,6 +37,14 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not RoboticsConsoleState cast) return; - _window.UpdateState(cast); + _window?.UpdateState(cast); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + _window?.Dispose(); } } diff --git a/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs b/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs index 87d7e62c392..fc7b234bccc 100644 --- a/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs +++ b/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs @@ -23,12 +23,11 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow public Action? OnDisablePressed; public Action? OnDestroyPressed; + private Entity _console; private string? _selected; private Dictionary _cyborgs = new(); - public EntityUid Entity; - - public RoboticsConsoleWindow() + public RoboticsConsoleWindow(EntityUid console) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -36,6 +35,9 @@ public RoboticsConsoleWindow() _lock = _entMan.System(); _sprite = _entMan.System(); + _console = (console, _entMan.GetComponent(console), null); + _entMan.TryGetComponent(_console, out _console.Comp2); + Cyborgs.OnItemSelected += args => { if (Cyborgs[args.ItemIndex].Metadata is not string address) @@ -64,11 +66,6 @@ public RoboticsConsoleWindow() DestroyButton.StyleClasses.Add(StyleBase.ButtonCaution); } - public void SetEntity(EntityUid uid) - { - Entity = uid; - } - public void UpdateState(RoboticsConsoleState state) { _cyborgs = state.Cyborgs; @@ -84,7 +81,7 @@ public void UpdateState(RoboticsConsoleState state) PopulateData(); - var locked = _lock.IsLocked(Entity); + var locked = _lock.IsLocked((_console, _console.Comp2)); DangerZone.Visible = !locked; LockedMessage.Visible = locked; } @@ -138,19 +135,13 @@ private void PopulateData() // how the turntables DisableButton.Disabled = !(data.HasBrain && data.CanDisable); + DestroyButton.Disabled = _timing.CurTime < _console.Comp1.NextDestroy; } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - if (_entMan.TryGetComponent(Entity, out RoboticsConsoleComponent? console)) - { - DestroyButton.Disabled = _timing.CurTime < console.NextDestroy; - } - else - { - DestroyButton.Disabled = true; - } + DestroyButton.Disabled = _timing.CurTime < _console.Comp1.NextDestroy; } } diff --git a/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs b/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs index 663bde15b0d..8f1723d1f22 100644 --- a/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs +++ b/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs @@ -30,9 +30,17 @@ public SalvageExpeditionConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new OfferingWindow(); _window.Title = Loc.GetString("salvage-expedition-window-title"); - _window.OpenCenteredLeft(); + _window.OnClose += Close; + _window?.OpenCenteredLeft(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + _window?.Dispose(); + _window = null; } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs b/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs index a248126a855..eafb692733f 100644 --- a/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs +++ b/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs @@ -21,9 +21,13 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.Title = Loc.GetString("salvage-magnet-window-title"); - _window.OpenCenteredLeft(); + if (_window is null) + { + _window = new OfferingWindow(); + _window.Title = Loc.GetString("salvage-magnet-window-title"); + _window.OnClose += Close; + _window.OpenCenteredLeft(); + } } protected override void UpdateState(BoundUserInterfaceState state) @@ -108,4 +112,15 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.AddOption(option); } } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + _window?.Close(); + _window?.Dispose(); + } + } } diff --git a/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs index b8b4fb8a746..086369aa264 100644 --- a/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs @@ -3,7 +3,6 @@ using Content.Shared.Shuttles.Events; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Shuttles.BUI; @@ -21,7 +20,8 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new IFFConsoleWindow(); + _window.OnClose += Close; _window.ShowIFF += SendIFFMessage; _window.ShowVessel += SendVesselMessage; _window.OpenCenteredLeft(); diff --git a/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs index f75759b042f..4bd44a47a8e 100644 --- a/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Shuttles.BUIStates; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using RadarConsoleWindow = Content.Client.Shuttles.UI.RadarConsoleWindow; namespace Content.Client.Shuttles.BUI; @@ -21,7 +20,18 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new RadarConsoleWindow(); + _window.OnClose += Close; + _window.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + { + _window?.Dispose(); + } } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs index e677181419e..af7b6055c80 100644 --- a/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Events; using JetBrains.Annotations; -using Robust.Client.UserInterface; using Robust.Shared.Map; namespace Content.Client.Shuttles.BUI; @@ -20,7 +19,9 @@ public ShuttleConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new ShuttleConsoleWindow(); + _window.OpenCentered(); + _window.OnClose += Close; _window.RequestFTL += OnFTLRequest; _window.RequestBeaconFTL += OnFTLBeaconRequest; diff --git a/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs b/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs index ed9bf40a481..3cc2a35d795 100644 --- a/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs +++ b/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Silicons.Borgs; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Silicons.Borgs; @@ -19,8 +18,9 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.SetEntity(Owner); + var owner = Owner; + + _menu = new BorgMenu(owner); _menu.BrainButtonPressed += () => { @@ -41,6 +41,10 @@ protected override void Open() { SendMessage(new BorgRemoveModuleBuiMessage(EntMan.GetNetEntity(module))); }; + + _menu.OnClose += Close; + + _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -51,4 +55,12 @@ protected override void UpdateState(BoundUserInterfaceState state) return; _menu?.UpdateState(msg); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + _menu?.Dispose(); + } } diff --git a/Content.Client/Silicons/Borgs/BorgMenu.xaml b/Content.Client/Silicons/Borgs/BorgMenu.xaml index 4cc2e41a8fb..7d8fd9fe57d 100644 --- a/Content.Client/Silicons/Borgs/BorgMenu.xaml +++ b/Content.Client/Silicons/Borgs/BorgMenu.xaml @@ -10,7 +10,7 @@ VerticalExpand="True"> - + diff --git a/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs b/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs index f6a861aa057..474a83b4530 100644 --- a/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs +++ b/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs @@ -21,33 +21,25 @@ public sealed partial class BorgMenu : FancyWindow public Action? NameChanged; public Action? RemoveModuleButtonPressed; + private readonly BorgChassisComponent? _chassis; + public readonly EntityUid Entity; public float AccumulatedTime; private string _lastValidName; private List _modules = new(); - public EntityUid Entity; - - public BorgMenu() + public BorgMenu(EntityUid entity) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - _lastValidName = NameLineEdit.Text; - - EjectBatteryButton.OnPressed += _ => EjectBatteryButtonPressed?.Invoke(); - BrainButton.OnPressed += _ => BrainButtonPressed?.Invoke(); - - NameLineEdit.OnTextChanged += OnNameChanged; - NameLineEdit.OnTextEntered += OnNameEntered; - NameLineEdit.OnFocusExit += OnNameFocusExit; + Entity = entity; - UpdateBrainButton(); - } + if (_entity.TryGetComponent(Entity, out var chassis)) + _chassis = chassis; - public void SetEntity(EntityUid entity) - { - Entity = entity; BorgSprite.SetEntity(entity); + ChargeBar.MaxValue = 1f; + ChargeBar.Value = 1f; if (_entity.TryGetComponent(Entity, out var nameIdentifierComponent)) { @@ -63,6 +55,17 @@ public void SetEntity(EntityUid entity) NameIdentifierLabel.Visible = false; NameLineEdit.Text = _entity.GetComponent(Entity).EntityName; } + + _lastValidName = NameLineEdit.Text; + + EjectBatteryButton.OnPressed += _ => EjectBatteryButtonPressed?.Invoke(); + BrainButton.OnPressed += _ => BrainButtonPressed?.Invoke(); + + NameLineEdit.OnTextChanged += OnNameChanged; + NameLineEdit.OnTextEntered += OnNameEntered; + NameLineEdit.OnFocusExit += OnNameFocusExit; + + UpdateBrainButton(); } protected override void FrameUpdate(FrameEventArgs args) @@ -86,7 +89,7 @@ public void UpdateState(BorgBuiState state) private void UpdateBrainButton() { - if (_entity.TryGetComponent(Entity, out BorgChassisComponent? chassis) && chassis.BrainEntity is { } brain) + if (_chassis?.BrainEntity is { } brain) { BrainButton.Text = _entity.GetComponent(brain).EntityName; BrainView.Visible = true; @@ -105,17 +108,17 @@ private void UpdateBrainButton() private void UpdateModulePanel() { - if (!_entity.TryGetComponent(Entity, out BorgChassisComponent? chassis)) + if (_chassis == null) return; ModuleCounter.Text = Loc.GetString("borg-ui-module-counter", - ("actual", chassis.ModuleCount), - ("max", chassis.MaxModules)); + ("actual", _chassis.ModuleCount), + ("max", _chassis.MaxModules)); - if (chassis.ModuleContainer.Count == _modules.Count) + if (_chassis.ModuleContainer.Count == _modules.Count) { var isSame = true; - foreach (var module in chassis.ModuleContainer.ContainedEntities) + foreach (var module in _chassis.ModuleContainer.ContainedEntities) { if (_modules.Contains(module)) continue; @@ -129,7 +132,7 @@ private void UpdateModulePanel() ModuleContainer.Children.Clear(); _modules.Clear(); - foreach (var module in chassis.ModuleContainer.ContainedEntities) + foreach (var module in _chassis.ModuleContainer.ContainedEntities) { var control = new BorgModuleControl(module, _entity); control.RemoveButtonPressed += () => diff --git a/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs b/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs index 56216b91847..d150735fa11 100644 --- a/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs +++ b/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.Silicons.Laws; using Content.Shared.Silicons.Laws.Components; using JetBrains.Annotations; -using Robust.Client.UserInterface; namespace Content.Client.Silicons.Laws.Ui; @@ -23,7 +22,18 @@ protected override void Open() { base.Open(); - _menu = this.CreateWindow(); + _menu = new(); + + _menu.OnClose += Close; + _menu.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + _menu?.Close(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs b/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs index 7d6a6cf2a5a..e8442d23908 100644 --- a/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs +++ b/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.SprayPainter; using Content.Shared.SprayPainter.Components; -using Robust.Client.UserInterface; +using Robust.Client.GameObjects; using Robust.Client.UserInterface.Controls; namespace Content.Client.SprayPainter.UI; @@ -10,6 +10,9 @@ public sealed class SprayPainterBoundUserInterface : BoundUserInterface [ViewVariables] private SprayPainterWindow? _window; + [ViewVariables] + private SprayPainterSystem? _painter; + public SprayPainterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -18,15 +21,27 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + if (!EntMan.TryGetComponent(Owner, out var comp)) + return; + + _window = new SprayPainterWindow(); + _painter = EntMan.System(); + + _window.OnClose += Close; _window.OnSpritePicked = OnSpritePicked; _window.OnColorPicked = OnColorPicked; - if (EntMan.TryGetComponent(Owner, out SprayPainterComponent? comp)) - { - _window.Populate(EntMan.System().Entries, comp.Index, comp.PickedColor, comp.ColorPalette); - } + _window.Populate(_painter.Entries, comp.Index, comp.PickedColor, comp.ColorPalette); + + _window.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + _window?.Dispose(); } private void OnSpritePicked(ItemList.ItemListSelectedEventArgs args) diff --git a/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs b/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs index e7bab71e38e..720a2efb9dd 100644 --- a/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs +++ b/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs @@ -1,5 +1,4 @@ using Content.Shared.StationRecords; -using Robust.Client.UserInterface; namespace Content.Client.StationRecords; @@ -16,12 +15,15 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new(); _window.OnKeySelected += key => SendMessage(new SelectStationRecord(key)); _window.OnFiltersChanged += (type, filterValue) => SendMessage(new SetStationRecordFilter(type, filterValue)); _window.OnDeleted += id => SendMessage(new DeleteStationRecord(id)); + _window.OnClose += Close; + + _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -33,4 +35,11 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + _window?.Close(); + } } diff --git a/Content.Client/Store/Ui/StoreBoundUserInterface.cs b/Content.Client/Store/Ui/StoreBoundUserInterface.cs index 7ed67f7b5dd..0010aedd964 100644 --- a/Content.Client/Store/Ui/StoreBoundUserInterface.cs +++ b/Content.Client/Store/Ui/StoreBoundUserInterface.cs @@ -2,7 +2,6 @@ using JetBrains.Annotations; using System.Linq; using Content.Shared.Store.Components; -using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Store.Ui; @@ -27,10 +26,13 @@ public StoreBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) protected override void Open() { - _menu = this.CreateWindow(); + _menu = new StoreMenu(); if (EntMan.TryGetComponent(Owner, out var store)) _menu.Title = Loc.GetString(store.Name); + _menu.OpenCentered(); + _menu.OnClose += Close; + _menu.OnListingButtonPressed += (_, listing) => { SendMessage(new StoreBuyListingMessage(listing)); @@ -75,6 +77,15 @@ protected override void UpdateState(BoundUserInterfaceState state) } } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + _menu?.Close(); + _menu?.Dispose(); + } + private void UpdateListingsWithSearchFilter() { if (_menu == null) diff --git a/Content.Client/Strip/StrippingMenu.cs b/Content.Client/Strip/StrippingMenu.cs index 1c46b4be35c..eea867b7948 100644 --- a/Content.Client/Strip/StrippingMenu.cs +++ b/Content.Client/Strip/StrippingMenu.cs @@ -1,3 +1,4 @@ +using Content.Client.Inventory; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Timing; @@ -10,12 +11,14 @@ public sealed class StrippingMenu : DefaultWindow public LayoutContainer InventoryContainer = new(); public BoxContainer HandsContainer = new() { Orientation = LayoutOrientation.Horizontal }; public BoxContainer SnareContainer = new(); + private StrippableBoundUserInterface _bui; public bool Dirty = true; - public event Action? OnDirty; - - public StrippingMenu() + public StrippingMenu(string title, StrippableBoundUserInterface bui) { + Title = title; + _bui = bui; + var box = new BoxContainer() { Orientation = LayoutOrientation.Vertical, Margin = new Thickness(0, 8) }; Contents.AddChild(box); box.AddChild(SnareContainer); @@ -36,7 +39,7 @@ protected override void FrameUpdate(FrameEventArgs args) return; Dirty = false; - OnDirty?.Invoke(); + _bui.UpdateMenu(); } } } diff --git a/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs b/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs index e3646c00cc3..9132dd6ed5f 100644 --- a/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs +++ b/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs @@ -1,7 +1,6 @@ using Content.Client.Eye; using Content.Shared.SurveillanceCamera; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.SurveillanceCamera.UI; @@ -26,12 +25,20 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new SurveillanceCameraMonitorWindow(); + + if (State != null) + { + UpdateState(State); + } + + _window.OpenCentered(); _window.CameraSelected += OnCameraSelected; _window.SubnetOpened += OnSubnetRequest; _window.CameraRefresh += OnCameraRefresh; _window.SubnetRefresh += OnSubnetRefresh; + _window.OnClose += Close; _window.CameraSwitchTimer += OnCameraSwitchTimer; _window.CameraDisconnect += OnCameraDisconnect; } diff --git a/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs b/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs index 0631d98993a..37384daafef 100644 --- a/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs +++ b/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Thief; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Thief; @@ -16,9 +15,21 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.OnApprove += SendApprove; - _window.OnSetChange += SendChangeSelected; + _window = new ThiefBackpackMenu(this); + _window.OnClose += Close; + _window.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + if (_window != null) + _window.OnClose -= Close; + + _window?.Dispose(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Thief/ThiefBackpackMenu.xaml.cs b/Content.Client/Thief/ThiefBackpackMenu.xaml.cs index aaee3576174..543772c704c 100644 --- a/Content.Client/Thief/ThiefBackpackMenu.xaml.cs +++ b/Content.Client/Thief/ThiefBackpackMenu.xaml.cs @@ -12,42 +12,46 @@ public sealed partial class ThiefBackpackMenu : FancyWindow [Dependency] private readonly IEntitySystemManager _sysMan = default!; private readonly SpriteSystem _spriteSystem; - public event Action? OnApprove; - public event Action? OnSetChange; + private readonly ThiefBackpackBoundUserInterface _owner; - public ThiefBackpackMenu() + public ThiefBackpackMenu(ThiefBackpackBoundUserInterface owner) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); _spriteSystem = _sysMan.GetEntitySystem(); - ApproveButton.OnPressed += args => + _owner = owner; + + ApproveButton.OnButtonDown += (args) => { - OnApprove?.Invoke(); + _owner.SendApprove(); }; } public void UpdateState(ThiefBackpackBoundUserInterfaceState state) { - SetsGrid.DisposeAllChildren(); - var selectedNumber = 0; - foreach (var (set, info) in state.Sets) + SetsGrid.RemoveAllChildren(); + int count = 0; + int selectedNumber = 0; + foreach (var set in state.Sets) { - var child = new ThiefBackpackSet(info, _spriteSystem); + var child = new ThiefBackpackSet(set.Value, _spriteSystem); child.SetButton.OnButtonDown += (args) => { - OnSetChange?.Invoke(set); + _owner.SendChangeSelected(set.Key); }; SetsGrid.AddChild(child); - if (info.Selected) + count++; + + if (set.Value.Selected) selectedNumber++; } Description.Text = Loc.GetString("thief-backpack-window-description", ("maxCount", state.MaxSelectedSets)); SelectedSets.Text = Loc.GetString("thief-backpack-window-selected", ("selectedCount", selectedNumber), ("maxCount", state.MaxSelectedSets)); - ApproveButton.Disabled = selectedNumber != state.MaxSelectedSets; + ApproveButton.Disabled = selectedNumber == state.MaxSelectedSets ? false : true; } } diff --git a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs index 4ae74a5d65e..4702f8f3659 100644 --- a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs +++ b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs @@ -1,7 +1,5 @@ using Content.Shared.Atmos.Components; using JetBrains.Annotations; -using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.UserInterface.Systems.Atmos.GasTank { @@ -15,7 +13,7 @@ public GasTankBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKe { } - public void SetOutputPressure(float value) + public void SetOutputPressure(in float value) { SendMessage(new GasTankSetPressureMessage { @@ -31,10 +29,9 @@ public void ToggleInternals() protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.SetTitle(EntMan.GetComponent(Owner).EntityName); - _window.OnOutputPressure += SetOutputPressure; - _window.OnToggleInternals += ToggleInternals; + _window = new GasTankWindow(this, EntMan.GetComponent(Owner).EntityName); + _window.OnClose += Close; + _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs index 12eeaa55de9..c23850a6503 100644 --- a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs +++ b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs @@ -15,28 +15,23 @@ namespace Content.Client.UserInterface.Systems.Atmos.GasTank; public sealed class GasTankWindow : BaseWindow { - [Dependency] private readonly IResourceCache _cache = default!; - private readonly RichTextLabel _lblPressure; private readonly FloatSpinBox _spbPressure; private readonly RichTextLabel _lblInternals; private readonly Button _btnInternals; - private readonly Label _topLabel; - - public event Action? OnOutputPressure; - public event Action? OnToggleInternals; - public GasTankWindow() + public GasTankWindow(GasTankBoundUserInterface owner, string uidName) { Control contentContainer; BoxContainer topContainer; TextureButton btnClose; + var resourceCache = IoCManager.Resolve(); var rootContainer = new LayoutContainer { Name = "GasTankRoot" }; AddChild(rootContainer); MouseFilter = MouseFilterMode.Stop; - var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); + var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); var back = new StyleBoxTexture { Texture = panelTex, @@ -83,17 +78,7 @@ public GasTankWindow() LayoutContainer.SetAnchorPreset(topContainerWrap, LayoutContainer.LayoutPreset.Wide); - var font = _cache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); - - _topLabel = new Label - { - FontOverride = font, - FontColorOverride = StyleNano.NanoGold, - VerticalAlignment = VAlignment.Center, - HorizontalExpand = true, - HorizontalAlignment = HAlignment.Left, - Margin = new Thickness(0, 0, 20, 0), - }; + var font = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); var topRow = new BoxContainer { @@ -101,7 +86,16 @@ public GasTankWindow() Margin = new Thickness(4, 2, 12, 2), Children = { - _topLabel, + (new Label + { + Text = uidName, + FontOverride = font, + FontColorOverride = StyleNano.NanoGold, + VerticalAlignment = VAlignment.Center, + HorizontalExpand = true, + HorizontalAlignment = HAlignment.Left, + Margin = new Thickness(0, 0, 20, 0), + }), (btnClose = new TextureButton { StyleClasses = {DefaultWindow.StyleClassWindowCloseButton}, @@ -174,22 +168,17 @@ public GasTankWindow() // Handlers _spbPressure.OnValueChanged += args => { - OnOutputPressure?.Invoke(args.Value); + owner.SetOutputPressure(args.Value); }; _btnInternals.OnPressed += args => { - OnToggleInternals?.Invoke(); + owner.ToggleInternals(); }; btnClose.OnPressed += _ => Close(); } - public void SetTitle(string name) - { - _topLabel.Text = name; - } - public void UpdateState(GasTankBoundUserInterfaceState state) { _lblPressure.SetMarkup(Loc.GetString("gas-tank-window-tank-pressure-text", ("tankPressure", $"{state.TankPressure:0.##}"))); diff --git a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs index eafab84ed63..17ddba77ffc 100644 --- a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs +++ b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs @@ -2,7 +2,6 @@ using Content.Shared.VendingMachines; using Robust.Client.UserInterface.Controls; using System.Linq; -using Robust.Client.UserInterface; namespace Content.Client.VendingMachines { @@ -29,14 +28,15 @@ protected override void Open() _cachedInventory = vendingMachineSys.GetAllInventory(Owner); - _menu = this.CreateWindow(); - _menu.OpenCenteredLeft(); - _menu.Title = EntMan.GetComponent(Owner).EntityName; + _menu = new VendingMachineMenu { Title = EntMan.GetComponent(Owner).EntityName }; + _menu.OnClose += Close; _menu.OnItemSelected += OnItemSelected; _menu.OnSearchChanged += OnSearchChanged; _menu.Populate(_cachedInventory, out _cachedFilteredIndex); + + _menu.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs b/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs index 891804674d3..f700c6663b9 100644 --- a/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs +++ b/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs @@ -1,13 +1,12 @@ using Content.Shared.VoiceMask; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.VoiceMask; public sealed class VoiceMaskBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _protomanager = default!; + [Dependency] private readonly IPrototypeManager _proto = default!; [ViewVariables] private VoiceMaskNameChangeWindow? _window; @@ -20,11 +19,12 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); - _window.ReloadVerbs(_protomanager); + _window = new(_proto); + _window.OpenCentered(); _window.OnNameChange += OnNameSelected; _window.OnVerbChange += verb => SendMessage(new VoiceMaskChangeVerbMessage(verb)); + _window.OnClose += Close; } private void OnNameSelected(string name) diff --git a/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs b/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs index 0dc41f807ab..16a28f9d9b3 100644 --- a/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs +++ b/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs @@ -17,7 +17,7 @@ public sealed partial class VoiceMaskNameChangeWindow : FancyWindow private string? _verb; - public VoiceMaskNameChangeWindow() + public VoiceMaskNameChangeWindow(IPrototypeManager proto) { RobustXamlLoader.Load(this); @@ -32,10 +32,12 @@ public VoiceMaskNameChangeWindow() SpeechVerbSelector.SelectId(args.Id); }; + ReloadVerbs(proto); + AddVerbs(); } - public void ReloadVerbs(IPrototypeManager proto) + private void ReloadVerbs(IPrototypeManager proto) { foreach (var verb in proto.EnumeratePrototypes()) { diff --git a/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs b/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs index 3f01808c422..f3e0c0a539a 100644 --- a/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs +++ b/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs @@ -1,6 +1,5 @@ using Robust.Client.GameObjects; using Content.Shared.Speech.Components; -using Robust.Client.UserInterface; namespace Content.Client.Weapons.Melee.UI; @@ -20,10 +19,17 @@ protected override void Open() { base.Open(); - _window = this.CreateWindow(); + _window = new MeleeSpeechWindow(); + if (State != null) + UpdateState(State); + + _window.OpenCentered(); + + _window.OnClose += Close; _window.OnBattlecryEntered += OnBattlecryChanged; } + private void OnBattlecryChanged(string newBattlecry) { SendMessage(new MeleeSpeechBattlecryChangedMessage(newBattlecry)); diff --git a/Content.Client/Wires/UI/WiresBoundUserInterface.cs b/Content.Client/Wires/UI/WiresBoundUserInterface.cs index edf1a2d3770..5a8869a204e 100644 --- a/Content.Client/Wires/UI/WiresBoundUserInterface.cs +++ b/Content.Client/Wires/UI/WiresBoundUserInterface.cs @@ -1,6 +1,5 @@ using Content.Shared.Wires; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Wires.UI { @@ -16,8 +15,10 @@ public WiresBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) protected override void Open() { base.Open(); - _menu = this.CreateWindow(); - _menu.OnAction += PerformAction; + + _menu = new WiresMenu(this); + _menu.OnClose += Close; + _menu.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Wires/UI/WiresMenu.cs b/Content.Client/Wires/UI/WiresMenu.cs index eccc548297c..7bccc208616 100644 --- a/Content.Client/Wires/UI/WiresMenu.cs +++ b/Content.Client/Wires/UI/WiresMenu.cs @@ -1,3 +1,4 @@ +using System; using System.Numerics; using Content.Client.Examine; using Content.Client.Resources; @@ -11,6 +12,10 @@ using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Animations; using Robust.Shared.Input; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Maths; +using Robust.Shared.Random; using static Robust.Client.UserInterface.Controls.BoxContainer; namespace Content.Client.Wires.UI @@ -19,6 +24,8 @@ public sealed class WiresMenu : BaseWindow { [Dependency] private readonly IResourceCache _resourceCache = default!; + public WiresBoundUserInterface Owner { get; } + private readonly Control _wiresHBox; private readonly Control _topContainer; private readonly Control _statusContainer; @@ -28,12 +35,11 @@ public sealed class WiresMenu : BaseWindow public TextureButton CloseButton { get; set; } - public event Action? OnAction; - - public WiresMenu() + public WiresMenu(WiresBoundUserInterface owner) { IoCManager.InjectDependencies(this); + Owner = owner; var rootContainer = new LayoutContainer {Name = "WireRoot"}; AddChild(rootContainer); @@ -251,12 +257,12 @@ public void Populate(WiresBoundUserInterfaceState state) control.WireClicked += () => { - OnAction?.Invoke(wire.Id, wire.IsCut ? WiresAction.Mend : WiresAction.Cut); + Owner.PerformAction(wire.Id, wire.IsCut ? WiresAction.Mend : WiresAction.Cut); }; control.ContactsClicked += () => { - OnAction?.Invoke(wire.Id, WiresAction.Pulse); + Owner.PerformAction(wire.Id, WiresAction.Pulse); }; } diff --git a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs index c7a74815b6b..2538caf6eb8 100644 --- a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs +++ b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs @@ -1,7 +1,6 @@ using Content.Shared.Xenoarchaeology.Equipment; using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.UserInterface; namespace Content.Client.Xenoarchaeology.Ui; @@ -19,7 +18,10 @@ protected override void Open() { base.Open(); - _consoleMenu = this.CreateWindow(); + _consoleMenu = new AnalysisConsoleMenu(); + + _consoleMenu.OnClose += Close; + _consoleMenu.OpenCentered(); _consoleMenu.OnServerSelectionButtonPressed += () => { From 6b57cf202062de26f2b4c92292a2e58b268d328e Mon Sep 17 00:00:00 2001 From: buntobaggins <113877683+buntobaggins@users.noreply.github.com> Date: Sat, 20 Jul 2024 20:29:21 -0700 Subject: [PATCH 093/134] Spationaut Hardsuit Light buff (#30049) Buffed the light on the Spationaut Hardsuit Co-authored-by: buntobaggins --- .../Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml index 7f0c0573005..ffa5747e871 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml @@ -111,6 +111,8 @@ - state: equipped-head - state: equipped-head-unshaded shader: unshaded + - type: PointLight + radius: 6 - type: PressureProtection highPressureMultiplier: 0.72 lowPressureMultiplier: 1000 From 87e52e50b4b353bfc2721bf243bc0ffe1f8264b9 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 21 Jul 2024 03:30:29 +0000 Subject: [PATCH 094/134] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index ed8f51b7865..1ed3320d344 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: metalgearsloth - changes: - - message: Add predicted UI opening for storage and PDAs. - type: Add - id: 6443 - time: '2024-04-26T08:16:24.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27214 - author: DrSmugleaf changes: - message: Fixed mobs that are able to pry doors not being able to do so by just @@ -3798,3 +3791,10 @@ id: 6942 time: '2024-07-20T05:53:58.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28748 +- author: buntobaggins + changes: + - message: Increased light radius on the Spationaut Hardsuit + type: Tweak + id: 6943 + time: '2024-07-21T03:29:21.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30049 From ad11a227662787531d3f0222a8acd8713d1047fd Mon Sep 17 00:00:00 2001 From: Morb0 <14136326+Morb0@users.noreply.github.com> Date: Sun, 21 Jul 2024 07:47:45 +0300 Subject: [PATCH 095/134] Update locale --- .../catalog/fills/backpacks/duffelbag.ftl | 2 + .../corvax/entities/clothing/neck/pins.ftl | 18 +++++ .../entities/clothing/head/helmets.ftl | 2 + .../entities/clothing/outerclothing/armor.ftl | 2 + .../piping/atmospherics/special.ftl | 2 + .../structures/wallmounts/signs/signs.ftl | 66 ++++++++----------- .../ru-RU/administration/commands/aghost.ftl | 2 +- .../administration/commands/babyjail.ftl | 16 +++++ .../administration/ui/admin-menu-window.ftl | 1 + .../administration/ui/tabs/babyjail-tab.ftl | 11 ++++ .../Locale/ru-RU/connection-messages.ftl | 4 ++ .../health-examinable-carbon.ftl | 6 ++ .../interaction-popup-component.ftl | 14 ++++ .../components/health-analyzer-component.ftl | 1 + .../Locale/ru-RU/portal/swap-teleporter.ftl | 1 + Resources/Locale/ru-RU/replays/replays.ftl | 1 + .../catalog/fills/backpacks/duffelbag.ftl | 2 + .../corvax/entities/clothing/neck/pins.ftl | 18 +++++ .../entities/clothing/head/helmets.ftl | 2 + .../entities/clothing/outerclothing/armor.ftl | 2 + .../piping/atmospherics/special.ftl | 2 + .../structures/wallmounts/signs/signs.ftl | 46 +++++-------- .../ss14-ru/prototypes/gamerules/midround.ftl | 2 - .../Locale/ru-RU/store/uplink-catalog.ftl | 2 + 24 files changed, 156 insertions(+), 69 deletions(-) create mode 100644 Resources/Locale/ru-RU/administration/commands/babyjail.ftl create mode 100644 Resources/Locale/ru-RU/administration/ui/tabs/babyjail-tab.ftl diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl index 4501e009511..a8ec9b10d8b 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl @@ -33,6 +33,8 @@ ent-ClothingBackpackChameleonFill = { ent-ClothingBackpackChameleon } .desc = { ent-ClothingBackpackChameleon.desc } ent-ClothingBackpackDuffelSyndicateEVABundle = syndicate EVA bundle .desc = Contains the Syndicate approved EVA suit. +ent-ClothingBackpackDuffelSyndicateRaidBundle = syndicate raid suit bundle + .desc = Contains the Syndicate's durable raid armor suit. ent-ClothingBackpackDuffelSyndicateHardsuitBundle = syndicate hardsuit bundle .desc = Contains the Syndicate's signature blood red hardsuit. ent-ClothingBackpackDuffelSyndicateEliteHardsuitBundle = syndicate elite hardsuit bundle diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/corvax/entities/clothing/neck/pins.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/corvax/entities/clothing/neck/pins.ftl index bda84f5cada..aae7a2bdddf 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/corvax/entities/clothing/neck/pins.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/corvax/entities/clothing/neck/pins.ftl @@ -1,18 +1,36 @@ +ent-ClothingNeckAtharaPin = starry sky pin + .desc = The pin of starry sky. ent-ClothingNeckUSSPPin = USSP pin .desc = The pin of United Soviet Socialist Planet. +ent-ClothingNeckCorvaxPin = cluster pin + .desc = The pin of cluster. ent-ClothingNeckDonkPin = Donk pin .desc = The pin of corporation Donk Pocket. ent-ClothingNeckEarthPin = Earth pin .desc = The pin of United Earth Government. +ent-ClothingNeckEchoPin = comet pin + .desc = The pin of comet. +ent-ClothingNeckElysiumPin = dark planet pin + .desc = The pin of dark planet. ent-ClothingNeckLogistikaPin = logistika pin .desc = The pin of corporation Kosmologistika. +ent-ClothingNeckMainPin = rocket pin + .desc = The pin of rocket. ent-ClothingNeckDeForestPin = DeForest pin .desc = The pin of corporation DeForest. ent-ClothingNeckNakamuraPin = Nakamura pin .desc = The pin of corporation Nakamura engineering. ent-ClothingNeckNanoTrasenPin = NanoTrasen pin .desc = The pin of corporation NanoTrasen. +ent-ClothingNeckNebulaPin = nebula pin + .desc = The pin of nebula. +ent-ClothingNeckNovaPin = ring planet pin + .desc = The pin of ring planet. ent-ClothingNeckSyndicakePin = Syndicake pin .desc = The pin of Syndicakes, on backside have a little numbers "2559". +ent-ClothingNeckSolarisPin = space cheese pin + .desc = The pin of space cheese. ent-ClothingNeckVitezstviPin = Vitezstvi pin .desc = The pin of corporation Vitezstvi. +ent-ClothingNeckWhiteListPin = quasar pin + .desc = The pin of quasar. diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/head/helmets.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/head/helmets.ftl index 1fb5e78748d..9e8d4c7ed4b 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/head/helmets.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/head/helmets.ftl @@ -40,6 +40,8 @@ ent-ClothingHeadHelmetERTEngineer = ERT engineer helmet .desc = An in-atmosphere helmet worn by engineering members of the Nanotrasen Emergency Response Team. Has orange highlights. ent-ClothingHeadHelmetERTJanitor = ERT janitor helmet .desc = An in-atmosphere helmet worn by janitorial members of the Nanotrasen Emergency Response Team. Has dark purple highlights. +ent-ClothingHeadHelmetRaid = syndicate raid helmet + .desc = An armored helmet for use with the syndicate raid suit. Very stylish. ent-ClothingHeadHelmetBone = bone helmet .desc = Cool-looking helmet made of skull of your enemies. ent-ClothingHeadHelmetPodWars = ironclad II helmet diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/outerclothing/armor.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/outerclothing/armor.ftl index 9c65d555cb2..99ba03fb031 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/outerclothing/armor.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/clothing/outerclothing/armor.ftl @@ -9,6 +9,8 @@ ent-ClothingOuterArmorBulletproof = bulletproof vest .desc = A Type III heavy bulletproof vest that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent. ent-ClothingOuterArmorReflective = reflective vest .desc = An armored vest with advanced shielding to protect against energy weapons. +ent-ClothingOuterArmorRaid = syndicate raid suit + .desc = A somewhat flexible and well-armored suit with a powerful shoulder mounted flashlight manufactured in the Gorlex Marauder's iconic blood-red color scheme, it does not protect it's wearer from space. ent-ClothingOuterArmorCult = acolyte armor .desc = An evil-looking piece of cult armor, made of bones. ent-ClothingOuterArmorHeavy = heavy armor suit diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/piping/atmospherics/special.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/piping/atmospherics/special.ftl index 88e2e076c65..3244e7535e7 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/piping/atmospherics/special.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/piping/atmospherics/special.ftl @@ -1,2 +1,4 @@ ent-AtmosDeviceFanTiny = tiny fan .desc = A tiny fan, releasing a thin gust of air. +ent-AtmosDeviceFanDirectional = directional fan + .desc = A thin fan, stopping the movement of gases across it. diff --git a/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/wallmounts/signs/signs.ftl b/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/wallmounts/signs/signs.ftl index 0f95786a6f0..35c14a88174 100644 --- a/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/wallmounts/signs/signs.ftl +++ b/Resources/Locale/en-US/ss14-ru/prototypes/entities/structures/wallmounts/signs/signs.ftl @@ -52,22 +52,26 @@ ent-SignDirectionalWash = washroom sign .desc = A direction sign, pointing to the way to a washroom. ent-SignAi = ai sign .desc = A sign, indicating an AI is present. +ent-SignAiUpload = ai upload sign + .desc = A sign, indicating an AI is present. ent-SignArcade = arcade sign .desc = A sign indicating the arcade. ent-SignArmory = armory sign .desc = A sign indicating the armory. ent-SignToolStorage = tool storage sign .desc = A sign indicating the tool storage room. -ent-SignAnomaly = xenoarchaeology lab sign +ent-SignAnomaly = xenoarcheology lab sign .desc = A sign indicating the xenoarchaeology lab. ent-SignAnomaly2 = anomaly lab sign .desc = A sign indicating the anomalous research lab. ent-SignAtmos = atmos sign .desc = A sign indicating the atmospherics area. -ent-SignAtmosMinsky = atmospherics sign - .desc = A sign indicating the atmospherics area. ent-SignBar = bar sign .desc = A sign indicating the bar. +ent-SignKitchen = kitchen sign + .desc = The heart of the home. And disease. +ent-SignTheater = theater sign + .desc = Would it even be Space Station without drama? ent-SignBarbershop = barbershop sign .desc = A sign indicating the barbershop. ent-SignBio = bio sign @@ -86,24 +90,22 @@ ent-SignChapel = chapel sign .desc = A sign indicating the chapel. ent-SignChem = chemistry sign .desc = A sign indicating the chemistry lab. -ent-SignChemistry1 = chemistry sign - .desc = A sign indicating the chemistry lab. -ent-SignChemistry2 = chemistry sign - .desc = A sign indicating the chemistry lab. ent-SignCloning = cloning sign .desc = A sign indicating the cloning lab. ent-SignConference = conference room sign - .desc = A sign indicating the conference room. -ent-SignCourt = court sign - .desc = A sign labelling the courtroom. + .desc = Where work happens. +ent-SignCryo = cryosleep sign + .desc = Just like that? You're gonna chicken out? ent-SignDisposalSpace = disposal sign .desc = A sign indicating a disposal area. ent-SignDoors = doors sign .desc = A sign indicating doors. -ent-SignDrones = drones sign - .desc = A sign indicating drones. -ent-SignEngine = engine sign - .desc = A sign indicating the engine room. +ent-SignRestroom = restroom sign + .desc = A sign indicating where you go to... What do you do here again? +ent-SignMaterials = materials sign + .desc = An omen to the juicy vault of steel, glass, and plastic that lays before you. +ent-SignEngine = power sign + .desc = Where the powa happens. ent-SignEngineering = engineering sign .desc = A sign indicating the engineering area. ent-SignEscapePods = escape pods sign @@ -119,29 +121,23 @@ ent-SignFire = fire sign ent-SignGravity = gravity sign .desc = A sign indicating the gravity generator. ent-SignHead = head sign - .desc = A sign with a hat on it. + .desc = An official sign indicating the dwellings of a Nanotrasen-certified head of department. ent-SignHydro1 = hydro sign .desc = A sign indicating a hydroponics area. -ent-SignHydro2 = hydro sign - .desc = A sign indicating a hydroponics area. -ent-SignHydro3 = hydro sign - .desc = A sign indicating a hydroponics area. ent-SignInterrogation = interrogation sign .desc = A sign indicating an interrogation room. ent-SignJanitor = janitor sign .desc = A sign labelling an area where the janitor works. ent-SignLaundromat = laundromat sign .desc = A sign indicating the laundromat. -ent-SignLawyer = lawyer sign - .desc = A sign labelling an area where the Lawyers work. +ent-SignLawyer = law sign + .desc = A sign indicating the presence of the (typically absent) rule of law. ent-SignLibrary = library sign .desc = A sign indicating the library. ent-SignMail = mail sign .desc = A sign indicating mail. ent-SignMedical = medbay sign .desc = A sign indicating the medical bay. -ent-SignMinerDock = miner dock sign - .desc = A sign indicating the miner dock. ent-SignMorgue = morgue sign .desc = A sign indicating the morgue. ent-SignNews = news sign @@ -162,14 +158,12 @@ ent-SignSalvage = salvage sign .desc = A sign indicating the salvage area. ent-SignScience = science sign .desc = A sign indicating the science area. -ent-SignScience1 = science sign - .desc = A sign indicating the science area. -ent-SignScience2 = science sign - .desc = A sign indicating the science area. -ent-SignShield = shield sign - .desc = A sign with a shield. -ent-SignShipDock = docking sign - .desc = A sign indicating the ship docking area. +ent-SignServer = server sign + .desc = Ever heard of Big Data? This is it, chump. The biggest. +ent-SignCans = canisters sign + .desc = A sign indicating the auspicious presence of gas canisters. +ent-SignShipDock = evac sign + .desc = A sign indicating the where the evac shuttle will (likely) arrive. ent-SignSpace = space sign .desc = A sign warning that the area ahead is nothing but cold, empty space. ent-SignSurgery = surgery sign @@ -178,8 +172,8 @@ ent-SignTelecomms = telecomms sign .desc = A sign indicating the telecommunications room. ent-SignToxins = toxins sign .desc = A sign indicating the toxin lab. -ent-SignToxins2 = toxins sign - .desc = A sign indicating the toxin lab. +ent-SignVault = vault sign + .desc = A sign indicating the vault. Who knows what secrets lie inside? ent-SignVirology = virology sign .desc = A sign indicating the virology lab. ent-SignCorrosives = corrosives warning sign @@ -212,12 +206,8 @@ ent-SignRadiation = radiation warning sign .desc = A sign indicating an ionizing radiation hazard. ent-SignXenobio = xenobio sign .desc = A sign indicating the xenobiology lab. -ent-SignXenobio2 = xenobio sign - .desc = A sign indicating the xenobiology lab. -ent-SignXenolab = xenolab sign - .desc = A sign indicating the xenobiology lab. ent-SignZomlab = zombie lab sign - .desc = A sign indicating the zombie lab. + .desc = The final remains of a shut-down Nanotrasen research project that aimed to harness the powers of Romerol. I wonder how that went... ent-SignSecureMedRed = red secure sign .desc = A sign indicating that the area ahead is a secure area. ent-SignSecureSmall = small secure sign diff --git a/Resources/Locale/ru-RU/administration/commands/aghost.ftl b/Resources/Locale/ru-RU/administration/commands/aghost.ftl index f4f15c2fabf..811231dcf16 100644 --- a/Resources/Locale/ru-RU/administration/commands/aghost.ftl +++ b/Resources/Locale/ru-RU/administration/commands/aghost.ftl @@ -1,3 +1,3 @@ -aghost-description = Делает вас призраком-админом. +cmd-aghost-desc = Makes you or others an admin ghost. aghost-no-mind-self = Вы не можете стать призраком! aghost-no-mind-other = Эта сущность не может стать призраком! diff --git a/Resources/Locale/ru-RU/administration/commands/babyjail.ftl b/Resources/Locale/ru-RU/administration/commands/babyjail.ftl new file mode 100644 index 00000000000..49515de3a5c --- /dev/null +++ b/Resources/Locale/ru-RU/administration/commands/babyjail.ftl @@ -0,0 +1,16 @@ +cmd-babyjail-desc = Toggles the baby jail, which enables stricter restrictions on who's allowed to join the server. +cmd-babyjail-help = Usage: babyjail +babyjail-command-enabled = Baby jail has been enabled. +babyjail-command-disabled = Baby jail has been disabled. +cmd-babyjail_show_reason-desc = Toggles whether or not to show connecting clients the reason why the baby jail blocked them from joining. +cmd-babyjail_show_reason-help = Usage: babyjail_show_reason +babyjail-command-show-reason-enabled = The baby jail will now show a reason to users it blocks from connecting. +babyjail-command-show-reason-disabled = The baby jail will no longer show a reason to users it blocks from connecting. +cmd-babyjail_max_account_age-desc = Gets or sets the maximum account age in minutes that an account can have to be allowed to connect with the baby jail enabled. +cmd-babyjail_max_account_age-help = Usage: babyjail_max_account_age +babyjail-command-max-account-age-is = The maximum account age for the baby jail is { $minutes } minutes. +babyjail-command-max-account-age-set = Set the maximum account age for the baby jail to { $minutes } minutes. +cmd-babyjail_max_overall_minutes-desc = Gets or sets the maximum overall playtime in minutes that an account can have to be allowed to connect with the baby jail enabled. +cmd-babyjail_max_overall_minutes-help = Usage: babyjail_max_overall_minutes +babyjail-command-max-overall-minutes-is = The maximum overall playtime for the baby jail is { $minutes } minutes. +babyjail-command-max-overall-minutes-set = Set the maximum overall playtime for the baby jail to { $minutes } minutes. diff --git a/Resources/Locale/ru-RU/administration/ui/admin-menu-window.ftl b/Resources/Locale/ru-RU/administration/ui/admin-menu-window.ftl index e12edbebd94..adb6fc5bc31 100644 --- a/Resources/Locale/ru-RU/administration/ui/admin-menu-window.ftl +++ b/Resources/Locale/ru-RU/administration/ui/admin-menu-window.ftl @@ -7,5 +7,6 @@ admin-menu-atmos-tab = Атмос admin-menu-round-tab = Раунд admin-menu-server-tab = Сервер admin-menu-panic-bunker-tab = Бункер +admin-menu-baby-jail-tab = Baby Jail admin-menu-players-tab = Игроки admin-menu-objects-tab = Объекты diff --git a/Resources/Locale/ru-RU/administration/ui/tabs/babyjail-tab.ftl b/Resources/Locale/ru-RU/administration/ui/tabs/babyjail-tab.ftl new file mode 100644 index 00000000000..eac90b467c3 --- /dev/null +++ b/Resources/Locale/ru-RU/administration/ui/tabs/babyjail-tab.ftl @@ -0,0 +1,11 @@ +admin-ui-baby-jail-window-title = Baby Jail +admin-ui-baby-jail-enabled = Baby Jail Enabled +admin-ui-baby-jail-disabled = Baby Jail Disabled +admin-ui-baby-jail-tooltip = The baby jail restricts players from joining if their account is too old or they do have too much overall playtime on this server. +admin-ui-baby-jail-show-reason = Show Reason +admin-ui-baby-jail-show-reason-tooltip = Show the user why they were blocked from connecting by the baby jail. +admin-ui-baby-jail-max-account-age = Max. Account Age +admin-ui-baby-jail-max-overall-minutes = Max. Overall Playtime +admin-ui-baby-jail-is-enabled = [font size=20][bold]The baby jail is currently enabled.[/bold][/font] +admin-ui-baby-jail-enabled-admin-alert = The baby jail has been enabled. +admin-ui-baby-jail-disabled-admin-alert = The baby jail has been disabled. diff --git a/Resources/Locale/ru-RU/connection-messages.ftl b/Resources/Locale/ru-RU/connection-messages.ftl index acf6aacb521..3d79b8bb44a 100644 --- a/Resources/Locale/ru-RU/connection-messages.ftl +++ b/Resources/Locale/ru-RU/connection-messages.ftl @@ -40,3 +40,7 @@ panic-bunker-account-reason-overall = [few] минуты *[other] минут }. +baby-jail-account-denied = This server is a newbie server, intended for new players and those who want to help them. New connections by accounts that are too old or are not on a whitelist are not accepted. Check out some other servers and see everything Space Station 14 has to offer. Have fun! +baby-jail-account-denied-reason = This server is a newbie server, intended for new players and those who want to help them. New connections by accounts that are too old or are not on a whitelist are not accepted. Check out some other servers and see everything Space Station 14 has to offer. Have fun! Reason: "{ $reason }" +baby-jail-account-reason-account = Your Space Station 14 account is too old. It must be younger than { $minutes } minutes +baby-jail-account-reason-overall = Your overall playtime on the server must be younger than { $minutes } $minutes diff --git a/Resources/Locale/ru-RU/health-examinable/health-examinable-carbon.ftl b/Resources/Locale/ru-RU/health-examinable/health-examinable-carbon.ftl index e4a23173669..4e20119b024 100644 --- a/Resources/Locale/ru-RU/health-examinable/health-examinable-carbon.ftl +++ b/Resources/Locale/ru-RU/health-examinable/health-examinable-carbon.ftl @@ -11,3 +11,9 @@ health-examinable-carbon-Heat-25 = [color=orange]{ CAPITALIZE($target) } име health-examinable-carbon-Heat-50 = [color=orange]{ CAPITALIZE($target) } имеет сильные ожоги на теле.[/color] health-examinable-carbon-Heat-75 = [color=orange]{ CAPITALIZE($target) } имеет ожоги третьей степени на теле![/color] health-examinable-carbon-Shock-50 = [color=lightgoldenrodyellow]{ CAPITALIZE($target) } имеет следы поражения током по всему телу![/color] +health-examinable-carbon-Cold-25 = [color=lightblue]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } minor frostbite across { POSS-ADJ($target) } body.[/color] +health-examinable-carbon-Cold-50 = [color=lightblue]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } major frostbite across { POSS-ADJ($target) } body.[/color] +health-examinable-carbon-Cold-75 = [color=lightblue]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } severe third-degree frostbite across { POSS-ADJ($target) } body![/color] +health-examinable-carbon-Caustic-25 = [color=yellowgreen]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } minor chemical burns.[/color] +health-examinable-carbon-Caustic-50 = [color=yellowgreen]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } chemical burns across { POSS-ADJ($target) } body.[/color] +health-examinable-carbon-Caustic-75 = [color=yellowgreen]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } severe chemical burns all over { POSS-ADJ($target) } body![/color] diff --git a/Resources/Locale/ru-RU/interaction/interaction-popup-component.ftl b/Resources/Locale/ru-RU/interaction/interaction-popup-component.ftl index 242243f0a2c..8bb1eecf606 100644 --- a/Resources/Locale/ru-RU/interaction/interaction-popup-component.ftl +++ b/Resources/Locale/ru-RU/interaction/interaction-popup-component.ftl @@ -58,11 +58,25 @@ petting-success-honkbot = Вы гладите { $target } по его сколь petting-success-mimebot = Вы гладите { $target } по { POSS-ADJ($target) } холодной металлической голове.. petting-success-cleanbot = Вы гладите { $target } по его влажной металлической голове. petting-success-medibot = Вы гладите { $target } по его стерильной металлической голове. +petting-success-generic-cyborg = You pet { THE($target) } on { POSS-ADJ($target) } metal head. +petting-success-salvage-cyborg = You pet { THE($target) } on { POSS-ADJ($target) } dirty metal head. +petting-success-engineer-cyborg = You pet { THE($target) } on { POSS-ADJ($target) } reflective metal head. +petting-success-janitor-cyborg = You pet { THE($target) } on { POSS-ADJ($target) } damp metal head. +petting-success-medical-cyborg = You pet { THE($target) } on { POSS-ADJ($target) } sterile metal head. +petting-success-service-cyborg = You pet { THE($target) } on { POSS-ADJ($target) } dapper looking metal head. +petting-success-syndicate-cyborg = You pet { THE($target) } on { POSS-ADJ($target) } menacing metal head. petting-failure-honkbot = Вы тянетесь погладить { $target }, но { $target } хонкает и уворачивается! petting-success-recycler = Вы гладите { $target } по { POSS-ADJ($target) } слегка пугающему стальному покрытию. petting-failure-cleanbot = Вы тянетесь погладить { $target }, но { $target } занят уборкой! petting-failure-mimebot = Вы тянетесь погладить { $target }, но { $target } занят мимированием! petting-failure-medibot = Вы тянетесь погладить { $target }, но { $target } едва не пронзает вашу руку шприцом! +petting-failure-generic-cyborg = You reach out to pet { THE($target) }, but { SUBJECT($target) } { CONJUGATE-BE($target) } busy stating laws! +petting-failure-salvage-cyborg = You reach out to pet { THE($target) }, but { SUBJECT($target) } { CONJUGATE-BE($target) } busy drilling! +petting-failure-engineer-cyborg = You reach out to pet { THE($target) }, but { SUBJECT($target) } { CONJUGATE-BE($target) } busy repairing! +petting-failure-janitor-cyborg = You reach out to pet { THE($target) }, but { SUBJECT($target) } { CONJUGATE-BE($target) } busy cleaning! +petting-failure-medical-cyborg = You reach out to pet { THE($target) }, but { SUBJECT($target) } { CONJUGATE-BE($target) } busy saving lives! +petting-failure-service-cyborg = You reach out to pet { THE($target) }, but { SUBJECT($target) } { CONJUGATE-BE($target) } busy serving others! +petting-failure-syndicate-cyborg = You reach out to pet { THE($target) }, but { POSS-ADJ($target) } treacherous affiliation makes you reconsider. hugging-success-generic = Вы обнимаете { $target }. hugging-success-generic-others = { CAPITALIZE($user) } обнимает { $target }. fence-rattle-success = *бдзынь* diff --git a/Resources/Locale/ru-RU/medical/components/health-analyzer-component.ftl b/Resources/Locale/ru-RU/medical/components/health-analyzer-component.ftl index 6aae0a99c32..7bbec446b53 100644 --- a/Resources/Locale/ru-RU/medical/components/health-analyzer-component.ftl +++ b/Resources/Locale/ru-RU/medical/components/health-analyzer-component.ftl @@ -12,3 +12,4 @@ health-analyzer-window-scan-mode-text = Режим сканирования: health-analyzer-window-scan-mode-active = АКТИВЕН health-analyzer-window-scan-mode-inactive = НЕАКТИВЕН health-analyzer-window-malnutrition = Тяжёлое недоедание +health-analyzer-popup-scan-target = { CAPITALIZE(THE($user)) } is trying to scan you! diff --git a/Resources/Locale/ru-RU/portal/swap-teleporter.ftl b/Resources/Locale/ru-RU/portal/swap-teleporter.ftl index 80a888ac450..67faeb8e292 100644 --- a/Resources/Locale/ru-RU/portal/swap-teleporter.ftl +++ b/Resources/Locale/ru-RU/portal/swap-teleporter.ftl @@ -5,6 +5,7 @@ swap-teleporter-popup-link-destroyed = Квантовая связь разор swap-teleporter-popup-teleport-cancel-time = Устройство перезаряжается! swap-teleporter-popup-teleport-cancel-link = Не связано с другим устройством! swap-teleporter-popup-teleport-other = { CAPITALIZE($entity) } активируется, и вы оказываетесь в другом месте. +swap-teleporter-popup-teleport-fail = { CAPITALIZE(THE($entity)) } activates and fails to transport you anywhere. swap-teleporter-verb-destroy-link = Разорвать квантовую связь swap-teleporter-examine-link-present = [color=forestgreen]Имеется квантовая связь с другим устройством.[/color] Alt-клик чтобы разорвать квантовую связь. swap-teleporter-examine-link-absent = [color=yellow]Квантовая связь отсутствует.[/color] Используйте на другом устройстве, чтобы установить квантовую связь. diff --git a/Resources/Locale/ru-RU/replays/replays.ftl b/Resources/Locale/ru-RU/replays/replays.ftl index aadb79a3ace..77701db2aff 100644 --- a/Resources/Locale/ru-RU/replays/replays.ftl +++ b/Resources/Locale/ru-RU/replays/replays.ftl @@ -38,3 +38,4 @@ replay-verb-spectate = Наблюдать cmd-replay-spectate-help = replay_spectate [сущность (опционально)] cmd-replay-spectate-desc = Прикрепляет или открепляет локального игрока к заданному uid сущности. cmd-replay-spectate-hint = Опциональный EntityUid +cmd-replay-toggleui-desc = Toggles the replay control UI. diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl index d8941b7c467..569f82486c8 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/backpacks/duffelbag.ftl @@ -46,6 +46,8 @@ ent-ClothingBackpackDuffelSyndicateC4tBundle = { ent-ClothingBackpackDuffelSyndi ent-ClothingBackpackChameleonFill = { ent-ClothingBackpackDuffelSyndicate } .suffix = Заполненный, Хамелеон .desc = { ent-ClothingBackpackDuffelSyndicate.desc } +ent-ClothingBackpackDuffelSyndicateRaidBundle = syndicate raid suit bundle + .desc = Contains the Syndicate's durable raid armor suit. ent-ClothingBackpackDuffelSyndicateEVABundle = { ent-ClothingBackpackDuffelSyndicate } .suffix = набор EVA Синдиката .desc = { ent-ClothingBackpackDuffelSyndicate.desc } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/corvax/entities/clothing/neck/pins.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/corvax/entities/clothing/neck/pins.ftl index 905f472f84e..6e70c30df32 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/corvax/entities/clothing/neck/pins.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/corvax/entities/clothing/neck/pins.ftl @@ -1,18 +1,36 @@ +ent-ClothingNeckAtharaPin = starry sky pin + .desc = The pin of starry sky. ent-ClothingNeckUSSPPin = значок СССП .desc = Значок Союза Советских Социалистических Планет. +ent-ClothingNeckCorvaxPin = cluster pin + .desc = The pin of cluster. ent-ClothingNeckDonkPin = значок Donk .desc = Значок корпорации Donk. ent-ClothingNeckEarthPin = значок Земли .desc = Значок Объединённого Правительства Земли. +ent-ClothingNeckEchoPin = comet pin + .desc = The pin of comet. +ent-ClothingNeckElysiumPin = dark planet pin + .desc = The pin of dark planet. ent-ClothingNeckLogistikaPin = значок Logistika .desc = Значок корпорации Kosmologistika. +ent-ClothingNeckMainPin = rocket pin + .desc = The pin of rocket. ent-ClothingNeckDeForestPin = значок DeForest .desc = Значок корпорации DeForest. ent-ClothingNeckNakamuraPin = значок Nakamura .desc = Значок корпорации Nakamura Engineering. ent-ClothingNeckNanoTrasenPin = значок Nanotrasen .desc = Значок корпорации Nanotrasen. +ent-ClothingNeckNebulaPin = nebula pin + .desc = The pin of nebula. +ent-ClothingNeckNovaPin = ring planet pin + .desc = The pin of ring planet. ent-ClothingNeckSyndicakePin = значок Синдикекса .desc = Значок Синдикексов, на обратной стороне можно разглядеть ряд цифр "2559". +ent-ClothingNeckSolarisPin = space cheese pin + .desc = The pin of space cheese. ent-ClothingNeckVitezstviPin = значок Vitezstvi .desc = Значок корпорации Vitezstvi. +ent-ClothingNeckWhiteListPin = quasar pin + .desc = The pin of quasar. diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/head/helmets.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/head/helmets.ftl index b33d4ccde68..05e99e3e532 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/head/helmets.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/head/helmets.ftl @@ -40,6 +40,8 @@ ent-ClothingHeadHelmetAtmosFire = пожарный атмос-шлем .desc = Пожарный шлем атмосферных техников, способный охладить пыл пользователя в любой ситуации. ent-ClothingHeadHelmetLing = хитиновый шлем .desc = Раздувает тело генокрада во всепоглощающий массив хитиновый брони. Обеспечивает высокую защиту от физических повреждений, более низкую от других типов. Его вес замедляет движение генокрада, а его поддержание замедляет выработку химических веществ. +ent-ClothingHeadHelmetRaid = syndicate raid helmet + .desc = An armored helmet for use with the syndicate raid suit. Very stylish. ent-ClothingHeadHelmetBone = костяной шлем .desc = Круто выглядящий шлем, сделанный из черепов ваших врагов. ent-ClothingHeadHelmetPodWars = шлем Броненосец II diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/outerclothing/armor.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/outerclothing/armor.ftl index 823bb577fc9..acd281cbea3 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/outerclothing/armor.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/clothing/outerclothing/armor.ftl @@ -9,6 +9,8 @@ ent-ClothingOuterArmorBulletproof = пуленепробиваемый жиле .desc = Тяжёлый бронежилет типа III, способный защитить владельца от традиционного метательного оружия и взрывчатки в незначительной степени. ent-ClothingOuterArmorReflective = отражающий бронежилет .desc = Бронежилет с усовершенствованной защитой от энергетического оружия. +ent-ClothingOuterArmorRaid = syndicate raid suit + .desc = A somewhat flexible and well-armored suit with a powerful shoulder mounted flashlight manufactured in the Gorlex Marauder's iconic blood-red color scheme, it does not protect it's wearer from space. ent-ClothingOuterArmorCult = доспехи аколита .desc = Зловещего вида броня культа, сделанная из костей. ent-ClothingOuterArmorHeavy = тяжёлый бронекостюм diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/piping/atmospherics/special.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/piping/atmospherics/special.ftl index 33eb6a17ae0..d41584dffb3 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/piping/atmospherics/special.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/piping/atmospherics/special.ftl @@ -1,2 +1,4 @@ ent-AtmosDeviceFanTiny = маленький вентилятор .desc = Маленький вентилятор, создающий лёгкий поток воздуха. +ent-AtmosDeviceFanDirectional = directional fan + .desc = A thin fan, stopping the movement of gases across it. diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/wallmounts/signs/signs.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/wallmounts/signs/signs.ftl index 032dfc3e8a0..439b7c45207 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/wallmounts/signs/signs.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/wallmounts/signs/signs.ftl @@ -52,6 +52,8 @@ ent-SignDirectionalWash = знак "уборная" .desc = Указатель в сторону уборной. ent-SignAi = знак "ИИ" .desc = { ent-BaseSign.desc } +ent-SignAiUpload = ai upload sign + .desc = A sign, indicating an AI is present. ent-SignArcade = знак "аркада" .desc = Указатель в сторону комнаты с аркадами. ent-SignArmory = знак "оружейная" @@ -64,18 +66,16 @@ ent-SignAnomaly2 = знак "лаборатория аномалий" .desc = Знак, указывающий на лабораторию аномалий. ent-SignAtmos = знак "атмос" .desc = Знак, указывающий на атмосферный отсек. -ent-SignAtmosMinsky = знак "атмос" - .desc = Знак, указывающий на атмосферный отсек. +ent-SignKitchen = kitchen sign + .desc = The heart of the home. And disease. +ent-SignTheater = theater sign + .desc = Would it even be Space Station without drama? ent-SignBar = знак "бар" .desc = Знак, указывающий на бар. ent-SignBarbershop = знак "барбершоп" .desc = Знак, указывающий барбершоп. ent-SignHydro1 = знак "гидропоника" .desc = Знак, указывающий на гидропонику. -ent-SignHydro2 = знак "гидропоника" - .desc = Знак, указывающий на гидропонику. -ent-SignHydro3 = знак "гидропоника" - .desc = Знак, указывающий на гидропонику. ent-SignLibrary = знак "библиотека" .desc = Знак, указывающий на библиотеку. ent-SignChapel = знак "церковь" @@ -84,18 +84,20 @@ ent-SignHead = знак "глава" .desc = Знак, указывающий на офис главы отдела. ent-SignConference = знак "конференц-зал" .desc = Знак, указывающий на конференц-зал. -ent-SignDrones = знак "дроны" - .desc = Знак, указывающий на хранилище дронов. ent-SignEngine = знак "двигатель суперматерии" .desc = Знак, указывающий на отсек двигателя суперматерии. +ent-SignCryo = cryosleep sign + .desc = Just like that? You're gonna chicken out? ent-SignCloning = знак "клонирование" .desc = Знак, указывающий на отсек клонирования. ent-SignInterrogation = знак "допросная" .desc = Знак, указывающий на допросную. +ent-SignRestroom = restroom sign + .desc = A sign indicating where you go to... What do you do here again? +ent-SignMaterials = materials sign + .desc = An omen to the juicy vault of steel, glass, and plastic that lays before you. ent-SignSurgery = знак "операционная" .desc = Знак, указывающий на операционную. -ent-SignCourt = знак "суд" - .desc = Знак, указывающий на суд. ent-SignTelecomms = знак "телекоммуникация" .desc = Знак, указывающий на отсек телекоммуникаций. ent-SignCargo = знак "снабжение" @@ -104,10 +106,6 @@ ent-SignCargoDock = знак "карго док" .desc = Знак, указывающий на док отдела снабжения. ent-SignChem = знак "хим лаб" .desc = Знак, указывающий на химическую лабораторию. -ent-SignChemistry1 = знак "хим лаб" - .desc = Знак, указывающий на химическую лабораторию. -ent-SignChemistry2 = знак "хим лаб" - .desc = Знак, указывающий на химическую лабораторию. ent-SignEscapePods = знак "капсулы" .desc = Знак, указывающий на спасательные капсулы. ent-SignShipDock = знак "стыковочный док" @@ -134,18 +132,16 @@ ent-SignLaundromat = знак "прачечная" .desc = Знак, указывающий на прачечную. ent-SignLawyer = знак "АВД" .desc = Знак, указывающий на офис АВД. -ent-SignScience1 = знак "наука" - .desc = Знак, указывающий на научный отсек. -ent-SignScience2 = знак "наука" - .desc = Знак, указывающий на научный отсек. ent-SignToxins = знак "токсины" .desc = Знак, указывающий на лабораторию токсинов. -ent-SignToxins2 = знак "токсины" - .desc = Знак, указывающий на лабораторию токсинов. ent-SignBridge = знак "мостик" .desc = Знак, указывающий на мостик. ent-SignNews = знак "новости" .desc = Знак, указывающий на место работы репортёра. +ent-SignServer = server sign + .desc = Ever heard of Big Data? This is it, chump. The biggest. +ent-SignCans = canisters sign + .desc = A sign indicating the auspicious presence of gas canisters. ent-SignBio = знак "био лаб" .desc = Знак, указывающий на биологическую лабораторию. ent-SignBiohazard = знак "биологическая угроза" @@ -156,6 +152,8 @@ ent-SignReception = знак "ресепшен" .desc = Знак, указывающий на ресепшен. ent-SignCanisters = знак "газовые баллоны" .desc = Знак, предупреждающий о канистрах под давлением. +ent-SignVault = vault sign + .desc = A sign indicating the vault. Who knows what secrets lie inside? ent-SignCorrosives = предупреждающий знак "едкие вещества" .desc = Знак, предупреждающий об опасности едких веществ. ent-SignSalvage = знак "утилизация" @@ -186,8 +184,6 @@ ent-SignMail = знак "почта" .desc = Знак, указывающий на почту. ent-SignMemetic = предупреждающий знак "меметическая угроза" .desc = Знак, предупреждающий о меметической угрозе. -ent-SignMinerDock = знак "шахтёрский док" - .desc = Знак, указывающий на шахтёрский док. ent-SignNosmoking = знак "не курить" .desc = Знак, предупреждающий о запрете курения в непосредственной близости. ent-SignOptical = предупреждающий знак "оптическое излучение" @@ -200,8 +196,6 @@ ent-SignSecure = знак "охрана" .desc = Знак, предупреждающий что территория впереди является охраняемой зоной. ent-SignSecurearea = знак "охраняемая территория" .desc = Знак, предупреждающий что территория впереди является охраняемой зоной. -ent-SignShield = знак "щит" - .desc = Знак со щитом. ent-SignOxidants = предупреждающий знак "окислитель" .desc = Знак, предупреждающий об опасности окисляющих веществ. ent-SignShock = знак "высокое напряжение" @@ -212,10 +206,6 @@ ent-SignVirology = знак "вирусология" .desc = Знак, указывающий на лабораторию вирусологии. ent-SignXenobio = знак "ксенобиология" .desc = Знак, указывающий на лабораторию ксенобиологии. -ent-SignXenobio2 = знак "ксенобиология" - .desc = Знак, указывающий на лабораторию ксенобиологии. -ent-SignXenolab = знак "ксенолаборатория" - .desc = Знак, указывающий на лабораторию ксенобиологии. ent-SignZomlab = знак "зомби-лаборатория" .desc = Знак, указывающий на лабораторию зомби. ent-SignSecureMedRed = красный знак "охрана" diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/gamerules/midround.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/gamerules/midround.ftl index ffd302b5a10..7416fb5c77f 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/gamerules/midround.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/gamerules/midround.ftl @@ -1,4 +1,2 @@ -ent-Ninja = { ent-BaseGameRule } - .desc = { ent-BaseGameRule.desc } ent-Thief = { ent-BaseGameRule } .desc = { ent-BaseGameRule.desc } diff --git a/Resources/Locale/ru-RU/store/uplink-catalog.ftl b/Resources/Locale/ru-RU/store/uplink-catalog.ftl index ee6efc17d0a..bc3557aa73a 100644 --- a/Resources/Locale/ru-RU/store/uplink-catalog.ftl +++ b/Resources/Locale/ru-RU/store/uplink-catalog.ftl @@ -220,6 +220,8 @@ uplink-hardsuit-carp-name = Скафандр карпа uplink-hardsuit-carp-desc = Выглядит как обычный костюм карпа, только космический, и заставляет космических карпов думать что вы один из них. uplink-eva-syndie-name = Набор EVA Синдиката uplink-eva-syndie-desc = Простой EVA-скафандр, который не даёт никакой защиты, кроме той, что необходима для выживания в космосе. +uplink-syndie-raid-name = Syndicate Raid Suit +uplink-syndie-raid-desc = A very durable and reasonably flexible suit of blood-red armor, reinforced against all common forms of damage but not capable of space walks. Comes with a sick helmet. uplink-hardsuit-syndieelite-name = Элитный скафандр Синдиката uplink-hardsuit-syndieelite-desc = Элитная версия кроваво-красного скафандра, отличающаяся повышенной мобильностью и огнеупорностью. Собственность Мародёров Горлекса. uplink-clothing-outer-hardsuit-juggernaut-name = Скафандр джаггернаута Cybersun From edb05e36bbddfd9809877debdcb20fbb2d1feb43 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sun, 21 Jul 2024 14:48:13 +1000 Subject: [PATCH 096/134] Reapply "Remove some BUI boilerplate" (#30214) (#30219) * Reapply "Remove some BUI boilerplate" (#30214) This reverts commit cb0ba66be38677d248ce11f809221230ebe89642. * Fix gas tank * Fix PA * Fix microwave * Comms console underwrap * Fix rcd * log wehs --- .../UI/AccessOverriderBoundUserInterface.cs | 45 +++-- .../Access/UI/AccessOverriderWindow.xaml.cs | 41 ++--- .../UI/AgentIDCardBoundUserInterface.cs | 19 +- .../Access/UI/AgentIDCardWindow.xaml.cs | 10 +- .../Ame/UI/AmeControllerBoundUserInterface.cs | 16 +- Content.Client/Ame/UI/AmeWindow.xaml.cs | 19 +- .../Ui/AnomalyGeneratorBoundUserInterface.cs | 20 +- .../Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs | 8 +- Content.Client/Arcade/BlockGameMenu.cs | 45 +++-- .../Arcade/SpaceVillainArcadeMenu.cs | 45 ++--- .../Arcade/UI/BlockGameBoundUserInterface.cs | 5 +- .../SpaceVillainArcadeBoundUserInterface.cs | 16 +- .../Monitor/UI/AirAlarmBoundUserInterface.cs | 12 +- .../Atmos/Monitor/UI/AirAlarmWindow.xaml.cs | 7 +- .../Atmos/UI/GasCanisterBoundUserInterface.cs | 9 +- .../Atmos/UI/GasFilterBoundUserInterface.cs | 11 +- .../Atmos/UI/GasFilterWindow.xaml.cs | 7 +- .../Atmos/UI/GasMixerBoundUserInteface.cs | 18 +- .../UI/GasPressurePumpBoundUserInterface.cs | 17 +- .../UI/GasThermomachineBoundUserInterface.cs | 17 +- .../UI/GasVolumePumpBoundUserInterface.cs | 19 +- .../Atmos/UI/SpaceHeaterBoundUserInterface.cs | 10 +- .../Jukebox/JukeboxBoundUserInterface.cs | 21 +-- .../CryostorageBoundUserInterface.cs | 15 +- .../CargoBountyConsoleBoundUserInterface.cs | 17 +- .../CargoPalletConsoleBoundUserInterface.cs | 15 +- .../CargoShuttleConsoleBoundUserInterface.cs | 24 +-- .../Cargo/UI/CargoShuttleMenu.xaml.cs | 13 +- .../UI/ChemMasterBoundUserInterface.cs | 20 +- .../UI/ReagentDispenserBoundUserInterface.cs | 27 +-- .../UI/TransferAmountBoundUserInterface.cs | 12 +- .../UI/CloningConsoleBoundUserInterface.cs | 25 +-- .../UI/ChameleonBoundUserInterface.cs | 16 +- ...CommunicationsConsoleBoundUserInterface.cs | 72 +++----- .../UI/CommunicationsConsoleMenu.xaml.cs | 81 +++++---- .../Computer/ComputerBoundUserInterface.cs | 15 +- .../UI/ConfigurationBoundUserInterface.cs | 28 +-- .../Configurable/UI/ConfigurationMenu.cs | 18 +- .../UI/FlatpackCreatorBoundUserInterface.cs | 14 +- .../UI/FlatpackCreatorMenu.xaml.cs | 13 +- .../Crayon/UI/CrayonBoundUserInterface.cs | 40 ++-- Content.Client/Crayon/UI/CrayonWindow.xaml.cs | 18 +- .../UI/DisposalRouterBoundUserInterface.cs | 22 +-- .../UI/DisposalTaggerBoundUserInterface.cs | 23 +-- .../DoorElectronicsBoundUserInterface.cs | 31 ++-- .../DoorElectronicsConfigurationMenu.xaml.cs | 21 ++- Content.Client/Fax/UI/FaxBoundUi.cs | 12 +- .../ForensicScannerBoundUserInterface.cs | 15 +- .../Gateway/UI/GatewayBoundUserInterface.cs | 16 +- .../Gateway/UI/GatewayWindow.xaml.cs | 10 +- .../UI/GravityGeneratorBoundUserInterface.cs | 23 +-- .../Gravity/UI/GravityGeneratorWindow.xaml.cs | 15 +- .../UI/HealthAnalyzerBoundUserInterface.cs | 23 +-- ...manoidMarkingModifierBoundUserInterface.cs | 4 +- .../Instruments/UI/BandMenu.xaml.cs | 6 +- .../Instruments/UI/ChannelsMenu.xaml.cs | 5 +- .../UI/InstrumentBoundUserInterface.cs | 36 +++- .../Instruments/UI/InstrumentMenu.xaml.cs | 171 ++++++++++-------- .../Inventory/StrippableBoundUserInterface.cs | 25 ++- Content.Client/Kitchen/UI/GrinderMenu.xaml.cs | 42 ++--- .../Kitchen/UI/MicrowaveBoundUserInterface.cs | 43 +---- .../Kitchen/UI/MicrowaveMenu.xaml.cs | 25 ++- .../UI/ReagentGrinderBoundUserInterface.cs | 34 ++-- .../UI/HandLabelerBoundUserInterface.cs | 16 +- .../Lathe/UI/LatheBoundUserInterface.cs | 17 +- Content.Client/Lathe/UI/LatheMenu.xaml.cs | 29 +-- .../UI/SignalTimerBoundUserInterface.cs | 24 +-- .../UI/SignalTimerWindow.xaml.cs | 24 +-- .../MagicMirrorBoundUserInterface.cs | 15 +- .../Ui/NewsWriterBoundUserInterface.cs | 18 +- .../MassMedia/Ui/NewsWriterMenu.xaml.cs | 6 +- .../Mech/Ui/MechBoundUserInterface.cs | 16 +- Content.Client/Mech/Ui/MechMenu.xaml.cs | 9 +- .../CrewMonitoringBoundUserInterface.cs | 18 +- .../CrewMonitoringWindow.xaml.cs | 17 +- .../NetworkConfiguratorBoundUserInterface.cs | 39 ++-- ...tworkConfiguratorConfigurationMenu.xaml.cs | 8 +- .../NetworkConfiguratorDeviceList.xaml.cs | 12 +- .../NetworkConfiguratorLinkMenu.xaml.cs | 16 +- .../NetworkConfiguratorListMenu.xaml.cs | 13 +- Content.Client/Nuke/NukeBoundUserInterface.cs | 17 +- .../WarDeclaratorBoundUserInterface.cs | 18 +- .../NukeOps/WarDeclaratorWindow.xaml.cs | 9 +- Content.Client/PDA/PdaBoundUserInterface.cs | 17 +- .../PDA/Ringer/RingerBoundUserInterface.cs | 4 +- .../Paper/UI/PaperBoundUserInterface.cs | 17 +- Content.Client/Paper/UI/PaperWindow.xaml.cs | 6 +- .../ParticleAcceleratorBoundUserInterface.cs | 16 +- .../UI/ParticleAcceleratorControlMenu.cs | 31 ++-- .../UI/NavMapBeaconBoundUserInterface.cs | 16 +- .../Pinpointer/UI/NavMapBeaconWindow.xaml.cs | 25 ++- .../UI/StationMapBoundUserInterface.cs | 15 +- .../Pinpointer/UI/StationMapWindow.xaml.cs | 11 +- .../UI/UntrackedMapBoundUserInterface.cs | 15 +- .../Power/APC/ApcBoundUserInterface.cs | 16 +- Content.Client/Power/APC/UI/ApcMenu.xaml.cs | 12 +- .../Power/Generator/GeneratorWindow.xaml.cs | 52 +++--- .../PortableGeneratorBoundUserInterface.cs | 25 ++- ...owerMonitoringConsoleBoundUserInterface.cs | 19 +- .../PowerMonitoringWindow.xaml.Widgets.cs | 6 +- .../Power/PowerMonitoringWindow.xaml.cs | 84 +++++---- Content.Client/RCD/RCDMenu.xaml.cs | 40 ++-- .../RCD/RCDMenuBoundUserInterface.cs | 16 +- .../Radio/Ui/IntercomBoundUserInterface.cs | 20 +- Content.Client/Radio/Ui/IntercomMenu.xaml.cs | 4 +- .../UI/DiskConsoleBoundUserInterface.cs | 15 +- .../UI/ResearchClientBoundUserInterface.cs | 16 +- .../ResearchClientServerSelectionMenu.xaml.cs | 11 +- .../UI/ResearchConsoleBoundUserInterface.cs | 28 +-- .../Research/UI/ResearchConsoleMenu.xaml.cs | 29 +-- .../UI/RoboticsConsoleBoundUserInterface.cs | 18 +- .../Robotics/UI/RoboticsConsoleWindow.xaml.cs | 25 ++- ...vageExpeditionConsoleBoundUserInterface.cs | 12 +- .../UI/SalvageMagnetBoundUserInterface.cs | 21 +-- .../BUI/IFFConsoleBoundUserInterface.cs | 4 +- .../BUI/RadarConsoleBoundUserInterface.cs | 14 +- .../BUI/ShuttleConsoleBoundUserInterface.cs | 5 +- .../Silicons/Borgs/BorgBoundUserInterface.cs | 18 +- Content.Client/Silicons/Borgs/BorgMenu.xaml | 2 +- .../Silicons/Borgs/BorgMenu.xaml.cs | 49 +++-- .../Laws/Ui/SiliconLawBoundUserInterface.cs | 14 +- .../UI/SprayPainterBoundUserInterface.cs | 27 +-- ...lStationRecordConsoleBoundUserInterface.cs | 13 +- .../Store/Ui/StoreBoundUserInterface.cs | 15 +- Content.Client/Strip/StrippingMenu.cs | 11 +- .../UI/SurveillanceCameraMonitorBoundUi.cs | 11 +- .../Thief/ThiefBackpackBoundUserInterface.cs | 19 +- .../Thief/ThiefBackpackMenu.xaml.cs | 28 ++- .../GasTank/GasTankBoundUserInterface.cs | 11 +- .../Systems/Atmos/GasTank/GasTankWindow.cs | 44 +++-- .../VendingMachineBoundUserInterface.cs | 8 +- .../VoiceMask/VoiceMaskBoundUserInterface.cs | 8 +- .../VoiceMaskNameChangeWindow.xaml.cs | 6 +- .../Melee/UI/MeleeSpeechBoundUserInterface.cs | 10 +- .../Wires/UI/WiresBoundUserInterface.cs | 7 +- Content.Client/Wires/UI/WiresMenu.cs | 16 +- .../Ui/AnalysisConsoleBoundUserInterface.cs | 6 +- 137 files changed, 1098 insertions(+), 1753 deletions(-) diff --git a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs index c1b63dc4d05..d80c600c03e 100644 --- a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs +++ b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.Containers.ItemSlots; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; using static Content.Shared.Access.Components.AccessOverriderComponent; @@ -23,6 +24,28 @@ protected override void Open() { base.Open(); + _window = this.CreateWindow(); + RefreshAccess(); + _window.Title = EntMan.GetComponent(Owner).EntityName; + _window.OnSubmit += SubmitData; + + _window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId)); + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + if (!args.WasModified()) + return; + + RefreshAccess(); + + if (State != null) + _window?.UpdateState(_prototypeManager, (AccessOverriderBoundUserInterfaceState) State); + } + + private void RefreshAccess() + { List> accessLevels; if (EntMan.TryGetComponent(Owner, out var accessOverrider)) @@ -30,38 +53,20 @@ protected override void Open() accessLevels = accessOverrider.AccessLevels; accessLevels.Sort(); } - else { accessLevels = new List>(); _accessOverriderSystem.Log.Error($"No AccessOverrider component found for {EntMan.ToPrettyString(Owner)}!"); } - _window = new AccessOverriderWindow(this, _prototypeManager, accessLevels) - { - Title = EntMan.GetComponent(Owner).EntityName - }; - - _window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId)); - - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); + _window?.SetAccessLevels(_prototypeManager, accessLevels); } protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); var castState = (AccessOverriderBoundUserInterfaceState) state; - _window?.UpdateState(castState); + _window?.UpdateState(_prototypeManager, castState); } public void SubmitData(List> newAccessList) diff --git a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs index 6025c3b551f..ba087718583 100644 --- a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs +++ b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs @@ -13,26 +13,24 @@ namespace Content.Client.Access.UI [GenerateTypedNameReferences] public sealed partial class AccessOverriderWindow : DefaultWindow { - [Dependency] private readonly ILogManager _logManager = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - - private readonly AccessOverriderBoundUserInterface _owner; private readonly Dictionary _accessButtons = new(); - public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototypeManager prototypeManager, - List> accessLevels) + public event Action>>? OnSubmit; + + public AccessOverriderWindow() { RobustXamlLoader.Load(this); - IoCManager.InjectDependencies(this); - var logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill); + } - _owner = owner; + public void SetAccessLevels(IPrototypeManager protoManager, List> accessLevels) + { + _accessButtons.Clear(); + AccessLevelGrid.DisposeAllChildren(); foreach (var access in accessLevels) { - if (!prototypeManager.TryIndex(access, out var accessLevel)) + if (!protoManager.TryIndex(access, out var accessLevel)) { - logMill.Error($"Unable to find accesslevel for {access}"); continue; } @@ -44,11 +42,16 @@ public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototype AccessLevelGrid.AddChild(newButton); _accessButtons.Add(accessLevel.ID, newButton); - newButton.OnPressed += _ => SubmitData(); + newButton.OnPressed += _ => + { + OnSubmit?.Invoke( + // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair + _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList()); + }; } } - public void UpdateState(AccessOverriderBoundUserInterfaceState state) + public void UpdateState(IPrototypeManager protoManager, AccessOverriderBoundUserInterfaceState state) { PrivilegedIdLabel.Text = state.PrivilegedIdName; PrivilegedIdButton.Text = state.IsPrivilegedIdPresent @@ -66,11 +69,11 @@ public void UpdateState(AccessOverriderBoundUserInterfaceState state) if (state.MissingPrivilegesList != null && state.MissingPrivilegesList.Any()) { - List missingPrivileges = new List(); + var missingPrivileges = new List(); foreach (string tag in state.MissingPrivilegesList) { - string privilege = Loc.GetString(_prototypeManager.Index(tag)?.Name ?? "generic-unknown"); + var privilege = Loc.GetString(protoManager.Index(tag)?.Name ?? "generic-unknown"); missingPrivileges.Add(privilege); } @@ -90,13 +93,5 @@ public void UpdateState(AccessOverriderBoundUserInterfaceState state) } } } - - private void SubmitData() - { - _owner.SubmitData( - - // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair - _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList()); - } } } diff --git a/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs b/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs index 761f52988a9..50add43dc91 100644 --- a/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs +++ b/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Access.Systems; using Content.Shared.StatusIcon; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Access.UI @@ -20,16 +21,11 @@ protected override void Open() { base.Open(); - _window?.Dispose(); - _window = new AgentIDCardWindow(this); - if (State != null) - UpdateState(State); + _window = this.CreateWindow(); - _window.OpenCentered(); - - _window.OnClose += Close; _window.OnNameChanged += OnNameChanged; _window.OnJobChanged += OnJobChanged; + _window.OnJobIconChanged += OnJobIconChanged; } private void OnNameChanged(string newName) @@ -61,14 +57,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetCurrentJob(cast.CurrentJob); _window.SetAllowedIcons(cast.Icons, cast.CurrentJobIconId); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); - } } } diff --git a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs index 6d0b2a184f4..071ce41a069 100644 --- a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs +++ b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs @@ -17,19 +17,19 @@ public sealed partial class AgentIDCardWindow : DefaultWindow [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IEntitySystemManager _entitySystem = default!; private readonly SpriteSystem _spriteSystem; - private readonly AgentIDCardBoundUserInterface _bui; private const int JobIconColumnCount = 10; public event Action? OnNameChanged; public event Action? OnJobChanged; - public AgentIDCardWindow(AgentIDCardBoundUserInterface bui) + public event Action>? OnJobIconChanged; + + public AgentIDCardWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); _spriteSystem = _entitySystem.GetEntitySystem(); - _bui = bui; NameLineEdit.OnTextEntered += e => OnNameChanged?.Invoke(e.Text); NameLineEdit.OnFocusExit += e => OnNameChanged?.Invoke(e.Text); @@ -67,7 +67,7 @@ public void SetAllowedIcons(HashSet> icons, string }; // Generate buttons textures - TextureRect jobIconTexture = new TextureRect + var jobIconTexture = new TextureRect { Texture = _spriteSystem.Frame0(jobIcon.Icon), TextureScale = new Vector2(2.5f, 2.5f), @@ -75,7 +75,7 @@ public void SetAllowedIcons(HashSet> icons, string }; jobIconButton.AddChild(jobIconTexture); - jobIconButton.OnPressed += _ => _bui.OnJobIconChanged(jobIconId); + jobIconButton.OnPressed += _ => OnJobIconChanged?.Invoke(jobIcon.ID); IconGrid.AddChild(jobIconButton); if (jobIconId.Equals(currentJobIconId)) diff --git a/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs b/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs index e84cf5d34de..3d65f751899 100644 --- a/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs +++ b/Content.Client/Ame/UI/AmeControllerBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Ame.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Ame.UI { @@ -16,9 +17,8 @@ protected override void Open() { base.Open(); - _window = new AmeWindow(this); - _window.OnClose += Close; - _window.OpenCentered(); + _window = this.CreateWindow(); + _window.OnAmeButton += ButtonPressed; } /// @@ -40,15 +40,5 @@ public void ButtonPressed(UiButton button) { SendMessage(new UiButtonPressedMessage(button)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } } } diff --git a/Content.Client/Ame/UI/AmeWindow.xaml.cs b/Content.Client/Ame/UI/AmeWindow.xaml.cs index 8b91ec59660..d6d580bcdaf 100644 --- a/Content.Client/Ame/UI/AmeWindow.xaml.cs +++ b/Content.Client/Ame/UI/AmeWindow.xaml.cs @@ -1,3 +1,4 @@ +using System.Linq; using Content.Client.UserInterface; using Content.Shared.Ame.Components; using Robust.Client.AutoGenerated; @@ -9,15 +10,17 @@ namespace Content.Client.Ame.UI [GenerateTypedNameReferences] public sealed partial class AmeWindow : DefaultWindow { - public AmeWindow(AmeControllerBoundUserInterface ui) + public event Action? OnAmeButton; + + public AmeWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - EjectButton.OnPressed += _ => ui.ButtonPressed(UiButton.Eject); - ToggleInjection.OnPressed += _ => ui.ButtonPressed(UiButton.ToggleInjection); - IncreaseFuelButton.OnPressed += _ => ui.ButtonPressed(UiButton.IncreaseFuel); - DecreaseFuelButton.OnPressed += _ => ui.ButtonPressed(UiButton.DecreaseFuel); + EjectButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.Eject); + ToggleInjection.OnPressed += _ => OnAmeButton?.Invoke(UiButton.ToggleInjection); + IncreaseFuelButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.IncreaseFuel); + DecreaseFuelButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.DecreaseFuel); } /// @@ -29,7 +32,7 @@ public void UpdateState(BoundUserInterfaceState state) var castState = (AmeControllerBoundUserInterfaceState) state; // Disable all buttons if not powered - if (Contents.Children != null) + if (Contents.Children.Any()) { ButtonHelpers.SetButtonDisabledRecursive(Contents, !castState.HasPower); EjectButton.Disabled = false; @@ -65,8 +68,8 @@ public void UpdateState(BoundUserInterfaceState state) CoreCount.Text = $"{castState.CoreCount}"; InjectionAmount.Text = $"{castState.InjectionAmount}"; // format power statistics to pretty numbers - CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply.ToString("N1")}"; - TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply.ToString("N1")}"; + CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply:N1}"; + TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply:N1}"; } } } diff --git a/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs b/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs index 5764d0a097d..5d1985485c4 100644 --- a/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs +++ b/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Gravity; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Anomaly.Ui; @@ -18,10 +19,8 @@ protected override void Open() { base.Open(); - _window = new(Owner); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.SetEntity(Owner); _window.OnGenerateButtonPressed += () => { @@ -37,18 +36,5 @@ protected override void UpdateState(BoundUserInterfaceState state) return; _window?.UpdateState(msg); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _window?.Dispose(); - } - - public void SetPowerSwitch(bool on) - { - SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on)); - } } diff --git a/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs b/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs index 08438e2a1b2..82d41192dd0 100644 --- a/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs +++ b/Content.Client/Anomaly/Ui/AnomalyGeneratorWindow.xaml.cs @@ -18,17 +18,21 @@ public sealed partial class AnomalyGeneratorWindow : FancyWindow public Action? OnGenerateButtonPressed; - public AnomalyGeneratorWindow(EntityUid gen) + public AnomalyGeneratorWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - EntityView.SetEntity(gen); EntityView.SpriteOffset = false; GenerateButton.OnPressed += _ => OnGenerateButtonPressed?.Invoke(); } + public void SetEntity(EntityUid uid) + { + EntityView.SetEntity(uid); + } + public void UpdateState(AnomalyGeneratorUserInterfaceState state) { _cooldownEnd = state.CooldownEndTime; diff --git a/Content.Client/Arcade/BlockGameMenu.cs b/Content.Client/Arcade/BlockGameMenu.cs index eeda2a31020..4a579fc4bf4 100644 --- a/Content.Client/Arcade/BlockGameMenu.cs +++ b/Content.Client/Arcade/BlockGameMenu.cs @@ -28,8 +28,6 @@ public sealed class BlockGameMenu : DefaultWindow private static readonly Vector2 BlockSize = new(15, 15); - private readonly BlockGameBoundUserInterface _owner; - private readonly PanelContainer _mainPanel; private readonly BoxContainer _gameRootContainer; @@ -58,10 +56,11 @@ public sealed class BlockGameMenu : DefaultWindow private bool _isPlayer = false; private bool _gameOver = false; - public BlockGameMenu(BlockGameBoundUserInterface owner) + public event Action? OnAction; + + public BlockGameMenu() { Title = Loc.GetString("blockgame-menu-title"); - _owner = owner; MinSize = SetSize = new Vector2(410, 490); @@ -176,7 +175,7 @@ public BlockGameMenu(BlockGameBoundUserInterface owner) }; _newGameButton.OnPressed += (e) => { - _owner.SendAction(BlockGamePlayerAction.NewGame); + OnAction?.Invoke(BlockGamePlayerAction.NewGame); }; pauseMenuContainer.AddChild(_newGameButton); pauseMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) }); @@ -186,7 +185,10 @@ public BlockGameMenu(BlockGameBoundUserInterface owner) Text = Loc.GetString("blockgame-menu-button-scoreboard"), TextAlign = Label.AlignMode.Center }; - _scoreBoardButton.OnPressed += (e) => _owner.SendAction(BlockGamePlayerAction.ShowHighscores); + _scoreBoardButton.OnPressed += (e) => + { + OnAction?.Invoke(BlockGamePlayerAction.ShowHighscores); + }; pauseMenuContainer.AddChild(_scoreBoardButton); _unpauseButtonMargin = new Control { MinSize = new Vector2(1, 10), Visible = false }; pauseMenuContainer.AddChild(_unpauseButtonMargin); @@ -199,7 +201,7 @@ public BlockGameMenu(BlockGameBoundUserInterface owner) }; _unpauseButton.OnPressed += (e) => { - _owner.SendAction(BlockGamePlayerAction.Unpause); + OnAction?.Invoke(BlockGamePlayerAction.Unpause); }; pauseMenuContainer.AddChild(_unpauseButton); @@ -257,7 +259,7 @@ public BlockGameMenu(BlockGameBoundUserInterface owner) }; _finalNewGameButton.OnPressed += (e) => { - _owner.SendAction(BlockGamePlayerAction.NewGame); + OnAction?.Invoke(BlockGamePlayerAction.NewGame); }; gameOverMenuContainer.AddChild(_finalNewGameButton); @@ -327,7 +329,10 @@ public BlockGameMenu(BlockGameBoundUserInterface owner) Text = Loc.GetString("blockgame-menu-button-back"), TextAlign = Label.AlignMode.Center }; - _highscoreBackButton.OnPressed += (e) => _owner.SendAction(BlockGamePlayerAction.Pause); + _highscoreBackButton.OnPressed += (e) => + { + OnAction?.Invoke(BlockGamePlayerAction.Pause); + }; menuContainer.AddChild(_highscoreBackButton); menuInnerPanel.AddChild(menuContainer); @@ -473,7 +478,7 @@ protected override void KeyboardFocusExited() private void TryPause() { - _owner.SendAction(BlockGamePlayerAction.Pause); + OnAction?.Invoke(BlockGamePlayerAction.Pause); } public void SetStarted() @@ -576,19 +581,19 @@ protected override void KeyBindDown(GUIBoundKeyEventArgs args) return; else if (args.Function == ContentKeyFunctions.ArcadeLeft) - _owner.SendAction(BlockGamePlayerAction.StartLeft); + OnAction?.Invoke(BlockGamePlayerAction.StartLeft); else if (args.Function == ContentKeyFunctions.ArcadeRight) - _owner.SendAction(BlockGamePlayerAction.StartRight); + OnAction?.Invoke(BlockGamePlayerAction.StartRight); else if (args.Function == ContentKeyFunctions.ArcadeUp) - _owner.SendAction(BlockGamePlayerAction.Rotate); + OnAction?.Invoke(BlockGamePlayerAction.Rotate); else if (args.Function == ContentKeyFunctions.Arcade3) - _owner.SendAction(BlockGamePlayerAction.CounterRotate); + OnAction?.Invoke(BlockGamePlayerAction.CounterRotate); else if (args.Function == ContentKeyFunctions.ArcadeDown) - _owner.SendAction(BlockGamePlayerAction.SoftdropStart); + OnAction?.Invoke(BlockGamePlayerAction.SoftdropStart); else if (args.Function == ContentKeyFunctions.Arcade2) - _owner.SendAction(BlockGamePlayerAction.Hold); + OnAction?.Invoke(BlockGamePlayerAction.Hold); else if (args.Function == ContentKeyFunctions.Arcade1) - _owner.SendAction(BlockGamePlayerAction.Harddrop); + OnAction?.Invoke(BlockGamePlayerAction.Harddrop); } protected override void KeyBindUp(GUIBoundKeyEventArgs args) @@ -599,11 +604,11 @@ protected override void KeyBindUp(GUIBoundKeyEventArgs args) return; else if (args.Function == ContentKeyFunctions.ArcadeLeft) - _owner.SendAction(BlockGamePlayerAction.EndLeft); + OnAction?.Invoke(BlockGamePlayerAction.EndLeft); else if (args.Function == ContentKeyFunctions.ArcadeRight) - _owner.SendAction(BlockGamePlayerAction.EndRight); + OnAction?.Invoke(BlockGamePlayerAction.EndRight); else if (args.Function == ContentKeyFunctions.ArcadeDown) - _owner.SendAction(BlockGamePlayerAction.SoftdropEnd); + OnAction?.Invoke(BlockGamePlayerAction.SoftdropEnd); } public void UpdateNextBlock(BlockGameBlock[] blocks) diff --git a/Content.Client/Arcade/SpaceVillainArcadeMenu.cs b/Content.Client/Arcade/SpaceVillainArcadeMenu.cs index e5542a5848e..1ee4c268184 100644 --- a/Content.Client/Arcade/SpaceVillainArcadeMenu.cs +++ b/Content.Client/Arcade/SpaceVillainArcadeMenu.cs @@ -8,8 +8,6 @@ namespace Content.Client.Arcade { public sealed class SpaceVillainArcadeMenu : DefaultWindow { - public SpaceVillainArcadeBoundUserInterface Owner { get; set; } - private readonly Label _enemyNameLabel; private readonly Label _playerInfoLabel; private readonly Label _enemyInfoLabel; @@ -17,11 +15,13 @@ public sealed class SpaceVillainArcadeMenu : DefaultWindow private readonly Label _enemyActionLabel; private readonly Button[] _gameButtons = new Button[3]; //used to disable/enable all game buttons - public SpaceVillainArcadeMenu(SpaceVillainArcadeBoundUserInterface owner) + + public event Action? OnPlayerAction; + + public SpaceVillainArcadeMenu() { MinSize = SetSize = new Vector2(300, 225); Title = Loc.GetString("spacevillain-menu-title"); - Owner = owner; var grid = new GridContainer { Columns = 1 }; @@ -47,32 +47,43 @@ public SpaceVillainArcadeMenu(SpaceVillainArcadeBoundUserInterface owner) grid.AddChild(_enemyActionLabel); var buttonGrid = new GridContainer { Columns = 3 }; - _gameButtons[0] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Attack) + _gameButtons[0] = new Button() { Text = Loc.GetString("spacevillain-menu-button-attack") }; + + _gameButtons[0].OnPressed += + _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Attack); buttonGrid.AddChild(_gameButtons[0]); - _gameButtons[1] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Heal) + _gameButtons[1] = new Button() { Text = Loc.GetString("spacevillain-menu-button-heal") }; + + _gameButtons[1].OnPressed += + _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Heal); buttonGrid.AddChild(_gameButtons[1]); - _gameButtons[2] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Recharge) + _gameButtons[2] = new Button() { Text = Loc.GetString("spacevillain-menu-button-recharge") }; + + _gameButtons[2].OnPressed += + _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Recharge); buttonGrid.AddChild(_gameButtons[2]); centerContainer = new CenterContainer(); centerContainer.AddChild(buttonGrid); grid.AddChild(centerContainer); - var newGame = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.NewGame) + var newGame = new Button() { Text = Loc.GetString("spacevillain-menu-button-new-game") }; + + newGame.OnPressed += _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.NewGame); grid.AddChild(newGame); Contents.AddChild(grid); @@ -99,23 +110,5 @@ public void UpdateInfo(SharedSpaceVillainArcadeComponent.SpaceVillainArcadeDataU _playerActionLabel.Text = message.PlayerActionMessage; _enemyActionLabel.Text = message.EnemyActionMessage; } - - private sealed class ActionButton : Button - { - private readonly SpaceVillainArcadeBoundUserInterface _owner; - private readonly SharedSpaceVillainArcadeComponent.PlayerAction _playerAction; - - public ActionButton(SpaceVillainArcadeBoundUserInterface owner, SharedSpaceVillainArcadeComponent.PlayerAction playerAction) - { - _owner = owner; - _playerAction = playerAction; - OnPressed += Clicked; - } - - private void Clicked(ButtonEventArgs e) - { - _owner.SendAction(_playerAction); - } - } } } diff --git a/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs b/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs index 1a3422dec0f..8fa8035afd6 100644 --- a/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs +++ b/Content.Client/Arcade/UI/BlockGameBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Arcade; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Arcade.UI; @@ -15,9 +16,7 @@ protected override void Open() { base.Open(); - _menu = new BlockGameMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); } protected override void ReceiveMessage(BoundUserInterfaceMessage message) diff --git a/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs b/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs index 40bbe8b2d8c..c0704530de2 100644 --- a/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs +++ b/Content.Client/Arcade/UI/SpaceVillainArcadeBoundUserInterface.cs @@ -1,4 +1,5 @@ using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.GameObjects; using Robust.Shared.ViewVariables; using static Content.Shared.Arcade.SharedSpaceVillainArcadeComponent; @@ -9,8 +10,6 @@ public sealed class SpaceVillainArcadeBoundUserInterface : BoundUserInterface { [ViewVariables] private SpaceVillainArcadeMenu? _menu; - //public SharedSpaceVillainArcadeComponent SpaceVillainArcade; - public SpaceVillainArcadeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { SendAction(PlayerAction.RequestData); @@ -25,10 +24,7 @@ protected override void Open() { base.Open(); - _menu = new SpaceVillainArcadeMenu(this); - - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); } protected override void ReceiveMessage(BoundUserInterfaceMessage message) @@ -36,12 +32,4 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) if (message is SpaceVillainArcadeDataUpdateMessage msg) _menu?.UpdateInfo(msg); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - _menu?.Dispose(); - } } diff --git a/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs b/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs index 8f3b507c806..2ae15188355 100644 --- a/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs +++ b/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Monitor.Components; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Log; @@ -20,16 +21,9 @@ protected override void Open() { base.Open(); - _window = new AirAlarmWindow(this); + _window = this.CreateWindow(); + _window.SetEntity(Owner); - if (State != null) - { - UpdateState(State); - } - - _window.OpenCentered(); - - _window.OnClose += Close; _window.AtmosDeviceDataChanged += OnDeviceDataChanged; _window.AtmosDeviceDataCopied += OnDeviceDataCopied; _window.AtmosAlarmThresholdChanged += OnThresholdChanged; diff --git a/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs b/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs index 43be67c9d6b..eeec11c7660 100644 --- a/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs +++ b/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml.cs @@ -47,7 +47,7 @@ public sealed partial class AirAlarmWindow : FancyWindow private CheckBox _autoMode => AutoModeCheckBox; - public AirAlarmWindow(BoundUserInterface owner) + public AirAlarmWindow() { RobustXamlLoader.Load(this); @@ -95,8 +95,11 @@ public AirAlarmWindow(BoundUserInterface owner) _sensors.Clear(); ResyncAllRequested!.Invoke(); }; + } - EntityView.SetEntity(owner.Owner); + public void SetEntity(EntityUid uid) + { + EntityView.SetEntity(uid); } public void UpdateState(AirAlarmUIState state) diff --git a/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs b/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs index a5e316a8def..7bf9b396d5e 100644 --- a/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasCanisterBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Atmos.Piping.Binary.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -21,14 +22,8 @@ protected override void Open() { base.Open(); - _window = new GasCanisterWindow(); + _window = this.CreateWindow(); - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; _window.ReleaseValveCloseButtonPressed += OnReleaseValveClosePressed; _window.ReleaseValveOpenButtonPressed += OnReleaseValveOpenPressed; _window.ReleasePressureSet += OnReleasePressureSet; diff --git a/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs b/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs index 1904e2b3402..2b8020924cf 100644 --- a/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasFilterBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Atmos.Piping.Trinary.Components; using Content.Shared.Localizations; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -28,14 +29,8 @@ protected override void Open() var atmosSystem = EntMan.System(); - _window = new GasFilterWindow(atmosSystem.Gases); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.PopulateGasList(atmosSystem.Gases); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.FilterTransferRateChanged += OnFilterTransferRatePressed; diff --git a/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs b/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs index 28766c688a0..62748b52592 100644 --- a/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs +++ b/Content.Client/Atmos/UI/GasFilterWindow.xaml.cs @@ -26,10 +26,9 @@ public sealed partial class GasFilterWindow : DefaultWindow public event Action? FilterTransferRateChanged; public event Action? SelectGasPressed; - public GasFilterWindow(IEnumerable gases) + public GasFilterWindow() { RobustXamlLoader.Load(this); - PopulateGasList(gases); ToggleStatusButton.OnPressed += _ => SetFilterStatus(!FilterStatus); ToggleStatusButton.OnPressed += _ => ToggleStatusButtonPressed?.Invoke(); @@ -73,7 +72,7 @@ public void SetGasFiltered(string? id, string name) SelectGasButton.Disabled = true; } - private void PopulateGasList(IEnumerable gases) + public void PopulateGasList(IEnumerable gases) { GasList.Add(new ItemList.Item(GasList) { @@ -81,7 +80,7 @@ private void PopulateGasList(IEnumerable gases) Text = Loc.GetString("comp-gas-filter-ui-filter-gas-none") }); - foreach (GasPrototype gas in gases) + foreach (var gas in gases) { var gasName = Loc.GetString(gas.Name); GasList.Add(GetGasItem(gas.ID, gasName, GasList)); diff --git a/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs b/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs index 709c06517cb..392fbf1cd9a 100644 --- a/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs +++ b/Content.Client/Atmos/UI/GasMixerBoundUserInteface.cs @@ -2,7 +2,7 @@ using Content.Shared.Atmos.Piping.Trinary.Components; using Content.Shared.Localizations; using JetBrains.Annotations; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -26,14 +26,7 @@ protected override void Open() { base.Open(); - _window = new GasMixerWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.MixerOutputPressureChanged += OnMixerOutputPressurePressed; @@ -83,12 +76,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetOutputPressure(cast.OutputPressure); _window.SetNodePercentages(cast.NodeOne); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs b/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs index 6eba2e0d215..220fdbe875c 100644 --- a/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasPressurePumpBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Localizations; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -26,14 +27,7 @@ protected override void Open() { base.Open(); - _window = new GasPressurePumpWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.PumpOutputPressureChanged += OnPumpOutputPressurePressed; @@ -67,12 +61,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetPumpStatus(cast.Enabled); _window.SetOutputPressure(cast.OutputPressure); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs b/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs index 1664c8b9d75..d62be8f4bb4 100644 --- a/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasThermomachineBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Atmos.Piping.Unary.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -31,14 +32,7 @@ protected override void Open() { base.Open(); - _window = new GasThermomachineWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed(); _window.TemperatureSpinbox.OnValueChanged += _ => OnTemperatureChanged(_window.TemperatureSpinbox.Value); @@ -91,12 +85,5 @@ protected override void UpdateState(BoundUserInterfaceState state) true => Loc.GetString("comp-gas-thermomachine-ui-title-heater") }; } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs b/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs index 1b39306181a..642f34c2f92 100644 --- a/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasVolumePumpBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Localizations; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Atmos.UI { @@ -26,14 +27,7 @@ protected override void Open() { base.Open(); - _window = new GasVolumePumpWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; _window.PumpTransferRateChanged += OnPumpTransferRatePressed; @@ -64,16 +58,9 @@ protected override void UpdateState(BoundUserInterfaceState state) if (_window == null || state is not GasVolumePumpBoundUserInterfaceState cast) return; - _window.Title = (cast.PumpLabel); + _window.Title = cast.PumpLabel; _window.SetPumpStatus(cast.Enabled); _window.SetTransferRate(cast.TransferRate); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } } diff --git a/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs b/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs index 4d8d1191e91..e70426575d4 100644 --- a/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/SpaceHeaterBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Atmos.Piping.Portable.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.Atmos.UI; @@ -21,14 +22,7 @@ protected override void Open() { base.Open(); - _window = new SpaceHeaterWindow(); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed(); _window.IncreaseTempRange.OnPressed += _ => OnTemperatureRangeChanged(_window.TemperatureChangeDelta); diff --git a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs index 60fe339069a..865dfc478d0 100644 --- a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs +++ b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs @@ -1,8 +1,7 @@ using Content.Shared.Audio.Jukebox; using Robust.Client.Audio; -using Robust.Client.Player; +using Robust.Client.UserInterface; using Robust.Shared.Audio.Components; -using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Client.Audio.Jukebox; @@ -23,9 +22,7 @@ protected override void Open() { base.Open(); - _menu = new JukeboxMenu(); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); _menu.OnPlayPressed += args => { @@ -100,19 +97,5 @@ public void SetTime(float time) SendMessage(new JukeboxSetTimeMessage(sentTime)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_menu == null) - return; - - _menu.OnClose -= Close; - _menu.Dispose(); - _menu = null; - } } diff --git a/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs b/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs index ffab1625483..09f3cec8fbf 100644 --- a/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs +++ b/Content.Client/Bed/Cryostorage/CryostorageBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Bed.Cryostorage; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Bed.Cryostorage; @@ -17,9 +18,7 @@ protected override void Open() { base.Open(); - _menu = new(); - - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.SlotRemoveButtonPressed += (ent, slot) => { @@ -30,8 +29,6 @@ protected override void Open() { SendMessage(new CryostorageRemoveItemBuiMessage(ent, hand, CryostorageRemoveItemBuiMessage.RemovalType.Hand)); }; - - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -45,12 +42,4 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Dispose(); - } } diff --git a/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs index d3365702bcf..44c40143d83 100644 --- a/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoBountyConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Client.Cargo.UI; using Content.Shared.Cargo.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Cargo.BUI; @@ -18,9 +19,7 @@ protected override void Open() { base.Open(); - _menu = new(); - - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.OnLabelButtonPressed += id => { @@ -31,8 +30,6 @@ protected override void Open() { SendMessage(new BountySkipMessage(id)); }; - - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState message) @@ -44,14 +41,4 @@ protected override void UpdateState(BoundUserInterfaceState message) _menu?.UpdateEntries(state.Bounties, state.UntilNextSkip); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (!disposing) - return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs index 20c23a48a0d..2461dafb5f3 100644 --- a/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoPalletConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Cargo.BUI; using Content.Shared.Cargo.Events; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Cargo.BUI; @@ -18,21 +19,9 @@ protected override void Open() { base.Open(); - _menu = new CargoPalletMenu(); + _menu = this.CreateWindow(); _menu.AppraiseRequested += OnAppraisal; _menu.SellRequested += OnSell; - _menu.OnClose += Close; - - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _menu?.Dispose(); - } } private void OnAppraisal() diff --git a/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs b/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs index 422d03707a0..02b721b9020 100644 --- a/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs +++ b/Content.Client/Cargo/BUI/CargoShuttleConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Cargo.BUI; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Cargo.BUI; @@ -9,6 +10,8 @@ namespace Content.Client.Cargo.BUI; [UsedImplicitly] public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [ViewVariables] private CargoShuttleMenu? _menu; @@ -19,24 +22,7 @@ public CargoShuttleConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base protected override void Open() { base.Open(); - var collection = IoCManager.Instance; - - if (collection == null) - return; - - _menu = new CargoShuttleMenu(collection.Resolve(), collection.Resolve().GetEntitySystem()); - _menu.OnClose += Close; - - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _menu?.Dispose(); - } + _menu = this.CreateWindow(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -45,6 +31,6 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not CargoShuttleConsoleBoundUserInterfaceState cargoState) return; _menu?.SetAccountName(cargoState.AccountName); _menu?.SetShuttleName(cargoState.ShuttleName); - _menu?.SetOrders(cargoState.Orders); + _menu?.SetOrders(EntMan.System(), _protoManager, cargoState.Orders); } } diff --git a/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs b/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs index c591f917da3..43b00089e16 100644 --- a/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs +++ b/Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs @@ -12,14 +12,9 @@ namespace Content.Client.Cargo.UI [GenerateTypedNameReferences] public sealed partial class CargoShuttleMenu : FancyWindow { - private readonly IPrototypeManager _protoManager; - private readonly SpriteSystem _spriteSystem; - - public CargoShuttleMenu(IPrototypeManager protoManager, SpriteSystem spriteSystem) + public CargoShuttleMenu() { RobustXamlLoader.Load(this); - _protoManager = protoManager; - _spriteSystem = spriteSystem; Title = Loc.GetString("cargo-shuttle-console-menu-title"); } @@ -33,19 +28,19 @@ public void SetShuttleName(string name) ShuttleNameLabel.Text = name; } - public void SetOrders(List orders) + public void SetOrders(SpriteSystem sprites, IPrototypeManager protoManager, List orders) { Orders.DisposeAllChildren(); foreach (var order in orders) { - var product = _protoManager.Index(order.ProductId); + var product = protoManager.Index(order.ProductId); var productName = product.Name; var row = new CargoOrderRow { Order = order, - Icon = { Texture = _spriteSystem.Frame0(product) }, + Icon = { Texture = sprites.Frame0(product) }, ProductName = { Text = Loc.GetString( diff --git a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs index 988fea7978b..3ef7f0ae73e 100644 --- a/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ChemMasterBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Containers.ItemSlots; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -27,13 +28,8 @@ protected override void Open() base.Open(); // Setup window layout/elements - _window = new ChemMasterWindow - { - Title = EntMan.GetComponent(Owner).EntityName, - }; - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.Title = EntMan.GetComponent(Owner).EntityName; // Setup static button actions. _window.InputEjectButton.OnPressed += _ => SendMessage( @@ -75,15 +71,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); // Update window state } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } } } diff --git a/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs b/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs index 99e5a3d3953..2ad1b718887 100644 --- a/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/ReagentDispenserBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Containers.ItemSlots; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -15,9 +16,6 @@ public sealed class ReagentDispenserBoundUserInterface : BoundUserInterface [ViewVariables] private ReagentDispenserWindow? _window; - [ViewVariables] - private ReagentDispenserBoundUserInterfaceState? _lastState; - public ReagentDispenserBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -32,14 +30,9 @@ protected override void Open() base.Open(); // Setup window layout/elements - _window = new() - { - Title = EntMan.GetComponent(Owner).EntityName, - HelpGuidebookIds = EntMan.GetComponent(Owner).Guides - }; - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.Title = EntMan.GetComponent(Owner).EntityName; + _window.HelpGuidebookIds = EntMan.GetComponent(Owner).Guides; // Setup static button actions. _window.EjectButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(SharedReagentDispenser.OutputSlotName)); @@ -63,19 +56,7 @@ protected override void UpdateState(BoundUserInterfaceState state) base.UpdateState(state); var castState = (ReagentDispenserBoundUserInterfaceState) state; - _lastState = castState; - _window?.UpdateState(castState); //Update window state } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } } } diff --git a/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs b/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs index 35df131312d..f1cb27a62a4 100644 --- a/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs +++ b/Content.Client/Chemistry/UI/TransferAmountBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.FixedPoint; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Chemistry.UI { @@ -18,7 +19,7 @@ public TransferAmountBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = new TransferAmountWindow(); + _window = this.CreateWindow(); _window.ApplyButton.OnPressed += _ => { @@ -28,15 +29,6 @@ protected override void Open() _window.Close(); } }; - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); } } } diff --git a/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs b/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs index 26f0994701e..62a02f37186 100644 --- a/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs +++ b/Content.Client/CloningConsole/UI/CloningConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; using Content.Shared.Cloning.CloningConsole; +using Robust.Client.UserInterface; namespace Content.Client.CloningConsole.UI { @@ -17,13 +18,11 @@ public CloningConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = new CloningConsoleWindow - { - Title = Loc.GetString("cloning-console-window-title") - }; - _window.OnClose += Close; + + _window = this.CreateWindow(); + _window.Title = Loc.GetString("cloning-console-window-title"); + _window.CloneButton.OnPressed += _ => SendMessage(new UiButtonPressedMessage(UiButton.Clone)); - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -32,19 +31,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.Populate((CloningConsoleBoundUserInterfaceState) state); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_window != null) - { - _window.OnClose -= Close; - _window.CloneButton.OnPressed -= _ => SendMessage(new UiButtonPressedMessage(UiButton.Clone)); - } - _window?.Dispose(); - } } } diff --git a/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs b/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs index 5b0d5fcf21f..83f6ba15662 100644 --- a/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs +++ b/Content.Client/Clothing/UI/ChameleonBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Clothing.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Clothing.UI; @@ -22,10 +23,8 @@ protected override void Open() { base.Open(); - _menu = new ChameleonMenu(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.OnIdSelected += OnIdSelected; - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -42,15 +41,4 @@ private void OnIdSelected(string selectedId) { SendMessage(new ChameleonPrototypeSelectedMessage(selectedId)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _menu?.Close(); - _menu = null; - } - } } diff --git a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs index 1c94d32bf8d..0310e91eeb0 100644 --- a/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs +++ b/Content.Client/Communications/UI/CommunicationsConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.CCVar; using Content.Shared.Chat; using Content.Shared.Communications; +using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Timing; @@ -8,34 +9,11 @@ namespace Content.Client.Communications.UI { public sealed class CommunicationsConsoleBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; [ViewVariables] private CommunicationsConsoleMenu? _menu; - [ViewVariables] - public bool CanAnnounce { get; private set; } - [ViewVariables] - public bool CanBroadcast { get; private set; } - - [ViewVariables] - public bool CanCall { get; private set; } - - [ViewVariables] - public bool CountdownStarted { get; private set; } - - [ViewVariables] - public bool AlertLevelSelectable { get; private set; } - - [ViewVariables] - public string CurrentLevel { get; private set; } = default!; - - [ViewVariables] - private TimeSpan? _expectedCountdownTime; - - public int Countdown => _expectedCountdownTime == null ? 0 : Math.Max((int) _expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0); - public CommunicationsConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -44,23 +22,25 @@ protected override void Open() { base.Open(); - _menu = new CommunicationsConsoleMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnAnnounce += AnnounceButtonPressed; + _menu.OnBroadcast += BroadcastButtonPressed; + _menu.OnAlertLevel += AlertLevelSelected; + _menu.OnEmergencyLevel += EmergencyShuttleButtonPressed; } public void AlertLevelSelected(string level) { - if (AlertLevelSelectable) + if (_menu!.AlertLevelSelectable) { - CurrentLevel = level; + _menu.CurrentLevel = level; SendMessage(new CommunicationsConsoleSelectAlertLevelMessage(level)); } } public void EmergencyShuttleButtonPressed() { - if (CountdownStarted) + if (_menu!.CountdownStarted) RecallShuttle(); else CallShuttle(); @@ -95,31 +75,23 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not CommunicationsConsoleInterfaceState commsState) return; - CanAnnounce = commsState.CanAnnounce; - CanBroadcast = commsState.CanBroadcast; - CanCall = commsState.CanCall; - _expectedCountdownTime = commsState.ExpectedCountdownEnd; - CountdownStarted = commsState.CountdownStarted; - AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0; - CurrentLevel = commsState.CurrentAlert; - if (_menu != null) { + _menu.CanAnnounce = commsState.CanAnnounce; + _menu.CanBroadcast = commsState.CanBroadcast; + _menu.CanCall = commsState.CanCall; + _menu.CountdownStarted = commsState.CountdownStarted; + _menu.AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0; + _menu.CurrentLevel = commsState.CurrentAlert; + _menu.CountdownEnd = commsState.ExpectedCountdownEnd; + _menu.UpdateCountdown(); - _menu.UpdateAlertLevels(commsState.AlertLevels, CurrentLevel); - _menu.AlertLevelButton.Disabled = !AlertLevelSelectable; - _menu.EmergencyShuttleButton.Disabled = !CanCall; - _menu.AnnounceButton.Disabled = !CanAnnounce; - _menu.BroadcastButton.Disabled = !CanBroadcast; + _menu.UpdateAlertLevels(commsState.AlertLevels, _menu.CurrentLevel); + _menu.AlertLevelButton.Disabled = !_menu.AlertLevelSelectable; + _menu.EmergencyShuttleButton.Disabled = !_menu.CanCall; + _menu.AnnounceButton.Disabled = !_menu.CanAnnounce; + _menu.BroadcastButton.Disabled = !_menu.CanBroadcast; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _menu?.Dispose(); - } } } diff --git a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs index bbca06f5194..63868e7a93e 100644 --- a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs +++ b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs @@ -1,31 +1,40 @@ -using Content.Client.UserInterface.Controls; -using System.Threading; +using System.Globalization; +using Content.Client.UserInterface.Controls; using Content.Shared.CCVar; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.XAML; using Robust.Shared.Configuration; +using Robust.Shared.Timing; using Robust.Shared.Utility; -using Timer = Robust.Shared.Timing.Timer; namespace Content.Client.Communications.UI { [GenerateTypedNameReferences] public sealed partial class CommunicationsConsoleMenu : FancyWindow { - private CommunicationsConsoleBoundUserInterface Owner { get; set; } - private readonly CancellationTokenSource _timerCancelTokenSource = new(); - [Dependency] private readonly IConfigurationManager _cfg = default!; - - public CommunicationsConsoleMenu(CommunicationsConsoleBoundUserInterface owner) + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly ILocalizationManager _loc = default!; + + public bool CanAnnounce; + public bool CanBroadcast; + public bool CanCall; + public bool AlertLevelSelectable; + public bool CountdownStarted; + public string CurrentLevel = string.Empty; + public TimeSpan? CountdownEnd; + + public event Action? OnEmergencyLevel; + public event Action? OnAlertLevel; + public event Action? OnAnnounce; + public event Action? OnBroadcast; + + public CommunicationsConsoleMenu() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - Owner = owner; - - var loc = IoCManager.Resolve(); - MessageInput.Placeholder = new Rope.Leaf(loc.GetString("comms-console-menu-announcement-placeholder")); + MessageInput.Placeholder = new Rope.Leaf(_loc.GetString("comms-console-menu-announcement-placeholder")); var maxAnnounceLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength); MessageInput.OnTextChanged += (args) => @@ -37,33 +46,38 @@ public CommunicationsConsoleMenu(CommunicationsConsoleBoundUserInterface owner) } else { - AnnounceButton.Disabled = !owner.CanAnnounce; + AnnounceButton.Disabled = !CanAnnounce; AnnounceButton.ToolTip = null; } }; - AnnounceButton.OnPressed += (_) => Owner.AnnounceButtonPressed(Rope.Collapse(MessageInput.TextRope)); - AnnounceButton.Disabled = !owner.CanAnnounce; + AnnounceButton.OnPressed += _ => OnAnnounce?.Invoke(Rope.Collapse(MessageInput.TextRope)); + AnnounceButton.Disabled = !CanAnnounce; - BroadcastButton.OnPressed += (_) => Owner.BroadcastButtonPressed(Rope.Collapse(MessageInput.TextRope)); - BroadcastButton.Disabled = !owner.CanBroadcast; + BroadcastButton.OnPressed += _ => OnBroadcast?.Invoke(Rope.Collapse(MessageInput.TextRope)); + BroadcastButton.Disabled = !CanBroadcast; AlertLevelButton.OnItemSelected += args => { var metadata = AlertLevelButton.GetItemMetadata(args.Id); if (metadata != null && metadata is string cast) { - Owner.AlertLevelSelected(cast); + OnAlertLevel?.Invoke(cast); } }; - AlertLevelButton.Disabled = !owner.AlertLevelSelectable; - EmergencyShuttleButton.OnPressed += (_) => Owner.EmergencyShuttleButtonPressed(); - EmergencyShuttleButton.Disabled = !owner.CanCall; + AlertLevelButton.Disabled = !AlertLevelSelectable; + + EmergencyShuttleButton.OnPressed += _ => OnEmergencyLevel?.Invoke(); + EmergencyShuttleButton.Disabled = !CanCall; + } + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); UpdateCountdown(); - Timer.SpawnRepeating(1000, UpdateCountdown, _timerCancelTokenSource.Token); } // The current alert could make levels unselectable, so we need to ensure that the UI reacts properly. @@ -105,32 +119,19 @@ public void UpdateAlertLevels(List? alerts, string currentAlert) public void UpdateCountdown() { - if (!Owner.CountdownStarted) + if (!CountdownStarted) { - CountdownLabel.SetMessage(""); + CountdownLabel.SetMessage(string.Empty); EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-call-shuttle"); return; } + var diff = MathHelper.Max((CountdownEnd - _timing.CurTime) ?? TimeSpan.Zero, TimeSpan.Zero); + EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-recall-shuttle"); var infoText = Loc.GetString($"comms-console-menu-time-remaining", - ("time", Owner.Countdown.ToString())); + ("time", diff.TotalSeconds.ToString(CultureInfo.CurrentCulture))); CountdownLabel.SetMessage(infoText); } - - public override void Close() - { - base.Close(); - - _timerCancelTokenSource.Cancel(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - _timerCancelTokenSource.Cancel(); - } } } diff --git a/Content.Client/Computer/ComputerBoundUserInterface.cs b/Content.Client/Computer/ComputerBoundUserInterface.cs index bdbfe03fa10..11c26b252e9 100644 --- a/Content.Client/Computer/ComputerBoundUserInterface.cs +++ b/Content.Client/Computer/ComputerBoundUserInterface.cs @@ -1,4 +1,5 @@ using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; namespace Content.Client.Computer @@ -19,10 +20,8 @@ protected override void Open() { base.Open(); - _window = (TWindow) _dynamicTypeFactory.CreateInstance(typeof(TWindow)); + _window = this.CreateWindow(); _window.SetupComputerWindow(this); - _window.OnClose += Close; - _window.OpenCentered(); } // Alas, this constructor has to be copied to the subclass. :( @@ -42,16 +41,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState((TState) state); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } - protected override void ReceiveMessage(BoundUserInterfaceMessage message) { _window?.ReceiveMessage(message); diff --git a/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs b/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs index 4fea44f2253..e4966f1ec43 100644 --- a/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs +++ b/Content.Client/Configurable/UI/ConfigurationBoundUserInterface.cs @@ -1,5 +1,6 @@ using System.Text.RegularExpressions; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using static Content.Shared.Configurable.ConfigurationComponent; namespace Content.Client.Configurable.UI @@ -9,9 +10,6 @@ public sealed class ConfigurationBoundUserInterface : BoundUserInterface [ViewVariables] private ConfigurationMenu? _menu; - [ViewVariables] - public Regex? Validation { get; internal set; } - public ConfigurationBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -19,10 +17,8 @@ public ConfigurationBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner protected override void Open() { base.Open(); - _menu = new ConfigurationMenu(this); - - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnConfiguration += SendConfiguration; } protected override void UpdateState(BoundUserInterfaceState state) @@ -30,9 +26,7 @@ protected override void UpdateState(BoundUserInterfaceState state) base.UpdateState(state); if (state is not ConfigurationBoundUserInterfaceState configurationState) - { return; - } _menu?.Populate(configurationState); } @@ -41,9 +35,12 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) { base.ReceiveMessage(message); + if (_menu == null) + return; + if (message is ValidationUpdateMessage msg) { - Validation = new Regex(msg.ValidationString, RegexOptions.Compiled); + _menu.Validation = new Regex(msg.ValidationString, RegexOptions.Compiled); } } @@ -51,16 +48,5 @@ public void SendConfiguration(Dictionary config) { SendMessage(new ConfigurationUpdatedMessage(config)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing && _menu != null) - { - _menu.OnClose -= Close; - _menu.Close(); - } - } } } diff --git a/Content.Client/Configurable/UI/ConfigurationMenu.cs b/Content.Client/Configurable/UI/ConfigurationMenu.cs index cc24af28692..29217eef7be 100644 --- a/Content.Client/Configurable/UI/ConfigurationMenu.cs +++ b/Content.Client/Configurable/UI/ConfigurationMenu.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Numerics; +using System.Text.RegularExpressions; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; @@ -13,23 +14,25 @@ namespace Content.Client.Configurable.UI { public sealed class ConfigurationMenu : DefaultWindow { - public ConfigurationBoundUserInterface Owner { get; } - private readonly BoxContainer _column; private readonly BoxContainer _row; private readonly List<(string name, LineEdit input)> _inputs; - public ConfigurationMenu(ConfigurationBoundUserInterface owner) + [ViewVariables] + public Regex? Validation { get; internal set; } + + public event Action>? OnConfiguration; + + public ConfigurationMenu() { MinSize = SetSize = new Vector2(300, 250); - Owner = owner; _inputs = new List<(string name, LineEdit input)>(); Title = Loc.GetString("configuration-menu-device-title"); - BoxContainer baseContainer = new BoxContainer + var baseContainer = new BoxContainer { Orientation = LayoutOrientation.Vertical, VerticalExpand = true, @@ -116,14 +119,13 @@ public void Populate(ConfigurationBoundUserInterfaceState state) private void OnConfirm(ButtonEventArgs args) { var config = GenerateDictionary(_inputs, "Text"); - - Owner.SendConfiguration(config); + OnConfiguration?.Invoke(config); Close(); } private bool Validate(string value) { - return Owner.Validation == null || Owner.Validation.IsMatch(value); + return Validation?.IsMatch(value) != false; } private Dictionary GenerateDictionary(IEnumerable<(string name, LineEdit input)> inputs, string propertyName) diff --git a/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs b/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs index 86f1b8b83c7..887492955e9 100644 --- a/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs +++ b/Content.Client/Construction/UI/FlatpackCreatorBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Construction.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Construction.UI { @@ -17,8 +18,8 @@ protected override void Open() { base.Open(); - _menu = new FlatpackCreatorMenu(Owner); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); _menu.PackButtonPressed += () => { @@ -27,14 +28,5 @@ protected override void Open() _menu.OpenCentered(); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } } } diff --git a/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs b/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs index 9f3d5695bb6..269694ebf9e 100644 --- a/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs +++ b/Content.Client/Construction/UI/FlatpackCreatorMenu.xaml.cs @@ -24,7 +24,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow private readonly FlatpackSystem _flatpack; private readonly MaterialStorageSystem _materialStorage; - private readonly EntityUid _owner; + private EntityUid _owner; [ValidatePrototypeId] public const string NoBoardEffectId = "FlatpackerNoBoardEffect"; @@ -33,7 +33,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow public event Action? PackButtonPressed; - public FlatpackCreatorMenu(EntityUid uid) + public FlatpackCreatorMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -42,14 +42,17 @@ public FlatpackCreatorMenu(EntityUid uid) _flatpack = _entityManager.System(); _materialStorage = _entityManager.System(); - _owner = uid; - PackButton.OnPressed += _ => PackButtonPressed?.Invoke(); - MaterialStorageControl.SetOwner(uid); InsertLabel.SetMarkup(Loc.GetString("flatpacker-ui-insert-board")); } + public void SetEntity(EntityUid uid) + { + _owner = uid; + MaterialStorageControl.SetOwner(uid); + } + protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); diff --git a/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs b/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs index e2c4d51ecd1..e5be0b1811f 100644 --- a/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs +++ b/Content.Client/Crayon/UI/CrayonBoundUserInterface.cs @@ -2,12 +2,15 @@ using Content.Shared.Crayon; using Content.Shared.Decals; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Crayon.UI { public sealed class CrayonBoundUserInterface : BoundUserInterface { + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [ViewVariables] private CrayonWindow? _menu; @@ -18,15 +21,29 @@ public CrayonBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey protected override void Open() { base.Open(); - _menu = new CrayonWindow(this); - - _menu.OnClose += Close; - var prototypeManager = IoCManager.Resolve(); - var crayonDecals = prototypeManager.EnumeratePrototypes().Where(x => x.Tags.Contains("crayon")); - _menu.Populate(crayonDecals); + _menu = this.CreateWindow(); + _menu.OnColorSelected += SelectColor; + _menu.OnSelected += Select; + PopulateCrayons(); _menu.OpenCenteredLeft(); } + private void PopulateCrayons() + { + var crayonDecals = _protoManager.EnumeratePrototypes().Where(x => x.Tags.Contains("crayon")); + _menu?.Populate(crayonDecals); + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + + if (!args.WasModified()) + return; + + PopulateCrayons(); + } + protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); @@ -43,16 +60,5 @@ public void SelectColor(Color color) { SendMessage(new CrayonColorMessage(color)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _menu?.Close(); - _menu = null; - } - } } } diff --git a/Content.Client/Crayon/UI/CrayonWindow.xaml.cs b/Content.Client/Crayon/UI/CrayonWindow.xaml.cs index 2a5801ccf2d..b97786cd41a 100644 --- a/Content.Client/Crayon/UI/CrayonWindow.xaml.cs +++ b/Content.Client/Crayon/UI/CrayonWindow.xaml.cs @@ -18,18 +18,17 @@ namespace Content.Client.Crayon.UI [GenerateTypedNameReferences] public sealed partial class CrayonWindow : DefaultWindow { - public CrayonBoundUserInterface Owner { get; } - private Dictionary? _decals; private string? _selected; private Color _color; - public CrayonWindow(CrayonBoundUserInterface owner) + public event Action? OnColorSelected; + public event Action? OnSelected; + + public CrayonWindow() { RobustXamlLoader.Load(this); - Owner = owner; - Search.OnTextChanged += _ => RefreshList(); ColorSelector.OnColorChanged += SelectColor; } @@ -38,16 +37,16 @@ private void SelectColor(Color color) { _color = color; - Owner.SelectColor(color); - + OnColorSelected?.Invoke(color); RefreshList(); } private void RefreshList() { // Clear - Grid.RemoveAllChildren(); - if (_decals == null) return; + Grid.DisposeAllChildren(); + if (_decals == null) + return; var filter = Search.Text; foreach (var (decal, tex) in _decals) @@ -89,7 +88,6 @@ private void ButtonOnPressed(ButtonEventArgs obj) { if (obj.Button.Name == null) return; - Owner.Select(obj.Button.Name); _selected = obj.Button.Name; RefreshList(); } diff --git a/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs b/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs index e8e77217ea5..296e71d3a95 100644 --- a/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs +++ b/Content.Client/Disposal/UI/DisposalRouterBoundUserInterface.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent; namespace Content.Client.Disposal.UI @@ -21,20 +22,16 @@ protected override void Open() { base.Open(); - _window = new DisposalRouterWindow(); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text); _window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text); - } private void ButtonPressed(UiAction action, string tag) { SendMessage(new UiActionMessage(action, tag)); - _window?.Close(); + Close(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -48,18 +45,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } - - } - } diff --git a/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs b/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs index 3aeed8dc802..7fc0eb85401 100644 --- a/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs +++ b/Content.Client/Disposal/UI/DisposalTaggerBoundUserInterface.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent; namespace Content.Client.Disposal.UI @@ -21,20 +22,17 @@ protected override void Open() { base.Open(); - _window = new DisposalTaggerWindow(); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text); _window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text); - } private void ButtonPressed(UiAction action, string tag) { + // TODO: This looks copy-pasted with the other mailing stuff... SendMessage(new UiActionMessage(action, tag)); - _window?.Close(); + Close(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -48,18 +46,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Dispose(); - } - } - - } - } diff --git a/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs b/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs index cd7ea717ce3..9b7e23c03aa 100644 --- a/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs +++ b/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Access; using Content.Shared.Doors.Electronics; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Doors.Electronics; @@ -18,6 +19,23 @@ public DoorElectronicsBoundUserInterface(EntityUid owner, Enum uiKey) : base(own protected override void Open() { base.Open(); + _window = this.CreateWindow(); + _window.OnAccessChanged += UpdateConfiguration; + Reset(); + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + + if (!args.WasModified()) + return; + + Reset(); + } + + private void Reset() + { List> accessLevels = new(); foreach (var accessLevel in _prototypeManager.EnumeratePrototypes()) @@ -29,10 +47,7 @@ protected override void Open() } accessLevels.Sort(); - - _window = new DoorElectronicsConfigurationMenu(this, accessLevels, _prototypeManager); - _window.OnClose += Close; - _window.OpenCentered(); + _window?.Reset(_prototypeManager, accessLevels); } protected override void UpdateState(BoundUserInterfaceState state) @@ -44,14 +59,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _window?.Dispose(); - } - public void UpdateConfiguration(List> newAccessList) { SendMessage(new DoorElectronicsUpdateConfigurationMessage(newAccessList)); diff --git a/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs index c01f13a462e..2112a562971 100644 --- a/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs +++ b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs @@ -15,22 +15,23 @@ namespace Content.Client.Doors.Electronics; [GenerateTypedNameReferences] public sealed partial class DoorElectronicsConfigurationMenu : FancyWindow { - private readonly DoorElectronicsBoundUserInterface _owner; - private AccessLevelControl _buttonsList = new(); + private readonly AccessLevelControl _buttonsList = new(); - public DoorElectronicsConfigurationMenu(DoorElectronicsBoundUserInterface ui, List> accessLevels, IPrototypeManager prototypeManager) + public event Action>>? OnAccessChanged; + + public DoorElectronicsConfigurationMenu() { RobustXamlLoader.Load(this); - - _owner = ui; - - _buttonsList.Populate(accessLevels, prototypeManager); AccessLevelControlContainer.AddChild(_buttonsList); + } + + public void Reset(IPrototypeManager protoManager, List> accessLevels) + { + _buttonsList.Populate(accessLevels, protoManager); - foreach (var (id, button) in _buttonsList.ButtonsList) + foreach (var button in _buttonsList.ButtonsList.Values) { - button.OnPressed += _ => _owner.UpdateConfiguration( - _buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); + button.OnPressed += _ => OnAccessChanged?.Invoke(_buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); } } diff --git a/Content.Client/Fax/UI/FaxBoundUi.cs b/Content.Client/Fax/UI/FaxBoundUi.cs index a95066a3b58..ca2e834b4fe 100644 --- a/Content.Client/Fax/UI/FaxBoundUi.cs +++ b/Content.Client/Fax/UI/FaxBoundUi.cs @@ -25,10 +25,7 @@ protected override void Open() { base.Open(); - _window = new FaxWindow(); - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.FileButtonPressed += OnFileButtonPressed; _window.CopyButtonPressed += OnCopyButtonPressed; _window.SendButtonPressed += OnSendButtonPressed; @@ -104,11 +101,4 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - _window?.Dispose(); - } } diff --git a/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs b/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs index ba49f11ea0f..08596b04e6e 100644 --- a/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs +++ b/Content.Client/Forensics/ForensicScannerBoundUserInterface.cs @@ -1,6 +1,7 @@ using Robust.Client.GameObjects; using Robust.Shared.Timing; using Content.Shared.Forensics; +using Robust.Client.UserInterface; namespace Content.Client.Forensics { @@ -21,11 +22,9 @@ public ForensicScannerBoundUserInterface(EntityUid owner, Enum uiKey) : base(own protected override void Open() { base.Open(); - _window = new ForensicScannerMenu(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.Print.OnPressed += _ => Print(); _window.Clear.OnPressed += _ => Clear(); - _window.OpenCentered(); } private void Print() @@ -62,6 +61,7 @@ protected override void UpdateState(BoundUserInterfaceState state) _printCooldown = cast.PrintCooldown; + // TODO: Fix this if (cast.PrintReadyAt > _gameTiming.CurTime) Timer.Spawn(cast.PrintReadyAt - _gameTiming.CurTime, () => { @@ -71,14 +71,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); - } } } diff --git a/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs b/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs index fdb3cdbc010..457b70ca7ca 100644 --- a/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs +++ b/Content.Client/Gateway/UI/GatewayBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Gateway; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Gateway.UI; @@ -17,24 +18,13 @@ protected override void Open() { base.Open(); - _window = new GatewayWindow(EntMan.GetNetEntity(Owner)); + _window = this.CreateWindow(); + _window.SetEntity(EntMan.GetNetEntity(Owner)); _window.OpenPortal += destination => { SendMessage(new GatewayOpenPortalMessage(destination)); }; - _window.OnClose += Close; - _window?.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _window?.Dispose(); - _window = null; - } } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Gateway/UI/GatewayWindow.xaml.cs b/Content.Client/Gateway/UI/GatewayWindow.xaml.cs index 889dd6e1759..1c779b2b350 100644 --- a/Content.Client/Gateway/UI/GatewayWindow.xaml.cs +++ b/Content.Client/Gateway/UI/GatewayWindow.xaml.cs @@ -22,7 +22,7 @@ public sealed partial class GatewayWindow : FancyWindow, public event Action? OpenPortal; private List _destinations = new(); - public readonly NetEntity Owner; + public NetEntity Owner; private NetEntity? _current; private TimeSpan _nextReady; @@ -46,16 +46,20 @@ public sealed partial class GatewayWindow : FancyWindow, /// private bool _isCooldownPending = true; - public GatewayWindow(NetEntity netEntity) + public GatewayWindow() { RobustXamlLoader.Load(this); var dependencies = IoCManager.Instance!; _timing = dependencies.Resolve(); - Owner = netEntity; NextUnlockBar.ForegroundStyleBoxOverride = new StyleBoxFlat(Color.FromHex("#C74EBD")); } + public void SetEntity(NetEntity entity) + { + + } + public void UpdateState(GatewayBoundUserInterfaceState state) { _destinations = state.Destinations; diff --git a/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs b/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs index d72da3e8120..32b40747d55 100644 --- a/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs +++ b/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.Gravity; using JetBrains.Annotations; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Gravity.UI { @@ -18,17 +18,8 @@ protected override void Open() { base.Open(); - _window = new GravityGeneratorWindow(this); - - /* - _window.Switch.OnPressed += _ => - { - SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(!IsOn)); - }; - */ - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.SetEntity(Owner); } protected override void UpdateState(BoundUserInterfaceState state) @@ -39,14 +30,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _window?.Dispose(); - } - public void SetPowerSwitch(bool on) { SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on)); diff --git a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs b/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs index 75f8eb479b5..6f04133b594 100644 --- a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs +++ b/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs @@ -12,22 +12,23 @@ public sealed partial class GravityGeneratorWindow : FancyWindow { private readonly ButtonGroup _buttonGroup = new(); - private readonly GravityGeneratorBoundUserInterface _owner; + public event Action? OnPowerSwitch; - public GravityGeneratorWindow(GravityGeneratorBoundUserInterface owner) + public GravityGeneratorWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - _owner = owner; - OnButton.Group = _buttonGroup; OffButton.Group = _buttonGroup; - OnButton.OnPressed += _ => _owner.SetPowerSwitch(true); - OffButton.OnPressed += _ => _owner.SetPowerSwitch(false); + OnButton.OnPressed += _ => OnPowerSwitch?.Invoke(true); + OffButton.OnPressed += _ => OnPowerSwitch?.Invoke(false); + } - EntityView.SetEntity(owner.Owner); + public void SetEntity(EntityUid uid) + { + EntityView.SetEntity(uid); } public void UpdateState(SharedGravityGeneratorComponent.GeneratorState state) diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs index dc0a3e9fccd..38760f4aa3c 100644 --- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs +++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.MedicalScanner; using JetBrains.Annotations; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.HealthAnalyzer.UI { @@ -17,12 +17,9 @@ public HealthAnalyzerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = new HealthAnalyzerWindow - { - Title = EntMan.GetComponent(Owner).EntityName, - }; - _window.OnClose += Close; - _window.OpenCentered(); + _window = this.CreateWindow(); + + _window.Title = EntMan.GetComponent(Owner).EntityName; } protected override void ReceiveMessage(BoundUserInterfaceMessage message) @@ -35,17 +32,5 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) _window.Populate(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_window != null) - _window.OnClose -= Close; - - _window?.Dispose(); - } } } diff --git a/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs b/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs index a8872604a4c..53977eb636b 100644 --- a/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs +++ b/Content.Client/Humanoid/HumanoidMarkingModifierBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Humanoid; using Content.Shared.Humanoid.Markings; +using Robust.Client.UserInterface; namespace Content.Client.Humanoid; @@ -20,8 +21,7 @@ protected override void Open() { base.Open(); - _window = new(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.OnMarkingAdded += SendMarkingSet; _window.OnMarkingRemoved += SendMarkingSet; _window.OnMarkingColorChange += SendMarkingSetNoResend; diff --git a/Content.Client/Instruments/UI/BandMenu.xaml.cs b/Content.Client/Instruments/UI/BandMenu.xaml.cs index 5fb293a194d..26cd1369e55 100644 --- a/Content.Client/Instruments/UI/BandMenu.xaml.cs +++ b/Content.Client/Instruments/UI/BandMenu.xaml.cs @@ -11,7 +11,9 @@ public sealed partial class BandMenu : DefaultWindow { private readonly InstrumentBoundUserInterface _owner; - public BandMenu(InstrumentBoundUserInterface owner) : base() + public EntityUid? Master; + + public BandMenu(InstrumentBoundUserInterface owner) { RobustXamlLoader.Load(this); @@ -40,7 +42,7 @@ public void Populate((NetEntity, string)[] nearby, IEntityManager entManager) { var uid = entManager.GetEntity(nent); var item = BandList.AddItem(name, null, true, uid); - item.Selected = _owner.Instrument?.Master == uid; + item.Selected = Master == uid; } } } diff --git a/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs b/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs index 2814d415365..c175e67842f 100644 --- a/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs +++ b/Content.Client/Instruments/UI/ChannelsMenu.xaml.cs @@ -51,7 +51,7 @@ private void OnClearPressed(BaseButton.ButtonEventArgs obj) } } - public void Populate() + public void Populate(InstrumentComponent? instrument) { ChannelList.Clear(); @@ -60,7 +60,8 @@ public void Populate() var item = ChannelList.AddItem(_owner.Loc.GetString("instrument-component-channel-name", ("number", i)), null, true, i); - item.Selected = !_owner.Instrument?.FilteredChannels[i] ?? false; + + item.Selected = !instrument?.FilteredChannels[i] ?? false; } } } diff --git a/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs b/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs index 0f5729f55b1..4816ce8c365 100644 --- a/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs +++ b/Content.Client/Instruments/UI/InstrumentBoundUserInterface.cs @@ -24,8 +24,6 @@ public sealed class InstrumentBoundUserInterface : BoundUserInterface [ViewVariables] private BandMenu? _bandMenu; [ViewVariables] private ChannelsMenu? _channelsMenu; - [ViewVariables] public InstrumentComponent? Instrument { get; private set; } - public InstrumentBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { IoCManager.InjectDependencies(this); @@ -43,14 +41,20 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) protected override void Open() { - if (!EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) - return; + _instrumentMenu = this.CreateWindow(); + _instrumentMenu.Title = EntMan.GetComponent(Owner).EntityName; - Instrument = instrument; - _instrumentMenu = new InstrumentMenu(this); - _instrumentMenu.OnClose += Close; + _instrumentMenu.OnOpenBand += OpenBandMenu; + _instrumentMenu.OnOpenChannels += OpenChannelsMenu; + _instrumentMenu.OnCloseChannels += CloseChannelsMenu; + _instrumentMenu.OnCloseBands += CloseBandMenu; - _instrumentMenu.OpenCentered(); + _instrumentMenu.SetMIDI(MidiManager.IsAvailable); + + if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) + { + _instrumentMenu.SetInstrument((Owner, instrument)); + } } protected override void Dispose(bool disposing) @@ -58,7 +62,12 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); if (!disposing) return; - _instrumentMenu?.Dispose(); + + if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) + { + _instrumentMenu?.RemoveInstrument(instrument); + } + _bandMenu?.Dispose(); _channelsMenu?.Dispose(); } @@ -72,6 +81,11 @@ public void OpenBandMenu() { _bandMenu ??= new BandMenu(this); + if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument)) + { + _bandMenu.Master = instrument.Master; + } + // Refresh cache... RefreshBands(); @@ -87,7 +101,9 @@ public void CloseBandMenu() public void OpenChannelsMenu() { _channelsMenu ??= new ChannelsMenu(this); - _channelsMenu.Populate(); + EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument); + + _channelsMenu.Populate(instrument); _channelsMenu.OpenCenteredRight(); } diff --git a/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs b/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs index da443e3fb5b..fc863648d79 100644 --- a/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs +++ b/Content.Client/Instruments/UI/InstrumentMenu.xaml.cs @@ -1,7 +1,10 @@ using System.IO; using System.Numerics; using System.Threading.Tasks; +using Content.Client.Interactable; +using Content.Shared.ActionBlocker; using Robust.Client.AutoGenerated; +using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; @@ -16,33 +19,23 @@ namespace Content.Client.Instruments.UI [GenerateTypedNameReferences] public sealed partial class InstrumentMenu : DefaultWindow { - private readonly InstrumentBoundUserInterface _owner; + [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private readonly IFileDialogManager _dialogs = default!; + [Dependency] private readonly IPlayerManager _player = default!; private bool _isMidiFileDialogueWindowOpen; - public InstrumentMenu(InstrumentBoundUserInterface owner) - { - RobustXamlLoader.Load(this); - - _owner = owner; + public event Action? OnOpenBand; + public event Action? OnOpenChannels; + public event Action? OnCloseBands; + public event Action? OnCloseChannels; - if (_owner.Instrument != null) - { - _owner.Instrument.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded; - Title = _owner.Entities.GetComponent(_owner.Owner).EntityName; - LoopButton.Disabled = !_owner.Instrument.IsMidiOpen; - LoopButton.Pressed = _owner.Instrument.LoopMidi; - ChannelsButton.Disabled = !_owner.Instrument.IsRendererAlive; - StopButton.Disabled = !_owner.Instrument.IsMidiOpen; - PlaybackSlider.MouseFilter = _owner.Instrument.IsMidiOpen ? MouseFilterMode.Pass : MouseFilterMode.Ignore; - } + public EntityUid Entity; - if (!_owner.MidiManager.IsAvailable) - { - UnavailableOverlay.Visible = true; - // We return early as to not give the buttons behavior. - return; - } + public InstrumentMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); InputButton.OnToggled += MidiInputButtonOnOnToggled; BandButton.OnPressed += BandButtonOnPressed; @@ -57,12 +50,34 @@ public InstrumentMenu(InstrumentBoundUserInterface owner) MinSize = SetSize = new Vector2(400, 150); } + public void SetInstrument(Entity entity) + { + Entity = entity; + var component = entity.Comp; + component.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded; + LoopButton.Disabled = !component.IsMidiOpen; + LoopButton.Pressed = component.LoopMidi; + ChannelsButton.Disabled = !component.IsRendererAlive; + StopButton.Disabled = !component.IsMidiOpen; + PlaybackSlider.MouseFilter = component.IsMidiOpen ? MouseFilterMode.Pass : MouseFilterMode.Ignore; + } + + public void RemoveInstrument(InstrumentComponent component) + { + component.OnMidiPlaybackEnded -= InstrumentOnMidiPlaybackEnded; + } + + public void SetMIDI(bool available) + { + UnavailableOverlay.Visible = !available; + } + private void BandButtonOnPressed(ButtonEventArgs obj) { if (!PlayCheck()) return; - _owner.OpenBandMenu(); + OnOpenBand?.Invoke(); } private void BandButtonOnToggled(ButtonToggledEventArgs obj) @@ -70,12 +85,15 @@ private void BandButtonOnToggled(ButtonToggledEventArgs obj) if (obj.Pressed) return; - _owner.Instruments.SetMaster(_owner.Owner, null); + if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) + { + _entManager.System().SetMaster(Entity, instrument.Master); + } } private void ChannelsButtonOnPressed(ButtonEventArgs obj) { - _owner.OpenChannelsMenu(); + OnOpenChannels?.Invoke(); } private void InstrumentOnMidiPlaybackEnded() @@ -85,8 +103,10 @@ private void InstrumentOnMidiPlaybackEnded() public void MidiPlaybackSetButtonsDisabled(bool disabled) { - if(disabled) - _owner.CloseChannelsMenu(); + if (disabled) + { + OnCloseChannels?.Invoke(); + } LoopButton.Disabled = disabled; StopButton.Disabled = disabled; @@ -100,7 +120,7 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) if (_isMidiFileDialogueWindowOpen) return; - _owner.CloseBandMenu(); + OnCloseBands?.Invoke(); var filters = new FileDialogFilters(new FileDialogFilters.Group("mid", "midi")); @@ -108,7 +128,7 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) // or focus the previously-opened window. _isMidiFileDialogueWindowOpen = true; - await using var file = await _owner.FileDialogManager.OpenFile(filters); + await using var file = await _dialogs.OpenFile(filters); _isMidiFileDialogueWindowOpen = false; @@ -129,9 +149,18 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) await file.CopyToAsync(memStream); - if (_owner.Instrument is not {} instrument - || !_owner.Instruments.OpenMidi(_owner.Owner, memStream.GetBuffer().AsSpan(0, (int) memStream.Length), instrument)) + if (!_entManager.TryGetComponent(Entity, out var instrument)) + { return; + } + + if (!_entManager.System() + .OpenMidi(Entity, + memStream.GetBuffer().AsSpan(0, (int) memStream.Length), + instrument)) + { + return; + } MidiPlaybackSetButtonsDisabled(false); if (InputButton.Pressed) @@ -140,7 +169,7 @@ private async void MidiFileButtonOnOnPressed(ButtonEventArgs obj) private void MidiInputButtonOnOnToggled(ButtonToggledEventArgs obj) { - _owner.CloseBandMenu(); + OnCloseBands?.Invoke(); if (obj.Pressed) { @@ -148,109 +177,99 @@ private void MidiInputButtonOnOnToggled(ButtonToggledEventArgs obj) return; MidiStopButtonOnPressed(null); - if(_owner.Instrument is {} instrument) - _owner.Instruments.OpenInput(_owner.Owner, instrument); + + if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) + _entManager.System().OpenInput(Entity, instrument); } - else if (_owner.Instrument is { } instrument) + else { - _owner.Instruments.CloseInput(_owner.Owner, false, instrument); - _owner.CloseChannelsMenu(); + _entManager.System().CloseInput(Entity, false); + OnCloseChannels?.Invoke(); } } private bool PlayCheck() { // TODO all of these checks should also be done server-side. - - var instrumentEnt = _owner.Owner; - var instrument = _owner.Instrument; - - if (instrument == null) + if (!_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) return false; - var localEntity = _owner.PlayerManager.LocalEntity; + var localEntity = _player.LocalEntity; // If we don't have a player or controlled entity, we return. if (localEntity == null) return false; // By default, allow an instrument to play itself and skip all other checks - if (localEntity == instrumentEnt) + if (localEntity == Entity) return true; - var container = _owner.Entities.System(); + var container = _entManager.System(); // If we're a handheld instrument, we might be in a container. Get it just in case. - container.TryGetContainingContainer(instrumentEnt, out var conMan); + container.TryGetContainingContainer(Entity, out var conMan); // If the instrument is handheld and we're not holding it, we return. - if ((instrument.Handheld && (conMan == null || conMan.Owner != localEntity))) + if (instrument.Handheld && (conMan == null || conMan.Owner != localEntity)) return false; - if (!_owner.ActionBlocker.CanInteract(localEntity.Value, instrumentEnt)) + if (!_entManager.System().CanInteract(localEntity.Value, Entity)) return false; // We check that we're in range unobstructed just in case. - return _owner.Interactions.InRangeUnobstructed(localEntity.Value, instrumentEnt); + return _entManager.System().InRangeUnobstructed(localEntity.Value, Entity); } private void MidiStopButtonOnPressed(ButtonEventArgs? obj) { MidiPlaybackSetButtonsDisabled(true); - if (_owner.Instrument is not {} instrument) - return; - - _owner.Instruments.CloseMidi(_owner.Owner, false, instrument); - _owner.CloseChannelsMenu(); + _entManager.System().CloseMidi(Entity, false); + OnCloseChannels?.Invoke(); } private void MidiLoopButtonOnOnToggled(ButtonToggledEventArgs obj) { - if (_owner.Instrument == null) - return; + var instrument = _entManager.System(); + + if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrumentComp)) + { + instrumentComp.LoopMidi = obj.Pressed; + } - _owner.Instrument.LoopMidi = obj.Pressed; - _owner.Instruments.UpdateRenderer(_owner.Owner, _owner.Instrument); + instrument.UpdateRenderer(Entity); } private void PlaybackSliderSeek(Range _) { // Do not seek while still grabbing. - if (PlaybackSlider.Grabbed || _owner.Instrument is not {} instrument) + if (PlaybackSlider.Grabbed) return; - _owner.Instruments.SetPlayerTick(_owner.Owner, (int)Math.Ceiling(PlaybackSlider.Value), instrument); + _entManager.System().SetPlayerTick(Entity, (int)Math.Ceiling(PlaybackSlider.Value)); } private void PlaybackSliderKeyUp(GUIBoundKeyEventArgs args) { - if (args.Function != EngineKeyFunctions.UIClick || _owner.Instrument is not {} instrument) + if (args.Function != EngineKeyFunctions.UIClick) return; - _owner.Instruments.SetPlayerTick(_owner.Owner, (int)Math.Ceiling(PlaybackSlider.Value), instrument); - } - - public override void Close() - { - base.Close(); - _owner.CloseBandMenu(); - _owner.CloseChannelsMenu(); + _entManager.System().SetPlayerTick(Entity, (int)Math.Ceiling(PlaybackSlider.Value)); } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - if (_owner.Instrument == null) + if (!_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument)) return; - var hasMaster = _owner.Instrument.Master != null; + var hasMaster = instrument.Master != null; BandButton.ToggleMode = hasMaster; BandButton.Pressed = hasMaster; - BandButton.Disabled = _owner.Instrument.IsMidiOpen || _owner.Instrument.IsInputOpen; - ChannelsButton.Disabled = !_owner.Instrument.IsRendererAlive; + BandButton.Disabled = instrument.IsMidiOpen || instrument.IsInputOpen; + ChannelsButton.Disabled = !instrument.IsRendererAlive; - if (!_owner.Instrument.IsMidiOpen) + if (!instrument.IsMidiOpen) { PlaybackSlider.MaxValue = 1; PlaybackSlider.SetValueWithoutEvent(0); @@ -260,8 +279,8 @@ protected override void FrameUpdate(FrameEventArgs args) if (PlaybackSlider.Grabbed) return; - PlaybackSlider.MaxValue = _owner.Instrument.PlayerTotalTick; - PlaybackSlider.SetValueWithoutEvent(_owner.Instrument.PlayerTick); + PlaybackSlider.MaxValue = instrument.PlayerTotalTick; + PlaybackSlider.SetValueWithoutEvent(instrument.PlayerTick); } } } diff --git a/Content.Client/Inventory/StrippableBoundUserInterface.cs b/Content.Client/Inventory/StrippableBoundUserInterface.cs index 7e50eb1c68a..132c5ed654c 100644 --- a/Content.Client/Inventory/StrippableBoundUserInterface.cs +++ b/Content.Client/Inventory/StrippableBoundUserInterface.cs @@ -41,7 +41,7 @@ public sealed class StrippableBoundUserInterface : BoundUserInterface public const string HiddenPocketEntityId = "StrippingHiddenEntity"; [ViewVariables] - private readonly StrippingMenu? _strippingMenu; + private StrippingMenu? _strippingMenu; [ViewVariables] private readonly EntityUid _virtualHiddenEntity; @@ -51,33 +51,30 @@ public StrippableBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, u _examine = EntMan.System(); _inv = EntMan.System(); _cuffable = EntMan.System(); - - // TODO update name when identity changes - var title = Loc.GetString("strippable-bound-user-interface-stripping-menu-title", ("ownerName", Identity.Name(Owner, EntMan))); - _strippingMenu = new StrippingMenu(title, this); - _strippingMenu.OnClose += Close; - - // TODO use global entity - // BUIs are opened and closed while applying comp sates, so spawning entities here is probably not the best idea. _virtualHiddenEntity = EntMan.SpawnEntity(HiddenPocketEntityId, MapCoordinates.Nullspace); } protected override void Open() { base.Open(); + + _strippingMenu = this.CreateWindow(); + _strippingMenu.OnDirty += UpdateMenu; + _strippingMenu.Title = Loc.GetString("strippable-bound-user-interface-stripping-menu-title", ("ownerName", Identity.Name(Owner, EntMan))); + _strippingMenu?.OpenCenteredLeft(); } protected override void Dispose(bool disposing) { - base.Dispose(disposing); - - EntMan.DeleteEntity(_virtualHiddenEntity); - if (!disposing) return; - _strippingMenu?.Dispose(); + if (_strippingMenu != null) + _strippingMenu.OnDirty -= UpdateMenu; + + EntMan.DeleteEntity(_virtualHiddenEntity); + base.Dispose(disposing); } public void DirtyMenu() diff --git a/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs b/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs index f97d8a73302..7884268c428 100644 --- a/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs +++ b/Content.Client/Kitchen/UI/GrinderMenu.xaml.cs @@ -12,42 +12,34 @@ namespace Content.Client.Kitchen.UI [GenerateTypedNameReferences] public sealed partial class GrinderMenu : FancyWindow { - private readonly IEntityManager _entityManager; - private readonly IPrototypeManager _prototypeManager; - private readonly ReagentGrinderBoundUserInterface _owner; + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; private readonly Dictionary _chamberVisualContents = new(); - public GrinderMenu(ReagentGrinderBoundUserInterface owner, IEntityManager entityManager, IPrototypeManager prototypeManager) + public event Action? OnToggleAuto; + public event Action? OnGrind; + public event Action? OnJuice; + public event Action? OnEjectAll; + public event Action? OnEjectBeaker; + public event Action? OnEjectChamber; + + public GrinderMenu() { RobustXamlLoader.Load(this); - _entityManager = entityManager; - _prototypeManager = prototypeManager; - _owner = owner; - AutoModeButton.OnPressed += owner.ToggleAutoMode; - GrindButton.OnPressed += owner.StartGrinding; - JuiceButton.OnPressed += owner.StartJuicing; - ChamberContentBox.EjectButton.OnPressed += owner.EjectAll; - BeakerContentBox.EjectButton.OnPressed += owner.EjectBeaker; + IoCManager.InjectDependencies(this); + AutoModeButton.OnPressed += _ => OnToggleAuto?.Invoke(); + GrindButton.OnPressed += _ => OnGrind?.Invoke(); + JuiceButton.OnPressed += _ => OnJuice?.Invoke(); + ChamberContentBox.EjectButton.OnPressed += _ => OnEjectAll?.Invoke(); + BeakerContentBox.EjectButton.OnPressed += _ => OnEjectBeaker?.Invoke(); ChamberContentBox.BoxContents.OnItemSelected += OnChamberBoxContentsItemSelected; BeakerContentBox.BoxContents.SelectMode = ItemList.ItemListSelectMode.None; } private void OnChamberBoxContentsItemSelected(ItemList.ItemListSelectedEventArgs args) { - _owner.EjectChamberContent(_chamberVisualContents[args.ItemIndex]); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _chamberVisualContents.Clear(); - GrindButton.OnPressed -= _owner.StartGrinding; - JuiceButton.OnPressed -= _owner.StartJuicing; - ChamberContentBox.EjectButton.OnPressed -= _owner.EjectAll; - BeakerContentBox.EjectButton.OnPressed -= _owner.EjectBeaker; - ChamberContentBox.BoxContents.OnItemSelected -= OnChamberBoxContentsItemSelected; + OnEjectChamber?.Invoke(_chamberVisualContents[args.ItemIndex]); } public void UpdateState(ReagentGrinderInterfaceState state) diff --git a/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs b/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs index 7e7dd2d6935..643ac47054b 100644 --- a/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs +++ b/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs @@ -3,6 +3,7 @@ using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Client.Graphics; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Timing; @@ -19,28 +20,15 @@ public sealed class MicrowaveBoundUserInterface : BoundUserInterface [ViewVariables] private readonly Dictionary _reagents = new(); - [Dependency] private readonly IGameTiming _gameTiming = default!; - - public MicrowaveUpdateUserInterfaceState currentState = default!; - - private IEntityManager _entManager; public MicrowaveBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { - _entManager = IoCManager.Resolve(); - } - - public TimeSpan GetCurrentTime() - { - return _gameTiming.CurTime; } protected override void Open() { base.Open(); - _menu = new MicrowaveMenu(this); - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.StartButton.OnPressed += _ => SendPredictedMessage(new MicrowaveStartCookMessage()); _menu.EjectButton.OnPressed += _ => SendPredictedMessage(new MicrowaveEjectMessage()); _menu.IngredientsList.OnItemSelected += args => @@ -74,38 +62,23 @@ protected override void Open() }; } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (!disposing) - { - return; - } - - _solids.Clear(); - _menu?.Dispose(); - } - protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); - if (state is not MicrowaveUpdateUserInterfaceState cState) + if (state is not MicrowaveUpdateUserInterfaceState cState || _menu == null) { return; } + _menu.IsBusy = cState.IsMicrowaveBusy; + _menu.CurrentCooktimeEnd = cState.CurrentCookTimeEnd; - _menu?.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0); - currentState = cState; - + _menu.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0); // TODO move this to a component state and ensure the net ids. - RefreshContentsDisplay(_entManager.GetEntityArray(cState.ContainedSolids)); - - if (_menu == null) return; + RefreshContentsDisplay(EntMan.GetEntityArray(cState.ContainedSolids)); //Set the cook time info label - var cookTime = cState.ActiveButtonIndex == 0 + var cookTime = cState.ActiveButtonIndex == 0 ? Loc.GetString("microwave-menu-instant-button") : cState.CurrentCookTime.ToString(); diff --git a/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs b/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs index b292e9f1465..13029e38469 100644 --- a/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs +++ b/Content.Client/Kitchen/UI/MicrowaveMenu.xaml.cs @@ -9,22 +9,21 @@ namespace Content.Client.Kitchen.UI [GenerateTypedNameReferences] public sealed partial class MicrowaveMenu : FancyWindow { - public sealed class MicrowaveCookTimeButton : Button - { - public uint CookTime; - } + [Dependency] private readonly IGameTiming _timing = default!; public event Action? OnCookTimeSelected; public ButtonGroup CookTimeButtonGroup { get; } - private readonly MicrowaveBoundUserInterface _owner; - public MicrowaveMenu(MicrowaveBoundUserInterface owner) + public bool IsBusy; + public TimeSpan CurrentCooktimeEnd; + + public MicrowaveMenu() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); CookTimeButtonGroup = new ButtonGroup(); InstantCookButton.Group = CookTimeButtonGroup; - _owner = owner; InstantCookButton.OnPressed += args => { OnCookTimeSelected?.Invoke(args, 0); @@ -65,14 +64,20 @@ public void ToggleBusyDisableOverlayPanel(bool shouldDisable) protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - if(!_owner.currentState.IsMicrowaveBusy) + + if (!IsBusy) return; - if(_owner.currentState.CurrentCookTimeEnd > _owner.GetCurrentTime()) + if (CurrentCooktimeEnd > _timing.CurTime) { CookTimeInfoLabel.Text = Loc.GetString("microwave-bound-user-interface-cook-time-label", - ("time",_owner.currentState.CurrentCookTimeEnd.Subtract(_owner.GetCurrentTime()).Seconds)); + ("time", CurrentCooktimeEnd.Subtract(_timing.CurTime).Seconds)); } } + + public sealed class MicrowaveCookTimeButton : Button + { + public uint CookTime; + } } } diff --git a/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs b/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs index e6f108b3050..bc4cc75b4d1 100644 --- a/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs +++ b/Content.Client/Kitchen/UI/ReagentGrinderBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Containers.ItemSlots; using Content.Shared.Kitchen; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Prototypes; @@ -8,8 +9,6 @@ namespace Content.Client.Kitchen.UI { public sealed class ReagentGrinderBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [ViewVariables] private GrinderMenu? _menu; @@ -21,20 +20,13 @@ protected override void Open() { base.Open(); - _menu = new GrinderMenu(this, EntMan, _prototypeManager); - _menu.OpenCentered(); - _menu.OnClose += Close; - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - { - return; - } - - _menu?.Dispose(); + _menu = this.CreateWindow(); + _menu.OnToggleAuto += ToggleAutoMode; + _menu.OnGrind += StartGrinding; + _menu.OnJuice += StartJuicing; + _menu.OnEjectAll += EjectAll; + _menu.OnEjectBeaker += EjectBeaker; + _menu.OnEjectChamber += EjectChamberContent; } protected override void UpdateState(BoundUserInterfaceState state) @@ -52,27 +44,27 @@ protected override void ReceiveMessage(BoundUserInterfaceMessage message) _menu?.HandleMessage(message); } - public void ToggleAutoMode(BaseButton.ButtonEventArgs args) + public void ToggleAutoMode() { SendMessage(new ReagentGrinderToggleAutoModeMessage()); } - public void StartGrinding(BaseButton.ButtonEventArgs? _ = null) + public void StartGrinding() { SendMessage(new ReagentGrinderStartMessage(GrinderProgram.Grind)); } - public void StartJuicing(BaseButton.ButtonEventArgs? _ = null) + public void StartJuicing() { SendMessage(new ReagentGrinderStartMessage(GrinderProgram.Juice)); } - public void EjectAll(BaseButton.ButtonEventArgs? _ = null) + public void EjectAll() { SendMessage(new ReagentGrinderEjectChamberAllMessage()); } - public void EjectBeaker(BaseButton.ButtonEventArgs? _ = null) + public void EjectBeaker() { SendMessage(new ItemSlotButtonPressedEvent(SharedReagentGrinder.BeakerSlotId)); } diff --git a/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs b/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs index 555f1ff09e6..6b656123412 100644 --- a/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs +++ b/Content.Client/Labels/UI/HandLabelerBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Labels; using Content.Shared.Labels.Components; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Labels.UI { @@ -23,13 +24,8 @@ protected override void Open() { base.Open(); - _window = new HandLabelerWindow(); - if (State != null) - UpdateState(State); + _window = this.CreateWindow(); - _window.OpenCentered(); - - _window.OnClose += Close; _window.OnLabelChanged += OnLabelChanged; Reload(); } @@ -51,13 +47,5 @@ public void Reload() _window.SetCurrentLabel(component.AssignedLabel); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } - } diff --git a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs index 6e6d1b91761..a599f79152e 100644 --- a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs +++ b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Lathe; using Content.Shared.Research.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Lathe.UI { @@ -17,9 +18,9 @@ protected override void Open() { base.Open(); - _menu = new LatheMenu(this); - _menu.OnClose += Close; - + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.OpenCenteredRight(); _menu.OnServerListButtonPressed += _ => { @@ -30,8 +31,6 @@ protected override void Open() { SendMessage(new LatheQueueRecipeMessage(recipe, amount)); }; - - _menu.OpenCenteredRight(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -50,13 +49,5 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Dispose(); - } } } diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml.cs b/Content.Client/Lathe/UI/LatheMenu.xaml.cs index f2f52b67b5b..6f530b76c75 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml.cs +++ b/Content.Client/Lathe/UI/LatheMenu.xaml.cs @@ -1,3 +1,4 @@ +using System.Buffers; using System.Linq; using System.Text; using Content.Client.Materials; @@ -22,7 +23,6 @@ public sealed partial class LatheMenu : DefaultWindow [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - private EntityUid _owner; private readonly SpriteSystem _spriteSystem; private readonly LatheSystem _lathe; private readonly MaterialStorageSystem _materialStorage; @@ -36,9 +36,10 @@ public sealed partial class LatheMenu : DefaultWindow public ProtoId? CurrentCategory; - public LatheMenu(LatheBoundUserInterface owner) + public EntityUid Entity; + + public LatheMenu() { - _owner = owner.Owner; RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -46,8 +47,6 @@ public LatheMenu(LatheBoundUserInterface owner) _lathe = _entityManager.System(); _materialStorage = _entityManager.System(); - Title = _entityManager.GetComponent(owner.Owner).EntityName; - SearchBar.OnTextChanged += _ => { PopulateRecipes(); @@ -60,8 +59,13 @@ public LatheMenu(LatheBoundUserInterface owner) FilterOption.OnItemSelected += OnItemSelected; ServerListButton.OnPressed += a => OnServerListButtonPressed?.Invoke(a); + } - if (_entityManager.TryGetComponent(owner.Owner, out var latheComponent)) + public void SetEntity(EntityUid uid) + { + Entity = uid; + + if (_entityManager.TryGetComponent(Entity, out var latheComponent)) { if (!latheComponent.DynamicRecipes.Any()) { @@ -69,7 +73,7 @@ public LatheMenu(LatheBoundUserInterface owner) } } - MaterialsList.SetOwner(owner.Owner); + MaterialsList.SetOwner(Entity); } /// @@ -102,13 +106,15 @@ public void PopulateRecipes() var sortedRecipesToShow = recipesToShow.OrderBy(p => p.Name); RecipeList.Children.Clear(); + _entityManager.TryGetComponent(Entity, out LatheComponent? lathe); + foreach (var prototype in sortedRecipesToShow) { EntityPrototype? recipeProto = null; - if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto) && entityProto != null) + if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto)) recipeProto = entityProto; - var canProduce = _lathe.CanProduce(_owner, prototype, quantity); + var canProduce = _lathe.CanProduce(Entity, prototype, quantity, component: lathe); var control = new RecipeControl(prototype, () => GenerateTooltipText(prototype), canProduce, recipeProto); control.OnButtonPressed += s => @@ -124,19 +130,20 @@ public void PopulateRecipes() private string GenerateTooltipText(LatheRecipePrototype prototype) { StringBuilder sb = new(); + var multiplier = _entityManager.GetComponent(Entity).MaterialUseMultiplier; foreach (var (id, amount) in prototype.RequiredMaterials) { if (!_prototypeManager.TryIndex(id, out var proto)) continue; - var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, _entityManager.GetComponent(_owner).MaterialUseMultiplier); + var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, multiplier); var sheetVolume = _materialStorage.GetSheetVolume(proto); var unit = Loc.GetString(proto.Unit); var sheets = adjustedAmount / (float) sheetVolume; - var availableAmount = _materialStorage.GetMaterialAmount(_owner, id); + var availableAmount = _materialStorage.GetMaterialAmount(Entity, id); var missingAmount = Math.Max(0, adjustedAmount - availableAmount); var missingSheets = missingAmount / (float) sheetVolume; diff --git a/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs b/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs index 09bdedfd94c..11abe8c2451 100644 --- a/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs +++ b/Content.Client/MachineLinking/UI/SignalTimerBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.MachineLinking; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Timing; namespace Content.Client.MachineLinking.UI; @@ -19,19 +20,14 @@ protected override void Open() { base.Open(); - _window = new SignalTimerWindow(this); - - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + _window.OnStartTimer += StartTimer; _window.OnCurrentTextChanged += OnTextChanged; _window.OnCurrentDelayMinutesChanged += OnDelayChanged; _window.OnCurrentDelaySecondsChanged += OnDelayChanged; } - public void OnStartTimer() + public void StartTimer() { SendMessage(new SignalTimerStartMessage()); } @@ -48,11 +44,6 @@ private void OnDelayChanged(string newDelay) SendMessage(new SignalTimerDelayChangedMessage(_window.GetDelay())); } - public TimeSpan GetCurrentTime() - { - return _gameTiming.CurTime; - } - /// /// Update the UI state based on server-sent info /// @@ -72,11 +63,4 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.SetTimerStarted(cast.TimerStarted); _window.SetHasAccess(cast.HasAccess); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } diff --git a/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs b/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs index b62595595e5..6133abfcb70 100644 --- a/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs +++ b/Content.Client/MachineLinking/UI/SignalTimerWindow.xaml.cs @@ -9,42 +9,44 @@ namespace Content.Client.MachineLinking.UI; [GenerateTypedNameReferences] public sealed partial class SignalTimerWindow : DefaultWindow { + [Dependency] private readonly IGameTiming _timing = default!; + private const int MaxTextLength = 5; public event Action? OnCurrentTextChanged; public event Action? OnCurrentDelayMinutesChanged; public event Action? OnCurrentDelaySecondsChanged; - private readonly SignalTimerBoundUserInterface _owner; - private TimeSpan? _triggerTime; private bool _timerStarted; - public SignalTimerWindow(SignalTimerBoundUserInterface owner) + public event Action? OnStartTimer; + + public SignalTimerWindow() { RobustXamlLoader.Load(this); - - _owner = owner; + IoCManager.InjectDependencies(this); CurrentTextEdit.OnTextChanged += e => OnCurrentTextChange(e.Text); CurrentDelayEditMinutes.OnTextChanged += e => OnCurrentDelayMinutesChange(e.Text); CurrentDelayEditSeconds.OnTextChanged += e => OnCurrentDelaySecondsChange(e.Text); - StartTimer.OnPressed += _ => OnStartTimer(); + StartTimer.OnPressed += _ => StartTimerWeh(); } - public void OnStartTimer() + private void StartTimerWeh() { if (!_timerStarted) { _timerStarted = true; - _triggerTime = _owner.GetCurrentTime() + GetDelay(); + _triggerTime = _timing.CurTime + GetDelay(); } else { SetTimerStarted(false); } - _owner.OnStartTimer(); + + OnStartTimer?.Invoke(); } protected override void FrameUpdate(FrameEventArgs args) @@ -54,9 +56,9 @@ protected override void FrameUpdate(FrameEventArgs args) if (!_timerStarted || _triggerTime == null) return; - if (_owner.GetCurrentTime() < _triggerTime.Value) + if (_timing.CurTime < _triggerTime.Value) { - StartTimer.Text = TextScreenSystem.TimeToString(_triggerTime.Value - _owner.GetCurrentTime()); + StartTimer.Text = TextScreenSystem.TimeToString(_triggerTime.Value - _timing.CurTime); } else { diff --git a/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs b/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs index f6979bf8d7b..0a87948ff62 100644 --- a/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs +++ b/Content.Client/MagicMirror/MagicMirrorBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Humanoid.Markings; using Content.Shared.MagicMirror; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.MagicMirror; @@ -17,7 +18,7 @@ protected override void Open() { base.Open(); - _window = new(); + _window = this.CreateWindow(); _window.OnHairSelected += tuple => SelectHair(MagicMirrorCategory.Hair, tuple.id, tuple.slot); _window.OnHairColorChanged += args => ChangeColor(MagicMirrorCategory.Hair, args.marking, args.slot); @@ -29,9 +30,6 @@ protected override void Open() args => ChangeColor(MagicMirrorCategory.FacialHair, args.marking, args.slot); _window.OnFacialHairSlotAdded += delegate () { AddSlot(MagicMirrorCategory.FacialHair); }; _window.OnFacialHairSlotRemoved += args => RemoveSlot(MagicMirrorCategory.FacialHair, args); - - _window.OnClose += Close; - _window.OpenCentered(); } private void SelectHair(MagicMirrorCategory category, string marking, int slot) @@ -65,14 +63,5 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.UpdateState(data); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _window?.Dispose(); - } } diff --git a/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs b/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs index 80eca82e324..22e5bc452a0 100644 --- a/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs +++ b/Content.Client/MassMedia/Ui/NewsWriterBoundUserInterface.cs @@ -1,6 +1,7 @@ using JetBrains.Annotations; using Content.Shared.MassMedia.Systems; using Content.Shared.MassMedia.Components; +using Robust.Client.UserInterface; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -9,8 +10,6 @@ namespace Content.Client.MassMedia.Ui; [UsedImplicitly] public sealed class NewsWriterBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IGameTiming _gameTiming = default!; - [ViewVariables] private NewsWriterMenu? _menu; @@ -21,10 +20,7 @@ public NewsWriterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, u protected override void Open() { - _menu = new NewsWriterMenu(_gameTiming); - - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.ArticleEditorPanel.PublishButtonPressed += OnPublishButtonPressed; _menu.DeleteButtonPressed += OnDeleteButtonPressed; @@ -32,16 +28,6 @@ protected override void Open() SendMessage(new NewsWriterArticlesRequestMessage()); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Close(); - _menu?.Dispose(); - } - protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); diff --git a/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs b/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs index e2d57935e3a..c059ce785af 100644 --- a/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs +++ b/Content.Client/MassMedia/Ui/NewsWriterMenu.xaml.cs @@ -10,17 +10,17 @@ namespace Content.Client.MassMedia.Ui; [GenerateTypedNameReferences] public sealed partial class NewsWriterMenu : FancyWindow { - private readonly IGameTiming _gameTiming; + [Dependency] private readonly IGameTiming _gameTiming = default!; private TimeSpan? _nextPublish; public event Action? DeleteButtonPressed; - public NewsWriterMenu(IGameTiming gameTiming) + public NewsWriterMenu() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); - _gameTiming = gameTiming; ContentsContainer.RectClipContent = false; // Customize scrollbar width and margin. This is not possible in xaml diff --git a/Content.Client/Mech/Ui/MechBoundUserInterface.cs b/Content.Client/Mech/Ui/MechBoundUserInterface.cs index 4172bdc90f1..2130a8c6099 100644 --- a/Content.Client/Mech/Ui/MechBoundUserInterface.cs +++ b/Content.Client/Mech/Ui/MechBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Mech.Components; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Mech.Ui; @@ -20,9 +21,8 @@ protected override void Open() { base.Open(); - _menu = new(Owner); - - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); _menu.OpenCenteredLeft(); _menu.OnRemoveButtonPressed += uid => @@ -60,16 +60,6 @@ public void UpdateEquipmentControls(MechBoundUiState state) } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (!disposing) - return; - - _menu?.Close(); - } - public UIFragment? GetEquipmentUi(EntityUid? uid) { var component = EntMan.GetComponentOrNull(uid); diff --git a/Content.Client/Mech/Ui/MechMenu.xaml.cs b/Content.Client/Mech/Ui/MechMenu.xaml.cs index fad76488086..6f39bc386ee 100644 --- a/Content.Client/Mech/Ui/MechMenu.xaml.cs +++ b/Content.Client/Mech/Ui/MechMenu.xaml.cs @@ -16,14 +16,15 @@ public sealed partial class MechMenu : FancyWindow public event Action? OnRemoveButtonPressed; - public MechMenu(EntityUid mech) + public MechMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); + } - _mech = mech; - - MechView.SetEntity(mech); + public void SetEntity(EntityUid uid) + { + MechView.SetEntity(uid); } public void UpdateMechStats() diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs index 39788809871..b1f239cd78e 100644 --- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs @@ -1,4 +1,5 @@ using Content.Shared.Medical.CrewMonitoring; +using Robust.Client.UserInterface; namespace Content.Client.Medical.CrewMonitoring; @@ -14,7 +15,7 @@ public CrewMonitoringBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { EntityUid? gridUid = null; - string stationName = string.Empty; + var stationName = string.Empty; if (EntMan.TryGetComponent(Owner, out var xform)) { @@ -26,10 +27,8 @@ protected override void Open() } } - _menu = new CrewMonitoringWindow(stationName, gridUid); - - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.Set(stationName, gridUid); } protected override void UpdateState(BoundUserInterfaceState state) @@ -44,13 +43,4 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs index 863412e5532..e861864c144 100644 --- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs @@ -23,22 +23,27 @@ namespace Content.Client.Medical.CrewMonitoring; [GenerateTypedNameReferences] public sealed partial class CrewMonitoringWindow : FancyWindow { - private readonly IEntityManager _entManager; - private readonly IPrototypeManager _prototypeManager; + [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; private readonly SpriteSystem _spriteSystem; private NetEntity? _trackedEntity; private bool _tryToScrollToListFocus; private Texture? _blipTexture; - public CrewMonitoringWindow(string stationName, EntityUid? mapUid) + public CrewMonitoringWindow() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); - _entManager = IoCManager.Resolve(); - _prototypeManager = IoCManager.Resolve(); _spriteSystem = _entManager.System(); + NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; + + } + + public void Set(string stationName, EntityUid? mapUid) + { _blipTexture = _spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png"))); if (_entManager.TryGetComponent(mapUid, out var xform)) @@ -49,8 +54,6 @@ public CrewMonitoringWindow(string stationName, EntityUid? mapUid) StationName.AddStyleClass("LabelBig"); StationName.Text = stationName; - - NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; NavMap.ForceNavMapUpdate(); } diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs index 80c98f143b9..f85220a9266 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Client.NetworkConfigurator.Systems; using Content.Shared.DeviceNetwork; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.NetworkConfigurator; @@ -35,14 +36,12 @@ protected override void Open() switch (UiKey) { case NetworkConfiguratorUiKey.List: - _listMenu = new NetworkConfiguratorListMenu(this); - _listMenu.OnClose += Close; + _listMenu = this.CreateWindow(); _listMenu.ClearButton.OnPressed += _ => OnClearButtonPressed(); - _listMenu.OpenCenteredRight(); + _listMenu.OnRemoveAddress += OnRemoveButtonPressed; break; case NetworkConfiguratorUiKey.Configure: - _configurationMenu = new NetworkConfiguratorConfigurationMenu(); - _configurationMenu.OnClose += Close; + _configurationMenu = this.CreateWindow(); _configurationMenu.Set.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Set); _configurationMenu.Add.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Add); //_configurationMenu.Edit.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Edit); @@ -50,12 +49,24 @@ protected override void Open() _configurationMenu.Copy.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Copy); _configurationMenu.Show.OnPressed += OnShowPressed; _configurationMenu.Show.Pressed = _netConfig.ConfiguredListIsTracked(Owner); - _configurationMenu.OpenCentered(); + _configurationMenu.OnRemoveAddress += OnRemoveButtonPressed; break; case NetworkConfiguratorUiKey.Link: - _linkMenu = new NetworkConfiguratorLinkMenu(this); - _linkMenu.OnClose += Close; - _linkMenu.OpenCentered(); + _linkMenu = this.CreateWindow(); + _linkMenu.OnLinkDefaults += args => + { + SendMessage(new NetworkConfiguratorLinksSaveMessage(args)); + }; + + _linkMenu.OnToggleLink += (left, right) => + { + SendMessage(new NetworkConfiguratorToggleLinkMessage(left, right)); + }; + + _linkMenu.OnClearLinks += () => + { + SendMessage(new NetworkConfiguratorClearLinksMessage()); + }; break; } } @@ -83,16 +94,6 @@ protected override void UpdateState(BoundUserInterfaceState state) } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _linkMenu?.Dispose(); - _listMenu?.Dispose(); - _configurationMenu?.Dispose(); - } - private void OnClearButtonPressed() { SendMessage(new NetworkConfiguratorClearDevicesMessage()); diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs index 19d04cd3464..fcd2f759187 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorConfigurationMenu.xaml.cs @@ -9,17 +9,23 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorConfigurationMenu : FancyWindow { + public event Action? OnRemoveAddress; + public NetworkConfiguratorConfigurationMenu() { RobustXamlLoader.Load(this); Clear.StyleClasses.Add(StyleBase.ButtonOpenLeft); Clear.StyleClasses.Add(StyleNano.StyleClassButtonColorRed); + DeviceList.OnRemoveAddress += args => + { + OnRemoveAddress?.Invoke(args); + }; } public void UpdateState(DeviceListUserInterfaceState state) { - DeviceList.UpdateState(null, state.DeviceList); + DeviceList.UpdateState(state.DeviceList, false); Count.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count)); } diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs index 8cfa97dc6c2..e75c60058cb 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorDeviceList.xaml.cs @@ -7,17 +7,19 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorDeviceList : ScrollContainer { - public void UpdateState(NetworkConfiguratorBoundUserInterface? ui, HashSet<(string address, string name)> devices) + public event Action? OnRemoveAddress; + + public void UpdateState(HashSet<(string address, string name)> devices, bool ui) { DeviceList.RemoveAllChildren(); foreach (var device in devices) { - DeviceList.AddChild(BuildDeviceListRow(ui, device)); + DeviceList.AddChild(BuildDeviceListRow(device, ui)); } } - private static BoxContainer BuildDeviceListRow(NetworkConfiguratorBoundUserInterface? ui, (string address, string name) savedDevice) + private BoxContainer BuildDeviceListRow((string address, string name) savedDevice, bool ui) { var row = new BoxContainer() { @@ -48,10 +50,10 @@ private static BoxContainer BuildDeviceListRow(NetworkConfiguratorBoundUserInter row.AddChild(name); row.AddChild(address); - if (ui != null) + if (ui) { row.AddChild(removeButton); - removeButton.OnPressed += _ => ui.OnRemoveButtonPressed(savedDevice.address); + removeButton.OnPressed += _ => OnRemoveAddress?.Invoke(savedDevice.address); } return row; diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs index c04b42f249b..8cdffd16af6 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorLinkMenu.xaml.cs @@ -18,20 +18,20 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow private readonly LinksRender _links; - private readonly List _sources = new(); private readonly List _sinks = new(); - private readonly NetworkConfiguratorBoundUserInterface _userInterface; - private (ButtonPosition position, string id, int index)? _selectedButton; private List<(string left, string right)>? _defaults; - public NetworkConfiguratorLinkMenu(NetworkConfiguratorBoundUserInterface userInterface) + public event Action? OnClearLinks; + public event Action? OnToggleLink; + public event Action>? OnLinkDefaults; + + public NetworkConfiguratorLinkMenu() { - _userInterface = userInterface; RobustXamlLoader.Load(this); var footerStyleBox = new StyleBoxFlat() @@ -52,7 +52,7 @@ public NetworkConfiguratorLinkMenu(NetworkConfiguratorBoundUserInterface userInt ButtonOk.OnPressed += _ => Close(); ButtonLinkDefault.OnPressed += _ => LinkDefaults(); - ButtonClear.OnPressed += _ => _userInterface.SendMessage(new NetworkConfiguratorClearLinksMessage()); + ButtonClear.OnPressed += _ => OnClearLinks?.Invoke(); } public void UpdateState(DeviceLinkUserInterfaceState linkState) @@ -98,7 +98,7 @@ private void LinkDefaults() if (_defaults == default) return; - _userInterface.SendMessage(new NetworkConfiguratorLinksSaveMessage(_defaults)); + OnLinkDefaults?.Invoke(_defaults); } private Button CreateButton(ButtonPosition position, string name, string description, string id, int index) @@ -138,7 +138,7 @@ private void OnButtonPressed(BaseButton.ButtonEventArgs args, ButtonPosition pos var left = _selectedButton.Value.position == ButtonPosition.Left ? _selectedButton.Value.id : id; var right = _selectedButton.Value.position == ButtonPosition.Left ? id : _selectedButton.Value.id; - _userInterface.SendMessage(new NetworkConfiguratorToggleLinkMessage(left, right)); + OnToggleLink?.Invoke(left, right); args.Button.Pressed = false; diff --git a/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs b/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs index fb4aec1974b..6294facaeed 100644 --- a/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs +++ b/Content.Client/NetworkConfigurator/NetworkConfiguratorListMenu.xaml.cs @@ -9,17 +9,20 @@ namespace Content.Client.NetworkConfigurator; [GenerateTypedNameReferences] public sealed partial class NetworkConfiguratorListMenu : FancyWindow { - private readonly NetworkConfiguratorBoundUserInterface _ui; - public NetworkConfiguratorListMenu(NetworkConfiguratorBoundUserInterface ui) + public event Action? OnRemoveAddress; + + public NetworkConfiguratorListMenu() { RobustXamlLoader.Load(this); - - _ui = ui; + DeviceList.OnRemoveAddress += args => + { + OnRemoveAddress?.Invoke(args); + }; } public void UpdateState(NetworkConfiguratorUserInterfaceState state) { DeviceCountLabel.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count)); - DeviceList.UpdateState(_ui, state.DeviceList); + DeviceList.UpdateState(state.DeviceList, true); } } diff --git a/Content.Client/Nuke/NukeBoundUserInterface.cs b/Content.Client/Nuke/NukeBoundUserInterface.cs index 59fbc5b319b..2e150423734 100644 --- a/Content.Client/Nuke/NukeBoundUserInterface.cs +++ b/Content.Client/Nuke/NukeBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Nuke; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Nuke { @@ -11,15 +12,13 @@ public sealed class NukeBoundUserInterface : BoundUserInterface [ViewVariables] private NukeMenu? _menu; - public NukeBoundUserInterface([NotNull] EntityUid owner, [NotNull] Enum uiKey) : base(owner, uiKey) + public NukeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } protected override void Open() { - _menu = new NukeMenu(); - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); _menu.OnKeypadButtonPressed += i => { @@ -62,15 +61,5 @@ protected override void UpdateState(BoundUserInterfaceState state) break; } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Close(); - _menu?.Dispose(); - } } } diff --git a/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs b/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs index ec055b3240c..ad4f1a75d47 100644 --- a/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs +++ b/Content.Client/NukeOps/WarDeclaratorBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Chat; using Content.Shared.NukeOps; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.Timing; @@ -11,8 +12,6 @@ namespace Content.Client.NukeOps; public sealed class WarDeclaratorBoundUserInterface : BoundUserInterface { [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly ILocalizationManager _localizationManager = default!; [ViewVariables] private WarDeclaratorWindow? _window; @@ -23,13 +22,7 @@ protected override void Open() { base.Open(); - _window = new WarDeclaratorWindow(_gameTiming, _localizationManager); - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.OnActivated += OnWarDeclaratorActivated; } @@ -42,13 +35,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - _window?.Dispose(); - } - private void OnWarDeclaratorActivated(string message) { var maxLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength); diff --git a/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs b/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs index b4a3f1c7fa5..aeceae13275 100644 --- a/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs +++ b/Content.Client/NukeOps/WarDeclaratorWindow.xaml.cs @@ -11,7 +11,8 @@ namespace Content.Client.NukeOps; [GenerateTypedNameReferences] public sealed partial class WarDeclaratorWindow : FancyWindow { - private readonly IGameTiming _gameTiming; + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly ILocalizationManager _localizationManager = default!; public event Action? OnActivated; @@ -19,15 +20,13 @@ public sealed partial class WarDeclaratorWindow : FancyWindow private TimeSpan _shuttleDisabledTime; private WarConditionStatus _status; - public WarDeclaratorWindow(IGameTiming gameTiming, ILocalizationManager localizationManager) + public WarDeclaratorWindow() { RobustXamlLoader.Load(this); - _gameTiming = gameTiming; - WarButton.OnPressed += (_) => OnActivated?.Invoke(Rope.Collapse(MessageEdit.TextRope)); - MessageEdit.Placeholder = new Rope.Leaf(localizationManager.GetString("war-declarator-message-placeholder")); + MessageEdit.Placeholder = new Rope.Leaf(_localizationManager.GetString("war-declarator-message-placeholder")); } protected override void FrameUpdate(FrameEventArgs args) diff --git a/Content.Client/PDA/PdaBoundUserInterface.cs b/Content.Client/PDA/PdaBoundUserInterface.cs index f8f4c67076c..37ce9c4280f 100644 --- a/Content.Client/PDA/PdaBoundUserInterface.cs +++ b/Content.Client/PDA/PdaBoundUserInterface.cs @@ -24,14 +24,13 @@ protected override void Open() if (_menu == null) CreateMenu(); - - _menu?.OpenCenteredLeft(); } private void CreateMenu() { - _menu = new PdaMenu(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.OpenCenteredLeft(); + _menu.FlashLightToggleButton.OnToggled += _ => { SendMessage(new PdaToggleFlashlightMessage()); @@ -96,7 +95,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _menu?.UpdateState(updateState); } - protected override void AttachCartridgeUI(Control cartridgeUIFragment, string? title) { _menu?.ProgramView.AddChild(cartridgeUIFragment); @@ -118,15 +116,6 @@ protected override void UpdateAvailablePrograms(List<(EntityUid, CartridgeCompon _menu?.UpdateAvailablePrograms(programs); } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } - private PdaBorderColorComponent? GetBorderColorComponent() { return EntMan.GetComponentOrNull(Owner); diff --git a/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs b/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs index a0688523f1e..170a296ac2e 100644 --- a/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs +++ b/Content.Client/PDA/Ringer/RingerBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.PDA; using Content.Shared.PDA.Ringer; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Shared.Timing; namespace Content.Client.PDA.Ringer @@ -18,9 +19,8 @@ public RingerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey protected override void Open() { base.Open(); - _menu = new RingtoneMenu(); + _menu = this.CreateWindow(); _menu.OpenToLeft(); - _menu.OnClose += Close; _menu.TestRingerButton.OnPressed += _ => { diff --git a/Content.Client/Paper/UI/PaperBoundUserInterface.cs b/Content.Client/Paper/UI/PaperBoundUserInterface.cs index 4b0ac868f01..f3ad1e347e7 100644 --- a/Content.Client/Paper/UI/PaperBoundUserInterface.cs +++ b/Content.Client/Paper/UI/PaperBoundUserInterface.cs @@ -1,4 +1,5 @@ using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Utility; using static Content.Shared.Paper.SharedPaperComponent; @@ -19,16 +20,13 @@ protected override void Open() { base.Open(); - _window = new PaperWindow(); - _window.OnClose += Close; - _window.OnSaved += Input_OnTextEntered; + _window = this.CreateWindow(); + _window.OnSaved += InputOnTextEntered; if (EntMan.TryGetComponent(Owner, out var visuals)) { _window.InitVisuals(Owner, visuals); } - - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -37,7 +35,7 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.Populate((PaperBoundUserInterfaceState) state); } - private void Input_OnTextEntered(string text) + private void InputOnTextEntered(string text) { SendMessage(new PaperInputTextMessage(text)); @@ -47,11 +45,4 @@ private void Input_OnTextEntered(string text) _window.Input.CursorPosition = new TextEdit.CursorPos(0, TextEdit.LineBreakBias.Top); } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _window?.Dispose(); - } } diff --git a/Content.Client/Paper/UI/PaperWindow.xaml.cs b/Content.Client/Paper/UI/PaperWindow.xaml.cs index 7a5fd652643..f7cace642ce 100644 --- a/Content.Client/Paper/UI/PaperWindow.xaml.cs +++ b/Content.Client/Paper/UI/PaperWindow.xaml.cs @@ -17,6 +17,7 @@ namespace Content.Client.Paper.UI public sealed partial class PaperWindow : BaseWindow { [Dependency] private readonly IInputManager _inputManager = default!; + [Dependency] private readonly IResourceCache _resCache = default!; private static Color DefaultTextColor = new(25, 25, 25); @@ -85,11 +86,10 @@ public void InitVisuals(EntityUid entity, PaperVisualsComponent visuals) // Randomize the placement of any stamps based on the entity UID // so that there's some variety in different papers. StampDisplay.PlacementSeed = (int)entity; - var resCache = IoCManager.Resolve(); // Initialize the background: PaperBackground.ModulateSelfOverride = visuals.BackgroundModulate; - var backgroundImage = visuals.BackgroundImagePath != null? resCache.GetResource(visuals.BackgroundImagePath) : null; + var backgroundImage = visuals.BackgroundImagePath != null? _resCache.GetResource(visuals.BackgroundImagePath) : null; if (backgroundImage != null) { var backgroundImageMode = visuals.BackgroundImageTile ? StyleBoxTexture.StretchMode.Tile : StyleBoxTexture.StretchMode.Stretch; @@ -127,7 +127,7 @@ public void InitVisuals(EntityUid entity, PaperVisualsComponent visuals) PaperContent.ModulateSelfOverride = visuals.ContentImageModulate; WrittenTextLabel.ModulateSelfOverride = visuals.FontAccentColor; - var contentImage = visuals.ContentImagePath != null ? resCache.GetResource(visuals.ContentImagePath) : null; + var contentImage = visuals.ContentImagePath != null ? _resCache.GetResource(visuals.ContentImagePath) : null; if (contentImage != null) { // Setup the paper content texture, but keep a reference to it, as we can't set diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs index cde5ba9ef79..ff1eae36f55 100644 --- a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs +++ b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Singularity.Components; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.ParticleAccelerator.UI { @@ -16,9 +17,10 @@ protected override void Open() { base.Open(); - _menu = new ParticleAcceleratorControlMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnOverallState += SendEnableMessage; + _menu.OnPowerState += SendPowerStateMessage; + _menu.OnScanPartsRequested += SendScanPartsMessage; } public void SendEnableMessage(bool enable) @@ -40,13 +42,5 @@ protected override void UpdateState(BoundUserInterfaceState state) { _menu?.DataUpdate((ParticleAcceleratorUIState) state); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _menu?.Dispose(); - _menu = null; - } } } diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs index c69e0271372..05a296edf39 100644 --- a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs +++ b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs @@ -18,9 +18,10 @@ namespace Content.Client.ParticleAccelerator.UI { public sealed class ParticleAcceleratorControlMenu : BaseWindow { - private readonly ShaderInstance _greyScaleShader; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly IResourceCache _cache = default!; - private readonly ParticleAcceleratorBoundUserInterface _owner; + private readonly ShaderInstance _greyScaleShader; private readonly Label _drawLabel; private readonly FastNoiseLite _drawNoiseGenerator; @@ -50,19 +51,22 @@ public sealed class ParticleAcceleratorControlMenu : BaseWindow private bool _shouldContinueAnimating; private int _maxStrength = 3; - public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owner) + public event Action? OnOverallState; + public event Action? OnPowerState; + public event Action? OnScanPartsRequested; + + public ParticleAcceleratorControlMenu() { + IoCManager.InjectDependencies(this); SetSize = new Vector2(400, 320); - _greyScaleShader = IoCManager.Resolve().Index("Greyscale").Instance(); + _greyScaleShader = _protoManager.Index("Greyscale").Instance(); - _owner = owner; _drawNoiseGenerator = new(); _drawNoiseGenerator.SetFractalType(FastNoiseLite.FractalType.FBm); _drawNoiseGenerator.SetFrequency(0.5f); - var resourceCache = IoCManager.Resolve(); - var font = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); - var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); + var font = _cache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); + var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); MouseFilter = MouseFilterMode.Stop; @@ -112,7 +116,8 @@ public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owne Text = Loc.GetString("particle-accelerator-control-menu-off-button"), StyleClasses = { StyleBase.ButtonOpenRight }, }; - _offButton.OnPressed += args => owner.SendEnableMessage(false); + + _offButton.OnPressed += args => OnOverallState?.Invoke(false); _onButton = new Button { @@ -120,7 +125,7 @@ public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owne Text = Loc.GetString("particle-accelerator-control-menu-on-button"), StyleClasses = { StyleBase.ButtonOpenLeft }, }; - _onButton.OnPressed += args => owner.SendEnableMessage(true); + _onButton.OnPressed += args => OnOverallState?.Invoke(true); var closeButton = new TextureButton { @@ -316,7 +321,7 @@ public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owne } }); - _scanButton.OnPressed += args => _owner.SendScanPartsMessage(); + _scanButton.OnPressed += args => OnScanPartsRequested?.Invoke(); _alarmControl.AnimationCompleted += s => { @@ -332,7 +337,7 @@ public ParticleAcceleratorControlMenu(ParticleAcceleratorBoundUserInterface owne PASegmentControl Segment(string name) { - return new(this, resourceCache, name); + return new(this, _cache, name); } UpdateUI(false, false, false, false); @@ -368,7 +373,7 @@ private void PowerStateChanged(ValueChangedEventArgs e) } _stateSpinBox.SetButtonDisabled(true); - _owner.SendPowerStateMessage(newState); + OnPowerState?.Invoke(newState); } protected override DragMode GetDragModeFor(Vector2 relativeMousePos) diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs b/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs index 3ebcf7cbced..0df6787170a 100644 --- a/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Pinpointer; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Pinpointer.UI; @@ -16,19 +17,16 @@ public NavMapBeaconBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, protected override void Open() { base.Open(); - _window = new NavMapBeaconWindow(Owner); - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); + + if (EntMan.TryGetComponent(Owner, out NavMapBeaconComponent? beacon)) + { + _window.SetEntity(Owner, beacon); + } _window.OnApplyButtonPressed += (label, enabled, color) => { SendMessage(new NavMapBeaconConfigureBuiMessage(label, enabled, color)); }; } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); - } } diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs b/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs index 968fe188f75..b77f1af0472 100644 --- a/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs +++ b/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs @@ -10,38 +10,37 @@ namespace Content.Client.Pinpointer.UI; [GenerateTypedNameReferences] public sealed partial class NavMapBeaconWindow : FancyWindow { - [Dependency] private readonly IEntityManager _entityManager = default!; - private string? _defaultLabel; private bool _defaultEnabled; private Color _defaultColor; public event Action? OnApplyButtonPressed; - public NavMapBeaconWindow(EntityUid beaconEntity) + public NavMapBeaconWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - if (!_entityManager.TryGetComponent(beaconEntity, out var navMap)) - return; - _defaultLabel = navMap.Text; - _defaultEnabled = navMap.Enabled; - _defaultColor = navMap.Color; - UpdateVisibleButton(navMap.Enabled); VisibleButton.OnPressed += args => UpdateVisibleButton(args.Button.Pressed); - - LabelLineEdit.Text = navMap.Text ?? string.Empty; LabelLineEdit.OnTextChanged += OnTextChanged; - - ColorSelector.Color = navMap.Color; ColorSelector.OnColorChanged += _ => TryEnableApplyButton(); TryEnableApplyButton(); ApplyButton.OnPressed += OnApplyPressed; } + public void SetEntity(EntityUid uid, NavMapBeaconComponent navMap) + { + _defaultLabel = navMap.Text; + _defaultEnabled = navMap.Enabled; + _defaultColor = navMap.Color; + + UpdateVisibleButton(navMap.Enabled); + LabelLineEdit.Text = navMap.Text ?? string.Empty; + ColorSelector.Color = navMap.Color; + } + private void UpdateVisibleButton(bool value) { VisibleButton.Pressed = value; diff --git a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs index 1483e75e732..7417fafede5 100644 --- a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs @@ -1,4 +1,4 @@ -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Pinpointer.UI; @@ -14,7 +14,6 @@ public StationMapBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, u protected override void Open() { base.Open(); - _window?.Close(); EntityUid? gridUid = null; if (EntMan.TryGetComponent(Owner, out var xform)) @@ -22,14 +21,8 @@ protected override void Open() gridUid = xform.GridUid; } - _window = new StationMapWindow(gridUid, Owner); - _window.OpenCentered(); - _window.OnClose += Close; - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); + _window = this.CreateWindow(); + _window.Title = EntMan.GetComponent(Owner).EntityName; + _window.Set(gridUid, Owner); } } diff --git a/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs b/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs index 1b01fe4e304..7cbb8b7d0db 100644 --- a/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs +++ b/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs @@ -9,19 +9,18 @@ namespace Content.Client.Pinpointer.UI; [GenerateTypedNameReferences] public sealed partial class StationMapWindow : FancyWindow { - public StationMapWindow(EntityUid? mapUid, EntityUid? trackedEntity) + public StationMapWindow() { RobustXamlLoader.Load(this); + } + + public void Set(EntityUid? mapUid, EntityUid? trackedEntity) + { NavMapScreen.MapUid = mapUid; if (trackedEntity != null) NavMapScreen.TrackedCoordinates.Add(new EntityCoordinates(trackedEntity.Value, Vector2.Zero), (true, Color.Cyan)); - if (IoCManager.Resolve().TryGetComponent(mapUid, out var metadata)) - { - Title = metadata.EntityName; - } - NavMapScreen.ForceNavMapUpdate(); } } diff --git a/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs b/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs index 57965b030a2..a3ca6f65da2 100644 --- a/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/UntrackedMapBoundUserInterface.cs @@ -1,4 +1,4 @@ -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Pinpointer.UI; @@ -14,22 +14,15 @@ public UntrackedStationMapBoundUserInterface(EntityUid owner, Enum uiKey) : base protected override void Open() { base.Open(); - _window?.Close(); EntityUid? gridUid = null; + // TODO: What this just looks like it's been copy-pasted wholesale from StationMapBoundUserInterface? if (EntMan.TryGetComponent(Owner, out var xform)) { gridUid = xform.GridUid; } - _window = new StationMapWindow(gridUid, null); - _window.OpenCentered(); - _window.OnClose += Close; - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); + _window = this.CreateWindow(); + _window.Set(gridUid, Owner); } } diff --git a/Content.Client/Power/APC/ApcBoundUserInterface.cs b/Content.Client/Power/APC/ApcBoundUserInterface.cs index fbcbf011569..759a5949ba6 100644 --- a/Content.Client/Power/APC/ApcBoundUserInterface.cs +++ b/Content.Client/Power/APC/ApcBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.APC; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Power.APC { @@ -19,9 +20,8 @@ protected override void Open() { base.Open(); - _menu = new ApcMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnBreaker += BreakerPressed; } protected override void UpdateState(BoundUserInterfaceState state) @@ -36,15 +36,5 @@ public void BreakerPressed() { SendMessage(new ApcToggleMainBreakerMessage()); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _menu?.Dispose(); - } - } } } diff --git a/Content.Client/Power/APC/UI/ApcMenu.xaml.cs b/Content.Client/Power/APC/UI/ApcMenu.xaml.cs index dbf68ea07b0..2f61ea63a86 100644 --- a/Content.Client/Power/APC/UI/ApcMenu.xaml.cs +++ b/Content.Client/Power/APC/UI/ApcMenu.xaml.cs @@ -17,13 +17,19 @@ namespace Content.Client.Power.APC.UI [GenerateTypedNameReferences] public sealed partial class ApcMenu : FancyWindow { - public ApcMenu(ApcBoundUserInterface owner) + public event Action? OnBreaker; + + public ApcMenu() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - EntityView.SetEntity(owner.Owner); - BreakerButton.OnPressed += _ => owner.BreakerPressed(); + BreakerButton.OnPressed += _ => OnBreaker?.Invoke(); + } + + public void SetEntity(EntityUid entity) + { + EntityView.SetEntity(entity); } public void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Power/Generator/GeneratorWindow.xaml.cs b/Content.Client/Power/Generator/GeneratorWindow.xaml.cs index bd5b75de1da..e975e5d466e 100644 --- a/Content.Client/Power/Generator/GeneratorWindow.xaml.cs +++ b/Content.Client/Power/Generator/GeneratorWindow.xaml.cs @@ -9,35 +9,39 @@ namespace Content.Client.Power.Generator; [GenerateTypedNameReferences] public sealed partial class GeneratorWindow : FancyWindow { - private readonly EntityUid _entity; - [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly ILocalizationManager _loc = default!; - private readonly SharedPowerSwitchableSystem _switchable; - private readonly FuelGeneratorComponent? _component; - private PortableGeneratorComponentBuiState? _lastState; + private EntityUid _entity; + + public float? MaximumPower; + + public event Action? OnPower; + public event Action? OnState; + public event Action? OnSwitchOutput; + public event Action? OnEjectFuel; - public GeneratorWindow(PortableGeneratorBoundUserInterface bui, EntityUid entity) + public GeneratorWindow() { - _entity = entity; RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - _entityManager.TryGetComponent(entity, out _component); - _switchable = _entityManager.System(); - - EntityView.SetEntity(entity); TargetPower.IsValid += IsValid; TargetPower.ValueChanged += (args) => { - bui.SetTargetPower(args.Value); + OnPower?.Invoke(args.Value); }; - StartButton.OnPressed += _ => bui.Start(); - StopButton.OnPressed += _ => bui.Stop(); - OutputSwitchButton.OnPressed += _ => bui.SwitchOutput(); - FuelEject.OnPressed += _ => bui.EjectFuel(); + StartButton.OnPressed += _ => OnState?.Invoke(true); + StopButton.OnPressed += _ => OnState?.Invoke(false); + OutputSwitchButton.OnPressed += _ => OnSwitchOutput?.Invoke(); + FuelEject.OnPressed += _ => OnEjectFuel?.Invoke(); + } + + public void SetEntity(EntityUid entity) + { + _entity = entity; + EntityView.SetEntity(entity); } private bool IsValid(int arg) @@ -45,7 +49,7 @@ private bool IsValid(int arg) if (arg < 0) return false; - if (arg > (_lastState?.MaximumPower / 1000.0f ?? 0)) + if (arg > (MaximumPower / 1000.0f ?? 0)) return false; return true; @@ -53,16 +57,17 @@ private bool IsValid(int arg) public void Update(PortableGeneratorComponentBuiState state) { - if (_component == null) + MaximumPower = state.MaximumPower; + + if (!_entityManager.TryGetComponent(_entity, out FuelGeneratorComponent? component)) return; - _lastState = state; if (!TargetPower.LineEditControl.HasKeyboardFocus()) TargetPower.OverrideValue((int)(state.TargetPower / 1000.0f)); - var efficiency = SharedGeneratorSystem.CalcFuelEfficiency(state.TargetPower, state.OptimalPower, _component); + var efficiency = SharedGeneratorSystem.CalcFuelEfficiency(state.TargetPower, state.OptimalPower, component); Efficiency.Text = efficiency.ToString("P1"); - var burnRate = _component.OptimalBurnRate / efficiency; + var burnRate = component.OptimalBurnRate / efficiency; var left = state.RemainingFuel / burnRate; Eta.Text = Loc.GetString( @@ -102,14 +107,15 @@ public void Update(PortableGeneratorComponentBuiState state) } var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableComponent? switchable); + var switcher = _entityManager.System(); OutputSwitchLabel.Visible = canSwitch; OutputSwitchButton.Visible = canSwitch; if (switchable != null) { - var voltage = _switchable.VoltageString(_switchable.GetVoltage(_entity, switchable)); + var voltage = switcher.VoltageString(switcher.GetVoltage(_entity, switchable)); OutputSwitchLabel.Text = Loc.GetString("portable-generator-ui-current-output", ("voltage", voltage)); - var nextVoltage = _switchable.VoltageString(_switchable.GetNextVoltage(_entity, switchable)); + var nextVoltage = switcher.VoltageString(switcher.GetNextVoltage(_entity, switchable)); OutputSwitchButton.Text = Loc.GetString("power-switchable-switch-voltage", ("voltage", nextVoltage)); OutputSwitchButton.Disabled = state.On; } diff --git a/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs b/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs index 30679d71fd6..550e1041b62 100644 --- a/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs +++ b/Content.Client/Power/Generator/PortableGeneratorBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Power.Generator; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Power.Generator; @@ -16,10 +17,25 @@ public PortableGeneratorBoundUserInterface(EntityUid owner, Enum uiKey) : base(o protected override void Open() { base.Open(); - _window = new GeneratorWindow(this, Owner); + _window = this.CreateWindow(); + _window.SetEntity(Owner); + _window.OnState += args => + { + if (args) + { + Start(); + } + else + { + Stop(); + } + }; + + _window.OnPower += SetTargetPower; + _window.OnEjectFuel += EjectFuel; + _window.OnSwitchOutput += SwitchOutput; _window.OpenCenteredLeft(); - _window.OnClose += Close; } protected override void UpdateState(BoundUserInterfaceState state) @@ -30,11 +46,6 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.Update(msg); } - protected override void Dispose(bool disposing) - { - _window?.Dispose(); - } - public void SetTargetPower(int target) { SendMessage(new PortableGeneratorSetTargetPowerMessage(target)); diff --git a/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs b/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs index dc1dcd03ef1..cbc343c06c6 100644 --- a/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs +++ b/Content.Client/Power/PowerMonitoringConsoleBoundUserInterface.cs @@ -1,4 +1,5 @@ using Content.Shared.Power; +using Robust.Client.UserInterface; namespace Content.Client.Power; @@ -11,9 +12,9 @@ public PowerMonitoringConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : b protected override void Open() { - _menu = new PowerMonitoringWindow(this, Owner); - _menu.OpenCentered(); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.SendPowerMonitoringConsoleMessageAction += SendPowerMonitoringConsoleMessage; } protected override void UpdateState(BoundUserInterfaceState state) @@ -22,9 +23,6 @@ protected override void UpdateState(BoundUserInterfaceState state) var castState = (PowerMonitoringConsoleBoundInterfaceState) state; - if (castState == null) - return; - EntMan.TryGetComponent(Owner, out var xform); _menu?.ShowEntites (castState.TotalSources, @@ -40,13 +38,4 @@ public void SendPowerMonitoringConsoleMessage(NetEntity? netEntity, PowerMonitor { SendMessage(new PowerMonitoringConsoleMessage(netEntity, group)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs b/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs index 74752ddc534..d9952992070 100644 --- a/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs +++ b/Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs @@ -32,7 +32,7 @@ private void UpdateWindowConsoleEntry if (windowEntry == null) return; - // Update sources and loads + // Update sources and loads UpdateEntrySourcesOrLoads(masterContainer, windowEntry.SourcesContainer, focusSources, _sourceIcon); UpdateEntrySourcesOrLoads(masterContainer, windowEntry.LoadsContainer, focusLoads, _loadIconPath); @@ -134,7 +134,7 @@ private void UpdateEntrySourcesOrLoads(BoxContainer masterContainer, BoxContaine subEntry.Button.OnButtonUp += args => { ButtonAction(subEntry, masterContainer); }; } - if (!_entManager.TryGetComponent(_owner, out var console)) + if (!_entManager.TryGetComponent(Entity, out var console)) return; // Update all children @@ -379,7 +379,7 @@ public PowerMonitoringWindowEntry(PowerMonitoringConsoleEntry entry) : base(entr AddChild(MainContainer); - // Grid container to hold the list of sources when selected + // Grid container to hold the list of sources when selected SourcesContainer = new BoxContainer() { Orientation = LayoutOrientation.Vertical, diff --git a/Content.Client/Power/PowerMonitoringWindow.xaml.cs b/Content.Client/Power/PowerMonitoringWindow.xaml.cs index 81fe1f4d047..e3043252486 100644 --- a/Content.Client/Power/PowerMonitoringWindow.xaml.cs +++ b/Content.Client/Power/PowerMonitoringWindow.xaml.cs @@ -15,13 +15,12 @@ namespace Content.Client.Power; [GenerateTypedNameReferences] public sealed partial class PowerMonitoringWindow : FancyWindow { - private readonly IEntityManager _entManager; + [Dependency] private IEntityManager _entManager = default!; private readonly SpriteSystem _spriteSystem; - private readonly IGameTiming _gameTiming; + [Dependency] private IGameTiming _gameTiming = default!; private const float BlinkFrequency = 1f; - private EntityUid? _owner; private NetEntity? _focusEntity; public event Action? SendPowerMonitoringConsoleMessageAction; @@ -34,31 +33,56 @@ public sealed partial class PowerMonitoringWindow : FancyWindow { PowerMonitoringConsoleGroup.APC, (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_triangle.png")), Color.LimeGreen) }, }; - public PowerMonitoringWindow(PowerMonitoringConsoleBoundUserInterface userInterface, EntityUid? owner) + public EntityUid Entity; + + public PowerMonitoringWindow() { RobustXamlLoader.Load(this); - _entManager = IoCManager.Resolve(); - _gameTiming = IoCManager.Resolve(); + IoCManager.InjectDependencies(this); _spriteSystem = _entManager.System(); - _owner = owner; + + // Set trackable entity selected action + NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; + + // Update nav map + NavMap.ForceNavMapUpdate(); + + // Set UI tab titles + MasterTabContainer.SetTabTitle(0, Loc.GetString("power-monitoring-window-label-sources")); + MasterTabContainer.SetTabTitle(1, Loc.GetString("power-monitoring-window-label-smes")); + MasterTabContainer.SetTabTitle(2, Loc.GetString("power-monitoring-window-label-substation")); + MasterTabContainer.SetTabTitle(3, Loc.GetString("power-monitoring-window-label-apc")); + + // Track when the MasterTabContainer changes its tab + MasterTabContainer.OnTabChanged += OnTabChanged; + + // Set UI toggles + ShowHVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.HighVoltage); + ShowMVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.MediumVoltage); + ShowLVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.Apc); + } + + public void SetEntity(EntityUid uid) + { + Entity = uid; // Pass owner to nav map - NavMap.Owner = _owner; + NavMap.Owner = uid; // Set nav map grid uid var stationName = Loc.GetString("power-monitoring-window-unknown-location"); - if (_entManager.TryGetComponent(owner, out var xform)) + if (_entManager.TryGetComponent(uid, out var xform)) { NavMap.MapUid = xform.GridUid; - // Assign station name + // Assign station name if (_entManager.TryGetComponent(xform.GridUid, out var stationMetaData)) stationName = stationMetaData.EntityName; var msg = new FormattedMessage(); - msg.AddMarkup(Loc.GetString("power-monitoring-window-station-name", ("stationName", stationName))); + msg.AddMarkupOrThrow(Loc.GetString("power-monitoring-window-station-name", ("stationName", stationName))); StationName.SetMessage(msg); } @@ -68,29 +92,6 @@ public PowerMonitoringWindow(PowerMonitoringConsoleBoundUserInterface userInterf StationName.SetMessage(stationName); NavMap.Visible = false; } - - // Set trackable entity selected action - NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap; - - // Update nav map - NavMap.ForceNavMapUpdate(); - - // Set UI tab titles - MasterTabContainer.SetTabTitle(0, Loc.GetString("power-monitoring-window-label-sources")); - MasterTabContainer.SetTabTitle(1, Loc.GetString("power-monitoring-window-label-smes")); - MasterTabContainer.SetTabTitle(2, Loc.GetString("power-monitoring-window-label-substation")); - MasterTabContainer.SetTabTitle(3, Loc.GetString("power-monitoring-window-label-apc")); - - // Track when the MasterTabContainer changes its tab - MasterTabContainer.OnTabChanged += OnTabChanged; - - // Set UI toggles - ShowHVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.HighVoltage); - ShowMVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.MediumVoltage); - ShowLVCable.OnToggled += _ => OnShowCableToggled(PowerMonitoringConsoleLineGroup.Apc); - - // Set power monitoring message action - SendPowerMonitoringConsoleMessageAction += userInterface.SendPowerMonitoringConsoleMessage; } private void OnTabChanged(int tab) @@ -113,10 +114,7 @@ public void ShowEntites PowerMonitoringConsoleEntry[] focusLoads, EntityCoordinates? monitorCoords) { - if (_owner == null) - return; - - if (!_entManager.TryGetComponent(_owner.Value, out var console)) + if (!_entManager.TryGetComponent(Entity, out var console)) return; // Update power status text @@ -161,13 +159,13 @@ public void ShowEntites } // Show monitor location - var mon = _entManager.GetNetEntity(_owner); + var mon = _entManager.GetNetEntity(Entity); - if (monitorCoords != null && mon != null) + if (monitorCoords != null && mon.IsValid()) { var texture = _spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png"))); var blip = new NavMapBlip(monitorCoords.Value, texture, Color.Cyan, true, false); - NavMap.TrackedEntities[mon.Value] = blip; + NavMap.TrackedEntities[mon] = blip; } // If the entry group doesn't match the current tab, the data is out dated, do not use it @@ -239,7 +237,7 @@ private void SetTrackedEntityFromNavMap(NetEntity? netEntity) if (netEntity == null) return; - if (!_entManager.TryGetComponent(_owner, out var console)) + if (!_entManager.TryGetComponent(Entity, out var console)) return; if (!console.PowerMonitoringDeviceMetaData.TryGetValue(netEntity.Value, out var metaData)) @@ -266,7 +264,7 @@ protected override void FrameUpdate(FrameEventArgs args) { AutoScrollToFocus(); - // Warning sign pulse + // Warning sign pulse var lit = _gameTiming.RealTime.TotalSeconds % BlinkFrequency > BlinkFrequency / 2f; SystemWarningPanel.Modulate = lit ? Color.White : new Color(178, 178, 178); } diff --git a/Content.Client/RCD/RCDMenu.xaml.cs b/Content.Client/RCD/RCDMenu.xaml.cs index 3eb0397a690..f0d27d6b1fb 100644 --- a/Content.Client/RCD/RCDMenu.xaml.cs +++ b/Content.Client/RCD/RCDMenu.xaml.cs @@ -20,31 +20,37 @@ public sealed partial class RCDMenu : RadialMenu [Dependency] private readonly IPrototypeManager _protoManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; - private readonly SpriteSystem _spriteSystem; - private readonly SharedPopupSystem _popup; + private SharedPopupSystem _popup; + private SpriteSystem _sprites; public event Action>? SendRCDSystemMessageAction; private EntityUid _owner; - public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) + public RCDMenu() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); - _spriteSystem = _entManager.System(); _popup = _entManager.System(); + _sprites = _entManager.System(); - _owner = owner; + OnChildAdded += AddRCDMenuButtonOnClickActions; + } + + public void SetEntity(EntityUid uid) + { + _owner = uid; + Refresh(); + } + public void Refresh() + { // Find the main radial container var main = FindControl("Main"); - if (main == null) - return; - // Populate secondary radial containers - if (!_entManager.TryGetComponent(owner, out var rcd)) + if (!_entManager.TryGetComponent(_owner, out var rcd)) return; foreach (var protoId in rcd.AvailablePrototypes) @@ -56,14 +62,10 @@ public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) continue; var parent = FindControl(proto.Category); - - if (parent == null) - continue; - var tooltip = Loc.GetString(proto.SetName); if ((proto.Mode == RcdMode.ConstructTile || proto.Mode == RcdMode.ConstructObject) && - proto.Prototype != null && _protoManager.TryIndex(proto.Prototype, out var entProto)) + proto.Prototype != null && _protoManager.TryIndex(proto.Prototype, out var entProto, logError: false)) { tooltip = Loc.GetString(entProto.Name); } @@ -84,7 +86,7 @@ public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) { VerticalAlignment = VAlignment.Center, HorizontalAlignment = HAlignment.Center, - Texture = _spriteSystem.Frame0(proto.Sprite), + Texture = _sprites.Frame0(proto.Sprite), TextureScale = new Vector2(2f, 2f), }; @@ -112,11 +114,9 @@ public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) // Set up menu actions foreach (var child in Children) + { AddRCDMenuButtonOnClickActions(child); - - OnChildAdded += AddRCDMenuButtonOnClickActions; - - SendRCDSystemMessageAction += bui.SendRCDSystemMessage; + } } private static string OopsConcat(string a, string b) @@ -153,7 +153,7 @@ private void AddRCDMenuButtonOnClickActions(Control control) var name = Loc.GetString(proto.SetName); if (proto.Prototype != null && - _protoManager.TryIndex(proto.Prototype, out var entProto)) + _protoManager.TryIndex(proto.Prototype, out var entProto, logError: false)) name = entProto.Name; msg = Loc.GetString("rcd-component-change-build-mode", ("name", name)); diff --git a/Content.Client/RCD/RCDMenuBoundUserInterface.cs b/Content.Client/RCD/RCDMenuBoundUserInterface.cs index a37dbcecf8c..1dd03626ae6 100644 --- a/Content.Client/RCD/RCDMenuBoundUserInterface.cs +++ b/Content.Client/RCD/RCDMenuBoundUserInterface.cs @@ -3,6 +3,7 @@ using JetBrains.Annotations; using Robust.Client.Graphics; using Robust.Client.Input; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.RCD; @@ -24,8 +25,9 @@ protected override void Open() { base.Open(); - _menu = new(Owner, this); - _menu.OnClose += Close; + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.SendRCDSystemMessageAction += SendRCDSystemMessage; // Open the menu, centered on the mouse var vpSize = _displayManager.ScreenSize; @@ -34,16 +36,8 @@ protected override void Open() public void SendRCDSystemMessage(ProtoId protoId) { - // A predicted message cannot be used here as the RCD UI is closed immediately + // A predicted message cannot be used here as the RCD UI is closed immediately // after this message is sent, which will stop the server from receiving it SendMessage(new RCDSystemMessage(protoId)); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - - _menu?.Dispose(); - } } diff --git a/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs b/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs index 7b3e39aa084..401e7edd44a 100644 --- a/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs +++ b/Content.Client/Radio/Ui/IntercomBoundUserInterface.cs @@ -1,6 +1,8 @@ using Content.Shared.Radio; using Content.Shared.Radio.Components; using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Radio.Ui; @@ -19,9 +21,12 @@ protected override void Open() { base.Open(); - var comp = EntMan.GetComponent(Owner); + _menu = this.CreateWindow(); - _menu = new((Owner, comp)); + if (EntMan.TryGetComponent(Owner, out IntercomComponent? intercom)) + { + _menu.Update((Owner, intercom)); + } _menu.OnMicPressed += enabled => { @@ -35,17 +40,6 @@ protected override void Open() { SendMessage(new SelectIntercomChannelMessage(channel)); }; - - _menu.OnClose += Close; - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); } public void Update(Entity ent) diff --git a/Content.Client/Radio/Ui/IntercomMenu.xaml.cs b/Content.Client/Radio/Ui/IntercomMenu.xaml.cs index 2e08913051c..20d2e4a3e54 100644 --- a/Content.Client/Radio/Ui/IntercomMenu.xaml.cs +++ b/Content.Client/Radio/Ui/IntercomMenu.xaml.cs @@ -18,15 +18,13 @@ public sealed partial class IntercomMenu : FancyWindow private readonly List _channels = new(); - public IntercomMenu(Entity entity) + public IntercomMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); MicButton.OnPressed += args => OnMicPressed?.Invoke(args.Button.Pressed); SpeakerButton.OnPressed += args => OnSpeakerPressed?.Invoke(args.Button.Pressed); - - Update(entity); } public void Update(Entity entity) diff --git a/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs b/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs index c14a8c5bd05..9641adb5b2d 100644 --- a/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs +++ b/Content.Client/Research/UI/DiskConsoleBoundUserInterface.cs @@ -1,5 +1,7 @@ using Content.Shared.Research; using Content.Shared.Research.Components; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Research.UI { @@ -16,10 +18,7 @@ protected override void Open() { base.Open(); - _menu = new(); - - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); _menu.OnServerButtonPressed += () => { @@ -31,14 +30,6 @@ protected override void Open() }; } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); - } - protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); diff --git a/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs b/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs index a0a2b58e889..288445e4dea 100644 --- a/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs +++ b/Content.Client/Research/UI/ResearchClientBoundUserInterface.cs @@ -1,4 +1,6 @@ using Content.Shared.Research.Components; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Research.UI { @@ -15,10 +17,9 @@ public ResearchClientBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - - _menu = new ResearchClientServerSelectionMenu(this); - _menu.OnClose += Close; - _menu.OpenCentered(); + _menu = this.CreateWindow(); + _menu.OnServerSelected += SelectServer; + _menu.OnServerDeselected += DeselectServer; } public void SelectServer(int serverId) @@ -37,12 +38,5 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not ResearchClientBoundInterfaceState rState) return; _menu?.Populate(rState.ServerCount, rState.ServerNames, rState.ServerIds, rState.SelectedServerId); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) return; - _menu?.Dispose(); - } } } diff --git a/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs b/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs index ceaa965e59f..d10f8b39f48 100644 --- a/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs +++ b/Content.Client/Research/UI/ResearchClientServerSelectionMenu.xaml.cs @@ -13,27 +13,26 @@ public sealed partial class ResearchClientServerSelectionMenu : DefaultWindow private int[] _serverIds = Array.Empty(); private int _selectedServerId = -1; - private ResearchClientBoundUserInterface Owner { get; } + public event Action? OnServerSelected; + public event Action? OnServerDeselected; - public ResearchClientServerSelectionMenu(ResearchClientBoundUserInterface owner) + public ResearchClientServerSelectionMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - Owner = owner; - Servers.OnItemSelected += OnItemSelected; Servers.OnItemDeselected += OnItemDeselected; } public void OnItemSelected(ItemList.ItemListSelectedEventArgs itemListSelectedEventArgs) { - Owner.SelectServer(_serverIds[itemListSelectedEventArgs.ItemIndex]); + OnServerSelected?.Invoke(_serverIds[itemListSelectedEventArgs.ItemIndex]); } public void OnItemDeselected(ItemList.ItemListDeselectedEventArgs itemListDeselectedEventArgs) { - Owner.DeselectServer(); + OnServerDeselected?.Invoke(); } public void Populate(int serverCount, string[] serverNames, int[] serverIds, int selectedServerId) diff --git a/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs b/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs index 2a9782045b8..2895ada61fb 100644 --- a/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs +++ b/Content.Client/Research/UI/ResearchConsoleBoundUserInterface.cs @@ -1,5 +1,8 @@ using Content.Shared.Research.Components; +using Content.Shared.Research.Prototypes; using JetBrains.Annotations; +using Robust.Client.UserInterface; +using Robust.Shared.Prototypes; namespace Content.Client.Research.UI; @@ -19,7 +22,8 @@ protected override void Open() var owner = Owner; - _consoleMenu = new ResearchConsoleMenu(owner); + _consoleMenu = this.CreateWindow(); + _consoleMenu.SetEntity(owner); _consoleMenu.OnTechnologyCardPressed += id => { @@ -30,10 +34,20 @@ protected override void Open() { SendMessage(new ConsoleServerSelectionMessage()); }; + } + + public override void OnProtoReload(PrototypesReloadedEventArgs args) + { + base.OnProtoReload(args); + + if (!args.WasModified()) + return; - _consoleMenu.OnClose += Close; + if (State is not ResearchConsoleBoundInterfaceState rState) + return; - _consoleMenu.OpenCentered(); + _consoleMenu?.UpdatePanels(rState); + _consoleMenu?.UpdateInformationPanel(rState); } protected override void UpdateState(BoundUserInterfaceState state) @@ -45,12 +59,4 @@ protected override void UpdateState(BoundUserInterfaceState state) _consoleMenu?.UpdatePanels(castState); _consoleMenu?.UpdateInformationPanel(castState); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _consoleMenu?.Dispose(); - } } diff --git a/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs b/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs index 77ebe6740c5..eafbe75fbb9 100644 --- a/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs +++ b/Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs @@ -25,14 +25,13 @@ public sealed partial class ResearchConsoleMenu : FancyWindow [Dependency] private readonly IEntityManager _entity = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IPlayerManager _player = default!; - private readonly TechnologyDatabaseComponent? _technologyDatabase; private readonly ResearchSystem _research; private readonly SpriteSystem _sprite; private readonly AccessReaderSystem _accessReader; - public readonly EntityUid Entity; + public EntityUid Entity; - public ResearchConsoleMenu(EntityUid entity) + public ResearchConsoleMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -40,21 +39,23 @@ public ResearchConsoleMenu(EntityUid entity) _research = _entity.System(); _sprite = _entity.System(); _accessReader = _entity.System(); - Entity = entity; ServerButton.OnPressed += _ => OnServerButtonPressed?.Invoke(); + } - _entity.TryGetComponent(entity, out _technologyDatabase); + public void SetEntity(EntityUid entity) + { + Entity = entity; } - public void UpdatePanels(ResearchConsoleBoundInterfaceState state) + public void UpdatePanels(ResearchConsoleBoundInterfaceState state) { TechnologyCardsContainer.Children.Clear(); var availableTech = _research.GetAvailableTechnologies(Entity); SyncTechnologyList(AvailableCardsContainer, availableTech); - if (_technologyDatabase == null) + if (!_entity.TryGetComponent(Entity, out TechnologyDatabaseComponent? database)) return; // i can't figure out the spacing so here you go @@ -66,7 +67,7 @@ public void UpdatePanels(ResearchConsoleBoundInterfaceState state) var hasAccess = _player.LocalEntity is not { } local || !_entity.TryGetComponent(Entity, out var access) || _accessReader.IsAllowed(local, Entity, access); - foreach (var techId in _technologyDatabase.CurrentTechnologyCards) + foreach (var techId in database.CurrentTechnologyCards) { var tech = _prototype.Index(techId); var cardControl = new TechnologyCardControl(tech, _prototype, _sprite, _research.GetTechnologyDescription(tech, includeTier: false), state.Points, hasAccess); @@ -74,7 +75,7 @@ public void UpdatePanels(ResearchConsoleBoundInterfaceState state) TechnologyCardsContainer.AddChild(cardControl); } - var unlockedTech = _technologyDatabase.UnlockedTechnologies.Select(x => _prototype.Index(x)); + var unlockedTech = database.UnlockedTechnologies.Select(x => _prototype.Index(x)); SyncTechnologyList(UnlockedCardsContainer, unlockedTech); } @@ -85,14 +86,14 @@ public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state) ("points", state.Points))); ResearchAmountLabel.SetMessage(amountMsg); - if (_technologyDatabase == null) + if (!_entity.TryGetComponent(Entity, out TechnologyDatabaseComponent? database)) return; var disciplineText = Loc.GetString("research-discipline-none"); var disciplineColor = Color.Gray; - if (_technologyDatabase.MainDiscipline != null) + if (database.MainDiscipline != null) { - var discipline = _prototype.Index(_technologyDatabase.MainDiscipline); + var discipline = _prototype.Index(database.MainDiscipline); disciplineText = Loc.GetString(discipline.Name); disciplineColor = discipline.Color; } @@ -103,10 +104,10 @@ public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state) MainDisciplineLabel.SetMessage(msg); TierDisplayContainer.Children.Clear(); - foreach (var disciplineId in _technologyDatabase.SupportedDisciplines) + foreach (var disciplineId in database.SupportedDisciplines) { var discipline = _prototype.Index(disciplineId); - var tier = _research.GetHighestDisciplineTier(_technologyDatabase, discipline); + var tier = _research.GetHighestDisciplineTier(database, discipline); // don't show tiers with no available tech if (tier == 0) diff --git a/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs b/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs index 6185979eee6..9a5159880f9 100644 --- a/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs +++ b/Content.Client/Robotics/UI/RoboticsConsoleBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Robotics; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Robotics.UI; @@ -16,7 +17,9 @@ protected override void Open() { base.Open(); - _window = new RoboticsConsoleWindow(Owner); + _window = this.CreateWindow(); + _window.SetEntity(Owner); + _window.OnDisablePressed += address => { SendMessage(new RoboticsConsoleDisableMessage(address)); @@ -25,9 +28,6 @@ protected override void Open() { SendMessage(new RoboticsConsoleDestroyMessage(address)); }; - _window.OnClose += Close; - - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -37,14 +37,6 @@ protected override void UpdateState(BoundUserInterfaceState state) if (state is not RoboticsConsoleState cast) return; - _window?.UpdateState(cast); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - _window?.Dispose(); + _window.UpdateState(cast); } } diff --git a/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs b/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs index fc7b234bccc..87d7e62c392 100644 --- a/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs +++ b/Content.Client/Robotics/UI/RoboticsConsoleWindow.xaml.cs @@ -23,11 +23,12 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow public Action? OnDisablePressed; public Action? OnDestroyPressed; - private Entity _console; private string? _selected; private Dictionary _cyborgs = new(); - public RoboticsConsoleWindow(EntityUid console) + public EntityUid Entity; + + public RoboticsConsoleWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -35,9 +36,6 @@ public RoboticsConsoleWindow(EntityUid console) _lock = _entMan.System(); _sprite = _entMan.System(); - _console = (console, _entMan.GetComponent(console), null); - _entMan.TryGetComponent(_console, out _console.Comp2); - Cyborgs.OnItemSelected += args => { if (Cyborgs[args.ItemIndex].Metadata is not string address) @@ -66,6 +64,11 @@ public RoboticsConsoleWindow(EntityUid console) DestroyButton.StyleClasses.Add(StyleBase.ButtonCaution); } + public void SetEntity(EntityUid uid) + { + Entity = uid; + } + public void UpdateState(RoboticsConsoleState state) { _cyborgs = state.Cyborgs; @@ -81,7 +84,7 @@ public void UpdateState(RoboticsConsoleState state) PopulateData(); - var locked = _lock.IsLocked((_console, _console.Comp2)); + var locked = _lock.IsLocked(Entity); DangerZone.Visible = !locked; LockedMessage.Visible = locked; } @@ -135,13 +138,19 @@ private void PopulateData() // how the turntables DisableButton.Disabled = !(data.HasBrain && data.CanDisable); - DestroyButton.Disabled = _timing.CurTime < _console.Comp1.NextDestroy; } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - DestroyButton.Disabled = _timing.CurTime < _console.Comp1.NextDestroy; + if (_entMan.TryGetComponent(Entity, out RoboticsConsoleComponent? console)) + { + DestroyButton.Disabled = _timing.CurTime < console.NextDestroy; + } + else + { + DestroyButton.Disabled = true; + } } } diff --git a/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs b/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs index 8f1723d1f22..663bde15b0d 100644 --- a/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs +++ b/Content.Client/Salvage/UI/SalvageExpeditionConsoleBoundUserInterface.cs @@ -30,17 +30,9 @@ public SalvageExpeditionConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : protected override void Open() { base.Open(); - _window = new OfferingWindow(); + _window = this.CreateWindow(); _window.Title = Loc.GetString("salvage-expedition-window-title"); - _window.OnClose += Close; - _window?.OpenCenteredLeft(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _window?.Dispose(); - _window = null; + _window.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs b/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs index eafb692733f..a248126a855 100644 --- a/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs +++ b/Content.Client/Salvage/UI/SalvageMagnetBoundUserInterface.cs @@ -21,13 +21,9 @@ protected override void Open() { base.Open(); - if (_window is null) - { - _window = new OfferingWindow(); - _window.Title = Loc.GetString("salvage-magnet-window-title"); - _window.OnClose += Close; - _window.OpenCenteredLeft(); - } + _window = this.CreateWindow(); + _window.Title = Loc.GetString("salvage-magnet-window-title"); + _window.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -112,15 +108,4 @@ protected override void UpdateState(BoundUserInterfaceState state) _window.AddOption(option); } } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - if (disposing) - { - _window?.Close(); - _window?.Dispose(); - } - } } diff --git a/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs index 086369aa264..b8b4fb8a746 100644 --- a/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/IFFConsoleBoundUserInterface.cs @@ -3,6 +3,7 @@ using Content.Shared.Shuttles.Events; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Shuttles.BUI; @@ -20,8 +21,7 @@ protected override void Open() { base.Open(); - _window = new IFFConsoleWindow(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.ShowIFF += SendIFFMessage; _window.ShowVessel += SendVesselMessage; _window.OpenCenteredLeft(); diff --git a/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs index 4bd44a47a8e..f75759b042f 100644 --- a/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Shuttles.BUIStates; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using RadarConsoleWindow = Content.Client.Shuttles.UI.RadarConsoleWindow; namespace Content.Client.Shuttles.BUI; @@ -20,18 +21,7 @@ protected override void Open() { base.Open(); - _window = new RadarConsoleWindow(); - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (disposing) - { - _window?.Dispose(); - } + _window = this.CreateWindow(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs index af7b6055c80..e677181419e 100644 --- a/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs +++ b/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Events; using JetBrains.Annotations; +using Robust.Client.UserInterface; using Robust.Shared.Map; namespace Content.Client.Shuttles.BUI; @@ -19,9 +20,7 @@ public ShuttleConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owne protected override void Open() { base.Open(); - _window = new ShuttleConsoleWindow(); - _window.OpenCentered(); - _window.OnClose += Close; + _window = this.CreateWindow(); _window.RequestFTL += OnFTLRequest; _window.RequestBeaconFTL += OnFTLBeaconRequest; diff --git a/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs b/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs index 3cc2a35d795..ed9bf40a481 100644 --- a/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs +++ b/Content.Client/Silicons/Borgs/BorgBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Silicons.Borgs; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Silicons.Borgs; @@ -18,9 +19,8 @@ protected override void Open() { base.Open(); - var owner = Owner; - - _menu = new BorgMenu(owner); + _menu = this.CreateWindow(); + _menu.SetEntity(Owner); _menu.BrainButtonPressed += () => { @@ -41,10 +41,6 @@ protected override void Open() { SendMessage(new BorgRemoveModuleBuiMessage(EntMan.GetNetEntity(module))); }; - - _menu.OnClose += Close; - - _menu.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -55,12 +51,4 @@ protected override void UpdateState(BoundUserInterfaceState state) return; _menu?.UpdateState(msg); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Dispose(); - } } diff --git a/Content.Client/Silicons/Borgs/BorgMenu.xaml b/Content.Client/Silicons/Borgs/BorgMenu.xaml index 7d8fd9fe57d..4cc2e41a8fb 100644 --- a/Content.Client/Silicons/Borgs/BorgMenu.xaml +++ b/Content.Client/Silicons/Borgs/BorgMenu.xaml @@ -10,7 +10,7 @@ VerticalExpand="True"> - + diff --git a/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs b/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs index 474a83b4530..f6a861aa057 100644 --- a/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs +++ b/Content.Client/Silicons/Borgs/BorgMenu.xaml.cs @@ -21,25 +21,33 @@ public sealed partial class BorgMenu : FancyWindow public Action? NameChanged; public Action? RemoveModuleButtonPressed; - private readonly BorgChassisComponent? _chassis; - public readonly EntityUid Entity; public float AccumulatedTime; private string _lastValidName; private List _modules = new(); - public BorgMenu(EntityUid entity) + public EntityUid Entity; + + public BorgMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - Entity = entity; + _lastValidName = NameLineEdit.Text; - if (_entity.TryGetComponent(Entity, out var chassis)) - _chassis = chassis; + EjectBatteryButton.OnPressed += _ => EjectBatteryButtonPressed?.Invoke(); + BrainButton.OnPressed += _ => BrainButtonPressed?.Invoke(); + NameLineEdit.OnTextChanged += OnNameChanged; + NameLineEdit.OnTextEntered += OnNameEntered; + NameLineEdit.OnFocusExit += OnNameFocusExit; + + UpdateBrainButton(); + } + + public void SetEntity(EntityUid entity) + { + Entity = entity; BorgSprite.SetEntity(entity); - ChargeBar.MaxValue = 1f; - ChargeBar.Value = 1f; if (_entity.TryGetComponent(Entity, out var nameIdentifierComponent)) { @@ -55,17 +63,6 @@ public BorgMenu(EntityUid entity) NameIdentifierLabel.Visible = false; NameLineEdit.Text = _entity.GetComponent(Entity).EntityName; } - - _lastValidName = NameLineEdit.Text; - - EjectBatteryButton.OnPressed += _ => EjectBatteryButtonPressed?.Invoke(); - BrainButton.OnPressed += _ => BrainButtonPressed?.Invoke(); - - NameLineEdit.OnTextChanged += OnNameChanged; - NameLineEdit.OnTextEntered += OnNameEntered; - NameLineEdit.OnFocusExit += OnNameFocusExit; - - UpdateBrainButton(); } protected override void FrameUpdate(FrameEventArgs args) @@ -89,7 +86,7 @@ public void UpdateState(BorgBuiState state) private void UpdateBrainButton() { - if (_chassis?.BrainEntity is { } brain) + if (_entity.TryGetComponent(Entity, out BorgChassisComponent? chassis) && chassis.BrainEntity is { } brain) { BrainButton.Text = _entity.GetComponent(brain).EntityName; BrainView.Visible = true; @@ -108,17 +105,17 @@ private void UpdateBrainButton() private void UpdateModulePanel() { - if (_chassis == null) + if (!_entity.TryGetComponent(Entity, out BorgChassisComponent? chassis)) return; ModuleCounter.Text = Loc.GetString("borg-ui-module-counter", - ("actual", _chassis.ModuleCount), - ("max", _chassis.MaxModules)); + ("actual", chassis.ModuleCount), + ("max", chassis.MaxModules)); - if (_chassis.ModuleContainer.Count == _modules.Count) + if (chassis.ModuleContainer.Count == _modules.Count) { var isSame = true; - foreach (var module in _chassis.ModuleContainer.ContainedEntities) + foreach (var module in chassis.ModuleContainer.ContainedEntities) { if (_modules.Contains(module)) continue; @@ -132,7 +129,7 @@ private void UpdateModulePanel() ModuleContainer.Children.Clear(); _modules.Clear(); - foreach (var module in _chassis.ModuleContainer.ContainedEntities) + foreach (var module in chassis.ModuleContainer.ContainedEntities) { var control = new BorgModuleControl(module, _entity); control.RemoveButtonPressed += () => diff --git a/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs b/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs index d150735fa11..56216b91847 100644 --- a/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs +++ b/Content.Client/Silicons/Laws/Ui/SiliconLawBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.Silicons.Laws; using Content.Shared.Silicons.Laws.Components; using JetBrains.Annotations; +using Robust.Client.UserInterface; namespace Content.Client.Silicons.Laws.Ui; @@ -22,18 +23,7 @@ protected override void Open() { base.Open(); - _menu = new(); - - _menu.OnClose += Close; - _menu.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); + _menu = this.CreateWindow(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs b/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs index e8442d23908..7d6a6cf2a5a 100644 --- a/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs +++ b/Content.Client/SprayPainter/UI/SprayPainterBoundUserInterface.cs @@ -1,6 +1,6 @@ using Content.Shared.SprayPainter; using Content.Shared.SprayPainter.Components; -using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; namespace Content.Client.SprayPainter.UI; @@ -10,9 +10,6 @@ public sealed class SprayPainterBoundUserInterface : BoundUserInterface [ViewVariables] private SprayPainterWindow? _window; - [ViewVariables] - private SprayPainterSystem? _painter; - public SprayPainterBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -21,27 +18,15 @@ protected override void Open() { base.Open(); - if (!EntMan.TryGetComponent(Owner, out var comp)) - return; - - _window = new SprayPainterWindow(); + _window = this.CreateWindow(); - _painter = EntMan.System(); - - _window.OnClose += Close; _window.OnSpritePicked = OnSpritePicked; _window.OnColorPicked = OnColorPicked; - _window.Populate(_painter.Entries, comp.Index, comp.PickedColor, comp.ColorPalette); - - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _window?.Dispose(); + if (EntMan.TryGetComponent(Owner, out SprayPainterComponent? comp)) + { + _window.Populate(EntMan.System().Entries, comp.Index, comp.PickedColor, comp.ColorPalette); + } } private void OnSpritePicked(ItemList.ItemListSelectedEventArgs args) diff --git a/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs b/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs index 720a2efb9dd..e7bab71e38e 100644 --- a/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs +++ b/Content.Client/StationRecords/GeneralStationRecordConsoleBoundUserInterface.cs @@ -1,4 +1,5 @@ using Content.Shared.StationRecords; +using Robust.Client.UserInterface; namespace Content.Client.StationRecords; @@ -15,15 +16,12 @@ protected override void Open() { base.Open(); - _window = new(); + _window = this.CreateWindow(); _window.OnKeySelected += key => SendMessage(new SelectStationRecord(key)); _window.OnFiltersChanged += (type, filterValue) => SendMessage(new SetStationRecordFilter(type, filterValue)); _window.OnDeleted += id => SendMessage(new DeleteStationRecord(id)); - _window.OnClose += Close; - - _window.OpenCentered(); } protected override void UpdateState(BoundUserInterfaceState state) @@ -35,11 +33,4 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(cast); } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - - _window?.Close(); - } } diff --git a/Content.Client/Store/Ui/StoreBoundUserInterface.cs b/Content.Client/Store/Ui/StoreBoundUserInterface.cs index 0010aedd964..7ed67f7b5dd 100644 --- a/Content.Client/Store/Ui/StoreBoundUserInterface.cs +++ b/Content.Client/Store/Ui/StoreBoundUserInterface.cs @@ -2,6 +2,7 @@ using JetBrains.Annotations; using System.Linq; using Content.Shared.Store.Components; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.Store.Ui; @@ -26,13 +27,10 @@ public StoreBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) protected override void Open() { - _menu = new StoreMenu(); + _menu = this.CreateWindow(); if (EntMan.TryGetComponent(Owner, out var store)) _menu.Title = Loc.GetString(store.Name); - _menu.OpenCentered(); - _menu.OnClose += Close; - _menu.OnListingButtonPressed += (_, listing) => { SendMessage(new StoreBuyListingMessage(listing)); @@ -77,15 +75,6 @@ protected override void UpdateState(BoundUserInterfaceState state) } } - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - _menu?.Close(); - _menu?.Dispose(); - } - private void UpdateListingsWithSearchFilter() { if (_menu == null) diff --git a/Content.Client/Strip/StrippingMenu.cs b/Content.Client/Strip/StrippingMenu.cs index eea867b7948..1c46b4be35c 100644 --- a/Content.Client/Strip/StrippingMenu.cs +++ b/Content.Client/Strip/StrippingMenu.cs @@ -1,4 +1,3 @@ -using Content.Client.Inventory; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Timing; @@ -11,14 +10,12 @@ public sealed class StrippingMenu : DefaultWindow public LayoutContainer InventoryContainer = new(); public BoxContainer HandsContainer = new() { Orientation = LayoutOrientation.Horizontal }; public BoxContainer SnareContainer = new(); - private StrippableBoundUserInterface _bui; public bool Dirty = true; - public StrippingMenu(string title, StrippableBoundUserInterface bui) - { - Title = title; - _bui = bui; + public event Action? OnDirty; + public StrippingMenu() + { var box = new BoxContainer() { Orientation = LayoutOrientation.Vertical, Margin = new Thickness(0, 8) }; Contents.AddChild(box); box.AddChild(SnareContainer); @@ -39,7 +36,7 @@ protected override void FrameUpdate(FrameEventArgs args) return; Dirty = false; - _bui.UpdateMenu(); + OnDirty?.Invoke(); } } } diff --git a/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs b/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs index 9132dd6ed5f..e3646c00cc3 100644 --- a/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs +++ b/Content.Client/SurveillanceCamera/UI/SurveillanceCameraMonitorBoundUi.cs @@ -1,6 +1,7 @@ using Content.Client.Eye; using Content.Shared.SurveillanceCamera; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.SurveillanceCamera.UI; @@ -25,20 +26,12 @@ protected override void Open() { base.Open(); - _window = new SurveillanceCameraMonitorWindow(); - - if (State != null) - { - UpdateState(State); - } - - _window.OpenCentered(); + _window = this.CreateWindow(); _window.CameraSelected += OnCameraSelected; _window.SubnetOpened += OnSubnetRequest; _window.CameraRefresh += OnCameraRefresh; _window.SubnetRefresh += OnSubnetRefresh; - _window.OnClose += Close; _window.CameraSwitchTimer += OnCameraSwitchTimer; _window.CameraDisconnect += OnCameraDisconnect; } diff --git a/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs b/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs index 37384daafef..0631d98993a 100644 --- a/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs +++ b/Content.Client/Thief/ThiefBackpackBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Thief; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Thief; @@ -15,21 +16,9 @@ protected override void Open() { base.Open(); - _window = new ThiefBackpackMenu(this); - _window.OnClose += Close; - _window.OpenCentered(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - if (!disposing) - return; - - if (_window != null) - _window.OnClose -= Close; - - _window?.Dispose(); + _window = this.CreateWindow(); + _window.OnApprove += SendApprove; + _window.OnSetChange += SendChangeSelected; } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Thief/ThiefBackpackMenu.xaml.cs b/Content.Client/Thief/ThiefBackpackMenu.xaml.cs index 543772c704c..aaee3576174 100644 --- a/Content.Client/Thief/ThiefBackpackMenu.xaml.cs +++ b/Content.Client/Thief/ThiefBackpackMenu.xaml.cs @@ -12,46 +12,42 @@ public sealed partial class ThiefBackpackMenu : FancyWindow [Dependency] private readonly IEntitySystemManager _sysMan = default!; private readonly SpriteSystem _spriteSystem; - private readonly ThiefBackpackBoundUserInterface _owner; + public event Action? OnApprove; + public event Action? OnSetChange; - public ThiefBackpackMenu(ThiefBackpackBoundUserInterface owner) + public ThiefBackpackMenu() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); _spriteSystem = _sysMan.GetEntitySystem(); - _owner = owner; - - ApproveButton.OnButtonDown += (args) => + ApproveButton.OnPressed += args => { - _owner.SendApprove(); + OnApprove?.Invoke(); }; } public void UpdateState(ThiefBackpackBoundUserInterfaceState state) { - SetsGrid.RemoveAllChildren(); - int count = 0; - int selectedNumber = 0; - foreach (var set in state.Sets) + SetsGrid.DisposeAllChildren(); + var selectedNumber = 0; + foreach (var (set, info) in state.Sets) { - var child = new ThiefBackpackSet(set.Value, _spriteSystem); + var child = new ThiefBackpackSet(info, _spriteSystem); child.SetButton.OnButtonDown += (args) => { - _owner.SendChangeSelected(set.Key); + OnSetChange?.Invoke(set); }; SetsGrid.AddChild(child); - count++; - - if (set.Value.Selected) + if (info.Selected) selectedNumber++; } Description.Text = Loc.GetString("thief-backpack-window-description", ("maxCount", state.MaxSelectedSets)); SelectedSets.Text = Loc.GetString("thief-backpack-window-selected", ("selectedCount", selectedNumber), ("maxCount", state.MaxSelectedSets)); - ApproveButton.Disabled = selectedNumber == state.MaxSelectedSets ? false : true; + ApproveButton.Disabled = selectedNumber != state.MaxSelectedSets; } } diff --git a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs index 4702f8f3659..4ae74a5d65e 100644 --- a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs +++ b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankBoundUserInterface.cs @@ -1,5 +1,7 @@ using Content.Shared.Atmos.Components; using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.UserInterface.Systems.Atmos.GasTank { @@ -13,7 +15,7 @@ public GasTankBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKe { } - public void SetOutputPressure(in float value) + public void SetOutputPressure(float value) { SendMessage(new GasTankSetPressureMessage { @@ -29,9 +31,10 @@ public void ToggleInternals() protected override void Open() { base.Open(); - _window = new GasTankWindow(this, EntMan.GetComponent(Owner).EntityName); - _window.OnClose += Close; - _window.OpenCentered(); + _window = this.CreateWindow(); + _window.SetTitle(EntMan.GetComponent(Owner).EntityName); + _window.OnOutputPressure += SetOutputPressure; + _window.OnToggleInternals += ToggleInternals; } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs index c23850a6503..fd5624ad8a7 100644 --- a/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs +++ b/Content.Client/UserInterface/Systems/Atmos/GasTank/GasTankWindow.cs @@ -15,23 +15,29 @@ namespace Content.Client.UserInterface.Systems.Atmos.GasTank; public sealed class GasTankWindow : BaseWindow { + [Dependency] private readonly IResourceCache _cache = default!; + private readonly RichTextLabel _lblPressure; private readonly FloatSpinBox _spbPressure; private readonly RichTextLabel _lblInternals; private readonly Button _btnInternals; + private readonly Label _topLabel; + + public event Action? OnOutputPressure; + public event Action? OnToggleInternals; - public GasTankWindow(GasTankBoundUserInterface owner, string uidName) + public GasTankWindow() { + IoCManager.InjectDependencies(this); Control contentContainer; BoxContainer topContainer; TextureButton btnClose; - var resourceCache = IoCManager.Resolve(); var rootContainer = new LayoutContainer { Name = "GasTankRoot" }; AddChild(rootContainer); MouseFilter = MouseFilterMode.Stop; - var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); + var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); var back = new StyleBoxTexture { Texture = panelTex, @@ -78,7 +84,17 @@ public GasTankWindow(GasTankBoundUserInterface owner, string uidName) LayoutContainer.SetAnchorPreset(topContainerWrap, LayoutContainer.LayoutPreset.Wide); - var font = resourceCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); + var font = _cache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); + + _topLabel = new Label + { + FontOverride = font, + FontColorOverride = StyleNano.NanoGold, + VerticalAlignment = VAlignment.Center, + HorizontalExpand = true, + HorizontalAlignment = HAlignment.Left, + Margin = new Thickness(0, 0, 20, 0), + }; var topRow = new BoxContainer { @@ -86,16 +102,7 @@ public GasTankWindow(GasTankBoundUserInterface owner, string uidName) Margin = new Thickness(4, 2, 12, 2), Children = { - (new Label - { - Text = uidName, - FontOverride = font, - FontColorOverride = StyleNano.NanoGold, - VerticalAlignment = VAlignment.Center, - HorizontalExpand = true, - HorizontalAlignment = HAlignment.Left, - Margin = new Thickness(0, 0, 20, 0), - }), + _topLabel, (btnClose = new TextureButton { StyleClasses = {DefaultWindow.StyleClassWindowCloseButton}, @@ -168,17 +175,22 @@ public GasTankWindow(GasTankBoundUserInterface owner, string uidName) // Handlers _spbPressure.OnValueChanged += args => { - owner.SetOutputPressure(args.Value); + OnOutputPressure?.Invoke(args.Value); }; _btnInternals.OnPressed += args => { - owner.ToggleInternals(); + OnToggleInternals?.Invoke(); }; btnClose.OnPressed += _ => Close(); } + public void SetTitle(string name) + { + _topLabel.Text = name; + } + public void UpdateState(GasTankBoundUserInterfaceState state) { _lblPressure.SetMarkup(Loc.GetString("gas-tank-window-tank-pressure-text", ("tankPressure", $"{state.TankPressure:0.##}"))); diff --git a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs index 17ddba77ffc..eafab84ed63 100644 --- a/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs +++ b/Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs @@ -2,6 +2,7 @@ using Content.Shared.VendingMachines; using Robust.Client.UserInterface.Controls; using System.Linq; +using Robust.Client.UserInterface; namespace Content.Client.VendingMachines { @@ -28,15 +29,14 @@ protected override void Open() _cachedInventory = vendingMachineSys.GetAllInventory(Owner); - _menu = new VendingMachineMenu { Title = EntMan.GetComponent(Owner).EntityName }; + _menu = this.CreateWindow(); + _menu.OpenCenteredLeft(); + _menu.Title = EntMan.GetComponent(Owner).EntityName; - _menu.OnClose += Close; _menu.OnItemSelected += OnItemSelected; _menu.OnSearchChanged += OnSearchChanged; _menu.Populate(_cachedInventory, out _cachedFilteredIndex); - - _menu.OpenCenteredLeft(); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs b/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs index f700c6663b9..891804674d3 100644 --- a/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs +++ b/Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs @@ -1,12 +1,13 @@ using Content.Shared.VoiceMask; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; using Robust.Shared.Prototypes; namespace Content.Client.VoiceMask; public sealed class VoiceMaskBoundUserInterface : BoundUserInterface { - [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly IPrototypeManager _protomanager = default!; [ViewVariables] private VoiceMaskNameChangeWindow? _window; @@ -19,12 +20,11 @@ protected override void Open() { base.Open(); - _window = new(_proto); + _window = this.CreateWindow(); + _window.ReloadVerbs(_protomanager); - _window.OpenCentered(); _window.OnNameChange += OnNameSelected; _window.OnVerbChange += verb => SendMessage(new VoiceMaskChangeVerbMessage(verb)); - _window.OnClose += Close; } private void OnNameSelected(string name) diff --git a/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs b/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs index 16a28f9d9b3..0dc41f807ab 100644 --- a/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs +++ b/Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs @@ -17,7 +17,7 @@ public sealed partial class VoiceMaskNameChangeWindow : FancyWindow private string? _verb; - public VoiceMaskNameChangeWindow(IPrototypeManager proto) + public VoiceMaskNameChangeWindow() { RobustXamlLoader.Load(this); @@ -32,12 +32,10 @@ public VoiceMaskNameChangeWindow(IPrototypeManager proto) SpeechVerbSelector.SelectId(args.Id); }; - ReloadVerbs(proto); - AddVerbs(); } - private void ReloadVerbs(IPrototypeManager proto) + public void ReloadVerbs(IPrototypeManager proto) { foreach (var verb in proto.EnumeratePrototypes()) { diff --git a/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs b/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs index f3e0c0a539a..3f01808c422 100644 --- a/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs +++ b/Content.Client/Weapons/Melee/UI/MeleeSpeechBoundUserInterface.cs @@ -1,5 +1,6 @@ using Robust.Client.GameObjects; using Content.Shared.Speech.Components; +using Robust.Client.UserInterface; namespace Content.Client.Weapons.Melee.UI; @@ -19,17 +20,10 @@ protected override void Open() { base.Open(); - _window = new MeleeSpeechWindow(); - if (State != null) - UpdateState(State); - - _window.OpenCentered(); - - _window.OnClose += Close; + _window = this.CreateWindow(); _window.OnBattlecryEntered += OnBattlecryChanged; } - private void OnBattlecryChanged(string newBattlecry) { SendMessage(new MeleeSpeechBattlecryChangedMessage(newBattlecry)); diff --git a/Content.Client/Wires/UI/WiresBoundUserInterface.cs b/Content.Client/Wires/UI/WiresBoundUserInterface.cs index 5a8869a204e..edf1a2d3770 100644 --- a/Content.Client/Wires/UI/WiresBoundUserInterface.cs +++ b/Content.Client/Wires/UI/WiresBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Wires; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Wires.UI { @@ -15,10 +16,8 @@ public WiresBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) protected override void Open() { base.Open(); - - _menu = new WiresMenu(this); - _menu.OnClose += Close; - _menu.OpenCenteredLeft(); + _menu = this.CreateWindow(); + _menu.OnAction += PerformAction; } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Wires/UI/WiresMenu.cs b/Content.Client/Wires/UI/WiresMenu.cs index 7bccc208616..eccc548297c 100644 --- a/Content.Client/Wires/UI/WiresMenu.cs +++ b/Content.Client/Wires/UI/WiresMenu.cs @@ -1,4 +1,3 @@ -using System; using System.Numerics; using Content.Client.Examine; using Content.Client.Resources; @@ -12,10 +11,6 @@ using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Animations; using Robust.Shared.Input; -using Robust.Shared.IoC; -using Robust.Shared.Localization; -using Robust.Shared.Maths; -using Robust.Shared.Random; using static Robust.Client.UserInterface.Controls.BoxContainer; namespace Content.Client.Wires.UI @@ -24,8 +19,6 @@ public sealed class WiresMenu : BaseWindow { [Dependency] private readonly IResourceCache _resourceCache = default!; - public WiresBoundUserInterface Owner { get; } - private readonly Control _wiresHBox; private readonly Control _topContainer; private readonly Control _statusContainer; @@ -35,11 +28,12 @@ public sealed class WiresMenu : BaseWindow public TextureButton CloseButton { get; set; } - public WiresMenu(WiresBoundUserInterface owner) + public event Action? OnAction; + + public WiresMenu() { IoCManager.InjectDependencies(this); - Owner = owner; var rootContainer = new LayoutContainer {Name = "WireRoot"}; AddChild(rootContainer); @@ -257,12 +251,12 @@ public void Populate(WiresBoundUserInterfaceState state) control.WireClicked += () => { - Owner.PerformAction(wire.Id, wire.IsCut ? WiresAction.Mend : WiresAction.Cut); + OnAction?.Invoke(wire.Id, wire.IsCut ? WiresAction.Mend : WiresAction.Cut); }; control.ContactsClicked += () => { - Owner.PerformAction(wire.Id, WiresAction.Pulse); + OnAction?.Invoke(wire.Id, WiresAction.Pulse); }; } diff --git a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs index 2538caf6eb8..c7a74815b6b 100644 --- a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs +++ b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleBoundUserInterface.cs @@ -1,6 +1,7 @@ using Content.Shared.Xenoarchaeology.Equipment; using JetBrains.Annotations; using Robust.Client.GameObjects; +using Robust.Client.UserInterface; namespace Content.Client.Xenoarchaeology.Ui; @@ -18,10 +19,7 @@ protected override void Open() { base.Open(); - _consoleMenu = new AnalysisConsoleMenu(); - - _consoleMenu.OnClose += Close; - _consoleMenu.OpenCentered(); + _consoleMenu = this.CreateWindow(); _consoleMenu.OnServerSelectionButtonPressed += () => { From 0b5fe2a9acdc6b324dce7f45f6839f780223202e Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Sun, 21 Jul 2024 01:27:18 -0400 Subject: [PATCH 097/134] PA ui cleanup + bugfixes (#28750) * ui and visual aspect + radio * finish jank ui shit and finish radio * remove radio * send it --------- Co-authored-by: metalgearsloth --- .../ParticleAcceleratorBoundUserInterface.cs | 5 +- .../UI/ParticleAcceleratorControlMenu.cs | 526 ------------------ .../UI/ParticleAcceleratorControlMenu.xaml | 74 +++ .../UI/ParticleAcceleratorControlMenu.xaml.cs | 311 +++++++++++ .../ParticleAcceleratorEmitterComponent.cs | 7 +- .../ParticleAcceleratorSystem.ControlBox.cs | 27 +- .../ParticleAcceleratorSystem.Parts.cs | 38 +- .../ParticleAcceleratorInterfaceWireAction.cs | 5 + .../ParticleAcceleratorLimiterWireAction.cs | 7 +- .../ParticleAcceleratorStrengthWireAction.cs | 4 + .../ui/particle-accelerator-control-menu.ftl | 24 +- .../Generation/PA/control_box.rsi/unlitp0.png | Bin 526 -> 529 bytes .../Generation/PA/control_box.rsi/unlitp1.png | Bin 533 -> 533 bytes .../Generation/PA/control_box.rsi/unlitp2.png | Bin 537 -> 539 bytes .../Generation/PA/control_box.rsi/unlitp3.png | Bin 870 -> 859 bytes 15 files changed, 462 insertions(+), 566 deletions(-) delete mode 100644 Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs create mode 100644 Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml create mode 100644 Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml.cs diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs index ff1eae36f55..93306f2fd1f 100644 --- a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs +++ b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs @@ -1,5 +1,4 @@ using Content.Shared.Singularity.Components; -using Robust.Client.GameObjects; using Robust.Client.UserInterface; namespace Content.Client.ParticleAccelerator.UI @@ -18,9 +17,11 @@ protected override void Open() base.Open(); _menu = this.CreateWindow(); + _menu.SetEntity(Owner); + _menu.OnOverallState += SendEnableMessage; _menu.OnPowerState += SendPowerStateMessage; - _menu.OnScanPartsRequested += SendScanPartsMessage; + _menu.OnScan += SendScanPartsMessage; } public void SendEnableMessage(bool enable) diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs deleted file mode 100644 index 05a296edf39..00000000000 --- a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs +++ /dev/null @@ -1,526 +0,0 @@ -using System.Numerics; -using Content.Client.Resources; -using Content.Client.Stylesheets; -using Content.Client.UserInterface.Controls; -using Content.Shared.Singularity.Components; -using Robust.Client.Animations; -using Robust.Client.Graphics; -using Robust.Client.ResourceManagement; -using Robust.Client.UserInterface; -using Robust.Client.UserInterface.Controls; -using Robust.Client.UserInterface.CustomControls; -using Robust.Shared.Noise; -using Robust.Shared.Prototypes; -using Robust.Shared.Timing; -using static Robust.Client.UserInterface.Controls.BoxContainer; - -namespace Content.Client.ParticleAccelerator.UI -{ - public sealed class ParticleAcceleratorControlMenu : BaseWindow - { - [Dependency] private readonly IPrototypeManager _protoManager = default!; - [Dependency] private readonly IResourceCache _cache = default!; - - private readonly ShaderInstance _greyScaleShader; - - private readonly Label _drawLabel; - private readonly FastNoiseLite _drawNoiseGenerator; - private readonly Button _onButton; - private readonly Button _offButton; - private readonly Button _scanButton; - private readonly Label _statusLabel; - private readonly SpinBox _stateSpinBox; - - private readonly BoxContainer _alarmControl; - private readonly Animation _alarmControlAnimation; - - private readonly PASegmentControl _endCapTexture; - private readonly PASegmentControl _fuelChamberTexture; - private readonly PASegmentControl _controlBoxTexture; - private readonly PASegmentControl _powerBoxTexture; - private readonly PASegmentControl _emitterForeTexture; - private readonly PASegmentControl _emitterPortTexture; - private readonly PASegmentControl _emitterStarboardTexture; - - private float _time; - private int _lastDraw; - private int _lastReceive; - - private bool _blockSpinBox; - private bool _assembled; - private bool _shouldContinueAnimating; - private int _maxStrength = 3; - - public event Action? OnOverallState; - public event Action? OnPowerState; - public event Action? OnScanPartsRequested; - - public ParticleAcceleratorControlMenu() - { - IoCManager.InjectDependencies(this); - SetSize = new Vector2(400, 320); - _greyScaleShader = _protoManager.Index("Greyscale").Instance(); - - _drawNoiseGenerator = new(); - _drawNoiseGenerator.SetFractalType(FastNoiseLite.FractalType.FBm); - _drawNoiseGenerator.SetFrequency(0.5f); - - var font = _cache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); - var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); - - MouseFilter = MouseFilterMode.Stop; - - _alarmControlAnimation = new Animation - { - Length = TimeSpan.FromSeconds(1), - AnimationTracks = - { - new AnimationTrackControlProperty - { - Property = nameof(Control.Visible), - KeyFrames = - { - new AnimationTrackProperty.KeyFrame(true, 0), - new AnimationTrackProperty.KeyFrame(false, 0.75f), - } - } - } - }; - - var back = new StyleBoxTexture - { - Texture = panelTex, - Modulate = Color.FromHex("#25252A"), - }; - back.SetPatchMargin(StyleBox.Margin.All, 10); - - var back2 = new StyleBoxTexture(back) - { - Modulate = Color.FromHex("#202023") - }; - - AddChild(new PanelContainer - { - PanelOverride = back, - MouseFilter = MouseFilterMode.Pass - }); - - _stateSpinBox = new SpinBox { Value = 0, IsValid = StrengthSpinBoxValid }; - _stateSpinBox.InitDefaultButtons(); - _stateSpinBox.ValueChanged += PowerStateChanged; - _stateSpinBox.LineEditDisabled = true; - - _offButton = new Button - { - ToggleMode = false, - Text = Loc.GetString("particle-accelerator-control-menu-off-button"), - StyleClasses = { StyleBase.ButtonOpenRight }, - }; - - _offButton.OnPressed += args => OnOverallState?.Invoke(false); - - _onButton = new Button - { - ToggleMode = false, - Text = Loc.GetString("particle-accelerator-control-menu-on-button"), - StyleClasses = { StyleBase.ButtonOpenLeft }, - }; - _onButton.OnPressed += args => OnOverallState?.Invoke(true); - - var closeButton = new TextureButton - { - StyleClasses = { "windowCloseButton" }, - HorizontalAlignment = HAlignment.Right, - Margin = new Thickness(0, 0, 8, 0) - }; - closeButton.OnPressed += args => Close(); - - var serviceManual = new Label - { - HorizontalAlignment = HAlignment.Center, - StyleClasses = { StyleBase.StyleClassLabelSubText }, - Text = Loc.GetString("particle-accelerator-control-menu-service-manual-reference") - }; - _drawLabel = new Label(); - var imgSize = new Vector2(32, 32); - AddChild(new BoxContainer - { - Orientation = LayoutOrientation.Vertical, - Children = - { - new Control - { - Margin = new Thickness(2, 2, 0, 0), - Children = - { - new Label - { - Text = Loc.GetString("particle-accelerator-control-menu-device-version-label"), - FontOverride = font, - FontColorOverride = StyleNano.NanoGold, - }, - closeButton - } - }, - new PanelContainer - { - PanelOverride = new StyleBoxFlat {BackgroundColor = StyleNano.NanoGold}, - MinSize = new Vector2(0, 2), - }, - new Control - { - MinSize = new Vector2(0, 4) - }, - - new BoxContainer - { - Orientation = LayoutOrientation.Horizontal, - VerticalExpand = true, - Children = - { - new BoxContainer - { - Orientation = LayoutOrientation.Vertical, - Margin = new Thickness(4, 0, 0, 0), - HorizontalExpand = true, - Children = - { - new BoxContainer - { - Orientation = LayoutOrientation.Horizontal, - Children = - { - new Label - { - Text = Loc.GetString("particle-accelerator-control-menu-power-label") + " ", - HorizontalExpand = true, - HorizontalAlignment = HAlignment.Left, - }, - _offButton, - _onButton - } - }, - new BoxContainer - { - Orientation = LayoutOrientation.Horizontal, - Children = - { - new Label - { - Text = Loc.GetString("particle-accelerator-control-menu-strength-label") + " ", - HorizontalExpand = true, - HorizontalAlignment = HAlignment.Left, - }, - _stateSpinBox - } - }, - new Control - { - MinSize = new Vector2(0, 10), - }, - _drawLabel, - new Control - { - VerticalExpand = true, - }, - (_alarmControl = new BoxContainer - { - Orientation = LayoutOrientation.Vertical, - Children = - { - new Label - { - Text = Loc.GetString("particle-accelerator-control-menu-alarm-control"), - FontColorOverride = Color.Red, - Align = Label.AlignMode.Center - }, - serviceManual - }, - Visible = false, - }), - } - }, - new BoxContainer - { - Orientation = LayoutOrientation.Vertical, - MinSize = new Vector2(186, 0), - Children = - { - (_statusLabel = new Label - { - HorizontalAlignment = HAlignment.Center - }), - new Control - { - MinSize = new Vector2(0, 20) - }, - new PanelContainer - { - HorizontalAlignment = HAlignment.Center, - PanelOverride = back2, - Children = - { - new GridContainer - { - Columns = 3, - VSeparationOverride = 0, - HSeparationOverride = 0, - Children = - { - new Control {MinSize = imgSize}, - (_endCapTexture = Segment("end_cap")), - new Control {MinSize = imgSize}, - (_controlBoxTexture = Segment("control_box")), - (_fuelChamberTexture = Segment("fuel_chamber")), - new Control {MinSize = imgSize}, - new Control {MinSize = imgSize}, - (_powerBoxTexture = Segment("power_box")), - new Control {MinSize = imgSize}, - (_emitterStarboardTexture = Segment("emitter_starboard")), - (_emitterForeTexture = Segment("emitter_fore")), - (_emitterPortTexture = Segment("emitter_port")), - } - } - } - }, - (_scanButton = new Button - { - Text = Loc.GetString("particle-accelerator-control-menu-scan-parts-button"), - HorizontalAlignment = HAlignment.Center - }) - } - } - } - }, - new StripeBack - { - Children = - { - new Label - { - Margin = new Thickness(4, 4, 0, 4), - Text = Loc.GetString("particle-accelerator-control-menu-check-containment-field-warning"), - HorizontalAlignment = HAlignment.Center, - StyleClasses = {StyleBase.StyleClassLabelSubText}, - } - } - }, - new BoxContainer - { - Orientation = LayoutOrientation.Horizontal, - Margin = new Thickness(12, 0, 0, 0), - Children = - { - new Label - { - Text = Loc.GetString("particle-accelerator-control-menu-foo-bar-baz"), - StyleClasses = {StyleBase.StyleClassLabelSubText} - } - } - }, - } - }); - - _scanButton.OnPressed += args => OnScanPartsRequested?.Invoke(); - - _alarmControl.AnimationCompleted += s => - { - if (_shouldContinueAnimating) - { - _alarmControl.PlayAnimation(_alarmControlAnimation, "warningAnim"); - } - else - { - _alarmControl.Visible = false; - } - }; - - PASegmentControl Segment(string name) - { - return new(this, _cache, name); - } - - UpdateUI(false, false, false, false); - } - - private bool StrengthSpinBoxValid(int n) - { - return n >= 0 && n <= _maxStrength && !_blockSpinBox; - } - - private void PowerStateChanged(ValueChangedEventArgs e) - { - ParticleAcceleratorPowerState newState; - switch (e.Value) - { - case 0: - newState = ParticleAcceleratorPowerState.Standby; - break; - case 1: - newState = ParticleAcceleratorPowerState.Level0; - break; - case 2: - newState = ParticleAcceleratorPowerState.Level1; - break; - case 3: - newState = ParticleAcceleratorPowerState.Level2; - break; - case 4: - newState = ParticleAcceleratorPowerState.Level3; - break; - default: - return; - } - - _stateSpinBox.SetButtonDisabled(true); - OnPowerState?.Invoke(newState); - } - - protected override DragMode GetDragModeFor(Vector2 relativeMousePos) - { - return DragMode.Move; - } - - public void DataUpdate(ParticleAcceleratorUIState uiState) - { - _assembled = uiState.Assembled; - UpdateUI(uiState.Assembled, uiState.InterfaceBlock, uiState.Enabled, - uiState.WirePowerBlock); - _statusLabel.Text = Loc.GetString("particle-accelerator-control-menu-status-label", - ("status", Loc.GetString(uiState.Assembled ? "particle-accelerator-control-menu-status-operational" : - "particle-accelerator-control-menu-status-incomplete"))); - UpdatePowerState(uiState.State, uiState.Enabled, uiState.Assembled, - uiState.MaxLevel); - UpdatePreview(uiState); - _lastDraw = uiState.PowerDraw; - _lastReceive = uiState.PowerReceive; - } - - private void UpdatePowerState(ParticleAcceleratorPowerState state, bool enabled, bool assembled, - ParticleAcceleratorPowerState maxState) - { - _stateSpinBox.OverrideValue(state switch - { - ParticleAcceleratorPowerState.Standby => 0, - ParticleAcceleratorPowerState.Level0 => 1, - ParticleAcceleratorPowerState.Level1 => 2, - ParticleAcceleratorPowerState.Level2 => 3, - ParticleAcceleratorPowerState.Level3 => 4, - _ => 0 - }); - - - _maxStrength = maxState == ParticleAcceleratorPowerState.Level3 ? 4 : 3; - if (_maxStrength > 3 && enabled && assembled) - { - _shouldContinueAnimating = true; - if (!_alarmControl.HasRunningAnimation("warningAnim")) - _alarmControl.PlayAnimation(_alarmControlAnimation, "warningAnim"); - } - else - _shouldContinueAnimating = false; - } - - private void UpdateUI(bool assembled, bool blocked, bool enabled, bool powerBlock) - { - _onButton.Pressed = enabled; - _offButton.Pressed = !enabled; - - var cantUse = !assembled || blocked || powerBlock; - _onButton.Disabled = cantUse; - _offButton.Disabled = cantUse; - _scanButton.Disabled = blocked; - - var cantChangeLevel = !assembled || blocked; - _stateSpinBox.SetButtonDisabled(cantChangeLevel); - _blockSpinBox = cantChangeLevel; - } - - private void UpdatePreview(ParticleAcceleratorUIState updateMessage) - { - _endCapTexture.SetPowerState(updateMessage, updateMessage.EndCapExists); - _controlBoxTexture.SetPowerState(updateMessage, true); - _fuelChamberTexture.SetPowerState(updateMessage, updateMessage.FuelChamberExists); - _powerBoxTexture.SetPowerState(updateMessage, updateMessage.PowerBoxExists); - _emitterStarboardTexture.SetPowerState(updateMessage, updateMessage.EmitterStarboardExists); - _emitterForeTexture.SetPowerState(updateMessage, updateMessage.EmitterForeExists); - _emitterPortTexture.SetPowerState(updateMessage, updateMessage.EmitterPortExists); - } - - protected override void FrameUpdate(FrameEventArgs args) - { - base.FrameUpdate(args); - - if (!_assembled) - { - _drawLabel.Text = Loc.GetString("particle-accelerator-control-menu-draw-not-available"); - return; - } - - _time += args.DeltaSeconds; - - var watts = 0; - if (_lastDraw != 0) - { - var val = _drawNoiseGenerator.GetNoise(_time, 0f); - watts = (int) (_lastDraw + val * 5); - } - - _drawLabel.Text = Loc.GetString("particle-accelerator-control-menu-draw", - ("watts", $"{watts:##,##0}"), - ("lastReceive", $"{_lastReceive:##,##0}")); - } - - private sealed class PASegmentControl : Control - { - private readonly ParticleAcceleratorControlMenu _menu; - private readonly string _baseState; - private readonly TextureRect _base; - private readonly TextureRect _unlit; - private readonly RSI _rsi; - - public PASegmentControl(ParticleAcceleratorControlMenu menu, IResourceCache cache, string name) - { - _menu = menu; - _baseState = name; - _rsi = cache.GetResource($"/Textures/Structures/Power/Generation/PA/{name}.rsi").RSI; - - AddChild(_base = new TextureRect { Texture = _rsi[$"completed"].Frame0 }); - AddChild(_unlit = new TextureRect()); - MinSize = _rsi.Size; - } - - public void SetPowerState(ParticleAcceleratorUIState state, bool exists) - { - _base.ShaderOverride = exists ? null : _menu._greyScaleShader; - _base.ModulateSelfOverride = exists ? null : new Color(127, 127, 127); - - if (!state.Enabled || !exists) - { - _unlit.Visible = false; - return; - } - - _unlit.Visible = true; - - var suffix = state.State switch - { - ParticleAcceleratorPowerState.Standby => "_unlitp", - ParticleAcceleratorPowerState.Level0 => "_unlitp0", - ParticleAcceleratorPowerState.Level1 => "_unlitp1", - ParticleAcceleratorPowerState.Level2 => "_unlitp2", - ParticleAcceleratorPowerState.Level3 => "_unlitp3", - _ => "" - }; - - if (!_rsi.TryGetState(_baseState + suffix, out var rState)) - { - _unlit.Visible = false; - return; - } - - _unlit.Texture = rState.Frame0; - } - } - } -} diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml new file mode 100644 index 00000000000..63f15837068 --- /dev/null +++ b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml @@ -0,0 +1,74 @@ + + + + + + + + + + + +